背景
在内核的开发中,总要先入个门。那么就要来编写第一个内核程序
入门
一个 module_init
程序是Linux内核模块的一部分,通过module_init
方法就能将程序载入内核。
module_init
方法需要以下步骤
- 编写
module_init
的代码,并将其保存为*.c
文件。 - 在代码中包含必要的头文件,如
<linux/module.h>
和<linux/kernel.h>
。 - 定义
module_init()
函数,该函数将在模块加载时被调用。 - 使用
MODULE_LICENSE()
宏指定您的代码的许可证。 - 在终端上使用
make
命令来编译代码。如果还没有安装内核头文件,则需要先安装它们。 - 将编译后的模块加载到内核中,使用
insmod
命令加载模块。如果需要卸载模块,则可以使用rmmod
命令。
环境准备
本实验使用的Ubuntu 22.04,不过不关键。
sudo apt-get install build-essential
sudo apt-get install linux-headers-$(uname -r)
sudo apt-get install dkms
编码
将以下程序写入 hello.c
#include <linux/module.h>
#include <linux/kernel.h>
int __init hello_init(void)
{
printk(KERN_INFO "Hello world!\n");
return 0;
}
void __exit hello_exit(void)
{
printk(KERN_INFO "Goodbye world!\n");
}
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
将以下程序写入 Makefile
obj-m := hello.o
CONFIG_MODULE_SIG=n
CONFIG_DEBUG_INFO=y
KERNEL_DIR := /lib/modules/$(shell uname -r)/build #指定内核源码
PWD := $(shell pwd) #指向当前目录
all:
make -C $(KERNEL_DIR) M=$(PWD) modules
clean:
make -C $(KERNEL_DIR) M=$(PWD) clean
将以上两个文件放入一个单独的目录
编译
在文件的目录下进行编译,仅执行命令
make
运行
insmod hello.ko
lsmod | grep hello
rmmod hello.ko
其中 insmod 是加载模块、lsmod是查看模块,rmmod是删除模块
查看结果
dmesg -T