在上一期中,我们介绍了Linux内核编译方法,这一期我们用一个例子来介绍如何向Linux内核中增加一个模块。

一、LKM内核模块

LKM是Loadable Kernel Module的缩写,意思是可加载内核模块。它有点儿像动态链接库,可在运行时加载,成为内核代码和数据的一部分,访问全部内核地址空间,也可运行时动态卸载(需要解决依赖关系,并释放内存空间),所谓的更新就是加载→卸载→加载的过程。LKM是大部分设备驱动、文件系统的存在形式。

为了编写内核模块,我们需要准备好编写的环境。首先,要指定内核源码或源码的头文件(即本模块是为哪个内核版本编写的),然后可以用VIM等编辑器编写,最后可以用gcc编译。

下图展示了一个简单的内核模块的示例代码:

在示例代码中我们可以看到两个重要的宏:moduleinit和moduleexit。这两个宏包含在init.h头文件中,规定了模块的入口和出口函数。而MODULELICENSE、MODULEAUTHOR和MODULE_DESCRIPTION三个函数则被包含在module.h头文件中[4]。

为了将这个模块的源码编译成可动态加载的内核模块,我们还需要修改Makefile:

注意,运行模块代码有两种方式,第一种方法是静态编译连接进内核,在系统启动过程中进行初始化;第二种方法是编译成可动态加载的module,通过insmod动态加载重定位到内核。这两种方式可以在Makefile中通过obj-y或obj-m选项进行选择[1]。使用obj  –m选项编译之后会生成.ko文件,可通过insmod将模块动态加载到内核中。

采用动态加载的方式有两个优点,一是可根据系统需要运行动态加载模块,以扩充内核功能,不需要时将其卸载,以释放内存空间;二是当需要修改内核功能时,只需编译相应模块,而不必重新编译整个内核[1]。

有五个与动态加载内核模块有关的命令[2]:

1.insmod:向Linux内核中插入一个模块;

2.rmmod:卸载内核中的模块;

3.lsmod:显示内核中的模块 ;

4.modprobe:可载入指定的个别模块,或是载入一组相依的模块。modprobe会根据depmod所产生的相依关系,决定要载入哪些模块。若在载入过程中发生错误,在modprobe会卸载整组的模块[3]。

5.modinfo:显示kernel模块的对象文件,以显示该模块的相关信息。

有时侯一个模块可能要调用其他模块中的函数,如果内核模块要引用内核代码中的符号则要通过内核符号表。内核符号表记录了内核中所有的符号(函数、全局变量等)的地址以及名字,在内核代码中通过printk("%pS\n",addr)可以打印符号名[5]。使用EXPORTSYMBOL可以将一个函数或全局变量以符号的方式导出给其他模块使用在使用时应先在被调用函数之后用EXPORTSYMBOL(函数名)将函数导出,然后在调用该函数的模块中用extern关键字引用该函数。在加载模块时应注意顺序,首先加载定义该函数的模块,然后加载调用该函数的模块[6]。内核启动后生成/proc/kallsyms,它包含了内核中的函数符号和全局变量。

二、结语

本期通过一个实例介绍如何编写和编译一个新的内核模块,下一期我们将对Linux各版本进行对比分析。

参考文献

[1]https://blog.csdn.net/yanxuan321/article/details/86606329

[2]https://blog.csdn.net/CPU1994GHz/article/details/79309221?utm_source=blogxgwz3

[3]https://baike.baidu.com/item/modprobe/7939608?fr=aladdin

[4]https://www.xuebuyuan.com/3181553.html

[5]https://www.cnblogs.com/sky-heaven/p/6297679.html

[6]https://www.cnblogs.com/Caden-liu8888/p/7725293.html

【华为云技术分享】Linux内核编程环境 (2)相关推荐

  1. 【华为云技术分享】Linux内核编程环境 (1)

    在上一期中,我们介绍了Linux内核的源码结构,这一期我们介绍Linux内核编程环境,首先介绍的是Linux内核的编译方法. 一.Linux内核编译方法 本期中我们以Linux 4.19.94版内核来 ...

  2. 【华为云技术分享】Linux内核补丁源码分析(1)

    在上一期中,我们介绍了Linux内核编程环境,在这一期中,我们将通过实例来介绍如何分析Linux内核的补丁. 一.Linux内核补丁 在"Linux内核发展史"中,我们简要介绍了L ...

  3. 【华为云技术分享】Linux内核的分布式编译(2)

    上一期中我们介绍了用源码包安装distcc的方法,这一期我们尝试用distcc对Linux 4.19.90内核进行分布式编译. 一.Linux内核的分布式编译 我们尝试用同一个子网中的三台服务器对Li ...

  4. 【华为云技术分享】“技术-经济范式”视角下的开源软件演进剖析-part 1

    前言 以互联网为代表的信息技术的迅猛发展对整个经济体系产生了巨大的影响.信息技术的发展一方面使知识的积累和传播更加迅速,知识爆炸性的增长:另一方面,使信息的获取变得越来越容易,信息交流的强度逐渐增加, ...

  5. 【华为云技术分享】“技术-经济范式”视角下的开源软件演进剖析-part 3

    4. 微观层面 4.1 个体动机 在开源软件发展之初, 商业组织的投入很少甚至没有, 完全是靠Richard Stallman 或者 linus Torvalds 这样的个人在努力推动开源软件艰难前行 ...

  6. 【华为云技术分享】三大前端技术(React,Vue,Angular)探密(下)

    [华为云技术分享]三大前端技术(React,Vue,Angular)探密(上) [Angular] Angular(通常被称为 "Angular 2+"或 "Angula ...

  7. 【华为云技术分享】直播回顾丨激发数据裂变新动能,HDC.Cloud云数据库前沿技术解读

    3月24日14:00-17:00,HDC.Cloud开发者沙龙系列云数据库专场直播线上开启,此次华为云数据库通过三场直播从NoSQL数据库新技术.数据库迁移.行业解决方案等方面对云端数据库进行深度解读 ...

  8. 【华为云技术分享】Linux内核的分布式编译(1)

    上一期中我们介绍了Linux内核模块依赖图的绘制方法,这一期中我们将介绍Linux内核的分布式编译方法和分布式编译工具distcc的安装过程. 一.Linux内核的分布式编译 分布式编译是指将源程序通 ...

  9. 【华为云技术分享】Linux内核发展史 (2)

    Linux是由赫尔辛基大学的Linus Torvalds开发的,在系统开发期间得到了因特网上广大UNIX程序员的帮助.它最初只是受Andy Tanenbaum教授的Minix(-个小型的类UNIX系统 ...

最新文章

  1. mysql客户端如何创建用户_mysql的创创建用户阶段 开启客户端登录和授权阶段
  2. linux创建文件怎么输入换行_Revit 怎么创建自定义的族文件?
  3. mysql select into和insert into select
  4. SpringMCV结构
  5. python常用的库介绍_Python的标准库介绍与常用的第三方库
  6. java json.stringify_JSON.stringify 语法实例讲解
  7. 如何在csdn写博客
  8. SpringBoot简明教程
  9. vue 图片放大查看器
  10. TOEFL 考场注意事项 考试须知
  11. html文档用什么浏览器打开,用什么打开HTML文件?
  12. 淘宝首页幻灯片(二) 居中按钮源代码
  13. 闪电侠第四季/全集The Flash迅雷下载
  14. 用友漏洞php,Phpwind GET型CSRF任意代码执行漏洞公开
  15. css中的各种选择器
  16. 如何静下心做些事情呢
  17. noip题库 —— 4.7反质数
  18. 5G多卡聚合路由器在高速公路收费中的应用
  19. 电动车充电桩显示无法连接服务器失败,电动车充电桩故障排除技巧
  20. NVIDIA Tesla GPU系列P4、T4、P40以及V100显卡性能的对比

热门文章

  1. ROS笔记(39) 串口配置
  2. java密码模块怎么做_密码模块设计
  3. springboot 优雅停机_SpringBoot 优雅停止服务的几种方法 第309篇
  4. file上传代码 ios_文件上传_iOS上传SDK_客户端上传_上传SDK_视频点播 - 阿里云
  5. oracle9i 全库备份,Windows下Oracle9i数据库文件如何自动备份?
  6. ios pull代码不提示成功_pullRefresh ios版问题 跪求大神帮助啊
  7. CCActionEase想说爱你也不难(上)
  8. linux虚拟串口及远程访问
  9. Python 竟能绘制如此酷炫的三维图
  10. .aspx页面 引用命名空间 (Import 指令,web.config)