文章目录
- 简述
-
- 实例
-
- 硬件相关
-
- uImage 相关
- Image 相关
- 虚拟地址
- PAGE_OFFSET
- TEXT_OFFSET
- swapper_pg_dir
- init_pg_dir
- idmap_pg_dir
- 物理地址
-
- 线性映射中 物理地址和虚拟地址的转换
- 其他
-
简述
boot地址侧
uboot 加载 uImage 到 地址A // 只存在于 "bootm + uImage"
uboot 将 Image 加载到 地址B // 存在于 "bootm + FITimages" "bootm + uImage" "booti + Image"
// arm64 linux 没有 uImage 没有zImage
// 但是可以做成uImage ,然后 bootm 启动
Image 加载地址"Load Address"的限制
TODO
虚拟内存侧
uboot 在 加载 内核最后一步, MMU 肯定是关的 // 不太关心 uboot 过程中会不会开MMU
Image 运行过程中 , MMU 会在 start_kernel 前 打开
开了 MMU 之后
物理地址 : 虚拟地址
ZRELADDR : TEXTADDR
实例
qemu virt arm64
Image 加载地址 : 40200000
kimage_vaddr : 0xffff800008000000 //
extern u64 kimage_voffset;
idmap
0x41124000 - 0x411248cc 恒等
// include/asm/sections.h:17:extern char __idmap_text_start[], __idmap_text_end[];
// ffff800008f24000 T __idmap_text_start
// ffff800008f24918 T __idmap_text_end
kernel map
0x40200000 - x
0xffff800008000000 - 0xffff80000a1b0000
硬件相关
PHYS_OFFSET
179 extern s64 memstart_addr;
180
include/asm/memory.h:181:#define PHYS_OFFSET ({ VM_BUG_ON(memstart_addr & 1); memstart_addr; }
uImage 相关
参考链接中的 uImage相关
Image 相关
虚拟地址
PAGE_OFFSET
// CONFIG_ARM64_VA_BITS=48
36
43 #define VA_BITS (CONFIG_ARM64_VA_BITS)
44 #define _PAGE_OFFSET(va) (-(UL(1) << (va)))
45 #define PAGE_OFFSET (_PAGE_OFFSET(VA_BITS))
46 #define KIMAGE_VADDR (MODULES_END)
47 #define MODULES_END (MODULES_VADDR + MODULES_VSIZE)
48 #define MODULES_VADDR (_PAGE_END(VA_BITS_MIN))
49 #define MODULES_VSIZE (SZ_128M)
50 #define VMEMMAP_START (-(UL(1) << (VA_BITS - VMEMMAP_SHIFT)))
51 #define VMEMMAP_END (VMEMMAP_START + VMEMMAP_SIZE)
52 #define PCI_IO_END (VMEMMAP_START - SZ_8M)
53 #define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE)
54 #define FIXADDR_TOP (VMEMMAP_START - SZ_32M)
TEXT_OFFSET
bootloader会把kernel image从外设copy到RAM中,那么具体copy到什么位置呢?
从RAM的起始地址开始吗?
实际上是从TEXT_OFFSET开始的,偏移这么一小段内存估计是为了bootloader和kernel之间传递一些信息。
所以,这里TEXT是指kernel text segment,而OFFSET是相对于RAM的首地址而言的。
TEXT_OFFSET必须要4K(0x1000)对齐并且TEXT_OFFSET的size不能大于2M(0x20 0000)。
TEXT_OFFSET 适用于 虚拟地址 和 物理地址
Image 对应的 物理地址 开端 为 PHYS_OFFSET + TEXT_OFFSET
Image 对应的 虚拟地址 开端 为 PAGE_OFFSET + TEXT_OFFSET
swapper_pg_dir
位于 链接脚本顶层
init_pg_dir
init_pg_dir 0x423a5000
init_pg_end 0x423a8000
idmap_pg_dir
idmap_pg_dir 0x41991000
idmap_pg_end 0x41994000
__idmap_text_start 0x41124000
物理地址
Image 物理地址
PHYS_OFFSET+TEXT_OFFSET
线性映射中 物理地址和虚拟地址的转换
virt_to_phys
phys_to_virt
其他
__relocate_kernel
(gdb) p/x $w9
$9 = 0x19070d0 // pa_start // // offset to reloc table // __rela_offset
(gdb) n
(gdb) p/x $w10
$10 = 0x4f4b20 // size // // size of reloc table // 4.96MB // __rela_size
(gdb) p/x $x11
$11 = 0xffff800008000000 // 偏差
(gdb) p/x $x9
$14 = 0xffff8000099070d0 // va_start
(gdb) p/x $x10
$15 = 0xffff800009dfbbf0 // va_end
X9 - X10 // 216,524 对
64bit 64bit 64bit
X12 X13 X14
addr TYPE value
if (TYPE == 1027(0x403)) *(uint64_t *)addr = value // include/asm/elf.h:69:#define R_AARCH64_RELATIVE 1027
arch/arm64/kernel/vmlinux.lds
12 . = ((((-(((1)) << ((((48))) - 1)))) + (0x08000000)));
13 .head.text : {
14 _text = .;
15 KEEP(*(.head.text))
16 }
84 .rela.dyn : ALIGN(8) {
85 *(.rela .rela*)
86 }
__rela_offset = ABSOLUTE(ADDR(.rela.dyn) - ((((-(((1)) << ((((48))) - 1)))) + (0x08000000)))); // 相对于 .head.text 的offset
__rela_size = SIZEOF(.rela.dyn);
$ aarch64-linux-gnu-readelf -S vmlinux
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[21] .rela.dyn RELA ffff8000099070d0 019170d0
00000000004f4b20 0000000000000018 A 0 0 8
map
ARM64 start_kernel 前 有 两段映射
第一段是identity mapping,其实就是把物理地址mapping到物理地址上去,在打开MMU的时候需要这样的mapping(ARM ARCH强烈推荐这么做的)。
第二段是kernel image mapping,内核代码欢快的执行当然需要将kernel running需要的地址(kernel txt、dernel rodata、data、bss等等)进行映射了,
210
227 .macro map_memory, tbl, rtbl, vstart, vend, flags, phys, pgds, istart, iend, tmp, count, sv
idmap map_memory x0, x1, x3, x6, x7, x3, x4, x10, x11, x12, x13, x14
kernel map_memory x0, x1, x5, x6, x7, x3, x4, x10, x11, x12, x13, x14
x0 0x41991000 1100550144
x1 0x0 0
x2 0x40 64
x3 0x41124000 1091715072
x4 0x200 512
x5 0x21 33
x6 0x411248cc 1091717324
x7 0x701 1793
x8 0x0 0
x9 0x0 0
x10 0x0 0
x11 0x0 0
x12 0x0 0
x13 0x0 0
x14 0x0 0
x15 0x0 0
x16 0x0 0
x17 0x0 0
x18 0x0 0
x19 0x0 0
x20 0x0 0
x21 0x48000000 1207959552
x22 0x0 0
x23 0x0 0
x24 0x0 0
x25 0x0 0
x26 0x0 0
x27 0x0 0
x28 0x419a0018 1100611608
x29 0x0 0
x30 0x419a0054 1100611668
x0 0x423a5000 1111117824
x1 0x41994000 1100562432
x2 0x40 64
x3 0x40200000 1075838976
x4 0x200 512
x5 0xffff800008000000 -140737354137600
x6 0xffff80000a1b0000 -140737318813696
x7 0x701 1793
x8 0x0 0
x9 0x0 0
x10 0x9 9
x11 0x8 8
x12 0x41000701 1090520833
x13 0x41200000 1092616192
x14 0x41993000 1100558336
x15 0x0 0
x16 0x0 0
x17 0x0 0
x18 0x0 0
x19 0x0 0
x20 0x0 0
x21 0x48000000 1207959552
x22 0x0 0
x23 0x0 0
x24 0x0 0
x25 0x0 0
x26 0x0 0
x27 0x0 0
x28 0x419a0018 1100611608
x29 0x0 0
x30 0x419a0054 1100611668