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
RCU (Read-Copy Update) 是一種資料同步機制,在 Linux 核心扮演重要作用。RCU 適用於頻繁的讀取 (即多個 reader)、但資料寫入 (即少量的 updater/writer) 卻不頻繁的情境,例如檔案系統,經常需要搜尋特定目錄,但對目錄的修改卻相對少,這就是 RCU 理想應用場景。
May 1, 2025Welcome message and DL Server - Daniel Bristot de Oliveira
Apr 30, 2025本文回顧微處理器的 atomic 指令及軟硬體設計考量、memory ordering 及 memory barrier、C11 標準的 <stdatomic.h> 及 Linux 核心介面,和探討經典 lock-free 資料結構和演算法案例。
Apr 26, 2025無論是作業系統核心、C 語言函式庫內部、程式開發框架,到應用程式,都不難見到 linked list 的身影,包含多種針對效能和安全議題所做的 linked list 變形,又還要考慮到應用程式的泛用性 (generic programming),是很好的進階題材。
Apr 25, 2025or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up