OpenHarmony輕量裝置Hi3861晶片開發板啟動流程分析

OpenHarmony開發者社群發表於2022-08-18

OpenHarmony輕量裝置Hi3861晶片開發板啟動流程分析

引言

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負責把作業系統運轉起來。

               


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70011554/viewspace-2910957/,如需轉載,請註明出處,否則將追究法律責任。

相關文章