实现一个简单的linux内核模块,实现简单的 Linux 内核模块

Linux 内核包含了许多的驱动,这些驱动都是由一个个模块组合而成,那么怎么编写一个简单的内核驱动模块?

模块源码框架

内核的模块需要按照一定的框架进行搭建,通常情况下都需要模块入口和模块出口

#include

#include

static int __init hello_init(void)

{

int i;

for(i = 0; i < 10; i++ ) {

printk(KERN_ALERT "Hey, How are you. digit %d\n", i);

}

return 0;

}

static void __exit hello_exit(void)

{

printk(KERN_ALERT "Bye man, I have been unload.\n");

}

module_init(hello_init);

module_exit(hello_exit);

MODULE_AUTHOR("Jackie Liu ");

MODULE_LICENSE("GPL");

首先需要定义一个 hello_init 的函数,然后通过 module_init 注册到内核中,同理的 hello_exit 也一样。MODULE_AUTHOR 并不是必须的,他仅仅告知使用者本模块的作者是谁,这个虽然对模块使用不产生什么影响,但是使用者尊重作者版权的态度还是要有的。MODULE_LICENSE 也并不是必须的,但是如果不显示声明模块采用 GPL 协议,那么很多的以 EXPORT_SYMBOL_GPL 导出的函数是无法使用的,通常情况下,建议大家都采用 GPL 授权模式,毕竟内核整个框架都是采用的 GPL 授权方案,如果你不懂什么是 GPL,那么请点击这里。

好了,一个简单的模块已经编写完毕,无论多了复杂的驱动,他总是需要一个入口和一个出口,就像一个再复杂的 C 语言程序都需要一个 main 入口一样。

Makefile 的编写

尽管我们按照套路完成了驱动的编写,都这还不够,正确的书写配套的 Makefile 也是成功的关键,内核驱动模块的 Makefile 与其他核外的进程程序不同,他编译出来的对象并不是二进制可执行文件

obj-m := hello.o

DIRS := /lib/modules/`uname -r`/build

all:

make -C $(DIRS) M=$(PWD) modules

clean:

rm -Rf*.o *.ko *.mod.c *.order *.symvers

编译、加载与卸载模块

准备好 Makefile 与 hello.c 源码文件,那么接下来可以演示如何加载与卸载模块

jackieliu@jackieliu-virtual-machine:~/modules$ make

make -C /lib/modules/`uname -r`/build M=/home/jackieliu/modules modules

make[1]: Entering directory '/usr/src/linux-headers-4.11.0-14-generic'

CC [M] /home/jackieliu/modules/hello.o

Building modules, stage 2.

MODPOST 1 modules

CC /home/jackieliu/modules/hello.mod.o

LD [M] /home/jackieliu/modules/hello.ko

make[1]: Leaving directory '/usr/src/linux-headers-4.11.0-14-generic'

编译阶段需要保证没有报错,并且正确的生成 hello.ko。然后使用 root 权限来加载这个模块并打印内核输出信息。

jackieliu@jackieliu-virtual-machine:~/modules$ sudo insmod hello.ko

jackieliu@jackieliu-virtual-machine:~/modules$ dmesg

[ 1760.276063] Hey, How are you. digit 0

[ 1760.276068] Hey, How are you. digit 1

[ 1760.276069] Hey, How are you. digit 2

[ 1760.276070] Hey, How are you. digit 3

[ 1760.276071] Hey, How are you. digit 4

[ 1760.276072] Hey, How are you. digit 5

[ 1760.276073] Hey, How are you. digit 6

[ 1760.276074] Hey, How are you. digit 7

[ 1760.276075] Hey, How are you. digit 8

[ 1760.276075] Hey, How are you. digit 9

dmesg 信息将模块的 hello_init 中需要打印的信息展现出来,表示模块已经正确的加载。然后通过 rmmod 来卸载模块并打印信息。

jackieliu@jackieliu-virtual-machine:~/modules$ sudo rmmod hello

jackieliu@jackieliu-virtual-machine:~/modules$ dmesg

[ 1880.180709] Bye man, I have been unload.

模块正确卸载,并打印信息。至此,一个简单的模块已经介绍完毕,食用愉快。

模块出口并不是一定需要,也可以不写,那么这样的模块在正常模式下是无法卸载的。 ↩︎

这个说法其实页不完全对,可执行文件的组成方式是 ELF 格式,内核模块的文件组成格式也是 ELF 格式。 ↩︎

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值