导言

OpenHarmony作为一款万物互联的操作体系,覆盖了从嵌入式实时物联网操作体系到移动操作体系的全覆盖,其间内核包括LiteOS-M,LiteOS-A和Linux。LiteOS-M内核是面向IoT范畴构建的轻量级物联网操作体系内核,首要面向没有MMU的处理器,架构如图1-1所示。

OpenHarmony轻量设备Hi3861芯片开发板发动流程剖析
图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所示。

OpenHarmony轻量设备Hi3861芯片开发板发动流程剖析

图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。

OpenHarmony轻量设备Hi3861芯片开发板发动流程剖析

图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跳转到操作体系代码如下:

OpenHarmony轻量设备Hi3861芯片开发板发动流程剖析

这部分是将该地址当函数作为跳转,由于FlashBoot和kernel,是两套代码程序,他们之间没有依赖引证联系,可是他们在一个地址空间,所以直接地址跳转,这也是从Boot到kernel通用的跳转方法。

  1. 芯片发动是从中止向量表的复位中止处理程序开端,接着把数据从Flash复制到RAM、清空bss数据段、初始化时钟、跳转到main函数。咱们经过检查asm文件的main函数,能够看出其间调用的函数如图4-1所示,从图4-1 咱们可得知调用的函数包括设置串口、校验版本号、装备板子、Kernel初始化、使用初始化和操作体系的调度工作,其间main函数坐落liblitekernel_flash.a(main.o)文件中。

OpenHarmony轻量设备Hi3861芯片开发板发动流程剖析

图4-1 main函数调用联系

LOS_KernelInit是担任初始化内核数据结构的,如图4-2所示,首要函数有OsMemSystemInit(内存初始化)、OsHwiInit(中止初始化)、OsTaskInit(使命初始化) ,这些进程首要意图是把内核相关的变量初始化,准备好大局信息,便利API函数去调用,API函数调用有必要在这些初始化完成后才干够。

  1. 从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之前把使命列表填好,这样才干确保用户使命或定时等功用参加了体系调度。

OpenHarmony轻量设备Hi3861芯片开发板发动流程剖析
图4-2 LOS_KernelInit函数调用联系

OpenHarmony轻量设备Hi3861芯片开发板发动流程剖析

图4-3 app_main函数调用联系

OpenHarmony轻量设备Hi3861芯片开发板发动流程剖析

图4-4 OHOS_Main函数调用联系

OpenHarmony轻量设备Hi3861芯片开发板发动流程剖析

图4-5 OHOS_SystemInit函数调用联系

用户使用的发动原理

  1. 在图4-5中出现的函数MODULE_INIT(run),便是调用终究调用用户程序的代码。

这是个宏界说,展开的调用联系 :basestartupbootstrap_liteservicessourcecore_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所示。

OpenHarmony轻量设备Hi3861芯片开发板发动流程剖析

图5-1 __zinitcall_run_start链接联系

检查map文件发现咱们自己的使用程序文件就在.zinitcall.run2.init中,如图5-2所示。

OpenHarmony轻量设备Hi3861芯片开发板发动流程剖析
图5-2 led_exapmle文件在map中的方位

  1. 从工作视点看发动中调用到了使用程序led_exapmle,所谓方位为.zinitcall.run2.init,但咱们在使用程序中的关联函数是SYS_RUN(LedExampleEntry),SYS_RUN的展开联系如图5-3所示,终究即是 zinitcall.run2.init,和程序工作时分的调用匹配在一起了。使用程序的调用联系便是编译链接阶段生成指定的段,初始化时调用指定段,这样完成了LiteOS-M的操作体系代码与使用程序代码的解耦。

OpenHarmony轻量设备Hi3861芯片开发板发动流程剖析
图5-3 SYS_RUN的展开联系

总结

本文向大家叙述了在没有部分源代码的情况下,怎么经过对map文件和asm文件的剖析然后得出Hi3861芯片开发板LiteOS-M的发动流程。总体进程便是最小硬件体系的装备完成后,LOS_KernelInit担任初始化体系到一个合适的状况,AppInit调用OpenHarmony和使用相关代码,最后LOS_Start担任把操作体系工作起来。

OpenHarmony轻量设备Hi3861芯片开发板发动流程剖析