#2020征文-开发板#SYS_RUN()和MODULE_INIT()之间的那些事

接触鸿蒙设备开发有一段时间了,也是时候好好挖一挖鸿蒙设备程序的启动流程了。app

 

破冰问题:鸿蒙设备程序从哪里开始运行的?ide

 

相信你们都已经很是清楚了,鸿蒙设备程序须要指定入口函数,具体表如今代码层面就是经过语句 SYS_RUN(app_entry); 指定,其中 app_entry 是设备程序入口函数名;而整个鸿蒙设备的启动流程也能够瓜熟蒂落的挖掘出来。以下图:函数

这看起来很是完美了,解决了全部问题!但是,我以为仍是有不清楚的地方,即:MODULE_INIT(run) 干了什么事?为何最终会调用到 app_entry() 这个入口函数?工具

 

接下来,咱们逐个问题的解决!post

 

本质问题:MODULE_INIT(run) 干了什么事?学习

 

要弄清楚这个问题,就得先来说讲 SYS_RUN() 到底是什么?!有同窗可能会认为 SYS_RUN(app_entry); 是一个函数调用语句,将设备程序入口地址注册到系统中,进而调用。从原理上这么理解没错,可细节上根本不是那么回事! SYS_RUN() 在用法上很像函数,但本质是一个宏!必须强调: 在 C 语言中没法在函数以外进行函数调用,而 SYS_RUN(app_entry); 出现的位置并不在任何函数中,因此它不多是函数调用。那会是什么呢?真相只有一个,只多是一个定义(声明)语句。为了证实这个结论,咱们将 SYS_RUN() 这个宏完全扒光了看个透彻。以下:ui

剖析:spa

最终,咱们能够知道:SYS_RUN(app_entry); 是定义了一个名为 __zinitcall_run_app_entry 的函数指针,其类型是 InitCall,不管是否使用都不会编译报错,而且强制编译使其最终存放在名为 .zinitcall.run2.init 的段中。3d

 

好!接下来就能够直接分析 MODULE_INIT(run) 了。指针

MODULE_INIT(run) 展开以后根本看不出和 app_entry 有任何关系啊!咱们用了九牛二虎之力把宏掰开了,可结果貌似一无所得!!!MODULE_INIT() 和 SYS_RUN() 之间的关系仍是很是不明朗,接下来该怎么办呢?

 

仔细观察这两个宏拼接出来的符号!

能够发现它们都和 zinitcall 有关,而且咱们也知道了 SYS_RUN(app_entry) 定义的全局指针就放在名为 .zinitcall.run2.init 的段中,因此能够推测:这个两个宏的关系是经过连接脚本关联的。

 

接下来,经过工具查看目标文件的段信息和符号信息。

经过输出能够知道,在名为 .zinitcall.run2.init 的段中确实存在 __zinitcall_run_app_entry 这个符号。

以后,动手翻源码。。。。

通过努力,咱们能够找到 \code-1.0\vendor\hisi\hi3861\hi3861\build\build_tmp\scripts\link.lds 文件,而且发现以下的脚本代码:


文章后续内容和附件能够点击下面的原文连接前往学习

原文连接:https://harmonyos.51cto.com/posts/2017#bkwz


想了解更多内容,请访问:

51CTO和华为官方战略合做共建的鸿蒙技术社区

https://harmonyos.51cto.com/#bkwz

相关文章
相关标签/搜索