嵌入式系统/ARM技术中的kbuild系统-编译到内核和编译成模块的区别
代码编译到内核和编译成模块在代码中有什么区别呢? 从模块的代码中看是一样的。入口函数都是module_init(fun),但是代码中的条件编译会使宏module_init()在编译到内核和编译成模块的情况下替换成不同的代码。 include/linux/init.h中可知 #ifndef MODULE ... #define module_init(x) __initcall(x); ... #else /* MODULE */ ... /* Each module must use one module_init(), or one n 在嵌入式系统和ARM技术中,kbuild系统是用来构建Linux内核及其模块的构建工具。kbuild系统允许开发者将代码编译进内核或编译为可加载的模块,这两种方式在某些方面存在显著差异。 让我们讨论将代码编译到内核的情况。当代码被编译并链接到内核映像中时,它直接成为内核的一部分。这意味着代码在内核启动时就会被执行,这部分代码被视为不可分割的内核组件。在源码中,如果使用了`module_init()`宏来定义一个初始化函数,当不定义`MODULE`宏时,kbuild系统会将其转换为`__initcall()`,这个宏将初始化函数放置在特定的初始化调用链中,如`.initcall6.init`段。这个调用链在内核启动过程中按照顺序执行,确保内核服务按需初始化。 相反,当代码编译成模块时,`MODULE`宏会被定义。在这种情况下,`module_init()`宏不会简单地转换为`__initcall()`,而是会生成一个`init_module()`函数,这个函数会在模块被加载时执行。模块提供了运行时可插入和移除的功能,这使得它们对于测试新功能或提供非核心功能非常有用。在模块中,`module_init()`宏定义了一个静态内联函数,并使用`alias`属性指向实际的初始化函数,这样在加载模块时,`init_module()`函数就会调用指定的初始化函数。 在 `/usr/src/linux/Makefile` 中,`MODFLAGS` 被设置为 `-DMODULE`,这个标志表明代码正在被编译为模块。`CFLAGS_MODULE` 和 `AFLAGS_MODULE` 将这些标志传递给编译器,确保模块代码被正确处理。 在模块的加载和卸载过程中,`init_module()` 和 `cleanup_module()` 分别用于执行初始化和清理操作。与内核中的初始化调用链不同,模块的初始化是在运行时进行的,而不是在内核启动时。 将代码编译到内核和编译成模块的主要区别在于执行时间和灵活性。内核中的代码在系统启动时执行,且不可动态移除;而模块代码可以在系统运行时加载和卸载,提供了一种灵活的扩展机制。此外,模块的使用还可以减小内核映像的大小,因为不是所有功能都必须在内核启动时就加载。 理解这些区别对于开发嵌入式系统和ARM平台上的Linux驱动程序至关重要,因为它影响着代码的组织、调试和优化策略。正确地使用kbuild系统可以帮助开发者更有效地管理他们的代码,同时确保系统的稳定性和性能。
- 粉丝: 4
- 资源: 952
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- bdwptqmxgj11.zip
- onnxruntime-win-x86
- onnxruntime-win-x64-gpu-1.20.1.zip
- vs2019 c++20 语法规范 头文件 <ratio> 的源码阅读与注释,处理分数的存储,加减乘除,以及大小比较等运算
- 首次尝试使用 Win,DirectX C++ 中的形状渲染套件.zip
- 预乘混合模式是一种用途广泛的三合一混合模式 它已经存在很长时间了,但似乎每隔几年就会被重新发现 该项目包括使用预乘 alpha 的描述,示例和工具 .zip
- 项目描述 DirectX 引擎支持版本 9、10、11 库 Microsoft SDK 功能相机视图、照明、加载网格、动画、蒙皮、层次结构界面、动画控制器、网格容器、碰撞系统 .zip
- 项目 wiki 文档中使用的代码教程的源代码库.zip
- 面向对象的通用GUI框架.zip
- 基于Java语言的PlayerBase游戏角色设计源码