Linux提供了这样一个机制,模块本身不编译在内核中,从而减小了内核的大小,模块可以被加载,与内核配合使用。
1. 编写测试用例
#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "Hello World Enter\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Hello World Exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("Love Linux");
MODULE_DESCRIPTION("A simple Hello World Module");
MODULE_ALIAS("A simple module");
2. 编写Makefile
obj-m := HelloDriver.o
all:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
3. 编译程序
love@ubuntu:~/workspace/Driver$ make
make -C /lib/modules/4.18.0-25-generic/build M=/home/love/workspace/Driver modules
make[1]: Entering directory '/usr/src/linux-headers-4.18.0-25-generic'
Makefile:970: "Cannot use CONFIG_STACK_VALIDATION=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel"
CC [M] /home/love/workspace/Driver/HelloDriver.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/love/workspace/Driver/HelloDriver.mod.o
LD [M] /home/love/workspace/Driver/HelloDriver.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.18.0-25-generic'
love@ubuntu:~/workspace/Driver$ ls
HelloDriver.c HelloDriver.mod.c HelloDriver.o modules.order
HelloDriver.ko HelloDriver.mod.o Makefile Module.symvers
4. 加载驱动
love@ubuntu:~/workspace/Driver$ insmod HelloDriver.ko
insmod: ERROR: could not insert module HelloDriver.ko: Operation not permitted
love@ubuntu:~/workspace/Driver$ sudo insmod HelloDriver.ko
[sudo] password for love:
love@ubuntu:~/workspace/Driver$ sudo lsmod
Module Size Used by
HelloDriver 16384 0
rfcomm 77824 4
vmw_vsock_vmci_transport 28672 2
5. 查看模块详细信息
love@ubuntu:~/workspace/Driver$ cat /proc/modules
HelloDriver 16384 0 - Live 0x0000000000000000 (OE)
rfcomm 77824 4 - Live 0x0000000000000000
vmw_vsock_vmci_transport 28672 2 - Live 0x0000000000000000
vsock 36864 3 vmw_vsock_vmci_transport, Live 0x0000000000000000
bnep 20480 2 - Live 0x0000000000000000
snd_ens1371 28672 6 - Live 0x0000000000000000
6. 查看内核中驱动模块的详细信息,已经加载成功后会自动生成
love@ubuntu:/sys/module/HelloDriver$ ls
coresize initsize notes sections taint
holders initstate refcnt srcversion uevent
love@ubuntu:/sys/module/HelloDriver$ tree -a
.
├── coresize
├── holders
├── initsize
├── initstate
├── notes
│ └── .note.gnu.build-id
├── refcnt
├── sections
│ ├── .gnu.linkonce.this_module
│ ├── __mcount_loc
│ ├── .note.gnu.build-id
│ ├── .rodata.str1.1
│ ├── .strtab
│ ├── .symtab
│ └── .text
├── srcversion
├── taint
└── uevent
3 directories, 15 files
7. 卸载驱动模块
love@ubuntu:~/workspace/Driver$ sudo rmmod HelloDriver
love@ubuntu:~/workspace/Driver$ ls
HelloDriver.c HelloDriver.mod.c HelloDriver.o modules.order
HelloDriver.ko HelloDriver.mod.o Makefile Module.symvers
8. 查看内核日志
9. 查看模块信息
love@ubuntu:~/workspace/Driver$ modinfo HelloDriver.ko
filename: /home/love/workspace/Driver/HelloDriver.ko
alias: A simple module
description: A simple Hello World Module
author: Love Linux
license: Dual BSD/GPL
srcversion: 8C40CCF84D6BF19DA74800F
depends:
retpoline: Y
name: HelloDriver
vermagic: 4.18.0-25-generic SMP mod_unload
love@ubuntu:~/workspace/Driver$