一级日韩免费大片,亚洲一区二区三区高清,性欧美乱妇高清come,久久婷婷国产麻豆91天堂,亚洲av无码a片在线观看

ARM Linux啟動(dòng)過(guò)程分析

時(shí)間:2024-07-25 21:19:53 計算機畢業(yè)論文 我要投稿
  • 相關(guān)推薦

ARM Linux啟動(dòng)過(guò)程分析

畢業(yè)論文


摘 要: 嵌入式 Linux 的可移植性使得我們可以在各種電子產(chǎn)品上看到它的身影。對于不
同體系結構的處理器來(lái)說(shuō)Linux的啟動(dòng)過(guò)程也有所不同。本文以S3C2410 ARM處理器為例,
詳細分析了系統上電后 bootloader的執行流程及 ARM Linux的啟動(dòng)過(guò)程。
關(guān)鍵詞:ARM Linux bootloader 啟動(dòng)過(guò)程
中圖分類(lèi)號:TP316
1. 引 言
Linux 最初是由瑞典赫爾辛基大學(xué)的學(xué)生 Linus Torvalds在1991 年開(kāi)發(fā)出來(lái)的,之后在
GNU的支持下,Linux 獲得了巨大的發(fā)展。雖然 Linux 在桌面 PC 機上的普及程度遠不及微
軟的 Windows 操作系統,但它的發(fā)展速度之快、用戶(hù)數量的日益增多,也是微軟所不能輕
視的。而近些年來(lái) Linux 在嵌入式領(lǐng)域的迅猛發(fā)展,更是給 Linux 注入了新的活力。
1個(gè)嵌入式 Linux 系統從軟件角度看可以分為4個(gè)部分[1]
:引導加載程序(bootloader),
Linux 內核,文件系統,應用程序。
其中 bootloader是系統啟動(dòng)或復位以后執行的第1段代碼,它主要用來(lái)初始化處理器及
外設,然后調用 Linux 內核。Linux 內核在完成系統的初始化之后需要掛載某個(gè)文件系統做
為根文件系統(Root Filesystem)。根文件系統是 Linux 系統的核心組成部分,它可以做為
Linux 系統中文件和數據的存儲區域,通常它還包括系統配置文件和運行應用軟件所需要的
庫。應用程序可以說(shuō)是嵌入式系統的“靈魂”,它所實(shí)現的功能通常就是設計該嵌入式系統
所要達到的目標。如果沒(méi)有應用程序的支持,任何硬件上設計精良的嵌入式系統都沒(méi)有實(shí)用
意義。
從以上分析我們可以看出 bootloader 和 Linux 內核在嵌入式系統中的關(guān)系和作用。
Bootloader在運行過(guò)程中雖然具有初始化系統和執行用戶(hù)輸入的命令等作用,但它最根本的
功能就是為了啟動(dòng) Linux 內核。在嵌入式系統開(kāi)發(fā)的過(guò)程中,很大1部分精力都是花在
bootloader 和 Linux 內核的開(kāi)發(fā)或移植上。如果能清楚的了解 bootloader 執行流程和 Linux
的啟動(dòng)過(guò)程,將有助于明確開(kāi)發(fā)過(guò)程中所需的工作,從而加速嵌入式系統的開(kāi)發(fā)過(guò)程。而這
正是本文的所要研究的內容。
2. Bootloader
2.1 Bootloader的概念和作用
Bootloader是嵌入式系統的引導加載程序,它是系統上電后運行的第1段程序,其作用
類(lèi)似于 PC 機上的 BIOS。在完成對系統的初始化任務(wù)之后,它會(huì )將非易失性存儲器(通常
是 Flash或 DOC 等)中的Linux 內核拷貝到 RAM 中去,然后跳轉到內核的第1條指令處繼
續執行,從而啟動(dòng) Linux 內核。
由此可見(jiàn),bootloader 和 Linux 內核有著(zhù)密不可分的聯(lián)系,要想清楚的了解 Linux內核
的啟動(dòng)過(guò)程,我們必須先得認識 bootloader的執行過(guò)程,這樣才能對嵌入式系統的整個(gè)啟動(dòng)
過(guò)程有清晰的掌握。
2.2 Bootloader的執行過(guò)程
不同的處理器上電或復位后執行的第1條指令地址并不相同,對于 ARM 處理器來(lái)說(shuō),
該地址為 0x00000000。對于1般的嵌入式系統,通常把 Flash 等非易失性存儲器映射到這個(gè)
地址處,而 bootloader就位于該存儲器的最前端,所以系統上電或復位后執行的第1段程序
便是 bootloader。而因為存儲 bootloader的存儲器不同,bootloader的執行過(guò)程也并不相同,
下面將具體分析。
嵌入式系統中廣泛采用的非易失性存儲器通常是 Flash,而 Flash 又分為 Nor Flash 和
Nand Flash 兩種。 它們之間的不同在于: Nor Flash 支持芯片內執行(XIP, eXecute In Place),
這樣代碼可以在Flash上直接執行而不必拷貝到RAM中去執行。而Nand Flash并不支持XIP,
所以要想執行 Nand Flash 上的代碼,必須先將其拷貝到 RAM中去,然后跳到 RAM 中去執
行。
實(shí)際應用中的 bootloader根據所需功能的不同可以設計得很復雜,除完成基本的初始化
系統和調用 Linux 內核等基本任務(wù)外,還可以執行很多用戶(hù)輸入的命令,比如設置 Linux 啟
動(dòng)參數,給 Flash 分區等;也可以設計得很簡(jiǎn)單,只完成最基本的功能。但為了能達到啟動(dòng)
Linux 內核的目的,所有的 bootloader都必須具備以下功能[2]

1) 初始化 RAM
因為 Linux 內核1般都會(huì )在 RAM 中運行,所以在調用 Linux 內核之前 bootloader 必須
設置和初始化 RAM,為調用 Linux內核做好準備。初始化 RAM 的任務(wù)包括設置 CPU 的控
制寄存器參數,以便能正常使用 RAM 以及檢測RAM 大小等。
2) 初始化串口
串口在 Linux 的啟動(dòng)過(guò)程中有著(zhù)非常重要的作用,它是 Linux內核和用戶(hù)交互的方式之
1。Linux 在啟動(dòng)過(guò)程中可以將信息通過(guò)串口輸出,這樣便可清楚的了解 Linux 的啟動(dòng)過(guò)程。
雖然它并不是 bootloader 必須要完成的工作,但是通過(guò)串口輸出信息是調試 bootloader 和
Linux 內核的強有力的工具,所以1般的 bootloader 都會(huì )在執行過(guò)程中初始化1個(gè)串口做為
調試端口。
3) 檢測處理器類(lèi)型
Bootloader在調用 Linux內核前必須檢測系統的處理器類(lèi)型,并將其保存到某個(gè)常量中
提供給 Linux 內核。Linux 內核在啟動(dòng)過(guò)程中會(huì )根據該處理器類(lèi)型調用相應的初始化程序。
4) 設置 Linux啟動(dòng)參數
Bootloader在執行過(guò)程中必須設置和初始化 Linux 的內核啟動(dòng)參數。目前傳遞啟動(dòng)參數
主要采用兩種方式:即通過(guò) struct param_struct 和struct tag(標記列表,tagged list)兩種結
構傳遞。struct param_struct 是1種比較老的參數傳遞方式,在 2.4 版本以前的內核中使用較
多。從 2.4 版本以后 Linux 內核基本上采用標記列表的方式。但為了保持和以前版本的兼容
性,它仍支持 struct param_struct 參數傳遞方式,只不過(guò)在內核啟動(dòng)過(guò)程中它將被轉換成標
記列表方式。
標記列表方式是種比較新的參數傳遞方式,它必須以 ATAG_CORE 開(kāi)始,并以
ATAG_NONE 結尾。中間可以根據需要加入其他列表。Linux內核在啟動(dòng)過(guò)程中會(huì )根據該啟
動(dòng)參數進(jìn)行相應的初始化工作。



[NextPage]


5) 調用 Linux內核映像
Bootloader完成的最后1項工作便是調用 Linux內核。如果 Linux 內核存放在 Flash 中,
并且可直接在上面運行(這里的 Flash 指 Nor Flash),那么可直接跳轉到內核中去執行。
但由于在 Flash 中執行代碼會(huì )有種種限制,而且速度也遠不及 RAM 快,所以1般的嵌
入式系統都是將 Linux內核拷貝到 RAM 中,然后跳轉到 RAM 中去執行。
不論哪種情況,在跳到 Linux 內核執行之前 CUP的寄存器必須滿(mǎn)足以下條件:r0=0,
r1=處理器類(lèi)型,r2=標記列表在 RAM中的地址。
3. Linux內核的啟動(dòng)過(guò)程
在 bootloader將 Linux 內核映像拷貝到 RAM 以后,可以通過(guò)下例代碼啟動(dòng) Linux 內核:
call_linux(0, machine_type, kernel_params_base)。
其中,machine_tpye 是 bootloader檢測出來(lái)的處理器類(lèi)型, kernel_params_base 是啟動(dòng)參
數在 RAM 的地址。通過(guò)這種方式將 Linux 啟動(dòng)需要的參數從 bootloader傳遞到內核。
Linux 內核有兩種映像:1種是非壓縮內核,叫 Image,另1種是它的壓縮版本,叫
zImage。根據內核映像的不同,Linux 內核的啟動(dòng)在開(kāi)始階段也有所不同。zImage 是 Image
經(jīng)過(guò)壓縮形成的,所以它的大小比 Image 小。但為了能使用 zImage,必須在它的開(kāi)頭加上
解壓縮的代碼,將 zImage 解壓縮之后才能執行,因此它的執行速度比 Image 要慢。但考慮
到嵌入式系統的存儲空容量1般比較小,采用 zImage 可以占用較少的存儲空間,因此犧牲
1點(diǎn)性能上的代價(jià)也是值得的。所以1般的嵌入式系統均采用壓縮內核的方式。
對于 ARM 系列處理器來(lái)說(shuō),zImage 的入口程序即為 arch/arm/boot/compressed/head.S。
它依次完成以下工作:開(kāi)啟 MMU 和 Cache,調用 decompress_kernel()解壓內核,最后通過(guò)
調用 call_kernel()進(jìn)入非壓縮內核 Image 的啟動(dòng)。下面將具體分析在此之后 Linux 內核的啟
動(dòng)過(guò)程。
3.1 Linux內核入口
Linux 非壓縮內核的入口位于文件/arch/arm/kernel/head-armv.S 中的 stext 段。該段的基
地址就是壓縮內核解壓后的跳轉地址。如果系統中加載的內核是非壓縮的 Image,那么
bootloader將內核從 Flash中拷貝到 RAM 后將直接跳到該地址處,從而啟動(dòng) Linux 內核。
不同體系結構的 Linux 系統的入口文件是不同的,而且因為該文件與具體體系結構有
關(guān),所以1般均用匯編語(yǔ)言編寫(xiě)[3]
。對基于 ARM 處理的 Linux 系統來(lái)說(shuō),該文件就是
head-armv.S。該程序通過(guò)查找處理器內核類(lèi)型和處理器類(lèi)型調用相應的初始化函數,再建
立頁(yè)表,最后跳轉到 start_kernel()函數開(kāi)始內核的初始化工作。
檢測處理器內核類(lèi)型是在匯編子函數__lookup_processor_type中完成的。通過(guò)以下代碼
可實(shí)現對它的調用:
bl __lookup_processor_type。
__lookup_processor_type調用結束返回原程序時(shí),會(huì )將返回結果保存到寄存器中。其中
r8 保存了頁(yè)表的標志位,r9 保存了處理器的 ID 號,r10 保存了與處理器相關(guān)的 stru
proc_info_list 結構地址。
檢測處理器類(lèi)型是在匯編子函數 __lookup_architecture_type 中完成的。與
__lookup_processor_type類(lèi)似,它通過(guò)代碼:“bl __lookup_processor_type”來(lái)實(shí)現對它的調
用。該函數返回時(shí),會(huì )將返回結構保存在 r5、r6 和 r7 3個(gè)寄存器中。其中 r5 保存了 RAM
的起始基地址,r6 保存了 I/O基地址,r7 保存了 I/O的頁(yè)表偏移地址。
當檢測處理器內核和處理器類(lèi)型結束后,將調用__create_page_tables 子函數來(lái)建立頁(yè)
表,它所要做的工作就是將 RAM 基地址開(kāi)始的 4M 空間的物理地址映射到 0xC0000000 開(kāi)
始的虛擬地址處。對筆者的 S3C2410 開(kāi)發(fā)板而言,RAM 連接到物理地址 0x30000000 處,
當調用 __create_page_tables 結束后 0x30000000 ~ 0x30400000 物理地址將映射到
0xC0000000~0xC0400000 虛擬地址處。
當所有的初始化結束之后,使用如下代碼來(lái)跳到 C 程序的入口函數 start_kernel()處,開(kāi)
始之后的內核初始化工作:
b SYMBOL_NAME(start_kernel)
3.2 start_kernel函數
start_kernel是所有 Linux 平臺進(jìn)入系統內核初始化后的入口函數,它主要完成剩余的與
硬件平臺相關(guān)的初始化工作,在進(jìn)行1系列與內核相關(guān)的初始化后,調用第1個(gè)用戶(hù)進(jìn)程-
init 進(jìn)程并等待用戶(hù)進(jìn)程的執行,這樣整個(gè) Linux 內核便啟動(dòng)完畢。該函數所做的具體工作
有[4][5]

1) 調用 setup_arch()函數進(jìn)行與體系結構相關(guān)的第1個(gè)初始化工作;
對不同的體系結構來(lái)說(shuō)該函數有不同的定義。對于 ARM 平臺而言,該函數定義在
arch/arm/kernel/Setup.c。它首先通過(guò)檢測出來(lái)的處理器類(lèi)型進(jìn)行處理器內核的初始化,然后
通過(guò) bootmem_init()函數根據系統定義的 meminfo 結構進(jìn)行內存結構的初始化,最后調用
paging_init()開(kāi)啟 MMU,創(chuàng )建內核頁(yè)表,映射所有的物理內存和 IO空間。
2) 創(chuàng )建異常向量表和初始化中斷處理函數;
3) 初始化系統核心進(jìn)程調度器和時(shí)鐘中斷處理機制;
4) 初始化串口控制臺(serial-console);
ARM-Linux 在初始化過(guò)程中1般都會(huì )初始化1個(gè)串口做為內核的控制臺,這樣內核在
啟動(dòng)過(guò)程中就可以通過(guò)串口輸出信息以便開(kāi)發(fā)者或用戶(hù)了解系統的啟動(dòng)進(jìn)程。
5) 創(chuàng )建和初始化系統 cache,為各種內存調用機制提供緩存,包括;動(dòng)態(tài)內存分配,虛擬文
件系統(VirtualFile System)及頁(yè)緩存。
6) 初始化內存管理,檢測內存大小及被內核占用的內存情況;
7) 初始化系統的進(jìn)程間通信機制(IPC);
當以上所有的初始化工作結束后,start_kernel()函數會(huì )調用 rest_init()函數來(lái)進(jìn)行最后的
初始化,包括創(chuàng )建系統的第1個(gè)進(jìn)程-init 進(jìn)程來(lái)結束內核的啟動(dòng)。Init 進(jìn)程首先進(jìn)行1系
列的硬件初始化,然后通過(guò)命令行傳遞過(guò)來(lái)的參數掛載根文件系統。最后 init 進(jìn)程會(huì )執行用
戶(hù)傳遞過(guò)來(lái)的“init=”啟動(dòng)參數執行用戶(hù)指定的命令,或者執行以下幾個(gè)進(jìn)程之1:
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()函數會(huì )被調用來(lái)使系統處于閑置(idle)狀態(tài)并
等待用戶(hù)程序的執行。至此,整個(gè) Linux 內核啟動(dòng)完畢。



[NextPage]


4. 結論
Linux 內核是1個(gè)非常龐大的工程,經(jīng)過(guò)10多年的發(fā)展,它已從從最初的幾百 KB 大小
發(fā)展到現在的幾百兆。清晰的了解它執行的每1個(gè)過(guò)程是件非常困難的事。但是在嵌入式開(kāi)
發(fā)過(guò)程中,我們并不需要10分清楚 linux 的內部工作機制,只要適當修改 linux 內核中那些
與硬件相關(guān)的部分,就可以將 linux 移植到其它目標平臺上。通過(guò)對 linux 的啟動(dòng)過(guò)程的分
析,我們可以看出哪些是和硬件相關(guān)的,哪些是 linux 內核內部已實(shí)現的功能,這樣在移植
linux 的過(guò)程中便有所針對。而 linux內核的分層設計將使 linux 的移植變得更加容易。
參考文獻
[1] 詹榮開(kāi).嵌入式系統bootloader技術(shù)內幕[EB/OL]. 2003.12.
[2] Russell King.Booting ARM Linux[Z].Linux Documentation.May 2002
[3] 劉淼.嵌入式系統接口設計與Linux驅動(dòng)程序開(kāi)發(fā)[M].北京航空航天大學(xué)出版社.2006.6
[4] William Gatliff. The Linux 2.4 Kernel’s Startup Procedure[DB/CD]. 2002 Embedded System Conference San
Francisco,March..2002
[5] Claudia Salzberg Rodriguez,Gordon Fischer,Steven Smolski.Linux內核編程[M].陳莉君,賀炎,劉霞林.機
械工業(yè)出版社.2006.7
ARM Linux Start-up Procedure Analysis
Yao Chengqiang Sun Wensheng
School of Telecommunication Engineering of Beijing University of Posts and
Telecommunications
Abstract
We can see embedded Linux in kinds of electronic products because of its portability. Linux’s
start-up procedure for different processors is also different. This paper provides the analysis of
bootloader execution process and Linux kernel start-up procedure - taking the S3C2410 ARM
processor as ex

[1]

【ARM Linux啟動(dòng)過(guò)程分析】相關(guān)文章:

解析基于A(yíng)RM9的Linux內存映射03-07

嵌入式ARM-Linux水產(chǎn)養殖監控系統的設計03-07

ARM嵌入式在通信領(lǐng)域的應用分析03-03

ARM7在嵌入式應用中啟動(dòng)程序的實(shí)現03-19

基于A(yíng)RM-μCLinux嵌入式系統啟動(dòng)引導的實(shí)現03-20

基于A(yíng)RM9微處理器與Linux操作系統的SD驅動(dòng)開(kāi)發(fā)03-07

職務(wù)分析—過(guò)程與方法初探03-18

職務(wù)分析―過(guò)程與方法初探12-07

最新SCI論文發(fā)表過(guò)程分析12-03

一级日韩免费大片,亚洲一区二区三区高清,性欧美乱妇高清come,久久婷婷国产麻豆91天堂,亚洲av无码a片在线观看