📖 推荐阅读:《Yocto项目实战教程:高效定制嵌入式Linux系统》
🎥 更多学习视频请关注 B 站:嵌入式Jerry
Linux 内核基础统简全解:Kbuild、内存分配和地址映射
Linux 内核基础知识似乎分散,但其实只要理清基本概念和应用场景,就能从完整结构观得到进程、内存、构建等多个角度的组合结果。本文将进行一段精简且全面的分析,实现概念 + 分析 + 示意图的组合,方便理解和记录。
一、Kbuild 是什么?
Kbuild 是 Linux 内核中用于描述每个相关源码目录应该怎样装配、编译和打包成内核或模块的组建机制。
虽然每个子目录中的文件名为 Makefile
,但其内容采用的是 Kbuild 特有语法,与传统 GNU Make 不同,因此通称为 Kbuild 文件。
Kbuild 基础用法
语法写法 | 含义 |
---|---|
obj-y += foo.o | 内存编译,装入核心 |
obj-m += bar.o | 编译为模块 bar.ko |
foo-objs := a.o b.o | foo.o 由多个完成单元构成 |
obj-$(CONFIG_XXX) += z.o | 根据 Kconfig 选项条件编译 |
示例:
obj-$(CONFIG_MYDEV) += mydriver.o
mydriver-objs := main.o helper.o
- 当配置中启用
CONFIG_MYDEV
,则构建模块mydriver.ko
- 该模块由
main.c
和helper.c
构成
构建进程流程图
make menuconfig
↓
生成 .config 含 CONFIG_XXX
↓
项目核心 Makefile 分析
↓
递归读取各目录 Makefile (Kbuild)
↓
构建 .o / .ko 相应目标
二、kmalloc 和 vmalloc 有什么区别?
对比项 | kmalloc | vmalloc |
---|---|---|
虚拟地址是否连续 | 是 | 是 |
物理地址是否连续 | 是 (DMA 选择) | 否 (paged memory) |
性能 | 高,直接映射 | 较低,页表查找、TLB 影响 |
配置大小 | 小(如 <1MB) | 可以配置大块内存 (四级 MB) |
通用场景 | 控制块,快速切换区块 | 大存储区,如图像 buffer 、清洗区 |
示意图:
kmalloc:
[虚拟地址] 连续
[物理地址] 连续
vmalloc:
[虚拟地址] 连续
[物理地址] 分散
三、什么是“直接映射区”?和“低端内存”有关吗?
概念
- 直接映射区:一段内核虚拟地址空间,对应于物理内存的线性映射,无页表转换,直接可用;
- 低端内存:指可被直接映射区映射的部分物理内存,通常是前 896MB
使用场景
virt_to_phys()
只能转换直接映射区内存kmalloc
得到的地址在直接映射区,因此能做 DMA
四、用户端请求的内存是否需要内核端重新分配?
答:不需要内核端重新分配,内核仅通过 页表将用户虚拟地址映射到物理页并创建映射关系即可
示意图
用户地址 → 页表映射 → 物理页
malloc() 内核分配 不需内核地址
五、代码运行时在内存中被分到哪些段?
段名 | 内容 |
---|---|
.text | 程序代码区域 |
.data | 已初始化全局变量 |
.bss | 未初始化全局变量 |
.rodata | 常量数据(如字符串) |
heap | 动态分配的 malloc 区 |
stack | 层级调用、局部变量 |
六、Kconfig 中的 select
和 depends on
有什么区别?
语法 | 含义 |
---|---|
depends on A | 表示依赖,A 未选则本项不可选 |
select A | 强制选中,选择本项时会自动启用 A,但 不检查 A 依赖 |
示意示例
config FOO
bool "Enable FOO"
depends on BAR
select BAZ
- 表示:只有 BAR=y 时才能选 FOO
- 选 FOO 时会强制选择 BAZ
如需可以继续扩展:
- 全套 Kbuild 子目录结构分析
- Kbuild 和 Kconfig 实际使用连动
- 内核地址映射和页表架构运行图
如需我可以为你生成配套实例、导图或按章节列表。
📖 推荐阅读:《Yocto项目实战教程:高效定制嵌入式Linux系统》
🎥 更多学习视频请关注 B 站:嵌入式Jerry