为了在运行时动态增加和删除某个功能,Linux内核引入了内核模块这一机制,可在内核运行时加载一组目标代码来实现某个特定的功能,这样在实际使用Linux的过程中就不需要重新编译内核代码来实现动态扩展。
为了深入Linux内核的学习,我们从编写一个简单的Linux内核模块开始。
创建一个名为helloworld.c的文件,内容如下:
- #include <linux/init.h>
- #include <linux/module.h>
-
- static int __init hello_init(void)
- {
- printk(KERN_INFO "hello world enter\n");
- return 0;
- }
-
- module_init(hello_init);
-
- static void __exit hello_exit(void)
- {
- printk(KERN_INFO "hello world exit\n");
- }
-
- module_exit(hello_exit);
-
- MODULE_AUTHOR("fukaiqiang");//作者
- MODULE_LICENSE("GPL v2");//模块许可证声明,一般用GPL v2
- MODULE_DESCRIPTION("A simple hello world module");//模块描述
- MODULE_ALIAS("hw"); //别名
Makefile
- KVERS = $(shell uname -r)
-
- obj-m := helloworld.o
-
- all:
- make -C /lib/modules/$(KVERS)/build M=$(PWD) modules
-
- clean:
- make -C /lib/modules/$(KVERS)/build M=$(PWD) clean
- rm -rf *.ko;
- $make
- make -C /lib/modules/4.15.0-142-generic/build M=/media/fukaiqiang/Disk960/Codes/kernel/hello_world
- make[1]: Entering directory '/usr/src/linux-headers-4.15.0-142-generic'
- CC [M] /media/fukaiqiang/Disk960/Codes/kernel/hello_world/helloworld.o
- Building modules, stage 2.
- MODPOST 1 modules
- CC /media/fukaiqiang/Disk960/Codes/kernel/hello_world/helloworld.mod.o
- LD [M] /media/fukaiqiang/Disk960/Codes/kernel/hello_world/helloworld.ko
- make[1]: Leaving directory '/usr/src/linux-headers-4.15.0-142-generic'
- uname -r 用于获取内核的版本
- obj-m 表示要生成的模块,其值组成为 <模块名>.o
- -C 这是make的递归调用,用在这里指进入/usr/src/linux-headers-4.15.0-142-generic,并递归这个目录下所有的Makefile进行make.
- M 并非是make的参数,而是内核编译的选项,所以M的值是/media/fukaiqiang/Disk960/Codes/kernel/hello_world
- make过程: 进入/usr/src/linux-headers-4.15.0-142-generic,通过hello_world.c生成hello_world.o,通过helloworld.mod.c生成helloworld.mod.o(不熟悉这个环节).链接hello_world.o和helloworld.mod.o生成helloworld.ko.离开/usr/src/linux-headers-4.15.0-142-generic.
-
- 作者:付凯强
- 链接:https://www.jianshu.com/p/d6c7314cdce7
- 来源:简书
- 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- $file helloworld.ko
- helloworld.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), BuildID[sha1]=225d75bec2feeab394d6567f8104a13874623dd1, not stripped
当看到 x86-64 的 ELF 文件,就证明编译成功了.
- $modinfo helloworld.ko
- filename: /media/fukaiqiang/Disk960/Codes/kernel/hello_world/helloworld.ko
- alias: hw
- description: A simple hello world module
- license: GPL v2
- author: fukaiqiang
- srcversion: 897BBFF3273E374126017CE
- depends:
- retpoline: Y
- name: helloworld
- vermagic: 4.15.0-142-generic SMP mod_unload
sudo insmod helloworld.ko
- lsmod | grep helloworld
- helloworld 16384 0
- dmesg
- [421558.748577] hello World enter
- { fukaiqiang@superman /sys/module/helloworld }
- $tree -a
- .
- ├── coresize
- ├── holders
- ├── initsize
- ├── initstate
- ├── notes
- │ └── .note.gnu.build-id
- ├── refcnt
- ├── sections
- │ ├── .exit.text
- │ ├── .gnu.linkonce.this_module
- │ ├── .init.text
- │ ├── __mcount_loc
- │ ├── .note.gnu.build-id
- │ ├── .rodata.str1.1
- │ ├── .strtab
- │ └── .symtab
- ├── srcversion
- ├── taint
- └── uevent
-
- 3 directories, 16 files