编写内核模块的基本步骤

一、前言

实验环境:

        系统:Ubuntu 23.04       

        内核:Linux-6.2.0-39-generic

二、具体步骤

1、环境准备

//更新一下

sudo apt update

//安装构建工具:build-essential包,这个包包括了ggc/g++编译器和make工具等。

sudo apt install build-essential

//安装内核头文件:安装与当前运行内核版本匹配的头文件

//可以uname-r这个指令查看内核版本,以6.2.0-39为例

//这个指令很有可能无法定位软件包

//可以用sudo apt search linux-headers-6.2 搜索以下6.2版本的软件包都有哪些

sudo apt install linux-headers-6.2.0-39-generic

        这个是我搜索结果中的一条。

2、编写模块代码

        首先需要创建一个包含模块的源代码的C文件。

        以下是一个简单的示例:

//这里可以选择你喜欢的编译器vim、gedit等都可以,这里我用的是nano

nano hello_world.c

#include <linux/module.h> // 必需的,包含对模块的支持
#include <linux/kernel.h> // 包含宏如KERN_INFO
#include <linux/init.h> // 包含__init和__exit宏

// 模块初始化函数
static int __init hello_world_init(void) {
    printk(KERN_INFO "Hello, world!\n");
    return 0; // 如果模块成功加载返回0,否则返回非0值
}

// 模块卸载函数
static void __exit hello_world_exit(void) {
    printk(KERN_INFO "Goodbye\n");
}

module_init(hello_world_init); // 宏用于加载模块
module_exit(hello_world_exit); // 宏用于卸载模块

//模块的元数据,其中声明许可证是必须有的,其他的可写可不写
MODULE_LICENSE("GPL"); // 声明许可证
MODULE_AUTHOR("Your Name"); // 声明作者
MODULE_DESCRIPTION("A simple Hello World Module"); // 声明模块描述
MODULE_VERSION("1.0"); // 声明模块版本

3、编写Makefile

nano Makefile

//内核源代码路径
KERNEL_DIR=/home/z/linux-system/linux-6.2
//模块对象文件
obj-m += characterdevice.o

all://默认目标用于编译模块
        make -C $(KERNEL_DIR) M=$(PWD) modules
clean://清理编译生成的文件
        make -C $(KERNEL_DIR) M=$(PWD) clean

下面给出一个交叉编译的例子,需要添加交叉编译器的前缀和路径

4、编译模块

make

编译会生成一个.ko文件

5、加载模块

insmod hello_world.ko

成功输出Hello_world

6、验证

dmesg | tail

这个是查看日志的指令,上面也可以看到加载模块的信息

7、卸载模块

rmmod hello_world

 输出Goodbye

三、可能出现的错误

1、缺失文件

解决:重新编译一下内核。

有时候编译器更新了,和编译内核时的编译器版本不一致也会报错

2、分隔符缺失

这种情况常见于复制过来的Makefile

这个时候make前面的是空格而不是TAB,改成TAB就好了

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值