ARM64 Linux的启动分析

来源:互联网 发布:ubuntu安装samba 编辑:程序博客网 时间:2024/06/08 03:12

ARM64 Linux的启动分析

 

1.     找到Linux启动流程

Linux启动,会启动内核编译后的文件vmlinux

vmlinux是一个ELF文件,按照./arch/arm64/kernel/vmlinux.lds设定的规则进行链接的

./arch/arm64/kernel/vmlinux.lds 是 ./arch/arm64/kernel/vmlinux.lds.S编译之后生成的

 

通过readelf可以看到vmlinux的入口地址为:0xfffffe0000080000


 

这个地址是怎么来的,对应内核代码中的哪个代码呢?最简单的方法是反汇编

对vmlinux反汇编的命令为:objdump -dxh vmlinux > vmlinux.s

在查找地址0xfffffe0000080000:grep fffffe0000080000 vmlinux.s

可以看到linux的第一条指令为:x13, x18, #0x16,对应的符号是:.head.text efi_head _text

 

查看ARM64的head.S可以看到如下代码

/*

 * Kernel startup entry point.

 * ---------------------------

 *

 * The requirements are:

 *   MMU = off, D-cache = off, I-cache = on or off,

 *   x0 = physical address to the FDT blob.

 *

 * This code is mostly position independent so you call this at

 * __pa(PAGE_OFFSET + TEXT_OFFSET).

 *

 * Note that the callee-saved registers are used for storing variables

 * that are useful before the MMU is enabled. The allocations are described

 * in the entry routines.

 */

              __HEAD

 

              /*

               * DO NOT MODIFY. Image header expected by Linux boot-loaders.

               */

#ifdef CONFIG_EFI

efi_head:

              /*

               * 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    0                                                      // reserved

#endif

 

HEAD为一个宏定义:#define __HEAD                  .section    ".head.text","ax"

 

如此就都对应上了:

第一个地址为__HEAD下面的指令,即efi_head标号内容

第一个指令为add         x13, x18,#0x16

紧接着就跳转到传统的启动地方b     stext

Stext 最后会调用启动内核函数  start_kernel

 

其实,总结一句话,就是在head.S中,紧挨着_HEAD下面的就是第一条执行的指令

在看ARM32的

         __HEAD

ENTRY(stext)

 ……

 

所以,加载vmlinux后,第一个就开始执行stext

 

2.     Vmlinux地址链接原理

 

前面讲了,vmlinux是按照vmlinux.lds链接的,vmlinux.lds是由vmlinux.lds.S生成的

 

看看vmlinux.lds.S就可以理解了

 

TEXT_OFFSET是在Makefile中定义的

vim ./arch/arm64/Makefile

可以是随机的,一般情况下定义为固定的0x80000

 

3.     地址的跳转

上电,CPU跳转到固定的一个地址执行UEFI代码

UEFI从vmlinux的头读取到入口地址为0xfffffe0000080000

因为已经使能过了MMU,所以找到虚拟地址0xfffffe0000080000,跳转到内核入口,开始加重内核

原创粉丝点击