linux内核模块基本框架练习

linux内核模块基本框架练习

my_test.c代码段

 1 /*                                                                                                                                                                                                               
 2  *包含两个头文件:
 3  *<linux/init.h>对应的是内核源代码的include/linux/init.h文件,包含了module_init()和module_exit()函数声明。
 4  *<linux/module.h>对应的是内核源码的include/linux/module.h文件,包含了MODULE_XXX等函数的声明。
 5  */
 6  
 7 #include <linux/init.h>
 8 #include <linux/module.h>
 9  
 10 /*
 11  *内核模块初始化函数。
 12  *这个函数在内核模块被加载时运行,可以使用insmod命令加载一个内核模块。
 13  */
 14 static int __init my_test_init(void)
 15 {
 16     printk("my first kernel module init\n");
 17     return 0;
 18 }
 19  
 20 /*
 21  *内核模块退出函数。
 22  *可以使用rmmod命令卸载一个内核模块。
 23  */
 24 static void __exit my_test_exit(void)
 25 {
 26     printk("goodbye\n");
 27 }
 28  
 29 /*
 30  *module_init()告诉内核这是该模块的入口。内核在各个模块初始化时有一个优先级顺序。
 31  *对于驱动模块来说,它的优先级不是特别高,而且内核把所有的模块的初始化函数都存放在一个特殊的段中来管理。
 32  */
 33 module_init(my_test_init);
 34 module_exit(my_test_exit);
 35  
 36 /*
 37  *MODULE_LICENSE()表示这个模块接受的软件许可协议。
 38  *MODULE_AUTHOR()用来描述该模块的作者信息,可以包括作者的姓名和邮箱等。
 39  *MODULE_DESCRIPTION()用来简单的描述该模块的用途或者功能介绍。
 40  *MODULE_ALIAS()为用户空间提供一个合适的别名。
 41  */
 42 MODULE_LICENSE("GPL");
 43 MODULE_AUTHOR("sjx");
 44 MODULE_DESCRIPTION("my test kernel module");
 45 MODULE_ALIAS("mytest");

Makefile文件

  1 # BASHINCLUDE指向正在运行Linux的内核变异目录。                                                                                                                                                                   
  2 # 一般来说,Linux系统的内核模块都会安装到/lib/modules这个目录下,通过`uname -r`命令可以找到对应的内核版本。
  3  
  4 BASHINCLUDE ?= /lib/modules/`uname -r`/build
  5  
  6 # 表示该内核模块需要哪些目标文件,格式是:
  7 # <模块名>-objs := <目标文件名>.o
  8 mytest-objs := my_test.o
  9  
 10 # 表示要生成的模块。注意:该模块的名字不能和目标文件的名字相同。
 11 # 格式是:obj-m :=<模块名>.o
 12 obj-m := mytest.o
 13  
 14 # 表示要编译执行的动作。
 15 all :
 16     make -C $(BASHINCLUDE) M=$(CURDIR) modules;
 17  
 18 # 表示执行make clean需要的动作。
 19 clean :
 20     $(MAKE) -C $(BASHINCLUDE) M=$(CURDIR) clean;
 21     rm -f *.ko;

执行make生成mytest.ko文件

sjx@sjx-PC:~/work/study/test/test-1$ ls
Makefile  my_test.c
sjx@sjx-PC:~/work/study/test/test-1$ make
make -C /lib/modules/`uname -r`/build M=/home/sjx/work/study/test/test-1 modules;
make[1]: 进入目录“/usr/src/linux-headers-5.4.70-amd64-desktop”
  CC [M]  /home/sjx/work/study/test/test-1/my_test.o
  LD [M]  /home/sjx/work/study/test/test-1/mytest.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC [M]  /home/sjx/work/study/test/test-1/mytest.mod.o
  LD [M]  /home/sjx/work/study/test/test-1/mytest.ko
make[1]: 离开目录“/usr/src/linux-headers-5.4.70-amd64-desktop”
sjx@sjx-PC:~/work/study/test/test-1$ ls
Makefile  modules.order  Module.symvers  my_test.c  mytest.ko  mytest.mod  mytest.mod.c  mytest.mod.o  my_test.o  mytest.o

可以通过file命令检查编译的模块是否正确.

sjx@sjx-PC:~/work/study/test/test-1$ file mytest.ko 
mytest.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), BuildID[sha1]=5fe83f4f20a74ddbc11fe613f9b1c638715029de, with debug_info, not stripped

也可以使用modinfo命令进一步检查

sjx@sjx-PC:~/work/study/test/test-1$ modinfo mytest.ko
filename:       /home/sjx/work/study/test/test-1/mytest.ko
alias:             mytest
description:   my test kernel module
author:          sjx
license:         GPL
srcversion:    3F1D46D94CA8792B542B12A
depends:        
retpoline:      Y
name:           mytest
vermagic:      5.4.70-amd64-desktop SMP mod_unload 

加载内核模块

$ sudo insmod mytest.ko

查看日志信息,查看module_init()打印的信息

sjx@sjx-PC:~/work/study/test/test-1$ sudo dmesg |grep  my
1445:[28028.835811] my first kernel module init

使用lsmod,查看mytest模块是否被加载

sjx@sjx-PC:~/work/study/test/test-1$ lsmod 
Module                  Size  Used by
mytest                 16384  0
ses                    20480  0
enclosure              16384  1 ses
scsi_transport_sas     40960  1 ses
uas                    28672  0

加载模块之后,系统会在/sys/modules目录下新建一个目录。

sjx@sjx-PC:/sys/module/mytest$ tree -a
.
├── coresize
├── holders
├── initsize
├── initstate
├── notes
│   ├── .note.gnu.build-id
│   └── .note.Linux
├── refcnt
├── sections
│   ├── .exit.text
│   ├── .gnu.linkonce.this_module
│   ├── .init.text
│   ├── __mcount_loc
│   ├── .note.gnu.build-id
│   ├── .note.Linux
│   ├── .rodata.str1.1
│   ├── .strtab
│   └── .symtab
├── srcversion
├── taint
└── uevent

3 directories, 18 files
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值