Linux 内核模块 hello world 程序

Linux 内核模块

LKM(Loadable Kernel module) 尽管 linux 是单内核的,但是 linux 提供了一种机制,允许用户动态的加载模块到内核中。我也是刚开始学习些内核模块,这里从一个简单的 hello world 程序开始,看下 LKM(Loadable Kernel module) 即内核模块编写与普通程序的不同。

内核模块结构

用户态程序

以 hello.c 为示例,在用户态程序下,C 语言代码如下。

#include <stdio.h>

int main(int argc, char** argv){
	print('hello world!\n');
	return 0;
}

执行该程序只需要通过 gcc -o hello hello.c 生成可执行文件 hello,然后通过./hello 就可以在 shell 中看见输出了,运行截图如下。
用户态 hello.c 执行结果

内核模块

内核模块 hello.c 代码如下, module.hkernel.h 几乎是每个内核模块都要包含的。

  • module_init() 在内核模块插入时执行。
  • module_exit 在内核模块卸载时执行。
  • MODULE_LICENSE 为模块遵循的开源许可证书
  1 // Filename: hello.c
  2 // Author: lbt
  3 // Create Date: 2020-08-01
  4 // Description: kernel module example
  5 
  6 #include <linux/module.h>
  7 #include <linux/kernel.h>
  8 
  9 int init_hello_module(void){
 10         printk("***************Start***************\n");
 11     printk("Hello World! Start of hello world module!\n");
 12     return 0;
 13 }
 14 
 15 void exit_hello_module(void){
 16         printk("###############End#################\n");
 17     printk("Hello World! End of hello world module!\n");
 18 }
 19 
 20 
 21 MODULE_LICENSE("Dual BSD/GPL");
 22 module_init(init_hello_module);
 23 module_exit(exit_hello_module);
 24 

编译并执行内核模块不同于用户态程序,需要编写 Makefile,上述程序的 Makefile 文件如下。执行 make 命令,不出现报错且在当前目录下生成了 hello.ko 即说明编译成功。
make 过程可能报错,我在 centos 最小化安装里,出现了错误。提示 Makefile 第 12 行的 make -C $(KERNEL_DIR) M=$(PWD) modules 执行错误,原因是 $(KERNEL_DIR) 指向的文件不存在,经查阅资料,该文件是一个软链接,链接指向 /usr/src/kernel/ 下面的文件, 如下图所示。centos 最小化安装没有内核开发包,需要使用 yum 手动安装,命令为 yum install -y kernel-devel,安装完成后重新 make 即可成功编译内核模块。
软链接指向

  1 # Filename: Makefile
  2 # Author: lbt
  3 # Create Date: 2020-08-01
  4 # Makefile of kernel module `hello`
  5 
  6 obj-m := hello.o # hello.o 与 hello.c 对应
  7 
  8 KERNEL_DIR := /lib/modules/$(shell uname -r)/build #指定内核源码
  9 PWD := $(shell pwd)  #指向当前目录
 10 
 11 all:
 12                 make -C $(KERNEL_DIR) M=$(PWD) modules
 13 clean:
 14                 make -C $(KERNEL_DIR) M=$(PWD) clean 

shell 下运行以下命令可以对编译好的内核进行控制和查看。

  • modinfo hello.ko 内核模块信息查看
  • insmod hello.ko 插入内核模块
  • dmesg 查看内核模块输出信息
  • rmmod hello.ko 卸载该内核模块

执行完 insmod hello.ko 后使用 dmesg 会看到以下信息:
插入 hello 模块到内核
执行完 rmmod hello.ko 后使用 dmesg 会看到以下信息:
卸载 hello 模块
至此,第一个 linux 内核模块编写完成。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ARM 是一种广泛使用的 CPU 架构,而 Linux 内核是一个开放源代码的操作系统内核。在 ARM 平台上,我们可以通过内核模块编程的方式与内核进行交互,实现一些自定义的功能。 下面,我们将介绍如何在 ARM Linux 上编写内核模块,并输出一个简单的 "Hello World" 消息。 ## 1. 环境准备 在开始编写内核模块之前,需要先准备好开发环境。具体步骤如下: 1. 安装交叉编译工具链。ARM 平台上的应用程序内核模块需要使用交叉编译工具链进行编译。可以从官网下载对应的交叉编译工具链,也可以使用已经编译好的交叉编译工具链。 2. 下载内核源代码。可以从官网下载对应版本的内核源代码,也可以使用已经编译好的内核源代码。 3. 配置内核源代码。需要在内核源代码根目录下运行配置命令 `make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig` 进行配置,选择需要的模块和功能。 ## 2. 编写内核模块 在准备好开发环境之后,可以开始编写内核模块了。具体步骤如下: 1. 创建一个新的文件夹,用于存放内核模块代码。 2. 创建一个新的 C 文件,命名为 `hello.c`。 3. 在 `hello.c` 文件中编写以下代码: ```c #include <linux/init.h> #include <linux/module.h> static int __init hello_init(void) { printk(KERN_INFO "Hello, world!\n"); return 0; } static void __exit hello_exit(void) { printk(KERN_INFO "Goodbye, world!\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("A simple hello world module"); ``` 这段代码定义了一个简单的内核模块,当模块加载时会输出 "Hello, world!" 消息,当模块卸载时会输出 "Goodbye, world!" 消息。 4. 使用交叉编译工具链进行编译。在终端中进入 `hello.c` 文件所在的文件夹,运行以下命令进行编译: ```bash arm-linux-gnueabi-gcc -Wall -Werror -O2 -o hello.ko -c hello.c ``` 这个命令将生成一个名为 `hello.ko` 的内核模块文件。 ## 3. 加载和卸载内核模块 在编写好内核模块后,我们需要将它加载到内核中进行测试。具体步骤如下: 1. 将 `hello.ko` 文件复制到 ARM Linux 系统上。 2. 在终端中进入 `hello.ko` 文件所在的文件夹,运行以下命令以加载内核模块: ```bash insmod hello.ko ``` 这个命令将调用内核中的 `init_module` 函数,执行 `hello_init` 函数,输出 "Hello, world!" 消息。 3. 查看系统日志,可以看到 "Hello, world!" 消息。 ```bash dmesg ``` 4. 在终端中运行以下命令以卸载内核模块: ```bash rmmod hello ``` 这个命令将调用内核中的 `cleanup_module` 函数,执行 `hello_exit` 函数,输出 "Goodbye, world!" 消息。 5. 再次查看系统日志,可以看到 "Goodbye, world!" 消息。 至此,我们已经成功地在 ARM Linux 上编写了一个简单的内核模块,并输出了 "Hello, world!" 消息。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值