linux2020
目的: 檢驗學員對 Linux 記憶體管理的認知
1
以下 Linux 核心模組程式碼嘗試模仿 Android Logging System,提供一個特製的裝置驅動程式,允許 userspace 透過 VFS 寫入日誌和紀錄追蹤。已知可在 Linux v4.15 運作。
Makefile
ccflags-y += -std=gnu99
obj-m := log.o
KERNELDIR ?= /lib/modules/`uname -r`/build
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) module
log.c
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/slab.h>
#define LOG_LINE_BUF_SIZE 256
#define LOG_BUF_OUTPUT_BUF_SIZE (LOG_LINE_BUF_SIZE * 4 * 4 * 32)
struct mylog {
void *buff;
ssize_t buf_write_size;
};
static struct mylog *mylog = NULL;
static int mylog_open(struct inode *inode, struct file *file) {
file->private_data = mylog;
printk("client: %s (%d)\n", current->comm, current->pid);
return 0;
}
static int mylog_release(struct inode *inode, struct file *file) {
struct mylog *mylog = file->private_data;
ClearPageReserved(virt_to_page(mylog->buff));
kfree(mylog->buff);
kfree(mylog);
return 0;
}
static int mylog_mmap(struct file *file, struct vm_area_struct *vma) {
struct mylog *mylog = AAA;
unsigned long pfn_start =
(virt_to_phys(mylog->buff) >> BBB) + CCC;
unsigned long size = vma->vm_end - vma->vm_start;
return remap_pfn_range(vma, vma->vm_start, pfn_start, size,
vma->vm_page_prot);
}
static const struct file_operations mylog_fops = {
.owner = THIS_MODULE,
.open = mylog_open,
.release = mylog_release,
.mmap = mylog_mmap,
};
static struct miscdevice mylog_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = "mylog",
.fops = &mylog_fops,
};
static int __init mylog_init(void) {
int ret = 0;
mylog = kzalloc(sizeof(struct mylog), GFP_KERNEL);
if (!mylog) {
ret = -ENOMEM;
goto err_mylog;
}
mylog->buff = kzalloc(LOG_BUF_OUTPUT_BUF_SIZE, GFP_KERNEL);
if (!mylog->buff) {
ret = -ENOMEM;
goto err_buff;
}
SetPageReserved(virt_to_page(mylog->buff));
ret = misc_register(&mylog_misc);
if (unlikely(ret)) {
pr_err("failed to register misc device!\n");
goto err_register;
}
return 0;
err_register:
kfree(mylog->buff);
err_buff:
kfree(mylog);
err_mylog:
return ret;
}
static void __exit mylog_exit(void) {
misc_deregister(&mylog_misc);
}
module_init(mylog_init);
module_exit(mylog_exit);
MODULE_LICENSE("GPL");
參考資訊:
請補完程式碼。
作答區
AAA = ?
(a)
NULL(b)
file->f_security
(c)
file->f_mapping
(d)
file->private_data
BBB = ?
(a)
PAGE_SHIFT
(b)
1(c)
2(d)
PAGE_SIZE
CCC = ?
(a)
1(b)
vma->vm_start
(c)
vma->vm_end
(d)
vma->vm_raend
(e)
vma->m_private_data
(f)
vma->vm_pgoff
延伸問題:
前一章所研讀的 patches 最終並未正式合併到 kernel 中。維護者 Peter Zijlstra 針對此做了修正與調整,重新釋出了進階的改動 [RFC][PATCH 00/10] sched/fair: Complete EEVDF。在此系列內容中,除了原本對 time slice/request size 的支援,Peter 還新增 delayed-dequeue 機制以彌補原始論文在 EEVDF 上的缺陷。這些改動將成為補足 EEVDF 的最後一塊拼圖。而本節將針對這一系列內容進行探討。
Sep 6, 2025無論是作業系統核心、C 語言函式庫內部、程式開發框架,到應用程式,都不難見到 linked list 的身影,包含多種針對效能和安全議題所做的 linked list 變形,又還要考慮到應用程式的泛用性 (generic programming),是很好的進階題材。
Sep 4, 2025資料整理: jserv
Aug 31, 2025本講座帶著學員重新探索函式呼叫背後的原理,從程式語言和計算機結構的發展簡史談起,讓學員自電腦軟硬體演化過程去掌握 calling convention 的考量,伴隨著 stack 和 heap 的操作,再探討 C 程式如何處理函式呼叫、跨越函式間的跳躍 (如 setjmp 和 longjmp),再來思索資訊安全和執行效率的議題。
Aug 28, 2025or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up