Linux内核6.6 内存管理 (17)map_kernel/map_mem/kaslr
1.map_kernel
https://elixir.bootlin.com/linux/v6.6/source/arch/arm64/mm/mmu.c#L754
在此处加上log打印
注意点:将指针变量强制转换成64位无符号整数,不然会模糊化地址,无法看到
此处
段类型 虚拟地址范围 特点说明 text 段 0xffff800080010000 ~ 0xffff800081070000 内核核心代码,永久驻留内存 rodata 段 0xffff800081070000 ~ 0xffff800081af0000 只读数据,后续会重映射为只读权限 inittext 段 0xffff800081af0000 ~ 0xffff800081be0000 初始化代码,启动后释放(temp 标记) initdata 段 0xffff800081be0000 ~ 0xffff8000823f0000 初始化数据,启动后释放(temp 标记) data 段 0xffff8000823f0000 ~ 0xffff8000828e0000 可读写数据(如全局变量),永久驻留
内核段(text/rodata 等):物理地址 = 虚拟地址 - 0xffff7ffffcc00000
同样这里可以对应上
0xffff7ffffcc00000+0x84ef0000相加的结果是:
0xffff800081af0000(text+rodata的结束地址)
同样我们可以使用cat /proc/kallsyms
,主要用于查看 当前运行的 Linux 内核中的符号表。
第一个是该符号在内存中的地址,第二个是符号类型,T是全局信号,最后是符号名称
同样我们可以找任何函数
2.map_mem
map_mem
负责将物理内存块映射到内核虚拟地址的「直接映射区」,核心规律是 虚拟地址 = 物理地址 + 直接映射偏移(直接映射区虚拟地址上限为 0xffff800000000000
3.kaslr
Kernel Address Space Layout Randomization
KASLR 的作用:在系统启动时,随机化内核的加载地址(包括 .text 段、模块、堆栈等)。
这样可以防止攻击者通过已知地址发起攻击,比如 ROP(Return-Oriented Programming)或内核漏洞利用。
每次重启系统后,kaslr都会使得内核的起始地址(如 _text
、_stext
)变化。
但是我们可以通过cmdline,手动关掉kaslr, nokaslr
关闭kaslr的作用:
1. 调试内核或驱动
- KASLR 会导致内核加载地址每次启动都不同。
- 如果你在使用
gdb
、addr2line
、objdump
等工具调试内核或驱动,地址不一致会让符号定位变得困难。 - 关闭 KASLR 后,地址固定,便于对照
vmlinux
文件进行调试。
2. 分析 crash dump(如 panic 或 oops)
- crash 日志中的地址是运行时地址。
- 如果 KASLR 开启,你需要先计算偏移量才能定位到源码位置。
- 关闭 KASLR 可以让 crash 地址直接对应源码,加快分析速度