精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

kernel執行第一個init應用程序的實現原理

冬至子 ? 來源:linux與SoC ? 作者:linux與SoC ? 2023-06-05 14:53 ? 次閱讀

1. 概述

Linux系統啟動過程中通過init_task創建0號idle進程。然后通過kernel_thread創建1號init進程。創建該進程時通過系統調用,在內核空間執行用戶空間的/sbin/init程序,通過該程序產生出shell,并依賴init衍生出其他進程。通過top命令查看當前系統環境下的進程列表,可以發現1號進程的為{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
...

我們在kernel代碼中會發現,創建1號init進程的方式,主要包括以下3種,如下圖所示:

圖片

2. 創建init進程的方式

2.1 ramdisk方式

在ramdisk環境下創建init進程時,需要在kernel CMDLINE中設置init程序的路徑位置,如下所示:

CONFIG_CMDLINE="...root=/dev/ram rdinit=/sbin/init..."

在kernel代碼中通過rdinit_setup()解析kernel CMDLINErdinit=字符串,賦值給全局變量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);

當完成ramdisk_execute_command賦值后,在kernel_init_freeable()ramdisk_execute_command進行檢查,若未檢查到有效的字符串,則將ramdisk_execute_command賦值為/init。然后,對ramdisk_execute_command進行訪問權限檢查,若失敗,則進行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檢查成功,則進入kernel_init()中,執行指定的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方式

通過kernel CMDLINE可以設定執行的init程序,例如:

CONFIG_CMDLINE="root=/dev/mmcblk1p2 rw console=ttySAC2,115200 init=/linuxrc rootwait"

在kernel代碼中通過init_setup()解析命令行參數"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()中執行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 默認方式

若以上兩種指定init程序的方式均以失敗告終,那么內核代碼kernel_init()會執行如下4個默認的init程序,若也失敗,則內核上報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系統
    +關注

    關注

    4

    文章

    592

    瀏覽量

    27360
  • CMD命令
    +關注

    關注

    0

    文章

    28

    瀏覽量

    8300
收藏 人收藏

    評論

    相關推薦

    編寫第一個QT程序

    學習種編程語言或編程環境,通常會先編寫“Hello World”程序。我們也用 Qt Creator 編寫
    發表于 11-21 10:41 ?1010次閱讀

    第一個arm9的應用程序helloworld需要掌握哪些內容?

    arm9的第一個應用程序 helloworld 的軟件 硬件平臺都有哪些?比如軟件開發環境需要搭建什么平臺 等等 ,路過的朋友不妨看看,謝謝。
    發表于 11-12 14:41

    【MiCOKit試用體驗】+第一個 MiCO 應用程序

    【MiCOKit試用體驗】+第一個 MiCO 應用程序對于開發板程序設計,第一個程序,hello world 是少不了的,今天我們來研究下
    發表于 10-23 21:50

    【Intel Edison試用體驗】+第一個應用程序“Hello World!”(3)

    本帖最后由 滿嘴讒言 于 2016-7-1 21:54 編輯 刷好了系統,我們就來配置交叉編譯環境和編寫第一個應用程序。1.第一步,下載交叉編譯工具鏈。因為我要在Linux的虛擬機下操作,所以
    發表于 07-01 21:49

    【HarmonyOS HiSpark IPC DIY Camera試用連載 】鴻蒙OS內核如何啟動第一個用戶進程init_lite

    和源碼位置,包括了kernel、startup子系統。Startup中的init_lite是kernel調用的第一個用戶態進程; 3.第一個
    發表于 11-20 10:27

    [文章] 【HarmonyOS HiSpark IPC DIY Camera試用連載 】鴻蒙OS內核如何啟動第一個用戶進程init_lite

    位置,包括了kernel、startup子系統。Startup中的init_lite是kernel調用的第一個用戶態進程;3.第一個用戶態進
    發表于 11-20 16:44

    鴻蒙liteos-a如何啟動第一個用戶進程init_lite

    init_lite是kernel調用的第一個用戶態進程; 3. 第一個用戶態進程init_liteInit_lite的位置: 官方手冊中對
    發表于 12-10 12:04

    鴻蒙liteos-a如何啟動第一個用戶進程init_lite

    init_lite是kernel調用的第一個用戶態進程; 3. 第一個用戶態進程init_liteInit_lite的位置: 官方手冊中對
    發表于 12-10 15:02

    Niobe第一個應用程序

    Niobe第一個應用程序HelloWorld沿襲程序界的傳統,第一個程序都是Hello World。在Niobe WiFi IoT開發板中,
    發表于 12-08 14:39

    Niobe第一個應用程序

    Niobe第一個應用程序HelloWorld沿襲程序界的傳統,第一個程序都是Hello World。在Niobe WiFi IoT開發板中,
    發表于 12-08 17:36

    使用單片機STM32執行第一個程序是什么

    使用單片機STM32執行第一個程序是startup_stm32f407xx.s指令名稱含義EQU給數字常量取符號名,相當于C語言中的d
    發表于 01-21 12:13

    Linux系統下init進程的前世今生

    kernel_thread產生的進程,其開始在內核態執行,然后通過系統調用,開始執行用戶空間的/sbin/
    發表于 04-28 17:23 ?962次閱讀

    第一個Xilinx Vitis IDE入門helloworld程序

    第一個Xilinx Vitis IDE入門helloworld程序
    發表于 01-23 06:37 ?8次下載
    <b class='flag-5'>第一個</b>Xilinx Vitis IDE入門helloworld<b class='flag-5'>程序</b>

    嵌入式Linux應用程序開發-(1)第一個嵌入式QT應用程序

    第一個嵌入式QT應用程序在成功安裝 Qt Creator 開發環境后,我們通過簡單的嵌入式Qt應用程序,來說明
    發表于 11-01 17:21 ?16次下載
    嵌入式Linux<b class='flag-5'>應用程序</b>開發-(1)<b class='flag-5'>第一個</b>嵌入式QT<b class='flag-5'>應用程序</b>

    如何編寫第一個hello world程序

    本文簡單介紹如何編寫第一個hello world程序,以及程序是如何被執行
    的頭像 發表于 03-02 17:31 ?8341次閱讀
    如何編寫<b class='flag-5'>第一個</b>hello world<b class='flag-5'>程序</b>