跳转内核前基本准备
参考./Documentation/arm64/booting.txt
Bootloader至少完成以下基本的初始化准备:
设置并初始化RAM(必须),引导加载程序应找到并初始化内核将用于系统中易失性数据存储的所有RAM。它以机器相关的方式执行此操作。(它可以使用内部算法来自动定位和调整所有RAM的大小,或者可以使用机器中RAM的知识或引导加载程序设计者认为合适的任何其他方法。)
设置设备树dtb(必须) , 设备树blob(dtb)必须8字节对齐,并且大小不能超过2兆字节。由于dtb将使用最大2 MB的块进行映射以可缓存,因此它不能放置在必须使用任何特定属性进行映射的任何2M区域内。注意:v4.2之前的版本还要求将DTB放置在512 MB区域内,从内核映像下方的text_offset字节开始计算。
解压缩内核映像(可选),AArch64内核当前不提供解压缩器,因此如果使用压缩的Image目标(例如Image.gz),则需要由引导加载程序执行解压缩(gzip等)。对于未实现此要求的引导加载程序,可以使用未经压缩内核编译。
调用内核映像(必须)。压缩内核头部如下:
u32 code0; /* 可执行code */
u32 code1; /* 可执行code */
u64 text_offset; /* 加载偏移,小端 */
u64 image_size; /* 有效映象尺寸,小端 */
u64 flags; /* 内核标志, 小端 */
u64 res2 = 0; /* 保留 */
u64 res3 = 0; /* 保留 */
u64 res4 = 0; /* 保留 */
u32 magic = 0x644d5241; /* 幻数,小端, "ARM\x64" */
u32 res5; /* 保留(用于PE COFF偏移量) */
进入内核之前,必须满足以下条件:
禁止所有具有DMA功能的设备,以免内存被虚假错误的网络数据包或磁盘数据损坏。
主CPU通用寄存器设置:
x0 =系统RAM中设备树Blob(dtb)的物理地址。
x1/x2/x3 = 0(保留供将来使用)
CPU模式
所有形式的中断都必须在PSTATE.DAIF中屏蔽(调试,SError,IRQ和FIQ)。
CPU必须位于EL2(推荐使用,以便可以访问虚拟化扩展)或非安全EL1中。
Caches, MMUs
MMU必须关闭。
指令缓存可以打开或关闭。
与加载的内核映像相对应的地址范围必须清除到PoC。如果存在系统缓存或启用了缓存的其他相关主服务器,则通常需要通过VA而不是通过设置/方式操作来维护缓存。
遵循VA对架构化缓存维护的系统缓存。必须配置并启用操作。
不遵循VA对架构化混存维护的系统缓存,必须配置和禁用操作(不推荐)。
架构定时器
必须在所有CPU上以定时器频率设置CNTFRQ,并且必须以一致的值设置CNTVOFF。如果在EL1处进入内核,则CNTHCTL_EL2必须在可用时设置EL1PCTEN(位0)。
连贯性
内核启动时,所有要由内核引导的CPU都必须属于同一一致性域。需要初始化定义的实现,才能在每个CPU上接收维护操作。
系统寄存器
所有将在其中输入内核映像的异常级别的可写体系结构系统寄存器都必须由更高级别的异常级别的软件初始化,以防止在UNKNOWN状态下执行。
对CPU模式,高速缓存,MMU,架构计时器,一致性和系统寄存器的要求适用于所有CPU。所有CPU必须以相同的异常级别进入内核。
主CPU必须直接跳转到内核映像的第一条指令。此CPU传递的设备树Blob必须为每个cpu节点包含一个“启用方法”属性。支持的启用方法如下所述。引导加载程序将生成这些设备树属性,并将其插入内核入口之前的blob中。
具有“旋转表”启用方法的CPU在其cpu节点中必须具有“ cpu-release-addr”属性。此属性标识自然对齐的64位零初始化内存位置。
具有“ psci”启用方法的CPU应该保留在内核之外(即,在内存节点中描述给内核的内存区域之外,或者在内核中通过/ memreserve /描述给内核描述的内存保留区域之外)。设备树)。内核将按照ARM文档编号ARM DEN 0022A(“ ARM处理器上的电源状态协调接口系统软件”)中的说明发出CPU_ON调用,以将CPU带入内核。设备树应包含一个“ psci”节点,参考/bindings/arm/psci.txt.
第二CPU通用寄存器设置的x0/x1/x2/x3都为0,保留。
内核启动init总过程
内核启动有两种方式,压缩格式或不压缩格式,压缩模式所不同的就是其入口位于arch/
—END—
如果喜欢右下点个在看,也会让我倍感鼓舞
关注置顶:扫描左下二维码关注公众号加星
讨论加群:扫描右下二维码添加,发送“加群”关注 | 加群 |