内核模块 编程编程

模块编程

大多数情景下,宏内核不会实时修改。
一些特殊的功能需要通过插件形式做成模块(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内核编程