本文永久更新鏈結位址
:[日期:2014-10-14]
[字型:大中小]
下面給出核心映像完整的啟動過程:
注意kernel_evecve呼叫的是與具體體系平台相關的實現,但它是乙個通用的系統呼叫,在linux/syscalls.h中宣告,這個標頭檔案中宣告了與體系結構無關的所有系統呼叫介面。只不過kernel_evecve在實現時是與體系結構相關的,每種體系結構都要提供它的實現。
從以上分析可以看出,如果使用新的cpio-initrd(或initramfs),kernel_init只負責核心初始化(包括載入核心模組、建立基於記憶體的rootfs以及載入cpio-initrd)。後續根檔案系統的掛載、init程序的啟動工作都交給cpio-initrd來完成。cpio-initrd相對於image-initrd承擔了更多的初始化責任,這種變化也可以看作是核心**的使用者層化的一種體現,實際上精簡核心**,將部分功能移植到使用者層必然是linux核心發展的乙個趨勢。如果是使用傳統的image-initrd的話,根檔案系統的掛載也會放在kernel_init()中,其中prepare_namespace完成掛載根檔案系統,init_post()完成執行/sbin/init,顯然這樣核心的**不夠精簡。
5、init程序
init是第乙個呼叫的使用標準c庫編譯的程式。在此之前,還沒有執行任何標準的c應用程式。在桌面linux系統上,第乙個啟動的程式通常是/sbin/init,它的程序號為1。init程序是所有程序的發起者和控制者,它有兩個作用:
(1)扮演終結父程序的角色:所有的孤兒程序都會被init程序接管。
(2)系統初始化工作:如設定鍵盤、字型,裝載模組,設定網路等。
在完成系統初始化工作之後,init程序將在控制台上執行getty(登入程式)等任務,我們熟悉的登入介面就出現了!
init程式的執行流程需要分專門的一節來討論,因為它有不同的實現方式。傳統的實現是基於unix system v init程序的,程式包為sysvinit(以前的redhat/fedora用的就是這個)。目前已經有多種sysvinit的替代產品了,這其中包括initng,它已經可以用於debian了,並且在ubuntu上也能工作。在同一位置上,solaris使用smf(service management facility),而mac os則使用 launchd。現在廣泛使用的是upstart init初始化程序,目前在ubuntu和fedora,還有其他系統中已經取代了sysvinit。
傳統的sysvinit daemon是乙個基於執行級別的初始化程式,它使用了執行級別(如單使用者、多使用者等)並通過從/etc/rcx.d目錄到/etc/init.d目錄的初始化指令碼的鏈結來啟動與終止系統服務。sysvinit無法很好地處理現代硬體,如熱插拔裝置、usb硬碟、網路檔案系統等。upstart系統則是事件驅動的,事件可能被硬體改動觸發,也可被啟動或關機或任務所觸發,或者也可能被系統上的任何其他程序所觸發。事件用於觸發任務或服務,統稱為作業。比如連線到乙個usb驅動器可能導致udev服務傳送乙個block-device-added事件,這可能引起乙個預定任務檢查/etc/fstab和掛載驅動器(如果需要的話)。再如,乙個apache web伺服器可能只有當網路和所需的檔案系統都可用時才能啟動。
upstart作業在/etc/init目錄及其子目錄下被定義。upstart系統相容sysvinit,它也會處理/etc/inittab和system v init指令碼(如果有的話)。在諸如近來的fedora版本的系統上,/etc/inittab可能只含有initdefault操作的id項。目前ubuntu系統預設沒有/etc/inittab,如果您想要指定乙個預設執行級別的話,您可以建立乙個。upstart也使用initctl命令來支援與upstart init守護程序的互動。這時您可以啟動或終止作業、列表作業、以及獲取作業的狀態、發出事件、重啟init程序,等等。
總的來說,x86架構的linux核心啟動過程分為6大步,分別為:
(1)實模式的入口函式_start():在header.s中,這裡會進入眾所周知的main函式,它拷貝bootloader的各個引數,執行基本硬體設定,解析命令列引數。
(2)保護模式的入口函式startup_32():在compressed/header_32.s中,這裡會解壓bzimage核心映像,載入vmlinux核心檔案。
(3)核心入口函式startup_32():在kernel/header_32.s中,這就是所謂的程序0,它會進入體系結構無關的start_kernel()函式,即眾所周知的linux核心啟動函式。start_kernel()會做大量的核心初始化操作,解析核心啟動的命令列引數,並啟動乙個核心執行緒來完成核心模組初始化的過程,然後進入空閒迴圈。
(4)核心模組初始化的入口函式kernel_init():在init/main.c中,這裡會啟動核心模組、建立基於記憶體的rootfs、載入initramfs檔案或cpio-initrd,並啟動乙個核心執行緒來執行其中的/init指令碼,完成真正根檔案系統的掛載。
(5)根檔案系統掛載指令碼/init:這裡會掛載根檔案系統、執行/sbin/init,從而啟動眾所周知的程序1。
(6)init程序的系統初始化過程:執行相關指令碼,以完成系統初始化,如設定鍵盤、字型,裝載模組,設定網路等,最後執行登入程式,出現登入介面。
如果從體系結構無關的視角來看,start_kernel()可以看作時體系結構無關的linux main函式,它是體系結構無關的**的統一入口函式,這也是為什麼檔案會命名為init/main.c的原因。這個main.c粘合劑把各種體系結構的**「粘合」到乙個統一的入口處。
整個核心啟動過程如下圖:
圖1 linux核心啟動過程
本文永久更新鏈結位址:
2345
分析Linux核心的啟動過程
第一章 環境 ubuntu 14.10 linux kernel 3.18.6 第二章 及除錯過程 環境搭建與核心準備 cd linuxkernel wget xz d linux 3.18.6.tar.xz tar xvf linux 3.18.6.tar cd linux 3.18.6 make...
linux核心啟動過程
第一步 電腦加電後cpu開始自身初始化,然後從某個固定位置 一般為0xfffffff0 取指令開始執行,此指令為跳轉指令,跳轉到bios 首部。第二步 bios開始加電自檢進行post power on self test 此階段完成系統硬體檢測,包括記憶體 系統匯流排檢測等,然後bios讀取啟動裝...
Linux核心啟動過程
linux核心啟動過程 第一篇日誌就摘錄一下linux核心的啟動過程,參考了 linux核心移植和yaffs2根檔案系統製作 嵌入式linux系統從軟體角度看可以分為四部分 引導引導程式 bootloader linux核心,檔案系統,應用程式。bootloader是系統啟動時執行的第一段 它主要用...