1d9f0492fSopenharmony_ci/*
2d9f0492fSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License.
5d9f0492fSopenharmony_ci * You may obtain a copy of the License at
6d9f0492fSopenharmony_ci *
7d9f0492fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8d9f0492fSopenharmony_ci *
9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and
13d9f0492fSopenharmony_ci * limitations under the License.
14d9f0492fSopenharmony_ci */
15d9f0492fSopenharmony_ci#include "init.h"
16d9f0492fSopenharmony_ci
17d9f0492fSopenharmony_ci#include <errno.h>
18d9f0492fSopenharmony_ci#include <poll.h>
19d9f0492fSopenharmony_ci#include <stdarg.h>
20d9f0492fSopenharmony_ci#include <stdlib.h>
21d9f0492fSopenharmony_ci#include <signal.h>
22d9f0492fSopenharmony_ci#include <time.h>
23d9f0492fSopenharmony_ci#include <sys/sysmacros.h>
24d9f0492fSopenharmony_ci#include <sys/stat.h>
25d9f0492fSopenharmony_ci#include <sys/types.h>
26d9f0492fSopenharmony_ci#include <sys/socket.h>
27d9f0492fSopenharmony_ci#include <linux/major.h>
28d9f0492fSopenharmony_ci
29d9f0492fSopenharmony_ci#include "config_policy_utils.h"
30d9f0492fSopenharmony_ci#include "device.h"
31d9f0492fSopenharmony_ci#include "fd_holder_service.h"
32d9f0492fSopenharmony_ci#include "key_control.h"
33d9f0492fSopenharmony_ci#include "init_control_fd_service.h"
34d9f0492fSopenharmony_ci#include "init_log.h"
35d9f0492fSopenharmony_ci#include "init_mount.h"
36d9f0492fSopenharmony_ci#include "init_group_manager.h"
37d9f0492fSopenharmony_ci#include "init_param.h"
38d9f0492fSopenharmony_ci#include "init_service.h"
39d9f0492fSopenharmony_ci#include "init_service_manager.h"
40d9f0492fSopenharmony_ci#include "init_utils.h"
41d9f0492fSopenharmony_ci#include "securec.h"
42d9f0492fSopenharmony_ci#include "fd_holder_internal.h"
43d9f0492fSopenharmony_ci#include "bootstage.h"
44d9f0492fSopenharmony_ci
45d9f0492fSopenharmony_cistatic int FdHolderSockInit(void)
46d9f0492fSopenharmony_ci{
47d9f0492fSopenharmony_ci    int sock = -1;
48d9f0492fSopenharmony_ci    int on = 1;
49d9f0492fSopenharmony_ci    int fdHolderBufferSize = FD_HOLDER_BUFFER_SIZE; // 4KiB
50d9f0492fSopenharmony_ci    sock = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
51d9f0492fSopenharmony_ci    if (sock < 0) {
52d9f0492fSopenharmony_ci        INIT_LOGE("Failed to create fd holder socket, err = %d", errno);
53d9f0492fSopenharmony_ci        return -1;
54d9f0492fSopenharmony_ci    }
55d9f0492fSopenharmony_ci
56d9f0492fSopenharmony_ci    setsockopt(sock, SOL_SOCKET, SO_RCVBUFFORCE, &fdHolderBufferSize, sizeof(fdHolderBufferSize));
57d9f0492fSopenharmony_ci    setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
58d9f0492fSopenharmony_ci
59d9f0492fSopenharmony_ci    if (access(INIT_HOLDER_SOCKET_PATH, F_OK) == 0) {
60d9f0492fSopenharmony_ci        INIT_LOGI("%s exist, remove it", INIT_HOLDER_SOCKET_PATH);
61d9f0492fSopenharmony_ci        unlink(INIT_HOLDER_SOCKET_PATH);
62d9f0492fSopenharmony_ci    }
63d9f0492fSopenharmony_ci    struct sockaddr_un addr;
64d9f0492fSopenharmony_ci    addr.sun_family = AF_UNIX;
65d9f0492fSopenharmony_ci    if (strncpy_s(addr.sun_path, sizeof(addr.sun_path),
66d9f0492fSopenharmony_ci        INIT_HOLDER_SOCKET_PATH, strlen(INIT_HOLDER_SOCKET_PATH)) != 0) {
67d9f0492fSopenharmony_ci        INIT_LOGE("Failed to copy fd hoder socket path");
68d9f0492fSopenharmony_ci        close(sock);
69d9f0492fSopenharmony_ci        return -1;
70d9f0492fSopenharmony_ci    }
71d9f0492fSopenharmony_ci    socklen_t len = (socklen_t)(offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path) + 1);
72d9f0492fSopenharmony_ci    if (bind(sock, (struct sockaddr *)&addr, len) < 0) {
73d9f0492fSopenharmony_ci        INIT_LOGE("Failed to binder fd folder socket %d", errno);
74d9f0492fSopenharmony_ci        close(sock);
75d9f0492fSopenharmony_ci        return -1;
76d9f0492fSopenharmony_ci    }
77d9f0492fSopenharmony_ci
78d9f0492fSopenharmony_ci    // Owned by root
79d9f0492fSopenharmony_ci    if (lchown(addr.sun_path, 0, 0)) {
80d9f0492fSopenharmony_ci        INIT_LOGW("Failed to change owner of fd holder socket, err = %d", errno);
81d9f0492fSopenharmony_ci    }
82d9f0492fSopenharmony_ci    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
83d9f0492fSopenharmony_ci    if (fchmodat(AT_FDCWD, addr.sun_path, mode, AT_SYMLINK_NOFOLLOW)) {
84d9f0492fSopenharmony_ci        INIT_LOGW("Failed to change mode of fd holder socket, err = %d", errno);
85d9f0492fSopenharmony_ci    }
86d9f0492fSopenharmony_ci    INIT_LOGI("Init fd holder socket done");
87d9f0492fSopenharmony_ci    return sock;
88d9f0492fSopenharmony_ci}
89d9f0492fSopenharmony_ci
90d9f0492fSopenharmony_civoid SystemInit(void)
91d9f0492fSopenharmony_ci{
92d9f0492fSopenharmony_ci    CloseStdio();
93d9f0492fSopenharmony_ci#ifndef STARTUP_INIT_TEST
94d9f0492fSopenharmony_ci    // Set up a session keyring that all processes will have access to.
95d9f0492fSopenharmony_ci    KeyCtrlGetKeyringId(KEY_SPEC_SESSION_KEYRING, 1);
96d9f0492fSopenharmony_ci#endif
97d9f0492fSopenharmony_ci    // umask call always succeeds and return the previous mask value which is not needed here
98d9f0492fSopenharmony_ci    (void)umask(DEFAULT_UMASK_INIT);
99d9f0492fSopenharmony_ci    MakeDirRecursive("/dev/unix/socket", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
100d9f0492fSopenharmony_ci    int sock = FdHolderSockInit();
101d9f0492fSopenharmony_ci    if (sock >= 0) {
102d9f0492fSopenharmony_ci        RegisterFdHoldWatcher(sock);
103d9f0492fSopenharmony_ci    }
104d9f0492fSopenharmony_ci    InitControlFd();
105d9f0492fSopenharmony_ci
106d9f0492fSopenharmony_ci    // sysclktz 0
107d9f0492fSopenharmony_ci    struct timezone tz = { 0 };
108d9f0492fSopenharmony_ci    if (settimeofday(NULL, &tz) == -1) {
109d9f0492fSopenharmony_ci        INIT_LOGE("Set time of day failed, err = %d", errno);
110d9f0492fSopenharmony_ci    }
111d9f0492fSopenharmony_ci}
112d9f0492fSopenharmony_ci
113d9f0492fSopenharmony_civoid LogInit(void)
114d9f0492fSopenharmony_ci{
115d9f0492fSopenharmony_ci    int ret = mknod("/dev/kmsg", S_IFCHR | S_IWUSR | S_IRUSR,
116d9f0492fSopenharmony_ci        makedev(MEM_MAJOR, DEV_KMSG_MINOR));
117d9f0492fSopenharmony_ci    if (ret == 0) {
118d9f0492fSopenharmony_ci        OpenLogDevice();
119d9f0492fSopenharmony_ci    }
120d9f0492fSopenharmony_ci}
121d9f0492fSopenharmony_ci
122d9f0492fSopenharmony_cistatic void WriteUptimeSysParam(const char *param, const char *uptime)
123d9f0492fSopenharmony_ci{
124d9f0492fSopenharmony_ci    char buf[64];
125d9f0492fSopenharmony_ci
126d9f0492fSopenharmony_ci    if (uptime == NULL) {
127d9f0492fSopenharmony_ci        snprintf_s(buf, sizeof(buf), sizeof(buf) - 1,
128d9f0492fSopenharmony_ci                   "%lld", GetUptimeInMicroSeconds(NULL));
129d9f0492fSopenharmony_ci        uptime = buf;
130d9f0492fSopenharmony_ci    }
131d9f0492fSopenharmony_ci    SystemWriteParam(param, uptime);
132d9f0492fSopenharmony_ci}
133d9f0492fSopenharmony_ci
134d9f0492fSopenharmony_ciINIT_TIMING_STAT g_bootJob = {{0}, {0}};
135d9f0492fSopenharmony_ci
136d9f0492fSopenharmony_cistatic void RecordInitBootEvent(const char *initBootEvent)
137d9f0492fSopenharmony_ci{
138d9f0492fSopenharmony_ci    const char *bootEventArgv[] = {"init", initBootEvent};
139d9f0492fSopenharmony_ci    PluginExecCmd("bootevent", ARRAY_LENGTH(bootEventArgv), bootEventArgv);
140d9f0492fSopenharmony_ci    return;
141d9f0492fSopenharmony_ci}
142d9f0492fSopenharmony_ci
143d9f0492fSopenharmony_ciINIT_STATIC void BootStateChange(int start, const char *content)
144d9f0492fSopenharmony_ci{
145d9f0492fSopenharmony_ci    if (start == 0) {
146d9f0492fSopenharmony_ci        clock_gettime(CLOCK_MONOTONIC, &(g_bootJob.startTime));
147d9f0492fSopenharmony_ci        RecordInitBootEvent(content);
148d9f0492fSopenharmony_ci        INIT_LOGI("boot job %s start.", content);
149d9f0492fSopenharmony_ci    } else {
150d9f0492fSopenharmony_ci        clock_gettime(CLOCK_MONOTONIC, &(g_bootJob.endTime));
151d9f0492fSopenharmony_ci        RecordInitBootEvent(content);
152d9f0492fSopenharmony_ci        long long diff = InitDiffTime(&g_bootJob);
153d9f0492fSopenharmony_ci        INIT_LOGI("boot job %s finish diff %lld us.", content, diff);
154d9f0492fSopenharmony_ci        if (strcmp(content, "boot") == 0) {
155d9f0492fSopenharmony_ci            WriteUptimeSysParam("ohos.boot.time.init", NULL);
156d9f0492fSopenharmony_ci        }
157d9f0492fSopenharmony_ci    }
158d9f0492fSopenharmony_ci}
159d9f0492fSopenharmony_ci
160d9f0492fSopenharmony_cistatic void InitLoadParamFiles(void)
161d9f0492fSopenharmony_ci{
162d9f0492fSopenharmony_ci    if (InUpdaterMode() != 0) {
163d9f0492fSopenharmony_ci        LoadDefaultParams("/etc/param/ohos_const", LOAD_PARAM_NORMAL);
164d9f0492fSopenharmony_ci        LoadDefaultParams("/etc/param", LOAD_PARAM_ONLY_ADD);
165d9f0492fSopenharmony_ci        LoadDefaultParams("/vendor/etc/param", LOAD_PARAM_ONLY_ADD);
166d9f0492fSopenharmony_ci        return;
167d9f0492fSopenharmony_ci    }
168d9f0492fSopenharmony_ci
169d9f0492fSopenharmony_ci    // Load developer mode param
170d9f0492fSopenharmony_ci    LoadDefaultParams("/proc/dsmm/developer", LOAD_PARAM_NORMAL);
171d9f0492fSopenharmony_ci
172d9f0492fSopenharmony_ci    // Load const params, these can't be override!
173d9f0492fSopenharmony_ci    LoadDefaultParams("/system/etc/param/ohos_const", LOAD_PARAM_NORMAL);
174d9f0492fSopenharmony_ci    CfgFiles *files = GetCfgFiles("etc/param");
175d9f0492fSopenharmony_ci    for (int i = MAX_CFG_POLICY_DIRS_CNT - 1; files && i >= 0; i--) {
176d9f0492fSopenharmony_ci        if (files->paths[i]) {
177d9f0492fSopenharmony_ci            LoadDefaultParams(files->paths[i], LOAD_PARAM_ONLY_ADD);
178d9f0492fSopenharmony_ci        }
179d9f0492fSopenharmony_ci    }
180d9f0492fSopenharmony_ci    FreeCfgFiles(files);
181d9f0492fSopenharmony_ci}
182d9f0492fSopenharmony_ci
183d9f0492fSopenharmony_ciINIT_STATIC void InitPreHook(const HOOK_INFO *hookInfo, void *executionContext)
184d9f0492fSopenharmony_ci{
185d9f0492fSopenharmony_ci    INIT_TIMING_STAT *stat = (INIT_TIMING_STAT *)executionContext;
186d9f0492fSopenharmony_ci    clock_gettime(CLOCK_MONOTONIC, &(stat->startTime));
187d9f0492fSopenharmony_ci}
188d9f0492fSopenharmony_ci
189d9f0492fSopenharmony_ciINIT_STATIC void InitPostHook(const HOOK_INFO *hookInfo, void *executionContext, int executionRetVal)
190d9f0492fSopenharmony_ci{
191d9f0492fSopenharmony_ci    INIT_TIMING_STAT *stat = (INIT_TIMING_STAT *)executionContext;
192d9f0492fSopenharmony_ci    clock_gettime(CLOCK_MONOTONIC, &(stat->endTime));
193d9f0492fSopenharmony_ci    long long diff = InitDiffTime(stat);
194d9f0492fSopenharmony_ci    INIT_LOGI("Executing hook [%d:%d] cost [%lld]us, result %d.",
195d9f0492fSopenharmony_ci        hookInfo->stage, hookInfo->prio, diff, executionRetVal);
196d9f0492fSopenharmony_ci}
197d9f0492fSopenharmony_ci
198d9f0492fSopenharmony_cistatic void InitSysAdj(void)
199d9f0492fSopenharmony_ci{
200d9f0492fSopenharmony_ci    const char* path = "/proc/self/oom_score_adj";
201d9f0492fSopenharmony_ci    const char* content = "-1000";
202d9f0492fSopenharmony_ci    int fd = open(path, O_RDWR);
203d9f0492fSopenharmony_ci    if (fd == -1) {
204d9f0492fSopenharmony_ci        return;
205d9f0492fSopenharmony_ci    }
206d9f0492fSopenharmony_ci    if (write(fd, content, strlen(content)) < 0) {
207d9f0492fSopenharmony_ci        close(fd);
208d9f0492fSopenharmony_ci        return;
209d9f0492fSopenharmony_ci    }
210d9f0492fSopenharmony_ci    close(fd);
211d9f0492fSopenharmony_ci    return;
212d9f0492fSopenharmony_ci}
213d9f0492fSopenharmony_ci
214d9f0492fSopenharmony_ciINIT_STATIC void TriggerServices(int startMode)
215d9f0492fSopenharmony_ci{
216d9f0492fSopenharmony_ci    int index = 0;
217d9f0492fSopenharmony_ci    int jobNum = 0;
218d9f0492fSopenharmony_ci    char jobName[64] = {0}; // 64 job name
219d9f0492fSopenharmony_ci    char cmd[64] = {0};  // 64 job name
220d9f0492fSopenharmony_ci    const int maxServiceInJob = 4; // 4 service in job
221d9f0492fSopenharmony_ci    InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL);
222d9f0492fSopenharmony_ci    while (node != NULL) {
223d9f0492fSopenharmony_ci        Service *service = node->data.service;
224d9f0492fSopenharmony_ci        if (service == NULL || service->startMode != startMode) {
225d9f0492fSopenharmony_ci            node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
226d9f0492fSopenharmony_ci            continue;
227d9f0492fSopenharmony_ci        }
228d9f0492fSopenharmony_ci        if (IsOnDemandService(service)) {
229d9f0492fSopenharmony_ci            if (CreateSocketForService(service) != 0) {
230d9f0492fSopenharmony_ci                INIT_LOGE("service %s exit! create socket failed!", service->name);
231d9f0492fSopenharmony_ci            }
232d9f0492fSopenharmony_ci            node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
233d9f0492fSopenharmony_ci            continue;
234d9f0492fSopenharmony_ci        }
235d9f0492fSopenharmony_ci        if (sprintf_s(cmd, sizeof(cmd), "start %s", service->name) <= 0) {
236d9f0492fSopenharmony_ci            node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
237d9f0492fSopenharmony_ci            continue;
238d9f0492fSopenharmony_ci        }
239d9f0492fSopenharmony_ci        if (index == 0) {
240d9f0492fSopenharmony_ci            if (sprintf_s(jobName, sizeof(jobName), "boot-service:service-%d-%03d", startMode, jobNum) <= 0) {
241d9f0492fSopenharmony_ci                node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
242d9f0492fSopenharmony_ci                continue;
243d9f0492fSopenharmony_ci            }
244d9f0492fSopenharmony_ci            jobNum++;
245d9f0492fSopenharmony_ci        }
246d9f0492fSopenharmony_ci        index++;
247d9f0492fSopenharmony_ci        AddCompleteJob(jobName, NULL, cmd);
248d9f0492fSopenharmony_ci        INIT_LOGV("Add %s to job %s", service->name, jobName);
249d9f0492fSopenharmony_ci        if (index == maxServiceInJob) {
250d9f0492fSopenharmony_ci            PostTrigger(EVENT_TRIGGER_BOOT, jobName, strlen(jobName));
251d9f0492fSopenharmony_ci            index = 0;
252d9f0492fSopenharmony_ci        }
253d9f0492fSopenharmony_ci        node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
254d9f0492fSopenharmony_ci    }
255d9f0492fSopenharmony_ci    if (index > 0) {
256d9f0492fSopenharmony_ci        PostTrigger(EVENT_TRIGGER_BOOT, jobName, strlen(jobName));
257d9f0492fSopenharmony_ci    }
258d9f0492fSopenharmony_ci}
259d9f0492fSopenharmony_ci
260d9f0492fSopenharmony_civoid ParseInitCfgByPriority(void)
261d9f0492fSopenharmony_ci{
262d9f0492fSopenharmony_ci    CfgFiles *files = GetCfgFiles("etc/init");
263d9f0492fSopenharmony_ci    for (int i = 0; files && i < MAX_CFG_POLICY_DIRS_CNT; i++) {
264d9f0492fSopenharmony_ci        if (files->paths[i]) {
265d9f0492fSopenharmony_ci            if (ReadFileInDir(files->paths[i], ".cfg", ParseInitCfg, NULL) < 0) {
266d9f0492fSopenharmony_ci                break;
267d9f0492fSopenharmony_ci            }
268d9f0492fSopenharmony_ci        }
269d9f0492fSopenharmony_ci    }
270d9f0492fSopenharmony_ci    FreeCfgFiles(files);
271d9f0492fSopenharmony_ci}
272d9f0492fSopenharmony_ci
273d9f0492fSopenharmony_civoid SystemConfig(const char *uptime)
274d9f0492fSopenharmony_ci{
275d9f0492fSopenharmony_ci    INIT_TIMING_STAT timingStat;
276d9f0492fSopenharmony_ci
277d9f0492fSopenharmony_ci    InitSysAdj();
278d9f0492fSopenharmony_ci
279d9f0492fSopenharmony_ci    HOOK_EXEC_OPTIONS options;
280d9f0492fSopenharmony_ci
281d9f0492fSopenharmony_ci    options.flags = 0;
282d9f0492fSopenharmony_ci    options.preHook = InitPreHook;
283d9f0492fSopenharmony_ci    options.postHook = InitPostHook;
284d9f0492fSopenharmony_ci    InitServiceSpace();
285d9f0492fSopenharmony_ci    HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, (void *)&timingStat, (void *)&options);
286d9f0492fSopenharmony_ci    RecordInitBootEvent("init.prepare");
287d9f0492fSopenharmony_ci
288d9f0492fSopenharmony_ci    HookMgrExecute(GetBootStageHookMgr(), INIT_PRE_PARAM_SERVICE, (void *)&timingStat, (void *)&options);
289d9f0492fSopenharmony_ci    if (InitParamService() != 0) {
290d9f0492fSopenharmony_ci        INIT_LOGE("[startup_failed]Init param service failed %d", SYS_PARAM_INIT_FAILED);
291d9f0492fSopenharmony_ci        ExecReboot("panic");
292d9f0492fSopenharmony_ci    }
293d9f0492fSopenharmony_ci    InitParseGroupCfg();
294d9f0492fSopenharmony_ci    RegisterBootStateChange(BootStateChange);
295d9f0492fSopenharmony_ci
296d9f0492fSopenharmony_ci    INIT_LOGI("boot stage: init finish.");
297d9f0492fSopenharmony_ci
298d9f0492fSopenharmony_ci    // The cgroupv1 hierarchy may be created asynchronously in the early stage,
299d9f0492fSopenharmony_ci    // so make sure it has been done before loading SELinux.
300d9f0492fSopenharmony_ci    struct stat sourceInfo = {0};
301d9f0492fSopenharmony_ci    if (stat("/dev/cgroup", &sourceInfo) == 0) {
302d9f0492fSopenharmony_ci        WaitForFile("/dev/memcg/procs", WAIT_MAX_SECOND);
303d9f0492fSopenharmony_ci    }
304d9f0492fSopenharmony_ci
305d9f0492fSopenharmony_ci    // load SELinux context and policy
306d9f0492fSopenharmony_ci    // Do not move position!
307d9f0492fSopenharmony_ci    PluginExecCmdByName("loadSelinuxPolicy", "");
308d9f0492fSopenharmony_ci    RecordInitBootEvent("init.prepare");
309d9f0492fSopenharmony_ci
310d9f0492fSopenharmony_ci    // after selinux loaded
311d9f0492fSopenharmony_ci    SignalInit();
312d9f0492fSopenharmony_ci
313d9f0492fSopenharmony_ci    RecordInitBootEvent("init.ParseCfg");
314d9f0492fSopenharmony_ci    LoadSpecialParam();
315d9f0492fSopenharmony_ci
316d9f0492fSopenharmony_ci    // parse parameters
317d9f0492fSopenharmony_ci    HookMgrExecute(GetBootStageHookMgr(), INIT_PRE_PARAM_LOAD, (void *)&timingStat, (void *)&options);
318d9f0492fSopenharmony_ci    InitLoadParamFiles();
319d9f0492fSopenharmony_ci
320d9f0492fSopenharmony_ci    // Write kernel uptime into system parameter
321d9f0492fSopenharmony_ci    WriteUptimeSysParam("ohos.boot.time.kernel", uptime);
322d9f0492fSopenharmony_ci
323d9f0492fSopenharmony_ci    // read config
324d9f0492fSopenharmony_ci    HookMgrExecute(GetBootStageHookMgr(), INIT_PRE_CFG_LOAD, (void *)&timingStat, (void *)&options);
325d9f0492fSopenharmony_ci    ReadConfig();
326d9f0492fSopenharmony_ci    RecordInitBootEvent("init.ParseCfg");
327d9f0492fSopenharmony_ci    INIT_LOGI("boot stage: parse config file finish.");
328d9f0492fSopenharmony_ci    HookMgrExecute(GetBootStageHookMgr(), INIT_POST_CFG_LOAD, (void *)&timingStat, (void *)&options);
329d9f0492fSopenharmony_ci
330d9f0492fSopenharmony_ci    IsEnableSandbox();
331d9f0492fSopenharmony_ci    // execute init
332d9f0492fSopenharmony_ci    PostTrigger(EVENT_TRIGGER_BOOT, "pre-init", strlen("pre-init"));
333d9f0492fSopenharmony_ci    PostTrigger(EVENT_TRIGGER_BOOT, "init", strlen("init"));
334d9f0492fSopenharmony_ci    TriggerServices(START_MODE_BOOT);
335d9f0492fSopenharmony_ci    PostTrigger(EVENT_TRIGGER_BOOT, "post-init", strlen("post-init"));
336d9f0492fSopenharmony_ci    TriggerServices(START_MODE_NORMAL);
337d9f0492fSopenharmony_ci    clock_gettime(CLOCK_MONOTONIC, &(g_bootJob.startTime));
338d9f0492fSopenharmony_ci}
339d9f0492fSopenharmony_ci
340d9f0492fSopenharmony_civoid SystemRun(void)
341d9f0492fSopenharmony_ci{
342d9f0492fSopenharmony_ci    StartParamService();
343d9f0492fSopenharmony_ci}
344