基于linux5.15内核翻译理解
Essentially, the boot loader should provide (as a minimum) the
following:
- Setup and initialise the RAM
- Setup the device tree
- Decompress the kernel image
- Call the kernel image
1、安装与初始化物理内存 (必须的)
boot loader需要初始化物理内存,内核将使用这些内存来存储volatile类型的数据。这个是与机器有关的,可能使用了内部算法自动的定位并取得物理内存的大小,
或者可能是机器有关内存方面的特性,也可能是boot loader设计者知道的获取内存某种方法。
2、安装设备树 (必须的)
dtb(device tree blob)必须位于8-BYTE对齐的位置并且不能超过2MB的大小。因为dtb会被映射到最大2MB的缓存块上,它不能放在任何映射了特定属性的2M区域内。
注意,在内4.2以前,要求将DTB放在内核镜像里以text_offset为起始位置的512M区域内。
3、解压内核镜像(这个是可选的)
arm64(aarch64)的内核当前并不提供自解压功能,因此需要解压在boot loader里完成(比如gzip格式)。如果boot loader不支持解压,可以使用不压缩的镜像来启动。
4、启动内核镜像
解压后的内核镜像包含64byte的头,头结构定义如下:
//u-boot-2020.04/arch/arm/lib/image.c
15 /* See Documentation/arm64/booting.txt in the Linux kernel */
16 struct Image_header {
17 uint32_t code0; /* Executable code */
18 uint32_t code1; /* Executable code */
19 uint64_t text_offset; /* Image load offset, LE */
20 uint64_t image_size; /* Effective Image size, LE */
21 uint64_t flags; /* Kernel flags, LE */
22 uint64_t res2; /* reserved */
23 uint64_t res3; /* reserved */
24 uint64_t res4; /* reserved */
25 uint32_t magic; /* Magic number */
26 uint32_t res5;
27 };//linux-5.15.73/arch/arm64/include/asm/image.h
44 struct arm64_image_header {
45 __le32 code0;
46 __le32 code1;
47 __le64 text_offset;
48 __le64 image_size;
49 __le64 flags;
50 __le64 res2;
51 __le64 res3;
52 __le64 res4;
53 __le32 magic;
54 __le32 res5;
55 };
在linux-5.15.73/arch/arm64/kernel/kexec_image.c中描述了启动过程解析header的过程;
(1)、在内核3.17版本以前,所有字段都是小端字节序,除非有特别说明。
(2)、code0/code1 是为了响应 stext 分支。
bootloader在加载完内核后,都会直接会跳转到image的头部,将控制权交给内核。无论是否打开了编译选项CONFIG_EFI,内核其实最终都会跳转到stext指明的段开始的代码处。
(3)、如果以EFI(可扩展固件接口 Extensible Firmware Interface)启动,code0/code1一开始就会被跳过。res5是指PE头和有EFI入口点(efi_stub_entry)的PE头的偏移。当efi完成了它的工作,就会跳转到 code0 的位置继续正常的启动流程。
//linux-4.19.125/arch/arm64/kernel/head.S
__HEAD
_head:/** DO NOT MODIFY. Image header expected by Linux boot-loaders.*/
#ifdef CONFIG_EFI/** This add instruction has no meaningful effect except that* its opcode forms the magic "MZ" signature required by UEFI.*/add x13, x18, #0x16b stext
#elseb stext // branch to kernel start, magic.long</