最简单的内核模块编程
程序员文章站
2022-06-05 17:28:25
...
最简单的内核模块编程
1、实验演示
- vi hello.c
#include <linux/init.h>
#include <linux/module.h>
int __init hello_init(void)
{
printk("hello world!\n");
return 0;
}
void __exit hello_exit(void)
{
printk("bye bye!\n");
}
module_init(hello_init);
module_exit(hello_exit);
- vi Makefile
obj-m += hello.o
all:
make -C /home/ta/driver/kernel M=$(PWD) modules
clean:
make -C /home/ta/driver/kernel M=$(PWD) clean
- make //编译驱动
- cp hello.ko ../../rootfs/ //将驱动拷贝到指定开发板
- insmod hello.ko //安装驱动模块
- dmesg //查看之前缓存的信息
- 观察到打印了”hello world”
- lsmod //查看安装的驱动模块
- rmmod hello //移除驱动模块
- lsmod
- dmesg
- 观察到打印了”bye bye”
- 注意1:
- 内核将打印信息分为8个等级,大于该等级的信息才会显示出来(数字越小越大),要显示信息,需要配置内核
- make menuconfig
- Kernel hacking —>
- (4) Default message log level (0-7) //改为4即可
- Kernel hacking —>
- make menuconfig
- 内核将打印信息分为8个等级,大于该等级的信息才会显示出来(数字越小越大),要显示信息,需要配置内核
- 注意2:
- 将上面的程序安装后会报内核被污染
- 解决方法:
- MODULE_LICENSE(“GPL”);加上这句话即可
2、代码解释
> #include <linux/init.h>
> #include <linux/module.h>
以上两行代码是写驱动程序必须加的头文件,它们在内核源码 include/linux/目录下
-
MODULE_LICENSE(“GPL”);
- 上面这句话意思是将该.c文件声明为*软件,如果不做声明 会导致内核被污染,会导致不能调用内核中的大部分函数
- 类似的还有:
- MODULE_AUTHOR
- MODULE_DESCRIPTION
- …..
int __init xxx(void) {}
- module_init(xxx);
- 如果模块中有一个函数希望在安装模块时被调用,必须写成上形式
- xxx是函数名,可以自己定
- __init是一个宏
- 意思是:被其修饰的代码链接到自定义的.init.text段,该段代码被执行一次后对应的内存空间就被释放
- module_init :如果希望函数在安装模块时被调用
__init宏:
#define __init __section(.init.text) __cold notrace
- void __exit xxx(void) {}
- module_exit(xxx);
- 如果模块中有一个函数希望在卸载模块是被调用,必须写成上面形式
- xxx是函数名,可以自己定
- __exit是一个宏
- 意思是:被其修饰的代码链接到自定义的.exit.text段,该段代码被执行一次后对应的内存空间就被释放
- module_exit :如果希望函数在模块卸载时被调用,需要这条
__exit宏:
#define __exit __section(.exit.text) __exitused __cold notrace
3、Makefile文件代码解释
- make -C /home/ta/driver/kernel M=$(PWD) modules
- -C:进到指定的目录进行读取Makefile,这样会将内核中的一些宏被定义
- M=$(PWD):然后返回到当前目录继续执行当前目录下的编译
- modules:编译内核模块的固定写法
上一篇: 阿里云Maven镜像
下一篇: 导出符号