本节用到的命令
命令 | 用途 |
---|---|
lsmod | 列出内核中当前被加载的模块 |
ls | list按指定需求列出文件列表 |
ll | “ls -a -l” 的别名 |
cat | 内建阅读器,像notepad |
modinfo | 获取核心Module信息 |
readelf | 一款工具用来展示elf文件内部的信息 |
分层
内核状态
内核空间里的部件
设备驱动程序
Linux中Moudle特指可加载内核模块
LKM
DIY一个刘姥姥程序带领我们进入内核大门
//main.c
/*定义了内核模块编写最基本宏和结构体,位于linux-[version]/include/linux/module.h*/
#include <linux/module.h>
//__init GCC工具链,初始化
static int __init llaolao_init(void)
{
int n = 0x1937;
printk(KERN_INFO "Hi,I am llaolao at address 0x%p stack 0x%p.\n",
llaolao_init,&n);
return 0;
}
static void __exit llaolao_exit(void)
{
printk("Exiting from 0x%p.....Bye,优快云 Friends\n",llaolao_exit);
}
//回调函数,被动调用
module_init(llaolao_init);
module_exit(llaolao_exit);
MODULE_AUTHOR("YY");
MODULE_DESCRIPTIONJ("LKM example - llaolao");
MODULE_LICENSE("GPL");/*非许可协议,不能调用其他模块代码,不能调用很多内核函数,强行call会失败*/
谈Moudle.h
Moudle.h很早的时候就存在了。
第一代作者是:Richard Hendersion
第二代作者是:Rusty Russell
由于前代linux暴露出来的缺陷XXX,开始重写。netfilter/iptables主要贡献者。
此外module.h还包含一个重要结构:
该结构是内核模块的“户籍档案”
颇为庞大的结构体
以链表形式相互关联,模块列表
只是LKM,不包括内核本身
Linux命令:
lsmod
列出当前加载的module.
module数量和系统复杂度,架构复杂度,以及硬件数量密切相关。
<linux/init.h>
#define module_init(......)......
#define module_exit(......)......
上面两个宏在实际代码中利用了attribute机制取到函数地址.
链接
Makefile文件相当于执行
$ make -C /lib/modules/x.y.z/build SUBDIRS=<> modules
ll和ls的区别
ll可以列出查看”.”开头的隐藏文件或文件夹
x.ko文件:可加载的LKM文件
x.o文件:编译.c产生的object文件
x.mod.c GCC工具链根据module.h中所定义宏内的编译指令动态生成。
加载模块时用以校验依赖的内核函数,
__moduversions section。
对被调用函数进行CRC检查来倡导源码开源,如果不是在本版本的Linux编译的很可能拒绝。检查代码在:kernel/module.c check_version(……)
查看.ko
$ modinfo *.ko
ELF是Linux基础格式,.ko其实是ELF格式的文件,具体格式请参照《Executable and Linking Format (ELF) Specification 1.2》
$readelf - h llaolao.ko
下表来自《Executable and Linking Format (ELF)》Optional部分与我经历实际情况不符,需要深究!
链接后 | 内存中 |
---|---|
ELF Header | ELF Header |
Program Header Table(Optional) | Program Header Table |
Section 0 | Setion 0 |
Section 1 | Section 1 |
Section … | Section … |
Section X | Section X |
Section Header Table | Section Header Table (Optional) |
内核态与用户态
天行健,君子自强不息
地势坤,君子厚德载物
分层
……
NTOSKRNL.EXE
HAL.DLL
Hardware
学习笔记整理自张银奎先生的讲座“Linux内核开发与调试”。
2016年9月20日