在Ubuntu下如何编译第一个内核模块?

运维 系统运维
内核模块是Linux内核向外部提供的一个插口,其全称为动态可加载内核模块(LoadableKernelModule,LKM),我们简称为模块。本文介绍了在Ubuntu系统下编译的第一个内核模块的方法。

Ubuntu系统属于linux系统,本文介绍了在Ubuntu下编译的***个内核模块的方法,具体内容如下所述。

内核模块是Linux内核向外部提供的一个插口,其全称为动态可加载内核模块(LoadableKernelModule,LKM),我们简称为模块。Linux内核之所以提供模块机制,是因为它本身是一个单内核(monolithickernel)。单内核的***优点是效率高,因为所有的内容都集成在一起,但其缺点是可扩展性和可维护性相对较差,模块机制就是为了弥补这一缺陷。

一、什么是模块

模块是具有独立功能的程序,它可以被单独编译,但不能独立运行。它在运行时被链接到内核作为内核的一部分在内核空间运行,这与运行在用户空间的进程是不同的。模块通常由一组函数和数据结构组成,用来实现一种文件系统、一个驱动程序或其他内核上层的功能。

应用程序与内核模块的比较

为了加深对内核模块的了解,表一给出应用程序与内核模块程序的比较。

表一应用程序与内核模块程序的比较

在Ubuntu下如何编译***个内核模块?

从表一我们可以看出,内核模块程序不能调用libc库中的函数,它运行在内核空间,且只有超级用户可以对其运行。另外,模块程序必须通过module_init()和module-exit()函数来告诉内核“我来了”和“我走了”。

二、编写一个简单的模块

模块和内核都在内核空间运行,模块编程在一定意义上说就是内核编程。因为内核版本的每次变化,其中的某些函数名也会相应地发生变化,因此模块编程与内核版本密切相关。以下例子针对Ubuntu9.10内核2.6.31-14-generic

1.程序举例

 

  1. #include  
  2.  
  3. #include  
  4.  
  5. #include  
  6.  
  7. MODULE_LICENSE("GPL");  
  8.  
  9. staticint__initlkp_init(void)  
  10.  
  11. {  
  12.  
  13. printk(KERN_ALERT"HelloWorld!\n");  
  14.  
  15. return0;  
  16.  
  17. }  
  18.  
  19. staticvoid__exitlkp_cleanup(void)  
  20.  
  21. {  
  22.  
  23. printk(KERN_ALERT"ByeWorld!\n");  
  24.  
  25. }  
  26.  
  27. module_init(lkp_init);  
  28.  
  29. module_exit(lkp_cleanup);  
  30.  
  31. MODULE_AUTHOR("heyutao");  
  32.  
  33. MODULE_DESCRIPTION("hello"); 

 

说明

所有模块都要使用头文件module.h,此文件必须包含进来。

头文件kernel.h包含了常用的内核函数。

头文件init.h包含了宏_init和_exit,它们允许释放内核占用的内存。

lkp_init是模块的初始化函数,它必需包含诸如要编译的代码、初始化数据结构等内容。

使用了printk()函数,该函数是由内核定义的,功能与C库中的printf()类似,它把要打印的信息输出到终端或系统日志。

lkp_cleanup是模块的退出和清理函数。此处可以做所有终止该驱动程序时相关的清理工作。

module_init()和cleanup_exit()是模块编程中最基本也是必须的两个函数。

module_init()是驱动程序初始化的入口点。而cleanup_exit()注销由模块提供的所有功能。

2编写Makefile文件,与hello.c放在同一个目录里

 

  1. obj-m:=hello.oKERNELBUILD:=/lib/modules/$(shelluname-r)/builddefault:make-C$(KERNELBUILD)M=$(shellpwd)modulesclean:rm-rf*.o*.ko*.mod.c.*.cmd*.markers*.order*.symvers.tmp_versions 

 

(注意makefile里面要求的tab)

KERNELBUILD:=/lib/modules/$(shelluname-r)/build是编译内核模块需要的Makefile的路径,Ubuntu下是

/lib/modules/2.6.31-14-generic/build

make-C$(KERNELBUILD)M=$(shellpwd)modules编译内核模块。-C将工作目录转到KERNELBUILD,调用该目录下的Makefile,并向这个Makefile传递参数M的值是$(shellpwd)modules。

3.编译模块

#sudomake(调用***个命令default)

这时,在hello.c所在文件夹就会有hello.ko,这个就是我们需要的内核模块啦

#sudomakeclean

清理编译垃圾,hello.ko也会清理掉。

4.插入模块,让其工作。注意必须是root权限

#sudoinsmod./hello.ko我们用dmesg就可以看到产生的内核信息啦,Helloworld!

如果没有输出"hellofromhelloworld",因为如果你在字符终端而不是终端模拟器下运行的话,就会输出,因为在终端模拟器下时会把内核消息输出到日志文件/var/log/kern.log中。

#sudormmod./hello再用dmesg可以看到Byeworld!

在Ubuntu下如何编译***个内核模块?

modutils是管理内核模块的一个软件包。可以在任何获得内核源代码的地方获取Modutils(modutils-x.y.z.tar.gz)源代码,然后选择***级别的patch.x.y.z等于或小于当前的内核版本,安装后在/sbin目录下就会有insomod、rmmod、ksyms、lsmod、modprobe等实用程序。当然,通常我们在加载Linux内核时,modutils已经被载入。1.Insmod命令调用insmod程序把需要插入的模块以目标代码的形式插入到内核中。在插入的时候,insmod自动调用init_module()函数运行。注意,只有超级用户才能使用这个命令,其命令格式为:#insmod[path]modulename.ko2.rmmod命令调用rmmod程序将已经插入内核的模块从内核中移出,rmmod会自动运行cleanup_module()函数,其命令格式为:#rmmod[path]modulename.ko3.lsmod命令调用lsmod程序将显示当前系统中正在使用的模块信息。实际上这个程序的功能就是读取/proc文件系统中的文件/proc/modules中的信息,其命令格式为:#lsmod4.ksyms命令

ksyms这个程序用来显示内核符号和模块符号表的信息。与lsmod相似,它的功能是读取/proc文件系统中的另一个文件/proc/kallsyms。

这就是在2.6.xx下一个最简单的模块编写过程。

总结:

希望本文介绍的在Ubuntu下编译的***个内核模块的方法能够对读者有所帮助,更多有关linux系统的知识还有待于读者去探索和学习。

【编辑推荐】

  1. Ubuntu10.04下如何移植QtE?
  2. 如何在Ubuntu下访问局域网服务器?
  3. 如何在Ubuntu下安装媒体中心XBMC?
  4. Ubuntu10.10下MySQL5.1如何进行集群配置?
  5. UbuntuLinux下USB转串口的应用及minicom的设置方法
责任编辑:韩亚珊 来源: 雨木林风
相关推荐

2014-07-24 14:35:26

Linux内核模块

2010-04-12 11:19:47

编译内核模块

2021-07-06 14:36:05

RustLinux内核模块

2009-12-17 15:28:32

内核模块编译

2023-05-08 08:05:42

内核模块Linux

2018-10-15 10:10:41

Linux内核补丁

2018-06-19 09:07:57

Linux内核模块

2010-01-22 11:01:04

linux内核模块

2011-06-24 13:38:32

QT 编译 安装

2023-09-28 13:21:32

2011-08-29 16:31:30

UbuntuAndroid

2019-07-08 20:00:35

Linux内核模块

2010-07-30 14:50:38

Flex项目

2021-12-30 11:26:31

语言编译器脚本

2011-07-06 18:31:21

Xcode 4 iPhone 模拟器

2010-02-26 15:38:29

Linux内核版本

2021-09-03 08:44:51

内核模块Linux社区

2021-04-07 13:38:27

Django项目视图

2023-09-21 22:43:17

Django框架

2021-12-02 08:00:00

Kubernetes集群容器
点赞
收藏

51CTO技术栈公众号