OpenHarmony移植案例與原理 - startup子系統之bootstrap_lite服務啟動引導部件(1)

      網友投稿 903 2025-04-02

      bootstrap_lite服務啟動引導組件提供了各服務和功能的啟動入口標識。在SAMGR(System ability manager,系統服務管理)啟動時,會調用bootstrap_lite標識的入口函數,并啟動系統服務。本文介紹下移植開發板時如何適配服務啟動引導部件bootstrap_lite,并介紹下相關的運行機制原理。bootstrap_lite啟動引導部件定義在build\lite\components\startup.json。bootstrap_lite啟動引導部件源代碼目錄如下:

      base/startup/bootstrap_lite/ # 啟動引導組件 └── services └── source # 啟動引導組件源文件目錄

      1、bootstrap_lite服務啟動引導部件適配示例

      1.1 產品解決方案配置啟用部件

      移植開發板適配startup子系統之bootstrap_lite服務啟動引導部件時,需要在產品解決方案的config.json增加下述配置項,可以參考vendor\bestechnic\display_demo\config.json中的配置示例:

      { "subsystem": "startup", "components": [ { "component": "bootstrap_lite" }, ...... ] },

      1.2 使用bootstrap服務啟動部件提供的初始化宏函數

      然后就可以使用bootstrap服務啟動部件提供的初始化宏函數SYS_SERVICE_INIT、APP_SERVICE_INIT等來自動初始化服務,示例代碼可以參考device\board\fnlink\v200zr\liteos_m\at\at_wifi.c中的用法,片段如下,可以看到調用了宏函數來初始化RegisterCustomATCmd函數實現的服務。device\board\bearpi\bearpi_hm_nano\app\目錄下有更多的使用示例。下文分析實現機制原理。

      static void RegisterCustomATCmd() { cmd_tbl_t cmd_list[] = { {"AT+IFCFG", 8, at_lwip_ifconfig, "AT+IFCFG - ifconfig\n"}, {"AT+STARTAP", 7, at_start_softap, "AT+STARTAP - start wifi softap\n"}, {"AT+STOPAP", 1, at_stop_softap, "AT+STOPAP - stop wifi softap\n"}, {"AT+STARTSTA", 1, at_start_wifista, "AT+STARTSTA - start wifi sta\n"}, {"AT+STOPSTA", 1, at_stop_wifista, "AT+STOPSTA - stop wifi sta\n"}, {"AT+DHCP", 3, at_setup_dhcp, "AT+DHCP - dhcp\n"}, {"AT+DHCPS", 3, at_setup_dhcps, "AT+DHCPS - dhcps\n"}, }; for (int i = 0; i < sizeof(cmd_list) / sizeof(cmd_tbl_t); i++) { console_cmd_add(&cmd_list[i]); } } SYS_SERVICE_INIT(RegisterCustomATCmd);

      1.3 鏈接腳本中增加zInit代碼段

      適配bootstrap_lite部件時,還需要在鏈接腳本文件中手動新增如下段,鏈接腳本示例可以參考//device/soc/bestechnic/bes2600/liteos_m/sdk/bsp/out/best2600w_liteos/_best2001.lds,還可以參考device\soc\hisilicon\hi3861v100\sdk_liteos\build\link\link.ld.S。從鏈接腳本片段中可以看出,有.zinitcall.bsp、.zinitcall.device、.zinitcall.core、.zinitcall.sys.service、.zinitcall.sys.feature、.zinitcall.run、.zinitcall.app.service、.zinitcall.app.feature、.zinitcall.test和.zinitcall.exit等幾種類型的段。

      /* zInit code and data - will be freed after init */ .zInit (.) : { __zinitcall_bsp_start = .; KEEP (*(.zinitcall.bsp0.init)) KEEP (*(.zinitcall.bsp1.init)) KEEP (*(.zinitcall.bsp2.init)) KEEP (*(.zinitcall.bsp3.init)) KEEP (*(.zinitcall.bsp4.init)) __zinitcall_bsp_end = .; . = ALIGN(4); __zinitcall_device_start = .; KEEP (*(.zinitcall.device0.init)) KEEP (*(.zinitcall.device1.init)) KEEP (*(.zinitcall.device2.init)) KEEP (*(.zinitcall.device3.init)) KEEP (*(.zinitcall.device4.init)) __zinitcall_device_end = .; . = ALIGN(4); __zinitcall_core_start = .; KEEP (*(.zinitcall.core0.init)) KEEP (*(.zinitcall.core1.init)) KEEP (*(.zinitcall.core2.init)) KEEP (*(.zinitcall.core3.init)) KEEP (*(.zinitcall.core4.init)) __zinitcall_core_end = .; . = ALIGN(4); __zinitcall_sys_service_start = .; KEEP (*(.zinitcall.sys.service0.init)) KEEP (*(.zinitcall.sys.service1.init)) KEEP (*(.zinitcall.sys.service2.init)) KEEP (*(.zinitcall.sys.service3.init)) KEEP (*(.zinitcall.sys.service4.init)) __zinitcall_sys_service_end = .; . = ALIGN(4); __zinitcall_sys_feature_start = .; KEEP (*(.zinitcall.sys.feature0.init)) KEEP (*(.zinitcall.sys.feature1.init)) KEEP (*(.zinitcall.sys.feature2.init)) KEEP (*(.zinitcall.sys.feature3.init)) KEEP (*(.zinitcall.sys.feature4.init)) __zinitcall_sys_feature_end = .; . = ALIGN(4); __zinitcall_run_start = .; KEEP (*(.zinitcall.run0.init)) KEEP (*(.zinitcall.run1.init)) KEEP (*(.zinitcall.run2.init)) KEEP (*(.zinitcall.run3.init)) KEEP (*(.zinitcall.run4.init)) __zinitcall_run_end = .; . = ALIGN(4); __zinitcall_app_service_start = .; KEEP (*(.zinitcall.app.service0.init)) KEEP (*(.zinitcall.app.service1.init)) KEEP (*(.zinitcall.app.service2.init)) KEEP (*(.zinitcall.app.service3.init)) KEEP (*(.zinitcall.app.service4.init)) __zinitcall_app_service_end = .; . = ALIGN(4); __zinitcall_app_feature_start = .; KEEP (*(.zinitcall.app.feature0.init)) KEEP (*(.zinitcall.app.feature1.init)) KEEP (*(.zinitcall.app.feature2.init)) KEEP (*(.zinitcall.app.feature3.init)) KEEP (*(.zinitcall.app.feature4.init)) __zinitcall_app_feature_end = .; . = ALIGN(4); __zinitcall_test_start = .; KEEP (*(.zinitcall.test0.init)) KEEP (*(.zinitcall.test1.init)) KEEP (*(.zinitcall.test2.init)) KEEP (*(.zinitcall.test3.init)) KEEP (*(.zinitcall.test4.init)) __zinitcall_test_end = .; . = ALIGN(4); __zinitcall_exit_start = .; KEEP (*(.zinitcall.exit0.init)) KEEP (*(.zinitcall.exit1.init)) KEEP (*(.zinitcall.exit2.init)) KEEP (*(.zinitcall.exit3.init)) KEEP (*(.zinitcall.exit4.init)) __zinitcall_exit_end = .; . = ALIGN(4); } > FLASH

      1.4 配置編譯時鏈接bootstrap庫

      另外,bootstrap_lite部件會編譯//base/startup/bootstrap_lite/services/source/bootstrap_service.c,該文件中,通過SYS_SERVICE_INIT將Init函數符號指定到__zinitcall_sys_service_start和__zinitcall_sys_service_end段中,由于沒有顯式調用Init函數,所以需要將它強制鏈接到最終的鏡像。可以參考device\board\goodix\gr5515_sk\liteos_m\config.gni文件中的鏈接選項。恒玄的開發板適配時,是配置到vendor\bestechnic\display_demo\config.json文件中的自己定義的配置項force_link_libs里,該配置項在device\soc\bestechnic\bes2600\BUILD.gn中被解析、鏈接。

      board_ld_flags = [ .... "-lbootstrap",

      1.5 調用OHOS_SystemInit接口

      函數void OHOS_SystemInit(void)定義在文件base\startup\bootstrap_lite\services\source\system_init.c中,在移植適配時,需要調用該接口。可以參考文件device\soc\bestechnic\bes2600\liteos_m\sdk\bsp\rtos\liteos\liteos_m\board.c中的使用示例。

      int main(void); extern void OHOS_SystemInit(void); ...... OHOS_SystemInit(); ...... while (1) { osDelay(1000); TRACE(0, "main idle"); } }

      2、bootstrap_lite服務啟動引導部件實現原理之system_init

      bootstrap_lite服務啟動部件實現了服務的自動初始化,即服務的初始化函數無需顯式調用,它是使用宏定義的方式申明,在系統啟動時自動被執行。實現原理是將服務啟動的函數通過宏申明之后,放在預定義好的zInit代碼段中,系統啟動的時候調用OHOS_SystemInit接口,遍歷該代碼段并調用其中的函數。因此在適配移植時,需要在device/soc/下面具體的芯片的鏈接腳本中添加zInit段,并且在main函數里調用OHOS_SystemInit接口。

      2.1 bootstrap_lite服務啟動引導部件的初始化宏

      bootstrap_lite服務啟動引導部件的初始化宏定義在文件utils\native\lite\include\ohos_init.h,片段如下。初始化函數宏SYS_SERVICE_INIT(func)用于標識核心系統服務的初始化入口,該宏識別的函數在啟動過程中核心系統服務優先級2階段被調用;初始化宏SYS_SERVICE_INIT_PRI(func, priority)可以指定優先級數值,優先級的取值范圍為[0,5),調用順序為0, 1, 2, 3, 4。

      /** * @brief Identifies the entry for initializing and starting a core system service by the * priority 2. * * This macro is used to identify the entry called at the priority 2 in the core system * service phase of the startup process. \n * * @param func Indicates the entry function for initializing and starting a core system service. * The type is void (*)(void). */ #define SYS_SERVICE_INIT(func) LAYER_INITCALL_DEF(func, sys_service, "sys.service") /** * @brief Identifies the entry for initializing and starting a core system service by the * specified priority. * * This macro is used to identify the entry called at the specified priority in the core system * service phase of the startup process. \n * * @param func Indicates the entry function for initializing and starting a core system service. * The type is void (*)(void). * @param priority Indicates the calling priority when starting the core system service in the * startup phase. The value range is [0,5), and the calling sequence is 0, 1, 2, 3, and 4. */ #define SYS_SERVICE_INIT_PRI(func, priority) LAYER_INITCALL(func, sys_service, "sys.service", priority)

      更多的初始化宏見下文的列表,處理這些初始化宏,還有可以指定優先級的版本XXX_PRI。

      2.2 LAYER_INITCALL宏定義

      OpenHarmony移植案例與原理 - startup子系統之bootstrap_lite服務啟動引導部件(1)

      從上文已知,bootstrap_lite服務啟動引導部件的初始化宏會調用LAYER_INITCALL_DEF和LAYER_INITCALL宏。這些宏的定義在文件utils\native\lite\include\ohos_init.h,代碼片段如下。⑴處聲明函數類型,無參無返回值。⑵處處理定義分層初始化共享庫宏LAYER_INIT_SHARED_LIB的情況,如果沒有定義該宏,則執行⑹。在文件foundation/distributedschedule/samgr_lite/samgr/BUILD.gn中定義了該宏,在移植適配芯片開發板時,沒有定義這個宏。⑶處定義5個分層初始化級別,⑷處定義7個構建值(constructor value,簡稱CTOR Value)。⑸處是宏LAYER_INITCALL的定義,該宏需要4個參數,分別是初始化服務或功能函數func;layer是分層名稱,支持的取值為device、core、sys_service、sys_feature、app_service、app_feature和run,拼裝為CTOR_VALUE_XXX;clayer參數在定義宏LAYER_INIT_SHARED_LIB時未使用;priority是優先級參數。attribute((constructor))表示這段代碼將在main函數前調用。當傳入參數為(myFunc, sys_feature, “sys.feature”, 2)時,函數宏替換為:static __attribute__((constructor(130 + 2))) void BOOT_sys_featurer2myFunc {myFunc();}。等于定義個一個新的啟動引導函數BOOT_sys_featurer2myFunc()。

      當沒有定義LAYER_INIT_SHARED_LIB宏時,執行⑹,當傳入參數為(myFunc, sys_feature, “sys.feature”, 2)時,函數宏替換為:static const InitCall __attribute__((used)) __zinitcall_sys_feature_myFunc __attribute__((section(".zinitcall.sys.feature2.init"))) = myFunc,除了__attribute__部分,等于聲明一個函數類型InitCall的變量__zinitcall_sys_feature_myFunc。該函數變量放入section段".zinitcall.sys.feature2.init"內,所以移植適配時,需要在芯片開發板的鏈接腳本里添加zInit代碼段。

      ⑴ typedef void (*InitCall)(void); #define USED_ATTR __attribute__((used)) ⑵ #ifdef LAYER_INIT_SHARED_LIB ⑶ #define LAYER_INIT_LEVEL_0 0 #define LAYER_INIT_LEVEL_1 1 #define LAYER_INIT_LEVEL_2 2 #define LAYER_INIT_LEVEL_3 3 #define LAYER_INIT_LEVEL_4 4 ⑷ #define CTOR_VALUE_device 100 #define CTOR_VALUE_core 110 #define CTOR_VALUE_sys_service 120 #define CTOR_VALUE_sys_feature 130 #define CTOR_VALUE_app_service 140 #define CTOR_VALUE_app_feature 150 #define CTOR_VALUE_run 700 ⑸ #define LAYER_INITCALL(func, layer, clayer, priority) \ static __attribute__((constructor(CTOR_VALUE_##layer + LAYER_INIT_LEVEL_##priority))) \ void BOOT_##layer##priority##func() {func();} #else ⑹ #define LAYER_INITCALL(func, layer, clayer, priority) \ static const InitCall USED_ATTR __zinitcall_##layer##_##func \ __attribute__((section(".zinitcall." clayer #priority ".init"))) = func #endif // Default priority is 2, priority range is [0, 4] #define LAYER_INITCALL_DEF(func, layer, clayer) \ LAYER_INITCALL(func, layer, clayer, 2)

      Bootstrap IoT 輕量級操作系統 LiteOS

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:《 跟老男孩學Linux運維:核心基礎篇(上)(第2版)》 —0.6 計算機和服務器的主要構成圖解
      下一篇:投資建設項目管理
      相關文章
      久久亚洲AV无码精品色午夜麻| 亚洲精品国产手机| 亚洲一区二区三区播放在线 | 亚洲中文字幕一二三四区| 亚洲美女人黄网成人女| 国产精品亚洲精品日韩已满| 亚洲中文字幕日产乱码高清app| 国产亚洲视频在线| 亚洲日本一区二区三区在线不卡| 精品国产亚洲一区二区三区在线观看| 亚洲欧美不卡高清在线| 亚洲精品无码成人| 久久久久亚洲国产AV麻豆| 亚洲成AV人片高潮喷水| WWW亚洲色大成网络.COM| 亚洲成a人片在线不卡一二三区| 亚洲爆乳少妇无码激情| yy6080亚洲一级理论| 亚洲高清无码专区视频| 精品亚洲成α人无码成α在线观看 | 亚洲中文字幕久久久一区| 亚洲人成片在线观看| 亚洲一级在线观看| 亚洲大成色www永久网址| 亚洲а∨天堂久久精品9966| 亚洲精品女同中文字幕| jizzjizz亚洲日本少妇| 亚洲国产免费综合| 亚洲午夜久久久久妓女影院| 亚洲国产成人片在线观看| 亚洲免费在线视频| 亚洲精品亚洲人成在线麻豆| 亚洲日产2021三区| 亚洲中文字幕无码久久| 婷婷亚洲综合五月天小说在线| 亚洲人成网站在线观看青青| 亚洲国产另类久久久精品黑人| 亚洲男人天堂av| 67194在线午夜亚洲| 久久精品国产亚洲AV未满十八| 亚洲日本va午夜中文字幕久久|