自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

2020征文-鴻蒙開發(fā)板SYS_RUN()和MODULE_INIT()之間的那些事

開發(fā)
相信大家都已經(jīng)非常清楚了,鴻蒙設(shè)備程序需要指定入口函數(shù),具體表現(xiàn)在代碼層面就是通過語句 SYS_RUN(app_entry); 指定,其中 app_entry 是設(shè)備程序入口函數(shù)名;而整個(gè)鴻蒙設(shè)備的啟動(dòng)流程也可以順理成章的挖掘出來。

[[357534]]

想了解更多內(nèi)容,請(qǐng)?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

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

 接觸鴻蒙設(shè)備開發(fā)有一段時(shí)間了,也是時(shí)候好好挖一挖鴻蒙設(shè)備程序的啟動(dòng)流程了。

破冰問題:鴻蒙設(shè)備程序從哪里開始運(yùn)行的?

相信大家都已經(jīng)非常清楚了,鴻蒙設(shè)備程序需要指定入口函數(shù),具體表現(xiàn)在代碼層面就是通過語句 SYS_RUN(app_entry); 指定,其中 app_entry 是設(shè)備程序入口函數(shù)名;而整個(gè)鴻蒙設(shè)備的啟動(dòng)流程也可以順理成章的挖掘出來。如下圖:

這看起來非常完美了,解決了所有問題!可是,我覺得還是有不清楚的地方,即:MODULE_INIT(run) 干了什么事?為什么最終會(huì)調(diào)用到 app_entry() 這個(gè)入口函數(shù)?

接下來,我們逐個(gè)問題的解決!

本質(zhì)問題:MODULE_INIT(run) 干了什么事?

要弄清楚這個(gè)問題,就得先來講講 SYS_RUN() 究竟是什么?!有同學(xué)可能會(huì)認(rèn)為 SYS_RUN(app_entry); 是一個(gè)函數(shù)調(diào)用語句,將設(shè)備程序入口地址注冊到系統(tǒng)中,進(jìn)而調(diào)用。從原理上這么理解沒錯(cuò),可細(xì)節(jié)上根本不是那么回事! SYS_RUN() 在用法上很像函數(shù),但本質(zhì)是一個(gè)宏!必須強(qiáng)調(diào): 在 C 語言中無法在函數(shù)之外進(jìn)行函數(shù)調(diào)用,而 SYS_RUN(app_entry); 出現(xiàn)的位置并不在任何函數(shù)中,所以它不可能是函數(shù)調(diào)用。那會(huì)是什么呢?真相只有一個(gè),只可能是一個(gè)定義(聲明)語句。為了證明這個(gè)結(jié)論,我們將 SYS_RUN() 這個(gè)宏徹底扒光了看個(gè)透徹。如下:

剖析:

最終,我們可以知道:SYS_RUN(app_entry); 是定義了一個(gè)名為 __zinitcall_run_app_entry 的函數(shù)指針,其類型是 InitCall,無論是否使用都不會(huì)編譯報(bào)錯(cuò),并且強(qiáng)制編譯使其最終存放在名為 .zinitcall.run2.init 的段中。

好!接下來就可以直接分析 MODULE_INIT(run) 了。

MODULE_INIT(run) 展開之后根本看不出和 app_entry 有任何關(guān)系啊!我們用了九牛二虎之力把宏掰開了,可結(jié)果貌似一無所獲!!!MODULE_INIT() 和 SYS_RUN() 之間的關(guān)系還是非常不明朗,接下來該怎么辦呢?

仔細(xì)觀察這兩個(gè)宏拼接出來的符號(hào)!


可以發(fā)現(xiàn)它們都和 zinitcall 有關(guān),并且我們也知道了 SYS_RUN(app_entry) 定義的全局指針就放在名為 .zinitcall.run2.init 的段中,所以可以推測:這個(gè)兩個(gè)宏的關(guān)系是通過鏈接腳本關(guān)聯(lián)的。

接下來,通過工具查看目標(biāo)文件的段信息和符號(hào)信息。


通過輸出可以知道,在名為 .zinitcall.run2.init 的段中確實(shí)存在 __zinitcall_run_app_entry 這個(gè)符號(hào)。

之后,動(dòng)手翻源碼。。。。

經(jīng)過努力,我們可以找到 \code-1.0\vendor\hisi\hi3861\hi3861\build\build_tmp\scripts\link.lds 文件,并且發(fā)現(xiàn)如下的腳本代碼:


這樣就真相大白了:

SYS_RUN(app_entry) 定義的函數(shù)指針 __zinitcall_run_app_entry 通過強(qiáng)制編譯的方式進(jìn)入 .zinitcall.run2.init 段中。在鏈接腳本中定義的兩個(gè)符號(hào) __zinitcall_run_start (理解為數(shù)組名)和 __zinitcall_run_end 分別指向 __zinitcall_run_app_entry 所在數(shù)據(jù)段的起始位置和結(jié)束位置。 又因?yàn)? MODULE_INIT(run) 的功能就是遍歷 __zinitcall_run_start 和 __zinitcall_run_end 所指定的區(qū)域(理解為函數(shù)指針數(shù)組),并調(diào)用每個(gè)單元(指針)所指向的函數(shù),因此,__zinitcall_run_app_entry 所指向的函數(shù)必然被調(diào)用,即:app_entry() 必然被調(diào)用。

更進(jìn)一步閱讀這個(gè)鏈接腳本可知:目標(biāo)文件中的 .zinitcall.run2.init 段最終會(huì)被鏈接并匯編進(jìn)一個(gè)名為 .zInit 的數(shù)據(jù)段中!

查看最終可執(zhí)行程序中的符號(hào)信息和段信息可證明這個(gè)結(jié)論。

最終可執(zhí)行程序中存在 __zinitcall_run_app_entry , __zinitcall_run_start 以及 __zinitcall_run_end, 并且 __zinitcall_run_app_entry 和 __zinitcall_run_start 的地址均為 0x004aeb1c,根據(jù)輸出的段信息可知,它們均位于 .zInit 段中。證畢!

總結(jié):

  1. 通過強(qiáng)制編譯鏈接構(gòu)成一個(gè)全局指針數(shù)組(每個(gè) SYS_RUN() 定義一個(gè)數(shù)組元素)
  2. 在鏈接腳本中定義符號(hào)自動(dòng)確認(rèn)這個(gè)數(shù)組的起始地址和結(jié)束地址
  3. MODULE_INIT() 通過遍歷的方式調(diào)用數(shù)組元素所指向的函數(shù)

PS:

大家如果感興趣可以自己親手動(dòng)手實(shí)驗(yàn)一下,所需材料和工具可在文末附件中下載。

1)編譯附件中的 hello_world 工程(基于Hi3861)

2)將下面編譯得到的目標(biāo)文件拷貝到工具目錄

\code-1.0\out\wifiiot\obj\applications\sample\wifi-iot\app\hello_world\hello_world.o

\code-1.0\out\wifiiot\Hi3861_wifiiot_app.out

3)執(zhí)行命令觀察結(jié)果

./nm hello_world.o

./objdump -h hello_world.o

./nm Hi3861_wifiiot_app.out

./objdump -h Hi3861_wifiiot_app.out

感嘆一下,這真是一個(gè)精妙絕倫的設(shè)計(jì)方案!這樣設(shè)計(jì),理論上支持任意多的設(shè)備程序,開發(fā)者只需要簡單的指定程序入口即可,完全不用關(guān)心背后的機(jī)制,也不用擔(dān)心最多支持多少程序的問題。

這一招,學(xué)到了!!!

想了解更多內(nèi)容,請(qǐng)?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

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

【編輯推薦】

 

責(zé)任編輯:jianghua 來源: 鴻蒙社區(qū)
相關(guān)推薦

2020-12-29 09:59:01

鴻蒙HarmonyOS智能家居

2020-12-16 10:05:48

鴻蒙開發(fā)板Onenet平臺(tái)

2020-12-15 11:57:49

Hi3861 HarmonyOS開發(fā)板

2020-12-10 12:12:32

鴻蒙開發(fā)板init_lite

2018-03-01 15:03:11

2020-12-07 12:34:33

開發(fā)板鴻蒙hello world

2020-12-11 12:45:04

鴻蒙Hi3861游戲

2020-12-21 09:57:52

OLED溫濕度計(jì)hi3861

2020-11-02 10:23:23

helloworld

2012-07-13 00:03:08

WEB前端開發(fā)WEB開發(fā)

2018-04-09 08:55:05

LinuxWindows頁面緩存

2022-04-01 15:54:01

DHCP網(wǎng)絡(luò)協(xié)議開發(fā)板

2012-08-30 09:41:23

移動(dòng)應(yīng)用開發(fā)

2020-12-17 12:06:49

鴻蒙應(yīng)用鴻蒙開發(fā)

2020-11-17 12:15:36

MQTT開發(fā)

2022-10-14 15:55:24

環(huán)境搭建鴻蒙

2021-12-30 16:12:07

鴻蒙HarmonyOS應(yīng)用

2010-08-12 13:39:46

Flex組件

2011-07-19 15:33:57

iPhone

2011-08-01 17:31:25

Xcode開發(fā) Cocoa
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)