当前位置: 首页 > 工具软件 > OpenSBI > 使用案例 >

OpenSBI简介-2

华星驰
2023-12-01

OpenSBI的启动分析

以fw_jump为例,从fw_jump.elf.ldS看到入口函数就是ENTRY(_start), _start定义在fw_base.S里面。
主要的启动流程都在fw_base.S里面,另外的三个文件主要是提供一些回调函数,不同的fw回调函数不同的实现方式。

3.1 初始化的大致流程
	下面概述下boot的大概流程
	1. 获取boot hart的id。对于fw_dynamic, fw_jump, fw_payload三种类型的fw, 获取boot hart的方法是不一样的。
		fw_jump和fw_payload这里直接返回-1, fw_dynamic这种fw情况有点不一样,启动fw_dynamic的上一级程序会把
		参数放到struct fw_dynamic_info里,用a2传给opensbi。

	2. 负责启动的core进行初始化,其他hart跳转到_wait_reocate_copy_done,等候启动hart完成初始化
	
	3. 重定位(动态库重定位,或加载地址和链接地址不相等的代码拷贝)
		把fw从当前运行的位置拷贝到编译是指定的位置,和uboot kernel的代码重定向是一样的。
	
	4. 设置boot阶段标志位BOOT_STATUES_RELOCATE_DONE,然后其他的core根据新的重定向后的代码,
		跳到_wait_for_boot_hart,等待初始化core的下一步的初始化
	
	5. 初始化core reset所有的寄存器,设置堆栈,清除BSS段
	
	6. 为每一个core分配堆栈和scrash空间,初始化scratch(即struct sbi_scratch结构体,此结构如图scrathch布局.png)
	
	7. 设备树重定位
	
	8. boot阶段设置为BOOT_STATUS_BOOT_HART_DONE,主core进入_start_warm,从core判断BOOT_STATUS_BOOT_HART_DONE到了后,
		延迟几个nop后也进入_start_warm。从core 执行3条nop指令是为了让boot core执行的最快。
	
	9. 也就是说所有的core都要执行_start_warm,也就是说所有的core都要执行下面的几个步骤
	
	10. 关闭和清理所有中断
	11. 设置mscratch和sp寄存器
	12. 设置mtvec trap处理寄存器为_trap_handler函数地址
	13. 调用c函数sbi_init
	14. 进一步的初始化,初始化一些板级资源,然后jump到下一级的boot
		通过函数sbi_hart_switch_mode(unsigned long arg0, unsigned long arg1, unsigned long next_addr, unsigned long next_mode, bool next_virt)
		跳到下一级boot,其中a0=arg0;a1=arg1; arg0里面是hart id, arg1里面是fdt的地址,如果有,没有就是0.
 类似资料: