Hi3861系统LoaderBoot和FlashBoot代码分析 原创

鸿蒙开发
发布于 2021-9-15 11:24
浏览
3收藏

第一部分LoadBoot:

之前文章介绍过Hi3861启动流程,Hi3861系统启动大体流程如下:
Hi3861系统LoaderBoot和FlashBoot代码分析-鸿蒙开发者社区
其中启动liteOs之前还有RomBoot,LoaderBoot,FlashBoot三个阶段,RomBoot是固化在芯片内部看不到代码,LoaderBoot和FlashBoot可以看到代码,今天分析一下LoaderBoot代码,LoaderBoot被加载运行后,负责与HiBurn交互进行操作系统固件的烧录工作。
LoaderBoot的入口函数在如下汇编文件中:
Hi3861系统LoaderBoot和FlashBoot代码分析-鸿蒙开发者社区
start_loaderboot是主要启动函数,负责一些一些硬件的初始化和命令处理的功能,然后进入一个死循环,命令处理就是与HiBurn的交互,可以看到如下打印语句是和HiBurn运行时一样的。

Hi3861系统LoaderBoot和FlashBoot代码分析-鸿蒙开发者社区
Hi3861系统LoaderBoot和FlashBoot代码分析-鸿蒙开发者社区
然后看一下HiBurn与LoaderBoot的命令与处理函数如下:
Hi3861系统LoaderBoot和FlashBoot代码分析-鸿蒙开发者社区
这是一个函数二维数组,根据指定的命令进行相应的处理,其中loader_download_image就是下载烧录固件的函数。
最后调用loader_serial_ymodem函数下载可以看到采用的时
ymodem协议。
Hi3861系统LoaderBoot和FlashBoot代码分析-鸿蒙开发者社区

第二部分FlashBoot:
Hi3861系统LoaderBoot和FlashBoot代码分析-鸿蒙开发者社区
FlashBoot负责启动固件也就是启动操作系统的,它的入口函数如下:
Hi3861系统LoaderBoot和FlashBoot代码分析-鸿蒙开发者社区
套路很一样,配方很一样,从汇编跳转到c入口:
hi_watchdog_disable();
hi_watchdog_enable(WDG_TIME_US);
boot_io_init();
ret = serial_init(UART0, default_uart_param);
if (ret != HI_ERR_SUCCESS) {
boot_msg0(“uart err”);
}
boot_extern_32k();
boot_flash_init();
​ret = hi_flash_partition_init();
if (ret != HI_ERR_SUCCESS) {
boot_msg0(“parti err”);
}
execute_upg_boot();
start_fastboot中设置了看门狗,初始化了io,flash,nv等最后调用
execute_upg_boot,execute_upg_boot中获取配置判断是升级还是启动,然后调用boot_head,boot_head如下:
Hi3861系统LoaderBoot和FlashBoot代码分析-鸿蒙开发者社区
获取完启动地址后调用boot_kernel启动了操作系统内核,boot_kernel函数实现
如下:
hi_void boot_kernel(uintptr_t kaddr)
{
asm volatile(“ecall”); /* switch U-MODE -> M-MODE */
hi_void (entry)(hi_void) = (hi_void)(kaddr);
entry();
}
这个函数有意思吧,不光嵌入了汇编,还拿地址当函数去跳转,为啥这样,
因为FlashBoot和kernel,是两套代码程序,他们之间没有依赖引用关系,
但是他们在一个地址空间,所以直接地址跳转,这也是从boot到kernel通用
的跳转方式。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2021-9-15 11:27:22修改
4
收藏 3
回复
举报
2条回复
按时间正序
/
按时间倒序
Whyalone
Whyalone

如下:

hi_void boot_kernel(uintptr_t kaddr)
{
asm volatile(“ecall”); /* switch U-MODE -> M-MODE */
hi_void (entry)(hi_void) = (hi_void)(kaddr);
entry();
}

这个函数有意思吧,不光嵌入了汇编,还拿地址当函数去跳转,为啥这样,
因为FlashBoot和kernel,是两套代码程序,他们之间没有依赖引用关系,
但是他们在一个地址空间,所以直接地址跳转,这也是从boot到kernel通用
的跳转方式。

1
回复
2021-9-16 10:25:25
liangkz_梁开祝
liangkz_梁开祝

 

回复
2021-9-16 10:59:32
回复
    相关推荐