




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、ARM Linux啟動(dòng)過程分析摘 要:嵌入式 Linux的可移植性使得我們可以在各種電子產(chǎn)品上看到它的身影。對(duì) 于不同體系結(jié)構(gòu)的處理器來說Linux的啟動(dòng)過程也有所不同。本文以 S3C2410 ARM 處理器為例,詳細(xì)分析了系統(tǒng)上電后bootloader的執(zhí)行流程及 ARM Linux 的啟動(dòng)過程。關(guān)鍵詞:ARM Linux bootloader 啟動(dòng)過程中圖分類號(hào):TP3161.引言Linux最初是由瑞典赫爾辛基大學(xué)的學(xué)生Linus Torvalds在 1991年開發(fā)出來的,之后在GNU 的支持下,Linux獲得了巨大的發(fā)展。雖然 Linux在桌面 PC機(jī)上的普及程度遠(yuǎn)不及 微軟的 Wind
2、ows操作系統(tǒng),但它的發(fā)展速度之快、用戶數(shù)量的日益增多,也是微軟所不能輕 視的。而近些年來Linux在嵌入式領(lǐng)域的迅猛發(fā)展,更是給 Linux注入了新的活力。一個(gè)嵌入式 Linux系統(tǒng)從軟件角度看可以分為四個(gè)部分1:引導(dǎo)加載程序(bootloader ),Linux內(nèi)核,文件系統(tǒng),應(yīng)用程序。其中 bootloader 是系統(tǒng)啟動(dòng)或復(fù)位以后執(zhí)行的第一段代碼,它主要用來初始化處理器及外設(shè),然后調(diào)用Linux內(nèi)核。Linux內(nèi)核在完成系統(tǒng)的初始化之后需要掛載某個(gè)文件系統(tǒng)做為根文件系統(tǒng)(Root Filesystem )。根文件系統(tǒng)是 Linux系統(tǒng)的核心組成部分,它可以做 為L(zhǎng)inux系統(tǒng)中文件和數(shù)
3、據(jù)的存儲(chǔ)區(qū)域,通常它還包括系統(tǒng)配置文件和運(yùn)行應(yīng)用軟件所需要的 庫(kù)。應(yīng)用程序可以說是嵌入式系統(tǒng)的靈魂”,它所實(shí)現(xiàn)的功能通常就是設(shè)計(jì)該嵌入式系統(tǒng) 所要達(dá)到的目標(biāo)。如果沒有應(yīng)用程序的支持, 任何硬件上設(shè)計(jì)精良的嵌入式系統(tǒng)都沒有實(shí)用 意義。從以上分析我們可以看出bootloader 和 Linux內(nèi)核在嵌入式系統(tǒng)中的關(guān)系和作用。Bootloader在運(yùn)行過程中雖然具有初始化系統(tǒng)和執(zhí)行用戶輸入的命令等作用,但它最根本的功能就是為了啟動(dòng)Linux內(nèi)核。在嵌入式系統(tǒng)開發(fā)的過程中,很大一部分精力都是花在bootloader 和 Linux內(nèi)核的開發(fā)或移植上。如果能清楚的了解bootloader執(zhí)行流程和Lin
4、ux的啟動(dòng)過程,將有助于明確開發(fā)過程中所需的工作,從而加速嵌入式系統(tǒng)的開發(fā)過程。而這正是本文的所要研究的內(nèi)容。2. Bootloader2.1 Bootloader 的概念和作用Bootloader是嵌入式系統(tǒng)的引導(dǎo)加載程序,它是系統(tǒng)上電后運(yùn)行的第一段程序,其作用類似于 PC機(jī)上的 BIOS。在完成對(duì)系統(tǒng)的初始化任務(wù)之后,它會(huì)將非易失性存儲(chǔ)器(通常是 Flash或 DOC 等)中的 Linux內(nèi)核拷貝到 RAM 中去,然后跳轉(zhuǎn)到內(nèi)核的第一條指令 處繼續(xù)執(zhí)行,從而啟動(dòng)Linux內(nèi)核。由此可見,bootloader 和 Linux內(nèi)核有著密不可分的聯(lián)系,要想清楚的了解Linux內(nèi)核的啟動(dòng)過程,我們
5、必須先得認(rèn)識(shí)bootloader 的執(zhí)行過程,這樣才能對(duì)嵌入式系統(tǒng)的整個(gè)啟動(dòng)過程有清晰的掌握。2.2 Bootloader 的執(zhí)行過程不同的處理器上電或復(fù)位后執(zhí)行的第一條指令地址并不相同,對(duì)于ARM 處理器來說,該地址為 0 x00000000。對(duì)于一般的嵌入式系統(tǒng),通常把 Flash 等非易失性存儲(chǔ)器映射到 這個(gè)地址處,而 bootloader 就位于該存儲(chǔ)器的最前端,所以系統(tǒng)上電或復(fù)位后執(zhí)行的第一段程序便是 bootloader。而因?yàn)榇鎯?chǔ) bootloader的存儲(chǔ)器不同,bootloader 的執(zhí)行過程也并不相 同,下面將具體分析。嵌入式系統(tǒng)中廣泛采用的非易失性存儲(chǔ)器通常是Flash
6、,而 Flash又分為 Nor Flash和Nand Flash 兩種。它們之間的不同在于:Nor Flash支持芯片內(nèi)執(zhí)行(XIP, eXecute InPlace),這樣代碼可以在 Flash上直接執(zhí)行而不必拷貝到RAM 中去執(zhí)行。而 Nand Flash并不支持 XIP ,所以要想執(zhí)行 Nand Flash上的代碼,必須先將其拷貝到RAM 中去,然后跳到RAM 中去執(zhí) 行。實(shí)際應(yīng)用中的bootloader 根據(jù)所需功能的不同可以設(shè)計(jì)得很復(fù)雜,除完成基本的初始化系統(tǒng)和調(diào)用 Linux內(nèi)核等基本任務(wù)外,還可以執(zhí)行很多用戶輸入的命令,比如設(shè)置Linux啟動(dòng)參數(shù),給 Flash分區(qū)等;也可以設(shè)計(jì)
7、得很簡(jiǎn)單,只完成最基本的功能。但為了能達(dá)到啟動(dòng)Linux內(nèi)核的目的,所有的 bootloader都必須具備以下功能2:1) 初始化 RAM因?yàn)?Linux 內(nèi)核一般都會(huì)在 RAM 中運(yùn)行,所以在調(diào)用 Linux 內(nèi)核之前 bootloader 必須 設(shè)置和初始化RAM,為調(diào)用 Linux內(nèi)核做好準(zhǔn)備。初始化 RAM 的任務(wù)包括設(shè)置 CPU 的 控制寄存器參數(shù),以便能正常使用RAM以及檢測(cè) RAM 大小等。2) 初始化串口串口在 Linux的啟動(dòng)過程中有著非常重要的作用,它是 Linux內(nèi)核和用戶交互的方式之Linux在啟動(dòng)過程中可以將信息通過串口輸出,這樣便可清楚的了解 程。雖然它并不是 bo
8、otloader 必須要完成的工作,但是通過串口輸出信息是調(diào)試和Linux內(nèi)核的強(qiáng)有力的工具,所以一般的bootloader都會(huì)在執(zhí)行過程中初始化一個(gè)串口做為調(diào)試端口。Linux的啟動(dòng)過3)檢測(cè)處理器類型Bootloader在調(diào)用 Linux內(nèi)核前必須檢測(cè)系統(tǒng)的處理器類型,并將其保存到某個(gè)常量中提供給 Linux內(nèi)核。Linux內(nèi)核在啟動(dòng)過程中會(huì)根據(jù)該處理器類型調(diào)用相應(yīng)的初始化程序。4)設(shè)置 Linux啟動(dòng)參數(shù)Bootloader在執(zhí)行過程中必須設(shè)置和初始化 Linux的內(nèi)核啟動(dòng)參數(shù)。目前傳遞啟動(dòng)參數(shù)主要采用兩種方式:即通過 struct param_struct 和 struct tag (
9、標(biāo)記列表,tagged list )兩 種結(jié)構(gòu)傳遞。struct param_struct是一種比較老的參數(shù)傳遞方式,在 2.4 版本以前的內(nèi)核中使用較多。從 2.4版本以后 Linux內(nèi)核基本上采用標(biāo)記列表的方式。但為了保持和以前版本的兼容性,它仍支持 struct param_struct參數(shù)傳遞方式,只不過在內(nèi)核啟動(dòng)過程中它將被轉(zhuǎn)換成標(biāo)記列表方式。標(biāo)記列表方式是種比較新的參數(shù)傳遞方式,它必須以ATAG_CORE 開始,并以ATAG_NONE 結(jié)尾。中間可以根據(jù)需要加入其他列表。Linux內(nèi)核在啟動(dòng)過程中會(huì)根據(jù)該啟動(dòng)參數(shù)進(jìn)行相應(yīng)的初始化工作。5)調(diào)用 Linux內(nèi)核映像Bootloader
10、完成的最后一項(xiàng)工作便是調(diào)用Linux內(nèi)核。如果 Linux內(nèi)核存放在 Flash中,并且可直接在上面運(yùn)行(這里的Flash指 Nor Flash),那么可直接跳轉(zhuǎn)到內(nèi)核中去執(zhí)行。但由于在 Flash中執(zhí)行代碼會(huì)有種種限制,而且速度也遠(yuǎn)不及 RAM 快,所以一般的嵌 入式系統(tǒng)都是將Linux內(nèi)核拷貝到 RAM 中,然后跳轉(zhuǎn)到 RAM 中去執(zhí)行。不論哪種情況,在跳到Linux內(nèi)核執(zhí)行之前 CUP 的寄存器必須滿足以下條件:r0 = 0,r1 =處理器類型,r2 =標(biāo)記列表在RAM中的地址。3. Linux內(nèi)核的啟動(dòng)過程在 bootloader 將 Linux內(nèi)核映像拷貝到RAM以后,可以通過下例代
11、碼啟動(dòng)Linux內(nèi)核:call_linux(0, machine_type, kernel_params_base)。其中,machine_tpye 是 bootloader 檢測(cè)出來的處理器類型,kernel_params_base 是啟動(dòng)參數(shù)在 RAM 的地址。通過這種方式將 Linux啟動(dòng)需要的參數(shù)從 bootloader傳遞到內(nèi)核。Linux內(nèi)核有兩種映像:一種是非壓縮內(nèi)核,叫Image ,另一種是它的壓縮版本,叫zImage。根據(jù)內(nèi)核映像的不同, Linux內(nèi)核的啟動(dòng)在開始階段也有所不同。zImage 是Image經(jīng)過壓縮形成的,所以它的大小比Image小。但為了能使用 zImage
12、 ,必須在它的開頭加上解壓縮的代碼,將zImage解壓縮之后才能執(zhí)行,因此它的執(zhí)行速度比Image要慢。但考慮到嵌入式系統(tǒng)的存儲(chǔ)空容量一般比較小,采用zImage可以占用較少的存儲(chǔ)空間,因此犧牲一點(diǎn)性能上的代價(jià)也是值得的。所以一般的嵌入式系統(tǒng)均采用壓縮內(nèi)核的方式。對(duì)于 ARM 系列處理器來說,zImage 的入口程序即為 arch/arm/boot/compressed/head.S。它依次完成以下工作:開啟MMU和 Cache,調(diào)用 decompress_kernel()解壓內(nèi)核,最后通過調(diào)用 call_kernel()進(jìn)入非壓縮內(nèi)核Image的啟動(dòng)。下面將具體分析在此之后Linux內(nèi)核的啟
13、動(dòng)過程。3.1 Linux內(nèi)核入口Linux非壓縮內(nèi)核的入口位于文件 /arch/arm/kernel/head-armv.S 中的 stext段。該段的基地址就是壓縮內(nèi)核解壓后的跳轉(zhuǎn)地址。如果系統(tǒng)中加載的內(nèi)核是非壓縮的Image ,那么bootloader 將內(nèi)核從 Flash中拷貝到 RAM 后將直接跳到該地址處,從而啟動(dòng) Linux內(nèi)核。 不同體系結(jié)構(gòu)的Linux系統(tǒng)的入口文件是不同的,而且因?yàn)樵撐募c具體體系結(jié)構(gòu)有關(guān),所以一般均用匯編語言編寫3。對(duì)基于 ARM 處理的 Linux系統(tǒng)來說,該文件就是head-armv.S。該程序通過查找處理器內(nèi)核類型和處理器類型調(diào)用相應(yīng)的初始化函數(shù),再
14、建 立頁表,最后跳轉(zhuǎn)到 start_kernel()函數(shù)開始內(nèi)核的初始化工作。檢測(cè)處理器內(nèi)核類型是在匯編子函數(shù)_lookup_processor_type中完成的。通過以下代碼可實(shí)現(xiàn)對(duì)它的調(diào)用:bl _lookup_processor_type。_lookup_processor_type調(diào)用結(jié)束返回原程序時(shí),會(huì)將返回結(jié)果保存到寄存器中。其中r8保存了頁表的標(biāo)志位,r9保存了處理器的 ID號(hào),r10保存了與處理器相關(guān)的struproc_info_list 結(jié)構(gòu)地址。檢測(cè)處理器類型是在匯編子函數(shù)_lookup_architecture_type中完成的。與_lookup_processor_ty
15、pe 類似,它通過代碼:“bl _lookup_processor_type 來實(shí)現(xiàn)對(duì)它的調(diào)用。該函數(shù)返回時(shí),會(huì)將返回結(jié)構(gòu)保存在 r5、r6和 r7三個(gè)寄存器中。其中 r5保存了 RAM 的起始基地址,r6保存了 I/O基地址,r7保存了 I/O的頁表偏移地址。當(dāng)檢測(cè)處理器內(nèi)核和處理器類型結(jié)束后,將調(diào)用_create_page_tables子函數(shù)來建立頁表,它所要做的工作就是將 RAM 基地址開始的 4M空間的物理地址映射到0 xC0000000開始的虛擬地址處。對(duì)筆者的 S3C2410 開發(fā)板而言,RAM連接到物理地址0 x30000000處,當(dāng)調(diào)用 _create_page_tables
16、結(jié)束后 0 x30000000 0 x30400000 物理地址將映射到 0XC0000000 0 xC0400000 虛擬地址處。當(dāng)所有的初始化結(jié)束之后,使用如下代碼來跳到C 程序的入口函數(shù)start_kernel()處,開始之后的內(nèi)核初始化工作:b SYMBOL_NAME(start_kernel)3.2 start_kernel 函數(shù)start_kernel 是所有 Linux平臺(tái)進(jìn)入系統(tǒng)內(nèi)核初始化后的入口函數(shù),它主要完成剩余的與 硬件平臺(tái)相關(guān)的初始化工作,在進(jìn)行一系列與內(nèi)核相關(guān)的初始化后,調(diào)用第一個(gè)用戶進(jìn)程一init 進(jìn)程并等待用戶進(jìn)程的執(zhí)行,這樣整個(gè) Linux內(nèi)核便啟動(dòng)完畢。該函數(shù)
17、所做的具體工 作有45:1) 調(diào)用 setup_arch()函數(shù)進(jìn)行與體系結(jié)構(gòu)相關(guān)的第一個(gè)初始化工作;對(duì)不同的體系結(jié)構(gòu)來說該函數(shù)有不同的定義。對(duì)于 ARM 平臺(tái)而言,該函數(shù)定義在arch/arm/kernel/Setup.c。它首先通過檢測(cè)出來的處理器類型進(jìn)行處理器內(nèi)核的初始化,然 后通過 bootmem_init()函數(shù)根據(jù)系統(tǒng)定義的meminfo結(jié)構(gòu)進(jìn)行內(nèi)存結(jié)構(gòu)的初始化,最后調(diào)用 paging_init()開啟 MMU,創(chuàng)建內(nèi)核頁表,映射所有的物理內(nèi)存和IO空間。2) 創(chuàng)建異常向量表和初始化中斷處理函數(shù);3) 初始化系統(tǒng)核心進(jìn)程調(diào)度器和時(shí)鐘中斷處理機(jī)制;4) 初始化串口控制臺(tái)(serial
18、-console );ARM-Linux在初始化過程中一般都會(huì)初始化一個(gè)串口做為內(nèi)核的控制臺(tái),這樣內(nèi)核在 啟動(dòng)過程中就可以通過串口輸出信息以便開發(fā)者或用戶了解系統(tǒng)的啟動(dòng)進(jìn)程。5) 創(chuàng)建和初始化系統(tǒng)cache ,為各種內(nèi)存調(diào)用機(jī)制提供緩存,包括;動(dòng)態(tài)內(nèi)存分配,虛擬文件系統(tǒng)(VirtualFile System )及頁緩存。6) 初始化內(nèi)存管理,檢測(cè)內(nèi)存大小及被內(nèi)核占用的內(nèi)存情況;7) 初始化系統(tǒng)的進(jìn)程間通信機(jī)制(IPC);當(dāng)以上所有的初始化工作結(jié)束后,start_kernel()函數(shù)會(huì)調(diào)用 rest_init()函數(shù)來進(jìn)行最后的初始化,包括創(chuàng)建系統(tǒng)的第一個(gè)進(jìn)程一 init 進(jìn)程來結(jié)束內(nèi)核的啟動(dòng)。
19、Init進(jìn)程首先進(jìn)行一系 列的硬件初始化,然后通過命令行傳遞過來的參數(shù)掛載根文件系統(tǒng)。最后init 進(jìn)程會(huì)執(zhí)行用 戶傳遞過來的“iniM ”啟動(dòng)參數(shù)執(zhí)行用戶指定的命令,或者執(zhí)行以下幾個(gè)進(jìn)程之一: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)當(dāng)所有的初始化工作結(jié)束后,cpu_idle()函數(shù)會(huì)被調(diào)用來使系統(tǒng)處于閑置(等待用戶程序的執(zhí)行。至此,整
20、個(gè) Linux內(nèi)核啟動(dòng)完畢。4.結(jié)論Linux內(nèi)核是一個(gè)非常龐大的工程,經(jīng)過十多年的發(fā)展,它已從從最初的幾百 發(fā)展到現(xiàn)在的幾百兆。清晰的了解它執(zhí)行的每一個(gè)過程是件非常困難的事。發(fā)過程中,我們并不需要十分清楚linux的內(nèi)部工作機(jī)制,只要適當(dāng)修改些與硬件相關(guān)的部分,就可以將linux移植到其它目標(biāo)平臺(tái)上。通過對(duì) linux的啟動(dòng)過程的分析,我們可以看出哪些是和硬件相關(guān)的,哪些是 linux內(nèi)核內(nèi)部已實(shí)現(xiàn)的功能,這樣在移植linux的過程中便有所針對(duì)。而 linux內(nèi)核的分層設(shè)計(jì)將使linux的移植變得更加容易。參考文獻(xiàn)1詹榮開. 嵌入式系統(tǒng) bootloader 技術(shù)內(nèi)幕 EB/OL.http:/ , 2003.12 .2 Russell King Booting ARM LinuxZ Linux Documentation May 20023 劉淼.嵌入式系統(tǒng)接口設(shè)計(jì)與Linux驅(qū)動(dòng)程序開發(fā)M.北京航空航天大學(xué)出版社.2006.64 William Gatliff The Linux 2.4 Kernel s Startup ProcedureDB/C20P2 Embed
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 泵類銷售員崗位面試問題及答案
- 保安隊(duì)長(zhǎng)崗位面試問題及答案
- 自動(dòng)化測(cè)試工程師崗位面試問題及答案
- 游戲數(shù)值策劃師崗位面試問題及答案
- 浙江省麗水市四校聯(lián)考2025屆高二下化學(xué)期末達(dá)標(biāo)檢測(cè)試題含解析
- 安徽師范大學(xué)附中2025屆高二下化學(xué)期末達(dá)標(biāo)檢測(cè)試題含解析
- 2025屆山西省同煤一中聯(lián)盟校高一下化學(xué)期末聯(lián)考試題含解析
- 2025屆浙江寧波市北侖區(qū)高二化學(xué)第二學(xué)期期末達(dá)標(biāo)檢測(cè)模擬試題含解析
- 公用澡堂制度管理辦法
- 幼兒園戶外活動(dòng)管理:現(xiàn)狀與對(duì)策探討
- 專題:閱讀理解 30篇 中考英語高分提升之新題速遞第二輯【含答案+解析】
- 企業(yè)面試題目和答案大全
- 抖音房產(chǎn)直播課件
- 2025至2030中國(guó)近視眼治療儀市場(chǎng)競(jìng)爭(zhēng)力剖析及企業(yè)經(jīng)營(yíng)形勢(shì)分析報(bào)告
- 2025年高考化學(xué)試卷(廣東卷)(空白卷)
- 體育老師招聘試題及答案
- 自然生態(tài)探險(xiǎn)之旅行業(yè)跨境出海項(xiàng)目商業(yè)計(jì)劃書
- 2025年北京市高考英語試卷真題(含答案解析)
- 西藏自治區(qū)拉薩市達(dá)孜區(qū)孜縣2025年七下英語期中質(zhì)量檢測(cè)模擬試題含答案
- 遼寧省沈陽市2023?2024學(xué)年高二下冊(cè)期末考試數(shù)學(xué)試卷2附解析
- 廚師三級(jí)考試試題及答案
評(píng)論
0/150
提交評(píng)論