IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> arm64 linux boot 常见的宏 与 符号 -> 正文阅读

[系统运维]arm64 linux boot 常见的宏 与 符号

简述

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

地址
$ ls  arch/arm64/boot/Image  -l 
-rw-rw-r-- 1 suweishuai suweishuai 34750976 May 28 21:48 boot/Image // 0x02124200 // 33.14MB

Image加载地址 	: 40200000  			// 对应符号 _text
Image最后一个字节地址:0x423b0000		// 对应符号 _
kimage_vaddr 	: 0xffff800008000000  	/* the virtual base of the kernel image */ // 固定值
image_voffset   : 0xffff7fffc7e00000	/* the offset between the kernel virtual and physical mappings */
	kimage_vaddr - Image加载地址(_text)
PAGE_OFFSET 	: 0xffff000000000000
__fdt_pointer	: 0x48000000

页表
  • 页表描述
页表描述
	arm64 四级映射,48bit,9+9+9+(9+12)
	对于section 映射,只有3级别
	下面所有的表项都是PGD表项/PUD表项/PMD表项
	每个表项8字节,寻址2M空间
  • for mmu_on
idmap
	物理地址:0x41124000 - 0x411248cc 恒等(虚拟地址=物理地址) 
	虚拟地址:0x41124000 - 0x411248cc
	__idmap_text_start 	- __idmap_text_end
	// 对应的kernel_map的虚拟地址范围 为 FFFF 8000 08F2 4000 - FFFF 8000 08F2 48CC
	// include/asm/sections.h:17:extern char __idmap_text_start[], __idmap_text_end[];
	// ffff800008f24000 T __idmap_text_start
	// ffff800008f24918 T __idmap_text_end
	ffff800009791000 D idmap_pg_dir   
	ffff800009794000 T idmap_pg_end   
	// 注意 : 页表项是 8byte
	// 0x41991000: 0x41992003  0x00000000  0x00000000  0x00000000 // 这个是PGD表项
	// 0x41992000: 0x00000000  0x00000000  0x41993003  0x00000000 // 这个是PUD表项
	// 0x41993040: 0x41000701  0x00000000  0x00000000  0x00000000 // 这个是 PMD表项 2M 映射 0x4100 0000 - 0x4120 0000
	
  • for kernel (临时内核(Image)页表)
kernel map
	物理地址:0x40200000 			- 	0x423b0000
	虚拟地址:0xffff800008000000  	-  	0xffff80000a1b0000
			  _text				    -       _end
	ffff800008000000 T _text
	ffff80000a1b0000 B _end
	ffff80000a1a5000 B init_pg_dir    
	ffff80000a1a8000 B init_pg_end
	ffff80000a1b0000 B _end // vmlinux 最后一个符号
	
	// 0x423a5800: 0x423a6003  0x00000000  0x00000000  0x00000000 // 这个是PGD表项
	
	// 0x423a6000: 0x423a7003  0x00000000  0x00000000  0x00000000 // 这个是PUD表项
	
	// 0x423a7200: 0x40200701  0x00000000  0x40400701  0x00000000 // PMD表项
	// 0x423a7210: 0x40600701  0x00000000  0x40800701  0x00000000
	// 0x423a7220: 0x40a00701  0x00000000  0x40c00701  0x00000000
	// 0x423a7230: 0x40e00701  0x00000000  0x41000701  0x00000000
	// 0x423a7240: 0x41200701  0x00000000  0x41400701  0x00000000
	// 0x423a7250: 0x41600701  0x00000000  0x41800701  0x00000000
	// 0x423a7260: 0x41a00701  0x00000000  0x41c00701  0x00000000
	// 0x423a7270: 0x41e00701  0x00000000  0x42000701  0x00000000
	// 0x423a7280: 0x42200701  0x00000000  0x00000000  0x00000000
	临时内核页表的起始虚拟地址由什么决定: KIMAGE_VADDR
		KIMAGE_VADDR 值 为 arch/arm64/kernel/vmlinux.lds 中的 _text 地址值
	155     . = KIMAGE_VADDR; //((((-(((1)) << ((((48))) - 1)))) + (0x08000000)));                                                         
	156                                                                                
	157     .head.text : {                                                             
	158         _text = .;                                                             
	159         HEAD_TEXT                                                              
	160     }
	注意 : 对于	VA_BITS >= 48 ,来讲, KIMAGE_VADDR 为固定值 : 0xffff800008000000

ffff800009794000 T tramp_pg_dir   
ffff800009795000 T reserved_pg_dir
ffff800009796000 T swapper_pg_dir 
ffff800008010800 T vectors
  • 其他问题
40000000-4020000有没有创建映射
	在 start_kernel 前 没有创建映射
40000000 - 40200000是干啥的?
	40000000 地址有bootloader ,但只有 9 字节,9字节是 Image 被加载的地址
Image 必须要从40200000启动吗?
	Documentation/arm64/booting.rst 中 必须从
	起始地址处 2MB 对齐处启动
	但是实验数据表明:
		偏移0MB不可启动,因为覆盖了bootloader
		偏移1MB/512KB/256KB/128KB/64KB/32KB 可启动
		偏移16KB 不可启动(不想查了)
		
dtb 的映射在哪里
	TODO
	
mmu_on 页表 与 kernel 页表的切换
	TTBR0_EL1 存储了 mmu_on 页表基址(0x41991000)
	TTBR1_EL1 存储了 kernel 页表基址(0x423a5000)
	SCTLR 	  存储了 0x200000034f4d91d(表示开了MMU)
	当访问 以类似地址 0x0000aaaabbbbcccdddd, 采用 TTBR0_EL0
	当访问 以类似地址 0xffffaaaabbbbcccdddd, 采用 TTBR0_EL1 
	__primary_switched 位于 0xffff8000097a032c , 当 pc 位于 0xffff8000097a032c  的时候,自动用TTBR0_EL1 (kernel 页表基址)
	就自动完成了 mmu_on 页表 与 kernel 页表的切换

硬件相关

PHYS_OFFSET

179 extern s64          memstart_addr;                                               
180 /* PHYS_OFFSET - the physical address of the start of memory. */ 
include/asm/memory.h:181:#define PHYS_OFFSET            ({ VM_BUG_ON(memstart_addr & 1); memstart_addr; }

uImage 相关

参考链接中的 uImage相关

Image 相关

虚拟地址

PAGE_OFFSET

PAGE_OFFSET      在 arm64 中 承担了 什么角色 , 和 __HEAD 有什么关系

 42 #if (PAGE_OFFSET & 0x1fffff) != 0                                                
 43 #error PAGE_OFFSET must be at least 2MB aligned                                  
 44 #endif                                                                           
 45                                                                                  
 46 /*                                                                               
 47  * Kernel startup entry point.                                                   
 48  * ---------------------------                                                   
 49  *                                                                               
 50  * The requirements are:                                                         
 51  *   MMU = off, D-cache = off, I-cache = on or off,                              
 52  *   x0 = physical address to the FDT blob.                                      
 53  *                                                                               
 54  * This code is mostly position independent so you call this at                  
 55  * __pa(PAGE_OFFSET).                                                            
 56  *                                                                               
 57  * Note that the callee-saved registers are used for storing variables           
 58  * that are useful before the MMU is enabled. The allocations are described      
 59  * in the entry routines.                                                        
 60  */                                                                              
 61     __HEAD

// CONFIG_ARM64_VA_BITS=48

 36 /*                                                                               
 37  * PAGE_OFFSET - the virtual address of the start of the linear map, at the      
 38  *               start of the TTBR1 address space.                               
 39  * PAGE_END - the end of the linear map, where all other kernel mappings begin.  
 40  * KIMAGE_VADDR - the virtual address of the start of the kernel image.          
 41  * VA_BITS - the maximum number of bits for virtual addresses.                   
 42  */                                                                              
 43 #define VA_BITS         (CONFIG_ARM64_VA_BITS)       // 48                            
 44 #define _PAGE_OFFSET(va)    (-(UL(1) << (va)))                                   
 45 #define PAGE_OFFSET     (_PAGE_OFFSET(VA_BITS))      // FFFF 0000 0000 0000                      
 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) 
运行时的页表
0000000000000000 0000ffffffffffff  	256TB  user
ffff000000000000 ffff7fffffffffff 	128TB kernel logical memory map // 内核地址的线性映射区
ffff800000000000 ffff9fffffffffff   128TB // 内核地址的非线性映射区
PAGE_OFFSET 不作用于临时页表阶段,而是作用于运行时页表阶段

在运行时, ffff000000000000  应该对应 __HEAD(即 _text)

PAGE_END

PAGE_OFFSET 	= (-(UL(1) << (48))) 	= 0xFFFF000000000000
PAGE_END 		= (-(UL(1) << (48-1))) 	= 0xFFFF800000000000

TEXT_OFFSET

arm64 没有 TEXT_OFFSET 的概念

swapper_pg_dir

swapper_pg_dir 不用于临时页表阶段
位于 链接脚本顶层
122266 ffff800009791000 D idmap_pg_dir                                                  
122267 ffff800009794000 T idmap_pg_end                                                  
122268 ffff800009794000 T tramp_pg_dir                                                  
122269 ffff800009795000 T reserved_pg_dir                                               
122270 ffff800009796000 T swapper_pg_dir                                               

164401 ffff80000a1a5000 B init_pg_dir                                                   
164402 ffff80000a1a8000 B init_pg_end
164403 ffff80000a1b0000 B _end

 43  idmap_pg_dir = .;                                                             
 44  . += ((((((48)) - 4) / (12 - 3)) - 1) * (1 << 12));
 45  idmap_pg_end = .;
 46  tramp_pg_dir = .;
 47  . += (1 << 12);
 48  reserved_pg_dir = .;
 49  . += (1 << 12);
 50  swapper_pg_dir = .;                                                           
 51  . += (1 << 12);                                                               
 52  . = ALIGN(0x00010000);                                                        
 53  __init_begin = .;
 ...
 106  _edata = .;                                                                     
 107  . = ALIGN((1 << 12)); __bss_start = .; . = ALIGN((1 << 12)); .sbss : AT(ADDR(.sbss) - 0) { *(.dynsbss) *(.sbss) *(.scommon) } .
     = ALIGN(0); .bss : AT(ADDR(.bss) - 0) { __hyp_bss_start = .; *(.hyp.bss) . = ALIGN((1 << 12)); __hyp_bss_end = .; . = ALIGN((1
    << 12)); *(.bss..page_aligned) . = ALIGN((1 << 12)); *(.dynbss) *(.bss) *(COMMON) } . = ALIGN(0); __bss_stop = .;
 108  . = ALIGN((1 << 12));                                                           
 109  init_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 物理地址

runtime __pa(_text)
runtime __pa(_end)

线性映射中 物理地址和虚拟地址的转换

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 /*                                                                               
211  * Map memory for specified virtual address range. Each level of page table needed supports
212  * multiple entries. If a level requires n entries the next page table level is assumed to be
213  * formed from n pages.                                                          
214  *                                                                               
215  *  tbl:    location of page table                                               
216  *  rtbl:   address to be used for first level page table entry (typically tbl + PAGE_SIZE)
217  *  vstart: virtual address of start of range                                    
218  *  vend:   virtual address of end of range - we map [vstart, vend - 1]          
219  *  flags:  flags to use to map last level entries                               
220  *  phys:   physical address corresponding to vstart - physical memory is contiguous
221  *  pgds:   the number of pgd entries                                            
222  *                                                                               
223  * Temporaries: istart, iend, tmp, count, sv - these need to be different registers
224  * Preserves:   vstart, flags                                                    
225  * Corrupts:    tbl, rtbl, vend, istart, iend, tmp, count, sv                    
226  */                                                                              
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

  • 1 idmap
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
  • 2 kernel
x0             0x423a5000          1111117824			// init_pg_dir
x1             0x41994000          1100562432
x2             0x40                64
x3             0x40200000          1075838976 			// _text(0x40200000)
x4             0x200               512					// PTRS_PER_PGD
x5             0xffff800008000000  -140737354137600		// KIMAGE_VADDR
x6             0xffff80000a1b0000  -140737318813696		// _end(0x423b0000)-_text(0x40200000)+KIMAGE_VADDR
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
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-06-06 17:33:28  更:2022-06-06 17:34:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 0:09:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码