1.前言
本文基于高通8996平台,kernel版本为3.18.31。
在lk执行的最后会调用boot_linux,它是通过SMC #0指令引发异常,从而进入到secure world,当然异常处理是位于QSEE,这部分代码没有开放,但是我们相应的通过参数传递了解压后的kernel image的地址和dtb的地址,按照arm boot specific我们有理由相信QSEE会将dtb地址赋值给x0,并跨过kernel image的偏移TEXT_OFFSET,执行head.S的第一条指令。
2.如何执行到head.S的第一条指令?
vmlinux.lds中定义了入口点:
ENTRY(_text)
SECTIONS
{
......
. = PAGE_OFFSET + TEXT_OFFSET;
.head.text : {
_text = .;
HEAD_TEXT
}
.......
}
其中PAGE_OFFSET为kernel image的相对0地址的虚拟地址偏移
#./arch/arm64/include/asm/memory.h
#define PAGE_OFFSET (UL(0xffffffffffffffff) << (VA_BITS - 1))
TEXT_OFFSET为kernel image的真实内容的偏移。
也就是说PAGE_OFFSET+TEXT_OFFSET为kernel真实内容的地址
#arch/arm64/Makefile
#The byte offset of the kernel image in RAM from the start of RAM.
ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y)
TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%03x000\n", int(512 * rand())}')
else
TEXT_OFFSET := 0x00080000
endif
因此_text的地址实际就是PAGE_OFFSET + TEXT_OFFSET,也就是head.S的文本段的首地址,因此当跳转到kernel image时就会从head.S的第一条指令开始运行,即:
b stext
实际上vmlinux.lds链接kernel image时,前0x80000(TEXT_OFFSET)是空置的,也就是从kernel image偏移TEXT_OFFSET才是kernel image的真实内容,也就是head.s的文本段,其中head.S前64字节为Image header:
.quad _kernel_offset_le // Image load offset from start of RAM, little-endian
.quad _kernel_size_le // Effective size of kernel image, little-endian
.quad _kernel_flags_le // Informative flags, little-endian
.quad 0 // reserved
.quad 0 // reserved
.quad 0 // reserved
.byte 0x41 // Magic number, "ARM\x64"
.byte 0x52
.byte 0x4d
.byte 0x64
以方便bootloader来拷贝内核
由于在lk启动kernel时,是通过SMC进入到QSEE,并传递了参数:kernel image首地址和dtb地址,因此有理由相信QSEE会从kernel image首地址+TEXT_OFFSET的位置取出head.S的第一条指令来执行。
参考文档
1.https://blog.csdn.net/xichangbao/article/details/51568782
2.https://www.cnblogs.com/smartjourneys/diary/2017/04/27/6774121.html
3.http://www.wowotech.net/armv8a_arch/arm64_initialize_1.html ARM64的启动过程之(一):内核第一个脚印
3.http://www.wowotech.net/armv8a_arch/create_page_tables.html ARM64的启动过程之(二):创建启动阶段的页表
4.http://www.wowotech.net/armv8a_arch/__cpu_setup.html ARM64的启动过程之(三):为打开MMU而进行的CPU初始化
5.http://www.wowotech.net/armv8a_arch/turn-on-mmu.html ARM64的启动过程之(四):打开MMU
6.https://blog.csdn.net/xichangbao/article/details/51568782 Kernel启动流程源码解析 1 head.S
7.https://blog.csdn.net/xichangbao/article/details/51605462 Kernel启动流程源码解析 2 head.S