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)
      
posted @ 2026-09-02 23:59  happysc  阅读(4)  评论(0)    收藏  举报