鴻蒙系統(tǒng)的啟動流程v2.0
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
鴻蒙系統(tǒng)的啟動流程
liangkz 2021.04.15 Ver2.0
- 目錄
- 1. 第一階段:U-Boot啟動..................................................................................... 3
- 2. 第二階段:匯編代碼引導(dǎo)LiteOS-a內(nèi)核........................................................ 3
- 3. 第三階段:內(nèi)核LiteOS-a的C語言啟動階段................................................ 4
- 4. 第四階段:鴻蒙系統(tǒng)框架層的啟動.............................................................. 14
- 5. 第四階段:鴻蒙系統(tǒng)框架層的啟動細(xì)節(jié)...................................................... 17
- 6. 鴻蒙應(yīng)用(APP)的啟動...................................................................................... 20
- 附錄A. #task命令查看進(jìn)程/線程信息(簡表).................................................... 21
聲明:
升級文檔到v2.0后可以聲明是原創(chuàng)的了。這是上了朱有鵬老師的免費(fèi)課《想讀懂鴻蒙2.0源碼,也許你需要先懂這些》(link:https://edu.51cto.com/course/27341.html?hm)之后,做的一些總結(jié)。
課程時間一個半小時,內(nèi)容也很多,學(xué)習(xí)過程中我發(fā)現(xiàn)朱老師的ppt上部分代碼/文件,在我本地的鴻蒙系統(tǒng)代碼上找不到,或者路徑不相同,所以我就做了一些整理。
這里僅摘取課程中的鴻蒙系統(tǒng)在HI3516DV300平臺上的啟動流程部分(從30:00開始講解啟動過程)進(jìn)行匯總和整理,如有錯誤,請朱老師和各位同學(xué)指正。后繼在學(xué)習(xí)過程中會繼續(xù)對本文當(dāng)作修正升級。附件升級了的v2.0文檔對閱讀更友好,歡迎下載收藏。
更新記錄:
我的本地代碼是基于最新發(fā)布的OpenHarmony 1.1.0 LTS(2021-04-01)版本抓取的,代碼根目錄OHOS1_1_0LTS:
- $repo init -u https://gitee.com/openharmony/manifest.git -b refs/tags/OpenHarmony_release_v1.1.0 --no-repo-verify
- $repo sync
在根目錄下執(zhí)行
- OHOS1_1_0LTS$ hb set
- [OHOS INFO] Input code path: .
- OHOS Which product do you need?
- ->ipcamera_hispark_taurus@hisilicon
- OHOS1_1_0LTS$ hb build
即可開始編譯 hi3516dv300 平臺代碼。
輸出的過程文件和最終bin,在以下路徑內(nèi):
- out\hispark_taurus\ipcamera_hispark_taurus
因?yàn)楸救诉€沒有開發(fā)板,無法燒錄、抓取log分析以及做相關(guān)的操作去驗(yàn)證。
1. 第一階段:U-Boot啟動
- System startup
- Uncompress Ok!
- U-Boot 2016.11 (......) hi3516dv300
- ............
- ............(省略)
- Hit any key to stop autoboot: 0
- MMC read: dev #0, block # 2048, count 16384 ... 16384 blocks read: OK
- ## Starting application at 0x80000000...
到此為止屬于U-Boot的啟動。
Uboot不屬于鴻蒙系統(tǒng),這里不做進(jìn)一步分析,代碼在目錄
- device\hisilicon\third_party\uboot\u-boot-2020.01
2. 第二階段:匯編代碼引導(dǎo)LiteOS-a內(nèi)核
Uboot引導(dǎo)liteos-a內(nèi)核啟動起來,需要有一個入口,在:
- kernel\liteos_a\tools\build\liteos.ld
打開這個文件,可見:
- ENTRY(reset_vector)
- INCLUDE board.ld
- SECTIONS
- {
- ......
- }
reset_vector 就是整個鴻蒙內(nèi)核啟動的入口點(diǎn),這是一個符號,定義在:
- kernel\liteos_a\arch\arm\arm\src\startup\reset_vector_mp.S
同目錄下還有一個reset_vector_up.S文件,因?yàn)镠I3516是ARM Cortex A7雙核處理器,所以需要看mp(多核)這個文件,up這個是單核的。
打開reset_vector_mp.S文件,找到“reset_vector:”符號,從這里開始跑匯編代碼,引導(dǎo)liteos-a內(nèi)核的啟動,一直到:
- “
- bl main
- _start_hang:
- b _start_hang
- ”
這里調(diào)用一個 main 函數(shù),然后執(zhí)行 _start_hang 進(jìn)入死循環(huán),至此匯編代碼階段就結(jié)束了。
通過main函數(shù)進(jìn)入內(nèi)核LiteOS-a啟動的C語言階段。
3. 第三階段:內(nèi)核LiteOS-a的C語言啟動階段
上面匯編階段調(diào)用的main函數(shù),位于:
- kernel\liteos_a\platform\main.c
main函數(shù)通過OsSystemInfo();函數(shù)里打印下面這些信息
- ******************Welcome******************
- Processor : Cortex-A7*2
- Run Mode : SMP
- GIC Rev : GICv2
- build time : ......
- Kernel : Huawei LiteOS 2.0.0.xxx
- ********************************************
- main core booting up...
- ...
- ...
從這一步的main開始讀liteos-a的C語言源碼,可以直接在鴻蒙代碼的
- kernel\liteos_a\platform\main.c
進(jìn)行閱讀理解。
- 不過,推薦從下面?zhèn)}庫拉代碼下來讀,
- 鴻蒙內(nèi)核源碼注解分析:
- https://gitee.com/weharmony/kernel_liteos_a_note.git
- 這是在鴻蒙官方開源項(xiàng)目 kernel_liteos_a 基礎(chǔ)上,給源代碼加上了給常詳細(xì)的中文注解,有利于加快理解。
- 需要注意的是,這個注解的內(nèi)核代碼可能版本稍舊,而上面repo下來的內(nèi)核部分代碼可能做了部分重構(gòu)和修改,會有少量的不同。
main函數(shù)截圖如下:
Line173行調(diào)用的OsMain()函數(shù),位于:
- kenerl\liteos_a\kernel\common\los_config.c
主要做了:
其中的:
- OsTickInit(......); // tick初始化,包含注冊中斷事件
硬件時鐘初始化,啟動節(jié)拍,注冊硬中斷
- OsKernelInitProcess(); // 完成內(nèi)核進(jìn)程的初始化
【鴻蒙內(nèi)核源碼注解分析上的API與OpenHarmony 1.1.0 LTS(2021-04-01)上的API,有少量差異,但功能基本上是一樣的?!?/p>
代碼都在:kernel\liteos_a\kernel\base\core\los_process.c 文件內(nèi)。
下面分別來看一下:
鴻蒙內(nèi)核源碼注解分析:OsKernelInitProcess()
OsCreateResourceFreeTask()函數(shù),下面的調(diào)用也是一樣的。
OpenHarmony 1.1.0 LTS(2021-04-01):OsSystemProcessCreate( )
由上面的代碼截圖可以看出:
- 創(chuàng)建2號進(jìn)程 KProcess,最高優(yōu)先級0,這是一個內(nèi)核態(tài)進(jìn)程。
- 創(chuàng)建KProcess的子線程ResourceTask,優(yōu)先級別5,用于資源回收
- 由KProcess復(fù)制(fork)出一個名叫 KIdle 的內(nèi)核態(tài)進(jìn)程,最低優(yōu)先級31
- KIdle進(jìn)程創(chuàng)建子線程Idle,優(yōu)先級別31,給CPU空閑的時候使用.
注意,此時1號進(jìn)程還沒有創(chuàng)建,它是用戶態(tài)根進(jìn)程,要到稍微后面才創(chuàng)建。
可以在shell內(nèi)執(zhí)行task命令查看進(jìn)程和線程信息,表格見附錄。
- OsSwtmrInit(); //軟時鐘模塊初始化
創(chuàng)建Swt_Task(software timmer)線程,父進(jìn)程是2號進(jìn)程KProcess,
- OsSystemInit(); //系統(tǒng)初始化
系統(tǒng)軟硬件的初始化,由2號進(jìn)程 KProcess創(chuàng)建“system_wq”“SystemInit”“memshow_Task”等線程。
“SystemInit”線程:
跳出內(nèi)核代碼,到外部提供的SystemInit()做系統(tǒng)初始化,在:
- device\hisilicon\hispark_taurus\sdk_liteos\mpp\module_init\src\system_init.c
里的SystemInit()函數(shù):
其中的:
- ProcFsInit()
創(chuàng)建和掛載/proc文件系統(tǒng),代碼見:
- kernel\liteos_a\fs\proc\os_adept\proc_init.c
- SDK_init() //calling SDK_init form HISI_SDK
初始化3516DV300特有的SDK,用內(nèi)部的DSP硬件來做視頻編解碼,只提供相關(guān)庫文件,不開源。
代碼在:
- device\hisilicon\hispark_taurus\sdk_liteos\mpp\module_init\src\sdk_init.c
- OsMountRootfs()
掛載根文件系統(tǒng):
- out\hispark_taurus\ipcamera_hispark_taurus\rootfs.tar
可以通過tar -tf rootfs.tar 命令查看里面都有些什么內(nèi)容,下面顯示一部分目錄:
OsUserInitProcess()
- kernel\liteos_a\kernel\base\core\los_process.c
回到內(nèi)核代碼,鴻蒙內(nèi)核源碼注解分析:OsUserInitProcess()【最新1.1.0 LTS代碼有重構(gòu),但意思一樣】
這時候才創(chuàng)建1號進(jìn)程Init,這是用戶態(tài)根進(jìn)程,優(yōu)先級別為28,
__user_init_entry 就是第一個用戶態(tài)根進(jìn)程的地址,它通過宏LITE_USER_SEC_ENTRY進(jìn)行定義:
代碼在:
- kernel\liteos_a\kernel\user\src\los_user_init.c
LiteOS_a操作系統(tǒng)起來后,到掛載根文件系統(tǒng),都處于內(nèi)核態(tài)(內(nèi)核空間),創(chuàng)建第一個用戶態(tài)根進(jìn)程Init時,
通過第一個用戶態(tài)程序的地址 __user_init_entry / LITE_USER_SEC_ENTRY [ 進(jìn)入OsUserInit() 并執(zhí)行系統(tǒng)調(diào)用
"sys_call3" 切換到用戶態(tài)(用戶空間) ] 去運(yùn)行g(shù)_initPath = "/bin/init" 程序。
簡單來說第一個用戶態(tài)根進(jìn)程,實(shí)際上運(yùn)行的就是/bin/init的代碼。
1. /kernel/liteos_a/apps目錄下,是liteoa_a自帶的內(nèi)核應(yīng)用,也就是內(nèi)核的用戶態(tài)進(jìn)程,
目前有 init、shell、tftp三個內(nèi)核應(yīng)用,編譯后會在下面路徑下生成同名的可執(zhí)行文件:
- out\hispark_taurus\ipcamera_hispark_taurus\obj\kernel\liteos_a\bin
其中init.c 做的事情很簡單,就是fork一個新的用戶態(tài)進(jìn)程并運(yùn)行"/bin/shell".
2. /base/startup/init_lite目錄下的init_lite組件(init_lite module)的詳細(xì)說明,見該目錄下的官方文檔【README_zh.md】。
查看BUILD.gn可看到它也會被編譯成 init 可執(zhí)行程序
在out\hispark_taurus\ipcamera_hispark_taurus\bin目錄下生成,同目錄下還有foundation、appspawn等可執(zhí)行程序。
3. 【疑惑、解疑】
寫本文檔的v1.0版本時,我就一直存在一個很大的疑惑,理論上LiteOS_a內(nèi)核的啟動,從內(nèi)核態(tài)切換到用戶態(tài)時,
系統(tǒng)調(diào)用["sys_call3" ]去運(yùn)行的 g_initPath = "/bin/init" ,應(yīng)該是上面1編譯出來的init才對,可是為什么會去運(yùn)行上面2編譯出來的init呢?
因?yàn)椴欢苯臃治鯾uild.py和gen_rootfs.py等編譯腳本,我只好用了最笨的分析方法,步驟如下:
3.1 可以確認(rèn)的是兩個init,大小不一樣,生成位置也不一樣,init的生成時間1要比2早大約2分鐘。
3.2 懷疑是gen_rootfs.py在生成rootfs.tar時,只拷貝了2的init而沒有拷貝1的init到rootfs/bin目錄下。
但馬上推翻了,因?yàn)?生成的shell、tftp內(nèi)核應(yīng)用同時也拷貝到了rootfs/bin目錄下,不應(yīng)該特殊處理init:
3.3 那就有可能是gen_rootfs.py在生成rootfs.tar時,先拷貝1的init/shell/tftp到/rootfs/bin,
接著再拷貝2的init/foundation/appspawn……到/rootfs/bin時,把1的init給替換掉了。
馬上驗(yàn)證一下。
重新啟動編譯,等2的init一生成,馬上將其改名為init5,等編譯完成后,重新打開rootfs.tar查看,
果不其然,rootfs/bin里面出現(xiàn)了init和init5,文件大小基本對應(yīng)得上,所以這就是真相。
3.4 有清楚gen_rootfs.py工作過程細(xì)節(jié)的同學(xué)麻煩從腳本分析入手確認(rèn)一下。
3.5 另,關(guān)于shell的疑問,也請懂的同學(xué)回復(fù)一下,這里就不分析和驗(yàn)證了:
kernel\liteos_a\apps\shell 會編譯成shell,據(jù)朱有鵬老師說這是精簡版的shell,
kernel\liteos_a\shell 這個也會編譯成shell,朱有鵬老師說是全功能版的shell,
這兩個版本的shell,哪個會在最終的gen_rootfs.py 時拷貝到 /bin 中?
通過上面的驗(yàn)證,確認(rèn)了LiteOS_a內(nèi)核的啟動,從內(nèi)核態(tài)切換到用戶態(tài)時,
系統(tǒng)調(diào)用["sys_call3" ]去運(yùn)行的 g_initPath = "/bin/init" ,確實(shí)是base\startup\init_lite 組件
編譯生成的init,也就是鴻蒙系統(tǒng)的第一個用戶態(tài)根進(jìn)程就是init_lite組件,這就進(jìn)入到了
鴻蒙系統(tǒng)的框架層framework的啟動。
4. 第四階段:鴻蒙系統(tǒng)框架層的啟動
這個應(yīng)用層實(shí)際上就是鴻蒙的framework,啟動init入口在:
- base\startup\init_lite\services\src\main.c
ReadFileToBuf()
這一步讀取的 /etc/init.cfg文件,在上面OsMountRootfs()掛載根文件系統(tǒng)的時候就掛載上了,它是
- vendor\hisilicon\hispark_taurus\init_configs\init_liteos_a_3516dv300.cfg
的副本,這個文件就包含了“pre-init”“init”“post-init”的相關(guān)操作,分別是設(shè)置掛載一些設(shè)備、設(shè)置好路徑,啟動服務(wù)等工作。
而后面的"services"則包含一組服務(wù)的定義,它們是系統(tǒng)里的關(guān)鍵進(jìn)程。
- DoJob("init")
由“1號進(jìn)程init”,在應(yīng)用層通過start指令創(chuàng)建和啟動:shell/apphilogcat/.../ai_server等3~9號進(jìn)程,它們都是用戶態(tài)進(jìn)程,父進(jìn)程都是“1號進(jìn)程init”。
init將根據(jù)上面cfg配置的job和services來做對應(yīng)的操作和啟動對應(yīng)的服務(wù)程序,并設(shè)置它們的uid、gid、進(jìn)程優(yōu)先級和權(quán)限等。
可以在shell內(nèi)執(zhí)行task命令查看進(jìn)程和線程信息,表格見文末。
- 【見官方文檔:base\startup\init_lite\README_zh.md】
- 這個init組件(即base\startup\init_lite)負(fù)責(zé)處理從內(nèi)核加載第一個用戶態(tài)進(jìn)程(1號進(jìn)程init)開始,到第一個應(yīng)用程序啟動之間的系統(tǒng)服務(wù)進(jìn)程啟動過程。
- init將系統(tǒng)啟動分為三個階段:
- “pre-init”階段:啟動系統(tǒng)服務(wù)之前需要先執(zhí)行的操作,例如掛載文件系統(tǒng)、創(chuàng)建文件夾、修改權(quán)限等
- “init”階段:系統(tǒng)服務(wù)啟動階段
- “post-init”階段:系統(tǒng)服務(wù)啟動完后還需要執(zhí)行的操作
- 上述每個階段在配置文件init.cfg中都用一個job表示,每個job都對應(yīng)一個命令集合,init通過依次執(zhí)行每個job中的命令來完成系統(tǒng)初始化。job執(zhí)行順序:先執(zhí)行“pre-init”,再執(zhí)行“init”,最后執(zhí)行“post-init”,所有job都集中放在init.cfg的jobs數(shù)組中。
- 除上述jobs數(shù)組之外,init.cfg中還有一個services數(shù)組,用于存放所有需要由init進(jìn)程啟動的系統(tǒng)關(guān)鍵服務(wù)的服務(wù)名、可執(zhí)行文件路徑、權(quán)限和其他屬性信息。
- 配置文件init.cfg位于代碼倉庫/vendor/hisilicon/hispark_aries/init_configs/目錄,部署在/etc/下,采用json格式,文件大小目前限制在100KB以內(nèi)。
- init組件會編譯成out\hispark_taurus\ipcamera_hispark_taurus目錄下的bin/init,同時打包在根文件系統(tǒng)rootfs.tar內(nèi),上面掛載根文件系統(tǒng)時,會掛載成/bin/init,由第三階段的最后一步OsUserInit()調(diào)用和執(zhí)行。
- 【見官方文檔:base\startup\init_lite\README_zh.md】
總結(jié):
Init_lite組件會編譯成out\hispark_taurus\ipcamera_hispark_taurus目錄下的bin/init,
然后在gen_rootfs.py生成rootfs.tar時替換掉系統(tǒng)自帶的內(nèi)核應(yīng)用init,成為系統(tǒng)第一個
用戶態(tài)根進(jìn)程的啟動程序。并由它開啟系統(tǒng)里的其他關(guān)鍵服務(wù)進(jìn)程。
5. 第四階段:鴻蒙系統(tǒng)框架層的啟動細(xì)節(jié)
上面第四階段簡單解釋了鴻蒙系統(tǒng)的關(guān)鍵系統(tǒng)進(jìn)程和相關(guān)服務(wù)的啟動。
這一小節(jié)就要看看shell/apphilogcat/.../ai_server等3~9號進(jìn)程的具體啟動過程和調(diào)用的相關(guān)代碼入口。
DoJob(“init”)會根據(jù)cmds的順序啟動相關(guān)服務(wù):
- "name" : "init",
- "cmds" : [
- "start shell",
- "start apphilogcat",
- "start foundation",
- "start bundle_daemon",
- "start appspawn",
- "start media_server",
- "start wms_server",
- "start hiview",
- "start sensor_service",
- "start ai_server"
- ]
這些服務(wù)程序都對應(yīng)在根目錄的/bin下存在(除了hiview?需平臺確認(rèn))
1.1 start shell
啟動shell服務(wù),進(jìn)程ID是3。精簡版和全功能版的shell,代碼分別在:
- kernel\liteos_a\apps\shell
- kernel\liteos_a\shell\full
具體跑哪個,目前存疑,待驗(yàn)證。
1.2 start apphilogcat
啟動apphilogcat服務(wù),進(jìn)程ID是4。
- base\hiviewdfx\hilog_lite
hilog_lite組件,提供DFX(Design For X,面向X的設(shè)計(jì))子系統(tǒng)在輕量系統(tǒng)和小型系統(tǒng)的流水日志功能。
詳情見目錄下的【README_zh.md】
- base\hiviewdfx\hilog_lite\services\apphilogcat\hiview_applogcat.c
- base\hiviewdfx\hilog_lite\services\hilogcat\hiview_logcat.c
main() 里面都是log文件的相關(guān)操作
1.3 start foundation
啟動foundation服務(wù),進(jìn)程ID是5。
- foundation\distributedschedule\safwk_lite
safwk_lite 是foundation進(jìn)程的實(shí)現(xiàn),負(fù)責(zé)提供基礎(chǔ)服務(wù)運(yùn)行的空進(jìn)程。
safwk_lite 屬于分布式任務(wù)調(diào)度子系統(tǒng)的一個模塊。
詳情見目錄下的【README_zh.md】 saf: system ability (SA) framework
- foundation\distributedschedule\safwk_lite\src\main.c
- main()里有調(diào)用: OHOS_SystemInit();
同文件有定義,不過是弱引用:
- void __attribute__((weak)) OHOS_SystemInit(void)
- {
- SAMGR_Bootstrap();
- }
在base\startup\bootstrap_lite\services\source\system_init.c 有另一個定義:
- void OHOS_SystemInit(void)
- {
- MODULE_INIT(bsp);
- MODULE_INIT(device);
- MODULE_INIT(core);
- SYS_INIT(service);
- SYS_INIT(feature);
MODULE_INIT(run); //SYS_RUN(HelloWorld); 從這里開始啟動,待驗(yàn)證。
- //系統(tǒng)服務(wù)框架子系統(tǒng)啟動 [system ability (SA) framework]
- //foundation\distributedschedule\samgr_lite
- SAMGR_Bootstrap();
1.4 start bundle_daemon
啟動bundle_daemon服務(wù),進(jìn)程ID是6。
- foundation\appexecfwk\appexecfwk_lite
包管理組件服務(wù),用戶程序框架子系統(tǒng)。
詳情見目錄下的【README_zh.md】
- foundation\appexecfwk\appexecfwk_lite\services\bundlemgr_lite\bundle_daemon\src\main.cpp
- main()里有調(diào)用: HOS_SystemInit();
同文件有定義,同樣是弱引用,不過暫未發(fā)現(xiàn)其他地方有定義:
- void __attribute__((weak)) HOS_SystemInit(void)
- {
- SAMGR_Bootstrap();
- }
1.5 start appspawn
啟動appspawn服務(wù),進(jìn)程ID是7。
- base\startup\appspawn_lite
appspawn_lite 應(yīng)用孵化器組件,負(fù)責(zé)接受應(yīng)用程序框架的命令孵化應(yīng)用進(jìn)程,設(shè)置其對應(yīng)權(quán)限,并調(diào)用應(yīng)用程序框架的入口。
詳情見目錄下的【README_zh.md】
- base\startup\appspawn_lite\services\src\main.c
main() 跑的流程基本上與bundle_daemon的一樣。
1.6 start media_server
啟動media_server服務(wù),進(jìn)程ID是8。
- foundation\multimedia\media_lite
media_lite媒體子系統(tǒng)組件(C++實(shí)現(xiàn)),提供播放、錄制、解析、解碼等接口能力,并提供媒體播放錄制引擎服務(wù)化能力。詳情見目錄下的【README_zh.md】
- foundation\multimedia\media_lite\services\media_main.cpp
1.7 start wms_server
啟動wms_server服務(wù),進(jìn)程ID是9。
- oundation\graphic\wms
圖形服務(wù)采用C/S架構(gòu),內(nèi)部分為窗口管理(WMS: Window Manager Service)和輸入事件管理(IMS: Input Manger Service)兩個子服務(wù)。APP調(diào)用客戶端接口完成窗口狀態(tài)獲取、事件處理等操作,服務(wù)端與硬件交互實(shí)現(xiàn)送顯、輸入事件分發(fā)等。
詳情見目錄下的【README_zh.md】
- foundation\graphic\wms\services\wms\wms.cpp
1.8 start hiview
啟動hiviewr服務(wù),進(jìn)程ID是10。
- base\hiviewdfx\hiview_lite
hiview_lite組件,提供DFX子系統(tǒng)整體的初始化功能,控制各組件按需啟動
- static void Init(void)
- {
- }
- SYS_SERVICE_INIT(Init);
1.9 start sensor_service
啟動sensor_server服務(wù),進(jìn)程ID是11。
- base\sensors\sensor_lite
泛Sensor服務(wù)子系統(tǒng)提供了輕量級sensor服務(wù)基礎(chǔ)框架。
詳情見目錄下的【README_zh.md】
1.10 start ai_server
啟動ai_server服務(wù),進(jìn)程ID是12。
- foundation\ai\engine
AI業(yè)務(wù)子系統(tǒng)是OpenHarmony提供原生的分布式AI能力的子系統(tǒng)。
詳情見目錄下的【README_zh.md】
5.11 HMOS的Service
HMOS的init進(jìn)程啟動后,接下來會啟動上面一系列的服務(wù)(應(yīng)該還會有其他更多的),對于這些服務(wù),鴻蒙OS有一個統(tǒng)一管理,所有的服務(wù)都被注冊到如下的動態(tài)數(shù)組當(dāng)中。
- base\startup\init_lite\services\src\init_service_manager.c
- static Service* g_services = NULL;
- static int g_servicesCnt = 0;
具體情況需閱讀代碼進(jìn)行理解。
6. 鴻蒙應(yīng)用(APP)的啟動
在hi3516dv300平臺(帶屏幕)的桌面(也就是launcher進(jìn)程)上點(diǎn)擊camera應(yīng)用圖標(biāo),這時候會啟動camera應(yīng)用程序,實(shí)際上會通過“7號進(jìn)程appspawn”創(chuàng)建子進(jìn)程“com.huawei.camera”,這是一個應(yīng)用程序進(jìn)程,其父進(jìn)程并不是launcher進(jìn)程,而是appspawn進(jìn)程。
實(shí)際上所有的應(yīng)用程序的父進(jìn)程都是appspawn進(jìn)程。
鴻蒙應(yīng)用開發(fā)的第一個示例程序“helloworld”的啟動也應(yīng)該類似。
- #include <stdio.h>
- #include "ohos_init.h"
- #include "ohos_types.h"
- void HelloWorld(void)
- {
- printf("[Init] Hello World!\n");
- }
- SYS_RUN(HelloWorld);
關(guān)于SYS_RUN()如何運(yùn)作,以便讓HelloWorld運(yùn)行起來,其他老師有非常詳細(xì)的解釋,這里不再復(fù)述。
附錄A. #task命令查看進(jìn)程/線程信息(簡表)
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)