linux 内核ARM64启动

基于linux5.15内核翻译理解

Essentially, the boot loader should provide (as a minimum) the
following:

  1. Setup and initialise the RAM
  2. Setup the device tree
  3. Decompress the kernel image
  4. 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指明的段开始的代码处。
linux 内核ARM64启动_第1张图片

(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, #0x16
    b   stext
#else
    b   stext               // branch to kernel start, magic
    .long

你可能感兴趣的:(Linux基础,嵌入式硬件,linux,arm)