1. 概述
Linux系統(tǒng)啟動(dòng)過(guò)程中通過(guò)init_task
創(chuàng)建0號(hào)idle進(jìn)程。然后通過(guò)kernel_thread
創(chuàng)建1號(hào)init進(jìn)程。創(chuàng)建該進(jìn)程時(shí)通過(guò)系統(tǒng)調(diào)用,在內(nèi)核空間執(zhí)行用戶(hù)空間的/sbin/init程序,通過(guò)該程序產(chǎn)生出shell
,并依賴(lài)init
衍生出其他進(jìn)程。通過(guò)top命令查看當(dāng)前系統(tǒng)環(huán)境下的進(jìn)程列表,可以發(fā)現(xiàn)1號(hào)進(jìn)程的為{linuxrc} init
[root@iTOP-4412]# top
Mem: 26404K used, 948572K free, 0K shrd, 3199543672K buff, 0K cached
CPU: 0.0% usr 6.0% sys 0.0% nic 94.0% idle 0.0% io 0.0% irq 0.0% sirq
Load average: 0.00 0.00 0.00 1/78 162
PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND
162 132 root R 3264 0.3 0 4.5 top
3 2 root IW 0 0.0 0 1.5 [kworker/0:0]
132 1 root S 3268 0.3 2 0.0 -/bin/sh
1 0 root S 3264 0.3 2 0.0 {linuxrc} init
...
我們?cè)趉ernel代碼中會(huì)發(fā)現(xiàn),創(chuàng)建1號(hào)init
進(jìn)程的方式,主要包括以下3種,如下圖所示:
2. 創(chuàng)建init進(jìn)程的方式
2.1 ramdisk方式
在ramdisk環(huán)境下創(chuàng)建init進(jìn)程時(shí),需要在kernel CMDLINE
中設(shè)置init程序的路徑位置,如下所示:
CONFIG_CMDLINE="...root=/dev/ram rdinit=/sbin/init..."
在kernel代碼中通過(guò)rdinit_setup()
解析kernel CMDLINE
中rdinit=
字符串,賦值給全局變量ramdisk_execute_command
。
static int __init rdinit_setup(char *str)
{
unsigned int i;
ramdisk_execute_command = str;
/* See "auto" comment in init_setup */
for (i = 1; i < MAX_INIT_ARGS; i++)
argv_init[i] = NULL;
return 1;
}
__setup("rdinit=", rdinit_setup);
當(dāng)完成ramdisk_execute_command
賦值后,在kernel_init_freeable()
對(duì)ramdisk_execute_command
進(jìn)行檢查,若未檢查到有效的字符串,則將ramdisk_execute_command
賦值為/init
。然后,對(duì)ramdisk_execute_command
進(jìn)行訪(fǎng)問(wèn)權(quán)限檢查,若失敗,則進(jìn)行rootfs掛載。
static noinline void __init kernel_init_freeable(void)
{
...
if (!ramdisk_execute_command)
ramdisk_execute_command = "/init";
if (ksys_access((const char __user *)
ramdisk_execute_command, 0) != 0) {
ramdisk_execute_command = NULL;
prepare_namespace();
}
...
}
若ramdisk_execute_command
檢查成功,則進(jìn)入kernel_init()
中,執(zhí)行指定的init程序。
static int __ref kernel_init(void *unused)
{
int ret;
kernel_init_freeable();
...
if (ramdisk_execute_command) {
ret = run_init_process(ramdisk_execute_command);
if (!ret)
return 0;
pr_err("Failed to execute %s (error %d)\\n",
ramdisk_execute_command, ret);
}
...
}
2.2 execute_command方式
通過(guò)kernel CMDLINE可以設(shè)定執(zhí)行的init程序,例如:
CONFIG_CMDLINE="root=/dev/mmcblk1p2 rw console=ttySAC2,115200 init=/linuxrc rootwait"
在kernel代碼中通過(guò)init_setup()
解析命令行參數(shù)"init="
,并賦值給execute_command
。
static int __init init_setup(char *str)
{
unsigned int i;
execute_command = str;
...
for (i = 1; i < MAX_INIT_ARGS; i++)
argv_init[i] = NULL;
return 1;
}
__setup("init=", init_setup);
最后,在kernel_init()
中執(zhí)行execute_command
所指定的init
程序。
static int __ref kernel_init(void *unused)
{
...
if (execute_command) {
ret = run_init_process(execute_command);
if (!ret)
return 0;
panic("Requested init %s failed (error %d).",
execute_command, ret);
}
...
panic("No working init found. Try passing init= option to kernel. "
"See Linux Documentation/admin-guide/init.rst for guidance.");
}
2.3 默認(rèn)方式
若以上兩種指定init程序的方式均以失敗告終,那么內(nèi)核代碼kernel_init()
會(huì)執(zhí)行如下4個(gè)默認(rèn)的init程序,若也失敗,則內(nèi)核上報(bào)panic。
static int __ref kernel_init(void *unused)
{
...
if (!try_to_run_init_process("/sbin/init") ||
!try_to_run_init_process("/etc/init") ||
!try_to_run_init_process("/bin/init") ||
!try_to_run_init_process("/bin/sh"))
return 0;
panic("No working init found. Try passing init= option to kernel. "
"See Linux Documentation/admin-guide/init.rst for guidance.");
}
-
Linux系統(tǒng)
+關(guān)注
關(guān)注
4文章
596瀏覽量
27521 -
CMD命令
+關(guān)注
關(guān)注
0文章
28瀏覽量
8351
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
編寫(xiě)第一個(gè)QT程序
第一個(gè)arm9的應(yīng)用程序helloworld需要掌握哪些內(nèi)容?
【MiCOKit試用體驗(yàn)】+第一個(gè) MiCO 應(yīng)用程序
【Intel Edison試用體驗(yàn)】+第一個(gè)應(yīng)用程序“Hello World!”(3)
【HarmonyOS HiSpark IPC DIY Camera試用連載 】鴻蒙OS內(nèi)核如何啟動(dòng)第一個(gè)用戶(hù)進(jìn)程init_lite
[文章] 【HarmonyOS HiSpark IPC DIY Camera試用連載 】鴻蒙OS內(nèi)核如何啟動(dòng)第一個(gè)用戶(hù)進(jìn)程init_lite
鴻蒙liteos-a如何啟動(dòng)第一個(gè)用戶(hù)進(jìn)程init_lite
鴻蒙liteos-a如何啟動(dòng)第一個(gè)用戶(hù)進(jìn)程init_lite
Niobe第一個(gè)應(yīng)用程序
Niobe第一個(gè)應(yīng)用程序
使用單片機(jī)STM32執(zhí)行的第一個(gè)程序是什么
Linux系統(tǒng)下init進(jìn)程的前世今生
第一個(gè)Xilinx Vitis IDE入門(mén)helloworld程序
![<b class='flag-5'>第一個(gè)</b>Xilinx Vitis IDE入門(mén)helloworld<b class='flag-5'>程序</b>](https://file.elecfans.com/web1/M00/DC/3B/pIYBAGAKUSiALqTqAAGG3udDUrE691.png)
嵌入式Linux應(yīng)用程序開(kāi)發(fā)-(1)第一個(gè)嵌入式QT應(yīng)用程序
![嵌入式Linux<b class='flag-5'>應(yīng)用程序</b>開(kāi)發(fā)-(1)<b class='flag-5'>第一個(gè)</b>嵌入式QT<b class='flag-5'>應(yīng)用程序</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評(píng)論