Linux啟動過程

來源:互聯網
上載者:User

標籤:

在Bootloader將 Linux 核心映像拷貝到 RAM 以後,可以通過下例代碼啟動 Linux 核心:  
call_linux(0, machine_type, kernel_params_base)。

其中,machine_tpye 是Bootloader檢測出來的處理器類型, kernel_params_base 是啟動參數在 RAM 的地址。通過這種方式將 Linux 啟動需要的參數從 bootloader傳遞到核心。

Linux核心有兩種映像:一種是非壓縮核心,叫Image,另一種是它的壓縮版本,叫zImage。根據核心的不同,Linux核心的啟動在開始階段有所不同。zImage是Image經過壓縮形成的,所以它比Image小。但為了能使用zImage,必須在它的開頭加上解壓縮的代碼,將zImage解壓縮之後才能執行,因此它的執行速度比Image要慢。對於ARM系列處理器來說,zImage的入口程式為arch/arm/boot/compressed/head.S。它依次完成以下工作:開啟MMU和Cache,調用decompress_kernel()解壓核心,最後通過調用call_kernel()進入非壓縮核心Image的啟動。下面具體分析在此之後Linux核心的啟動過程。

1、Linux核心入口

Linux非壓縮核心的入口位於檔案/arch/arm/kernel/head-armv.S中的stext段。該段的基地址就是壓縮核心解壓後的跳轉地址。如果系統載入的核心是非壓縮的Image,那麼Bootloader將核心從Flash中拷貝到RAM後將直接跳到該地址處,從而啟動Linux核心。不同體型結構的Linux系統的入口檔案是不同的,而且因為該檔案與具體體繫結構有關,所以一般均用組合語言編寫。對基於ARM處理器的Linux系統來說,該檔案就是head-armv.S。該程式通過尋找處理器核心類型和處理器類型調用相應的初始化函數,再建立頁表,最後跳轉到start_kernel()函數開始核心的初始化工作。

檢測處理器核心類型的彙編子函數__lookup_processor_type中完成的,通過以下代碼可實現對它的調用:bl __lookup_processor_type

__lookup_processor_type調用結束返回來源程式時,會將返回結果儲存到寄存器中。其中其中r8 儲存了頁表的標誌位,r9 儲存了處理器的 識別碼,r10 儲存了與處理器相關的 struct proc_info_list 結構地址。

檢測處理器類型是在彙編子函數 __lookup_architecture_type 中完成的。與 __lookup_processor_type類似,它通過代碼:“bl __lookup_processor_type”來實現對它的調用。該函數返回時,會將返回結構儲存在 r5、r6 和 r7 三個寄存器中。其中 r5 儲存了 RAM 的起始基地址,r6 儲存了 I/O基地址,r7 儲存了 I/O的頁表位移地址。

當檢測處理器核心和處理器類型結束後,將調用__create_page_tables 子函數來建立頁表,它所要做的工作就是將 RAM 基地址開始的 4M 空間的物理地址映射到 0xC0000000 開始的虛擬位址處。對筆者的 S3C2410 開發板而言,RAM 串連到物理地址 0x30000000 處,當調用 __create_page_tables 結束後 0x30000000 ~ 0x30400000 物理地址將映射到 0xC0000000~0xC0400000 虛擬位址處。

當所有的初始化結束之後,使用如下代碼來跳到 C 程式的入口函數 start_kernel()處,開始之後的核心初始化工作:b SYMBOL_NAME(start_kernel)

2、start_kernel函數

start_kernel是所有Linux平台進入系統核心初始化後的入口函數,它主要完成剩餘的與硬體平台相關的初始化工作,在進行一系列與核心相關的初始化後,調用第一個使用者進程init 進程並等待使用者進程的執行,這樣整個Linux核心便啟動完畢。

該函數所做的具體工作有:調用setup_arch()函數進行與體繫結構相關的第一個初始化工作;對於不同的體繫結構來說該函數有不同的定義。對於ARM平台而言,該函數定義在arch/arm/kernel/Setup.c

它首先通過檢測出來的處理器類型進行處理器核心的初始化,然後通過 bootmem_init()函數根據系統定義的 meminfo 結構進行記憶體結構的初始化,最後調用paging_init()開啟 MMU,建立核心頁表,映射所有的實體記憶體和 IO空間。建立異常向量表和初始化中斷處理函數;初始化系統核心進程調度器和時鐘中斷處理機制;初始化串口控制台(serial-console);建立和初始化系統cache,為各種記憶體調用機制提供緩衝,包括動態記憶體分配,虛擬檔案系統(VirtualFile System)及頁緩衝。初始化記憶體管理,檢測記憶體大小及被核心佔用的記憶體情況;初始化系統的處理序間通訊機制(IPC);

當以上所有的初始化工作結束後,start_kernel()函數會調用 rest_init()函數來進行最後的初始化,包括建立系統的第一個進程-init 進程來結束核心的啟動。

init 進程首先進行一系列的硬體初始化,然後通過命令列傳遞過來的參數掛載根檔案系統。最後 init 進程會執行使用者傳遞過來的“init=”啟動參數執行使用者指定的命令,或者執行以下幾個進程之一:  
execve("/sbin/init",argv_init,envp_init) 
execve("/etc/init",argv_init,envp_init) 
execve("/bin/init",argv_init,envp_init) 
execve("/bin/sh",argv_init,envp_init)  
當所有的初始化工作結束後,cpu_idle()函數會被調用來使系統處於閑置(idle)狀態並等待使用者程式的執行。至此,整個 Linux 核心啟動完畢。

Linux啟動過程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.