init进程(即进程1,或者说linuxrc)的详解
以下內容源于朱有鵬嵌入式課程的學習,如有侵權,請告知刪除。
一、init進程詳解1
1、init進程完成了從內核態向用戶態的轉變
(1)一個進程先后兩種狀態
- init進程剛開始運行的時候是內核態,它屬于一個內核線程,然后運行一個用戶態下面的程序后,把自己強行轉成了用戶態(后面的進程需要工作在用戶態下)。
- 因為init進程自身完成了從內核態到用戶態的過渡,因此后續的其他進程都可以工作在用戶態。
(2)init進程在內核態下的工作內容
- 主要是掛載根文件系統,并試圖找到用戶態下的那個init程序。
- init進程要把自己轉成用戶態就必須運行一個用戶態的應用程序(這個應用程序名字一般也叫init),要運行這個應用程序就必須得找到這個應用程序,要找到這個應用程序就必須得掛載根文件系統,因為所有的應用程序都在文件系統中。
- 內核源代碼中的所有函數都處于內核態,執行其中任何一個都不能脫離內核態。應用程序必須不屬于內核源代碼,這樣才能保證應用程序處于用戶態。這里執行的init程序和內核不在一起,由根文件系統另外提供。
(3)init進程在用戶態下的工作內容
- init進程大部分有意義的工作都是在用戶態下進行的。
- init進程對操作系統的意義在于:其他所有的用戶進程都直接或者間接派生自init進程。
(4)init進程如何從內核態跳躍到用戶態?還能回來不?
- init進程處于內核態時,通過函數kernel_execve來執行一個用戶空間編譯連接的應用程序就跳躍到用戶態了。
- 跳躍過程中進程號沒有改變,一直是進程1。
- 跳躍過程是單向的,一旦執行init程序轉到用戶態,整個操作系統就算真正運轉起來了,以后只能在用戶態下工作,用戶態下想要進入內核態只能通過調用API。
2、init進程構建了用戶交互界面
(1)init進程是其他用戶進程的老祖宗。
- linux系統中一個進程的創建是通過其父進程創建出來的。根據這個理論只要有一個父進程就能生出一堆子孫進程了。
(2)init啟動了login進程(用戶登錄進程)、命令行進程(提供命令行環境)、shell進程(提供命令解釋和執行)。
(3)shell進程啟動了其他用戶進程。
- 命令行和shell一旦工作,用戶就可以在命令行下通過./xx的方式來執行其他應用程序,每一個應用程序的運行就是一個進程。
二、init進程詳解2
1、打開控制臺
(1)linux系統中每個進程都有自己的一個文件描述符表,表中存儲的是本進程打開的文件。
(2)linux系統中一切皆是文件,因此設備也是以文件的方式來訪問的。
- 要訪問一個設備,就要打開此設備對應的文件描述符。譬如/dev/fb0這個設備文件就代表LCD顯示器設備,/dev/buzzer代表蜂鳴器設備,/dev/console代表控制臺設備。
(3)這里打開了/dev/console文件,并且復制了2次文件描述符,一共得到了3個文件描述符。
- 這三個文件描述符分別是0、1、2,就是所謂的標準輸入、標準輸出、標準錯誤這3個文件描述符。
(4)進程1打開了這3個文件描述符,因此進程1衍生出來的所有的進程默認都具有這3個文件描述符。
2、掛載根文件系統
(1)prepare_namespace函數掛載根文件系統。
(2)根文件系統在哪里?根文件系統的文件系統類型是什么??
- uboot通過傳參來告訴內核這些信息。
- uboot傳參中的root=/dev/mmcblk0p2 rw 這一句就是告訴內核根文件系統在哪里。
- uboot傳參中的rootfstype=ext3這一句就是告訴內核rootfs的類型。
(3)掛載結果
- 如果內核掛載根文件系統成功,則會打印出:VFS: Mounted root (ext3 filesystem) on device 179:2。(也可能其他數字)
- 如果掛載根文件系統失敗,則會打印:No filesystem could mount root, tried: ?yaffs2
(4)如果內核啟動時掛載rootfs失敗,則后面無法執行。
- 內核中設置了啟動失敗休息5s自動重啟的機制,因此這里會自動重啟,所以有時候大家會看到反復重啟的情況。
(5)如果掛載rootfs失敗,可能的原因有
- 最常見的錯誤就是uboot的bootargs設置不對。
- rootfs燒錄失敗(fastboot燒錄不容易出錯)。
- rootfs本身制作失敗的。
3、執行用戶態下的進程1程序
(1)一旦掛載rootfs成功,則進入rootfs中尋找應用程序的init程序(在init_post()函數中),找到后用run_init_process去執行。
(2)如果確定init程序是誰?
- 先從uboot傳參cmdline中看有沒有指定,如果有指定先執行cmdline中指定的程序。cmdline中的init=/linuxrc這個就是指定rootfs中哪個程序是init程序。這里的指定方式就表示我們rootfs的根目錄下面有個名字叫linuxrc的程序,這個程序就是init程序。
- 如果uboot傳參cmdline中沒有init=xx或者cmdline中指定的這個xx執行失敗,還有備用方案。第一備用:/sbin/init,第二備用:/etc/init,第三備用:/bin/init,第四備用:/bin/sh。如果以上都不成功,則沒有辦法了。
總結
以上是生活随笔為你收集整理的init进程(即进程1,或者说linuxrc)的详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux系统开发|QT制作聊天软件实验
- 下一篇: 三菱PLC的编程语言有指令表、梯形图、步