OpenHarmony移植案例原理 - startup子系统之bootstrap_lite服务启动引导部件(2)

网友投稿 854 2022-05-30

2.3 OHOS_SystemInit函数

函数OHOS_SystemInit()定义在文件base\startup\bootstrap_lite\services\source\system_init.c,代码如下。调用宏函数MODULE_INIT、SYS_INIT和函数SAMGR_Bootstrap()进行初始化启动。

void OHOS_SystemInit(void) { MODULE_INIT(bsp); MODULE_INIT(device); MODULE_INIT(core); SYS_INIT(service); SYS_INIT(feature); MODULE_INIT(run); SAMGR_Bootstrap(); }

我们详细分析下宏函数MODULE_INIT和SYS_INIT的源代码,这2个宏函数在文件base\startup\bootstrap_lite\services\source\core_main.h中定义,代码如下。这些宏函数的参数大都为name和step,name取值为bsp、device、core、service、feature、run,step取值为0。从⑺和⑻处可以看出,分别调用SYS_CALL、MODULE_CALL两个宏,第二个参数设置为0。⑸处定义的MODULE_BEGIN函数,用于返回链接脚本中定义的代码段的开始地址,当传入参数为bsp时,返回&__zinitcall_bsp_start,MODULE_BEGIN函数被展开为如下片段:

{ extern InitCall __zinitcall_sys_start; \ InitCall *initCall = &__zinitcall_bsp_start; \ (initCall); \ }

⑹处定义的MODULE_END函数,用于返回链接脚本中定义的代码段的结束地址,当传入参数为bsp时,返回&__zinitcall_bsp_end,MODULE_END函数被展开为如下片段:

{ extern InitCall __zinitcall_bsp_end; \ InitCall *initCall = &__zinitcall_bsp_end; \ (initCall); \ }

⑶和⑷处定义的SYS_BEGIN、SYS_END代码类似,分于返回链接脚本中定义的标记系统服务或特性的代码段的开始、结束地址,即&__zinitcall_sys_service_start、&__zinitcall_sys_service_end、&__zinitcall_sys_feature_start、&__zinitcall_sys_feature_end。⑴处定义的SYS_CALL函数,分别获取链接脚本中zInit代码段的开始initcall和结束地址initend,这些地址存放的是初始化函数的地址,语句 (*initcall)()会循环调用执行这些初始化函数。⑵处MODULE_CALL宏类似。

⑴ #define SYS_CALL(name, step) \ do { \ InitCall *initcall = (InitCall *)(SYS_BEGIN(name, step)); \ InitCall *initend = (InitCall *)(SYS_END(name, step)); \ for (; initcall < initend; initcall++) { \ (*initcall)(); \ } \ } while (0) ⑵ #define MODULE_CALL(name, step) \ do { \ InitCall *initcall = (InitCall *)(MODULE_BEGIN(name, step)); \ InitCall *initend = (InitCall *)(MODULE_END(name, step)); \ for (; initcall < initend; initcall++) { \ (*initcall)(); \ } \ } while (0) ...... ⑶ #define SYS_BEGIN(name, step) \ ({ extern InitCall __zinitcall_sys_##name##_start; \ InitCall *initCall = &__zinitcall_sys_##name##_start; \ (initCall); \ }) ⑷ #define SYS_END(name, step) \ ({ extern InitCall __zinitcall_sys_##name##_end; \ InitCall *initCall = &__zinitcall_sys_##name##_end; \ (initCall); \ }) ⑸ #define MODULE_BEGIN(name, step) \ ({ extern InitCall __zinitcall_##name##_start; \ InitCall *initCall = &__zinitcall_##name##_start; \ (initCall); \ }) ⑹ #define MODULE_END(name, step) \ ({ extern InitCall __zinitcall_##name##_end; \ InitCall *initCall = &__zinitcall_##name##_end; \ (initCall); \ }) ⑺ #define SYS_INIT(name) \ do { \ SYS_CALL(name, 0); \ } while (0) ⑻ #define MODULE_INIT(name) \ do { \ MODULE_CALL(name, 0); \ } while (0)

3、 bootstrap_lite服务启动引导部件实现原理之bootstrap_service

在文件base\startup\bootstrap_lite\services\source\bootstrap_service.h中定义了2个宏函数INIT_APP_CALL和INIT_TEST_CALL,分别用来调用代码段&__zinitcall_app_XXX_start、&__zinitcall_app_XXX_end和&__zinitcall_test_start、&__zinitcall_test_end之间的初始化启动函数。bootstrap_service.h文件中的宏和base\startup\bootstrap_lite\services\source\core_main.h文件中的宏类似,不再一一分析。

3.1 结构体struct Bootstrap

在文件base\startup\bootstrap_lite\services\source\bootstrap_service.c中定义了结构体struct Bootstrap,如下代码⑵处。其中结构体中的INHERIT_SERVICE定义在文件foundation/distributedschedule/samgr_lite/interfaces/kits/samgr/service.h,见代码片段⑴处。

⑴ #define INHERIT_SERVICE \ const char *(*GetName)(Service * service); \ BOOL (*Initialize)(Service * service, Identity identity); \ BOOL (*MessageHandle)(Service * service, Request * request); \ TaskConfig (*GetTaskConfig)(Service * service) ...... ⑵ typedef struct Bootstrap { INHERIT_SERVICE; Identity identity; uint8 flag; } Bootstrap;

结构体Identity定义在文件foundation\distributedschedule\samgr_lite\interfaces\kits\samgr\message.h中,用于标识一个服务或特性。

/** * @brief Identifies a service and feature. * * You can use this structure to identity a {@link IUnknown} feature to which messages will be * sent through the asynchronous function of {@link IUnknown}. \n * */ struct Identity { /** Service ID */ int16 serviceId; /** Feature ID */ int16 featureId; /** Message queue ID */ MQueueId queueId; };

3.2 Init(void)函数

讲解移植适配示例时,我们已经知道,bootstrap_lite部件会编译//base/startup/bootstrap_lite/services/source/bootstrap_service.c,该文件通过函数宏SYS_SERVICE_INIT将Init()函数符号灌段到__zinitcall_sys_service_start和__zinitcall_sys_service_end代码段中,代码片段如下。下文再详细分析GetName、Initialize、MessageHandle和GetTaskConfig函数。

static const char *GetName(Service *service); static BOOL Initialize(Service *service, Identity identity); static TaskConfig GetTaskConfig(Service *service); static BOOL MessageHandle(Service *service, Request *request); static void Init(void) { static Bootstrap bootstrap; bootstrap.GetName = GetName; bootstrap.Initialize = Initialize; bootstrap.MessageHandle = MessageHandle; bootstrap.GetTaskConfig = GetTaskConfig; bootstrap.flag = FALSE; SAMGR_GetInstance()->RegisterService((Service *)&bootstrap); } SYS_SERVICE_INIT(Init);

3.3 GetName和Initialize函数

GetName函数代码如下,其中BOOTSTRAP_SERVICE定义在文件foundation\distributedschedule\samgr_lite\interfaces\kits\samgr\samgr_lite.h中,取值为"Bootstrap",表示启动引导服务。

static const char *GetName(Service *service) { (void)service; return BOOTSTRAP_SERVICE; }

Initialize函数定义如下,用于设置启动引导服务的标识信息。

static BOOL Initialize(Service *service, Identity identity) { Bootstrap *bootstrap = (Bootstrap *)service; bootstrap->identity = identity; return TRUE; }

3.4 MessageHandle函数和GetTaskConfig函数

MessageHandle函数和GetTaskConfig函数代码如下,MessageHandle函数用于处理各种请求,请求消息编号定义request->msgId定义在文件foundation\distributedschedule\samgr_lite\interfaces\kits\samgr\samgr_lite.h中的枚举enum BootMessage,如下⑴处所示。在MessageHandle函数中,当请求的消息编号为BOOT_SYS_COMPLETED系统服务初始化完成时,检查应用服务是否加载。当应用没有加载时,执行INIT_APP_CALL宏函数调用zInit代码段上的应用服务和应用特性初始化函数。然后执行⑶,调用函数SAMGR_SendResponseByIdentity进行响应。GetTaskConfig函数用于获取任务配置。

⑴ typedef enum BootMessage { /** Message indicating that the core system service is initialized */ /** 标识核心系统服务初始化完成 */ BOOT_SYS_COMPLETED, /** Message indicating that the system and application-layer services are initialized */ /** 标识应用层服务初始化完成 */ BOOT_APP_COMPLETED, /** Message indicating service registration during running */ /** 标识运行时的服务注册 */ BOOT_REG_SERVICE, /** Maximum number of message IDs */ /** 标识消息最大值,butt是烟蒂;屁股;枪托的意思,表示尾部吧 */ BOOTSTRAP_BUTT } BootMessage; ...... static BOOL MessageHandle(Service *service, Request *request) { Bootstrap *bootstrap = (Bootstrap *)service; switch (request->msgId) { case BOOT_SYS_COMPLETED: ⑵ if ((bootstrap->flag & LOAD_FLAG) != LOAD_FLAG) { INIT_APP_CALL(service); INIT_APP_CALL(feature); bootstrap->flag |= LOAD_FLAG; } ⑶ (void)SAMGR_SendResponseByIdentity(&bootstrap->identity, request, NULL); break; case BOOT_APP_COMPLETED: (void)SAMGR_SendResponseByIdentity(&bootstrap->identity, request, NULL); break; case BOOT_REG_SERVICE: (void)SAMGR_SendResponseByIdentity(&bootstrap->identity, request, NULL); break; default: break; } return TRUE; } static TaskConfig GetTaskConfig(Service *service) { (void)service; // The bootstrap service uses a stack of 2 KB (0x800) in size and a queue of 20 elements. // You can adjust it according to the actual situation. TaskConfig config = {LEVEL_HIGH, PRI_NORMAL, 0x800, 20, SHARED_TASK}; return config; }

参考站点

OpenHarmony / startup_bootstrap_lite

HarmonyOS Device > 文档 > 指南 > 基础能力: bootstrap服务启动组件

启动恢复子系统.md

轻量带屏解决方案之恒玄芯片移植案例

小结

OpenHarmony移植案例与原理 - startup子系统之bootstrap_lite服务启动引导部件(2)

本文介绍了startup子系统之bootstrap_lite服务启动引导部件的移植适配案例及原理。因为时间关系,仓促写作,或能力限制,若有失误之处,请各位读者多多指正。感谢阅读,有什么问题,请留言。

Bootstrap IoT 轻量级操作系统 LiteOS

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:华为FusionInsight MRS实战 - Flink增强特性之可视化开发平台FlinkSever开发学习
下一篇:IT运维服务规范(模板)
相关文章