了解更多开源内容请访问:开源基础软件社区https://ost.51cto.comOpenHarmony轻量器Hi3861启动过程分析芯片开发板Linux。LiteOS-M内核是为物联网领域打造的轻量级物联网操作系统内核。它主要用于没有MMU的处理器。架构如图1-1所示。图1-1LiteOS-M架构图Hi3861是一款高度集成的2.4GHzSoCWiFi芯片,采用高性能32位微处理器,最高工作频率160MHz,内嵌352KBSRAM、288KBROM和2MBFlash。目前市面上使用LiteOS-M的OpenHarmony开发板厂商有神凯鸿、润禾软件、雄派等。由于海思的SDK是以库文件的形式提供的,所以不同的Hi3861芯片开发板的启动流程是一样的。的。Hi3861Boot介绍Boot是操作系统启动前的软件。通用名称是bootloader。Hi3861的引导分为四个部分:RomBoot、FlashBoot、LoaderBoot。CommonBoot,如图2-1所示。图2-1Hi3861Boot启动流程●RomBoot功能包括:加载LoaderBoot到RAM,进一步使用LoaderBoot下载image到Flash,编程EFUSE,验证并启动FlashBoot。FlashBoot分为A面和A面,如果A面验证成功,则直接启动。如果验证失败,则转到B侧。如果B侧验证成功,则修复A侧,然后开机。否则,它将被重置并重新启动。●FlashBoot功能包括:升级固件、验证和启动固件。●LoaderBoot功能包括:下载镜像到Flash,烧录EFUSE(例如:secureboot/Flash加密相关密钥等)。●CommonBoot是Flashboot和LoaderBoot共享的一个功能模块。相关文档介绍,Hi3861的LiteOS-M代码在SDK中以库文件的形式提供。虽然看不到源码,但不代表不能分析启动过程。我们可以分析map文件和asm文件。开始。这两个文件是通过编译链接工具生成的。asm文件是一个汇编程序源文件。可以查看函数之间的调用关系。映射文件包括全局符号、函数地址以及占用的空间和位置。map和asm文件的主要作用是在开发板死机时分析死机原因。我们在分析函数跳转关系的时候,不需要了解太多的汇编。我们只需要知道基本的跳转语句和赋值语句即可。这两个文件位于out目录下与操作系统固件相同的目录下,如图3-1所示。图3-1Hi3861asm和map文件位置图一个编译好的固件通常有以下几个部分:1)RO段包括只读代码段(codesegment/.textsegment)和常量段(RODatasegment/.constdatasegment)).2)RW段(.data段)是指已经初始化为非零值的可变段。3)ZI段(.bss段)是指未初始化或初始化为0的变量段。我们源代码的函数和字符串常量位于text段。LiteOS-M启动过程介绍1)嵌入式处理器和操作系统结构相似,启动过程也大致相似。从芯片上电开始,Boot将控制权交给操作系统,Hi3861从Boot跳转到操作系统。代码如下:这部分是使用地址作为函数进行跳转,因为FlashBoot和kernel是两套代码程序,它们之间没有依赖和引用关系,而是在同一个地址空间,所以直接地址跳转,也是从Boot到Kernel的通用跳转方式。2)芯片从中断向量表的resetinterrupthandler开始,然后将数据从Flash拷贝到RAM,清除bss数据段,初始化时钟,跳转到main函数。通过查看asm文件的main函数,我们可以看到调用的函数如图4-1所示。由图4-1可知,调用的函数包括设置串口、校验版本号、配置板卡、初始化Kernel。,应用程序初始化和操作系统的调度运行,其中main函数位于liblitekernel_flash.a(main.o)文件中。图4-1主要函数调用关系LOS_KernelInit负责初始化内核数据结构,如图4-2所示,主要函数有OsMemSystemInit(内存初始化)、OsHwiInit(中断初始化)、OsTaskInit(任务初始化),主要这些进程的目的是初始化内核相关变量,准备全局信息,方便API函数调用。API函数调用必须在这些初始化完成后完成。3)从没有sdk的AppInit启动,可以看到源码,AppInit函数位于libwifiiot_app.a(app_main.o)中,部分截图如图4-3,源码为app_main.c,调用函数包括获取SDK版本号、外设初始化、ipc初始化、flash分区、WiFi初始化、tcp/ip初始化,然后跳转到OpenHarmony独有的函数OHOS_Main。OHOS_Main位于libwifiiot_app.a(ohos_main.o)中,源代码为ohos_main.c,主要完成OpenHarmony系统和用户应用相关的调用。里面的主要函数是OHOS_SystemInit,如图4-4所示,它调用了用户自己编写的应用程序的应用任务相关代码,如图4-5所示,实现了在LOS_start之前填充任务列表,所以以确保用户任务或定时功能参与系统调度。图4-2LOS_KernelInit函数调用关系图4-3app_main函数调用关系图4-4OHOS_Main函数调用关系图4-5OHOS_SystemInit函数调用关系用户应用启动原理1)函数MODULE_INIT(run),是调用代码最后调用用户程序。这是一个宏定义,扩展调用关系:\base\startup\bootstrap_lite\services\source\core_main.h定义,从MODULE_CALL,MODULE_BEGIN,MODULE_END,最终调用地址为__zinitcall_##name##_start,MODULE_INIT(run)调用的函数地址为__zinitcall_run_start。通过查看链接文件,发现__zinitcall_run_start中包含.zinitcall.run0.init),如图5-1所示。图5-1__zinitcall_run_start链接关系查看map文件,发现我们自己的应用程序文件在.zinitcall.run2.init中,如图5-2所示。图5-2led_exapmle文件在图中的位置2)从运行来看,应用程序led_exapmle在启动时被调用,所谓的位置是.zinitcall.run2.init,但是我们在应用程序中的关联函数就是SYS_RUN(LedExampleEntry),SYS_RUN的展开关系如图5-3所示,最后就是zinitcall.run2.init,匹配程序运行时的调用。应用程序的调用关系是在编译链接阶段生成指定段,在初始化时调用指定段,实现了操作系统代码与LiteOS-M应用程序代码的解耦。图5-3SYS_RUN扩展关系汇总本文介绍了如何通过分析map文件和asm文件获取Hi3861芯片开发板LiteOS-M的启动过程,不包含部分源码。整体流程是,最小硬件系统配置完成后,LOS_KernelInit负责将系统初始化到合适的状态,AppInit调用OpenHarmony和应用相关代码,最后LOS_Start负责运行操作系统。了解更多开源知识,请访问:开源基础软件社区https://ost.51cto.com。
