内核模块 编程编程
模块编程
大多数情景下,宏内核不会实时修改。
一些特殊的功能需要通过插件形式做成模块(M)。
内核模块形式上独立,但运行时与内核成一个整体。
--------------------
模块依赖:
模块与内核及其他模块间的全局符号可以互相访问。
提供符号的模块需要优先加载、优先编译,垫后卸载。
编译不同目录下有依赖关系的模块时,优先编译输出符号模块;
再将生成的符号表 Module.symvers 拷到输入模块 Makefile 目录。
--------------------
模块编程与应用编程对比:
|不同点 | 内核模块 | 应用程序 |
|-------| ------------------------- | ---------------------------------- |
|API来源 | 不能使用任何库函数 | 各种库函数均可以使用 |
|运行空间| 内核空间 | 用户空间 |
|运行权限| 特权模式运行 | 非特权模式运行 |
|编译方式| 编译进内核镜像或.ko文件 | elf格式的应用程序可执行文件 |
|运行方式| 模块中的函数在需要时被动调用 | 从main开始顺序执行 |
|入口函数| init_module | main |
|退出方式| cleanup_module | main函数返回或调用exit |
|浮点支持| 一般不涉及,所以printk不支持| 支持浮点运算,printf可以打印浮点数据 |
|并发考虑| 需考虑多种执行流并发的情况 | 只需考虑多任务并行的竞态 |
|程序出错| 可能会导致整个系统崩溃 | 只会让自己崩溃 |
执行流:代码执行的环境上下文,包括任务流和异常流
用户态执行流:
app 内代码执行在用户态。
app 调用系统调用函数。运行于内核态,但属于 app
内核态任务流:一直运行于内核态的内核线程中。
异常流:一直运行在内核态,用于处理异常。
内核符号表说明:包括模块导出符号
/proc/kallsyms:运行时的内核符号表。
/boot/System.map:编译后的内核符号表。
头文件
内核专用头文件:include/linux
include/linux/init.h:驱动初始化和退出相关的函数。
include/linux/module.h:模块相关函数原型及宏定义。
include/linux/kernel.h:内核相关的函数、变量及宏。
include/linux/export.h:将符号从内核导出到模块。
CPU架构相关:
arch/$(ARCH)/include
板级硬件相关:
arch/$(ARCH)/plat-xx/include
arch/$(ARCH)/mach-xx/include
--------------------
内核 Makefile 中,头文件相关变量和格式:
LINUXINCLUDE:内核中的头文件路径变量。
添加路径:-I<prefix_path>/include
Linux内核模块编译、加载、运行机制分析、版本控制、许可声明、内核污染、模块传参、模块签名机制、out-of-tree动态模块编译及Makefile模板编写,尽在《Linux内核编程》,详情点击:王利涛老师个人淘宝店:Linux内核编程