Linux内核镜像学习笔记
内核镜像的vmlinux是一个ELF格式,
vmlinux: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), statically linked, with debug_info, not stripped
可通过readelf -S命令来查看linux的image镜像的各个段;
有
- 头代码段(.head.text)包括
- primary_entry
- preserve_boot_args
- map_memory初始页表相关工具宏定义
- __create_page_tables初始页表
- 正式代码段.text包括:
内核镜像关键符号变量
- PAGE_OFFSET、KIMAGE_VADDR、PHYS_OFFSET符号
- 前两个是符号,编译阶段确定的,静态的。PHYS_OFFSET应该是变量。
- PAGE_OFFSET: 页偏移。内核线性映射的虚拟地址起始基准。
定义有
典型值:#define VA_BITS (CONFIG_ARM64_VA_BITS) #define _PAGE_OFFSET(va) (-(UL(1) << (va))) #define PAGE_OFFSET (_PAGE_OFFSET(VA_BITS))0xffffff8000000000(VA_BITS=48) - KIMAGE_VADDR:内核镜像的虚拟起始地址。
实际上就是代码段的起始地址。等同于_text符号。也即.head.text段的起始。
典型值:ffffffc010000000 - PHYS_OFFSET: 物理偏移。定义了主内存在物理地址空间的开始位置。
典型值:0x00200000。
注意: 和__PHYS_OFFSET区分。__PHYS_OFFSET仅用于内核引导阶段。而PHYS_OFFSET适用于内核引导后的工作。
- kimage_vaddr和kimage_voffset
- 都是变量。
- kimage_vaddr: 等同于KIMAGE_VADDR
- kimage_voffset: kimage_vaddr - __PHYS_OFFSET (这里)。用于提供
定义有
内核地址转换
- 内核的虚拟地址到物理地址有两种转换方式: 线性和镜像转换。
- 线性转换是指:内核动态内存分配(kmalloc、__get_free_pages)的内存区。
- 镜像转换是指: 内核镜像的代码段和静态变量。
- 转换函数定义如下
@arch/arm64/include/asm/memory.h#define __is_lm_address(addr) (((u64)(addr) ^ PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET)) #define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET) #define __kimg_to_phys(addr) ((addr) - kimage_voffset)

浙公网安备 33010602011771号