潤小云解讀鴻蒙OS系列(七):鴻蒙OS的第一個用戶態進程init

Init是鴻蒙OS的第一個用戶態進程,相似於如今Linux發行版中的systemdInit進程的代碼在base\startup\services\init_lite實現。shell

 

main函數數組

本函數的註解很是清晰,總共4步,app

  1. 打印系統信息
  2. 註冊信號處理函數
  3. 讀取系統配置文件並進行相關處理
  4. 進入循環等待信號處理

 

下面分別解讀一下1-3步的相關代碼ide

 

PrintSysInfo函數函數

本函數主要功能就是打印系統信息。post

詳細的看GetVersionId函數,因爲代碼比較長,咱們主要看核心處理的部分:ui

主要功能就是獲取設備的相關類型,廠商,品牌,型號等信息。具體看一個函數GetProductTypespa

咱們能夠看到,只是調用了硬件抽象層的函數HalGetProcutType,而這個函數依據不一樣的硬件有不一樣的實現,所以咱們就不繼續往下深刻了。操作系統

 

SignalInitModule函數3d

 

從信號處理函數來看,init進程主要助理兩個信號,SIGCHLDSIGTERM

先說簡單的SIGTERM信號,這時候init會經過StopAllService函數結束全部的系統服務。若是是收到某個服務終止的SIGCHLD信號,則要視服務的重要性進行處理,有可能重啓系統。具體服務包括哪些則經過配置文件進行定義,後續詳細說明。

 

InitReadCfg函數

InitReadCfg這個函數,感受名稱不是很合適,由於不光是讀了配置文件,實際還經過DoJob函數,執行了不少啓動前,中和後的操做。

配置文件的地址以下:

#define INIT_CONFIGURATION_FILE "/etc/init.cfg"

看一下具體init.cfg的一個例子,來自於HiSpark AI Camera套件

vendor\huawei\camera\init_configs\init_liteos_a_3516dv300.cfg

這裏面定義了init先後中須要執行的jobs以及init啓動完成以後啓動的服務。

 

{

    "jobs" : [{

            "name" : "pre-init",

            "cmds" : [

                "mkdir /storage/data/log",

                "chmod 0755 /storage/data/log",

                "chown 4 4 /storage/data/log",

                "mkdir /storage/data/softbus",

                "chmod 0700 /storage/data/softbus",

                "chown 7 7 /storage/data/softbus",

                "mkdir /sdcard",

                "chmod 0777 /sdcard",

                "mount vfat /dev/mmcblk0 /sdcard rw,umask=000",

                "mount vfat /dev/mmcblk1 /sdcard rw,umask=000"

            ]

        }, {

            "name" : "init",

            "cmds" : [

                "start shell",

                "start apphilogcat",

                "start foundation",

                "start bundle_daemon",

                "start appspawn",

                "start media_server",

                "start wms_server"

            ]

        }, {

            "name" : "post-init",

            "cmds" : [

                "chown 0 99 /dev/dev_mgr",

                "chown 0 99 /dev/hdfwifi",

                "chown 0 99 /dev/gpio",

                "chown 0 99 /dev/i2c-0",

                "chown 0 99 /dev/i2c-1",

                "chown 0 99 /dev/i2c-2",

                "chown 0 99 /dev/i2c-3",

                "chown 0 99 /dev/i2c-4",

                "chown 0 99 /dev/i2c-5",

                "chown 0 99 /dev/i2c-6",

                "chown 0 99 /dev/i2c-7",

                "chown 0 99 /dev/uartdev-0",

                "chown 0 99 /dev/uartdev-1",

                "chown 0 99 /dev/uartdev-2",

                "chown 0 99 /dev/uartdev-3",

                "chown 0 99 /dev/spidev0.0",

                "chown 0 99 /dev/spidev1.0",

                "chown 0 99 /dev/spidev2.0",

                "chown 0 99 /dev/spidev2.1"

         ]

        }

    ],

    "services" : [{

            "name" : "foundation",

            "path" : "/bin/foundation",

            "uid" : 7,

            "gid" : 7,

            "once" : 0,

            "importance" : 1,

            "caps" : [10, 11, 12, 13]

        }, {

            "name" : "shell",

            "path" : "/bin/shell",

            "uid" : 2,

            "gid" : 2,

            "once" : 0,

            "importance" : 0,

            "caps" : [4294967295]

        }, {

            "name" : "appspawn",

            "path" : "/bin/appspawn",

            "uid" : 1,

            "gid" : 1,

            "once" : 0,

            "importance" : 0,

            "caps" : [2, 6, 7, 8, 23]

        }, {

            "name" : "apphilogcat",

            "path" : "/bin/apphilogcat",

            "uid" : 4,

            "gid" : 4,

            "once" : 1,

            "importance" : 0,

            "caps" : []

        }, {

            "name" : "media_server",

            "path" : "/bin/media_server",

            "uid" : 5,

            "gid" : 5,

            "once" : 1,

            "importance" : 0,

            "caps" : []

        }, {

            "name" : "wms_server",

            "path" : "/bin/wms_server",

            "uid" : 0,

            "gid" : 0,

            "once" : 1,

            "importance" : 0,

            "caps" : []

        }, {

            "name" : "bundle_daemon",

            "path" : "/bin/bundle_daemon",

            "uid" : 8,

            "gid" : 8,

            "once" : 0,

            "importance" : 0,

            "caps" : [0, 1]

        }

    ]

}

 

 

鴻蒙OSService

鴻蒙OSinit進程啓動後,如上面的例子所示init進程接下來會啓動不少服務,對於這些服務,鴻蒙OS有一個統一管理,全部的服務都被註冊到以下的動態數組當中。

 

Service的定義

從定義中不難看出,對於每一個Service,除了基本的名字,可執行文件路徑,進程id,還記錄了這個Servicecrash次數和第一次crash的時間,另外還定義了Service的屬性和權限。

對於屬性,參考以下常量定義,主要是在該Service奔潰以後是否須要重啓。

// service attributes

#define SERVICE_ATTR_INVALID      0x001  // option invalid

#define SERVICE_ATTR_ONCE         0x002  // do not restart when it exits

#define SERVICE_ATTR_NEED_RESTART 0x004  // will restart in the near future

#define SERVICE_ATTR_NEED_STOP    0x008  // will stop in reap

#define SERVICE_ATTR_IMPORTANT    0x010  // will reboot if it crash

 

對於Perms,則依據操做系統的定義而不一樣。

 

對於Service,都有啓動,中止和重啓三個動做。

 

對於Service Manager,則提供瞭如下動做:

void RegisterServices(Service* services, int servicesCnt);

void StartServiceByName(const char* serviceName);

void StopAllServices();

void ReapServiceByPID(int pid);
相關文章
相關標籤/搜索