从零写OS(四十八):内核模块 —— insmod/rmmod
动态链接实现之后,内核能加载 PIE 可执行文件了。这章把同样的 ELF 重定位思路用到内核自身:实现内核模块,让内核在运行时动态加载/卸载功能。 验证: / # insmod hello.ko hello from module! / # rmmod hello bye from module! .ko 文件是什么 .ko 是一种特殊的 ELF 文件,类型是 ET_REL(可重定位目标文件)——也就是还没有链接的 .o 文件。 和普通可执行文件的区别: 普通 ELF 内核模块(.ko) 已链接,地址固定 未链接,需要重定位 用户态运行 内核态运行 main() 入口 module_init / module_exit 依赖 libc 依赖内核导出符号 内核符号表(ksyms) 模块代码需要调用内核函数(比如 kprintf)。内核把对外开放的函数注册到一张符号表里: static ksym_t ksyms[] = { { "kprintf", (uint64_t)kprintf }, { "kmalloc", (uint64_t)kmalloc }, { "kfree", (uint64_t)kfree }, { NULL, 0 } }; uint64_t ksym_lookup(const char *name) { for (int i = 0; ksyms[i].name; i++) if (strcmp(ksyms[i].name, name) == 0) return ksyms[i].addr; return 0; } 加载流程 insmod 的工作分四步: ...