引言
OpenHarmony作为一款万物互联的操作系统,笼罩了从嵌入式实时物联网操作系统到挪动操作系统的全笼罩,其中内核包含LiteOS-M,LiteOS-A和Linux。LiteOS-M内核是面向IoT畛域构建的轻量级物联网操作系统内核,次要面向没有MMU的处理器,架构如图1-1所示。
图1-1 LiteOS-M架构图
Hi3861是一款高度集成的2.4GHz SoC WiFi芯片,采纳高性能 32bit 微处理器,最大工作频率 160MHz,内嵌 SRAM 352KB、ROM 288KB、Flash 2MB。目前市面上的采纳LiteOS-M的OpenHarmony开发板厂商有深开鸿、润和软件、小熊派,因为海思的SDK是以库文件的模式提供的,所以不同的Hi3861芯片开发板启动流程是一样的。
Hi3861 Boot介绍
Boot是操作系统启动之前的软件,通用叫法是bootloader,Hi3861的boot分为4局部:RomBoot、FlashBoot、LoaderBoot、 CommonBoot,如图2-1所示。
图2-1 Hi3861 Boot启动流程
● RomBoot性能包含:加载LoaderBoot到RAM,进一步利用LoaderBoot下载镜像到Flash、烧写 EFUSE, 校验并疏导FlashBoot。FlashBoot分为AB面,A面校验胜利间接启动,校验失败会去校验B面,B面校验胜利会修复A面再疏导启动,否则复位重启。
● FlashBoot性能包含:降级固件,校验并疏导固件。
● LoaderBoot性能包含:下载镜像到Flash, 烧写EFUSE(例如:平安启动/Flash加密相干密钥等)。
● CommonBoot为Flashboot与LoaderBoot共用的功能模块。
相干文件介绍
Hi3861的LiteOS-M代码是SDK中以库文件的模式提供的,尽管咱们无奈看到源代码,但这不代表咱们剖析不了启动流程,咱们能够从剖析map文件和asm这两个文件动手。这两个文件都是编译链接工具生成的,其中asm文件是汇编程序源文件,能够查看函数之间的调用关系,map文件里包含全局符号、函数地址及占用的空间和地位。map和asm文件次要作用是当开发板解体时用于剖析其解体的起因,咱们剖析函数跳转关系时并不需要晓得太多汇编,只须要晓得根本的跳转语句和赋值语句即可,这两个文件位于out目录下和操作系统固件平级的目录,如图3-1。
图3-1 Hi3861 asm和map文件位置图
一个编译实现的固件通常有以下几局部:
1) RO段包含只读代码段(code段/.text段)和常量段(RO Data段/.constdata段)。
2) RW段(.data段)指已被初始化成非0值的变量段。
3) ZI段(.bss段)指未被初始化或初始化为0的变量段。
咱们源代码的函数和字符串常量都位于text段。
LiteOS-M启动流程介绍
1) 嵌入式处理器和操作系统都具备相似的构造启动流程也大体类似,从芯片上电开始Boot把控制权交给操作系统,Hi3861从Boot跳转到操作系统代码如下:
这部分是将该地址当函数作为跳转,因为FlashBoot和kernel,是两套代码程序,他们之间没有依赖援用关系,然而他们在一个地址空间,所以间接地址跳转,这也是从Boot到kernel通用的跳转形式。
2) 芯片启动是从中断向量表的复位中断处理程序开始,接着把数据从Flash复制到RAM、清空bss数据段、初始化时钟、跳转到main函数。咱们通过查看asm文件的main函数,能够看出其中调用的函数如图4-1所示,从图4-1 咱们可得悉调用的函数包含设置串口、校验版本号、配置板子、Kernel初始化、利用初始化和操作系统的调度运行,其中main函数位于liblitekernel_flash.a(main.o)文件中。
图4-1 main函数调用关系
LOS_KernelInit是负责初始化内核数据结构的,如图4-2所示,次要函数有OsMemSystemInit(内存初始化)、OsHwiInit(中断初始化)、OsTaskInit(工作初始化) ,这些过程次要目标是把内核相干的变量初始化,筹备好全局信息,不便API函数去调用,API函数调用必须在这些初始化实现后才能够。
3) 从AppInit开始脱离了sdk,能够看到源代码了,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-2 LOS_KernelInit函数调用关系
图4-3 app_main函数调用关系
图4-4 OHOS_Main函数调用关系
图4-5 OHOS_SystemInit函数调用关系
用户利用的启动原理
1) 在图4-5中呈现的函数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-2 led_exapmle文件在map中的地位
2) 从运行角度看启动中调用到了应用程序led_exapmle,所谓地位为.zinitcall.run2.init,但咱们在应用程序中的关联函数是SYS_RUN(LedExampleEntry),SYS_RUN的开展关系如图5-3所示,最终即是 zinitcall.run2.init,和程序运行时候的调用匹配在一起了。应用程序的调用关系就是编译链接阶段生成指定的段,初始化时调用指定段,这样实现了LiteOS-M的操作系统代码与利用程序代码的解耦。
图5-3 SYS_RUN的开展关系
总结
本文向大家讲述了在没有局部源代码的状况下,如何通过对map文件和asm文件的剖析从而得出Hi3861芯片开发板LiteOS-M的启动流程。总体过程就是最小硬件零碎的配置实现后,LOS_KernelInit负责初始化零碎到一个适合的状态,AppInit调用OpenHarmony和利用相干代码,最初LOS_Start负责把操作系统运行起来。