新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > u-boot啟動(dòng)過程分析——基于lpc2210的移植代碼

u-boot啟動(dòng)過程分析——基于lpc2210的移植代碼

作者: 時(shí)間:2012-08-30 來源:網(wǎng)絡(luò) 收藏

系統(tǒng)啟動(dòng)的入口點(diǎn)。既然我們現(xiàn)在要分析u-boot的啟動(dòng)過程,就必須先找到u-boot最先實(shí)現(xiàn)的是哪些代碼,最先完成的是哪些任務(wù)。另一方面一個(gè)可執(zhí)行的image必須有一個(gè)入口點(diǎn),并且只能有一個(gè)全局入口點(diǎn),所以要通知編譯器這個(gè)入口在哪里。由此我們可以找到程序的入口點(diǎn)是在/board//u-boot.lds中指定的,其中ENTRY(_STart)說明程序從_start開始運(yùn)行,而他指向的是cpu/arm7tdmi/start.o文件。因?yàn)槲覀冇玫氖茿RM7TDMI的cpu架構(gòu),在復(fù)位后從地址0x00000000取它的第一條指令,所以我們將Flash映射到這個(gè)地址上,這樣在系統(tǒng)加電后,cpu將首先執(zhí)行u-boot程序。

u-boot的啟動(dòng)過程是多階段實(shí)現(xiàn)的,分了兩個(gè)階段。依賴于cpu體系結(jié)構(gòu)的代碼(如設(shè)備初始化代碼等)通常都放在stage1中,而且通常都是用匯編語言來實(shí)現(xiàn),以達(dá)到短小精悍的目的。而stage2則通常是用C語言來實(shí)現(xiàn)的,這樣可以實(shí)現(xiàn)復(fù)雜的功能,而且代碼具有更好的可讀性和可移植性。

下面我們先詳細(xì)分析下stage1中的代碼,如圖2所示:

u-boot啟動(dòng)過程分析——基于lpc2210的移植代碼

圖2 Start.s程序流程

代碼真正開始是在_start,設(shè)置異常向量表,這樣在cpu發(fā)生異常時(shí)就跳轉(zhuǎn)到/cpu/arm7tdmi/interrupts中去執(zhí)行相應(yīng)得中斷代碼。在interrupts文件中大部分的異常代碼都沒有實(shí)現(xiàn)具體的功能,只是打印一些異常消息,其中關(guān)鍵的是reset中斷代碼,跳到reset入口地址。

reset復(fù)位入口之前有一些段的聲明。在reset中,首先是將cpu設(shè)置為svc32模式下,并屏蔽所有irq和fiq。在u-boot中除了定時(shí)器使用了中斷外,其他的基本上都不需要使用中斷,比如串口通信和網(wǎng)絡(luò)等通信等,在u-boot中只要完成一些簡(jiǎn)單的通信就可以了,所以在這里屏蔽掉了所有的中斷響應(yīng)。

初始化外部總線。這部分首先設(shè)置了I/O口功能,包括串口、網(wǎng)絡(luò)接口等的設(shè)置,其他I/O口都設(shè)置為GPIO。然后設(shè)置BCFG0~BCFG3,即外部總線控制器。這里bank0對(duì)應(yīng)Flash,設(shè)置為16位寬度,總線速度設(shè)為最慢,以實(shí)現(xiàn)穩(wěn)定的操作;Bank1對(duì)應(yīng)DRAM,設(shè)置和Flash相同;Bank2對(duì)應(yīng)RTL8019。

接下來是cpu關(guān)鍵設(shè)置,包括系統(tǒng)重映射(告訴處理器在系統(tǒng)發(fā)生中斷的時(shí)候到外部存儲(chǔ)器中去讀取中斷向量表)和系統(tǒng)頻率。

lowlevel_init,設(shè)定RAM的時(shí)序,并將中斷控制器清零。這些部分和特定的平臺(tái)有關(guān),但大致的流程都是一樣的。

下面就是代碼的搬移階段了。為了獲得更快的執(zhí)行速度,通常把stage2加載到RAM空間中來執(zhí)行,因此必須為加載Boot Loader的stage2準(zhǔn)備好一段可用的RAM空間范圍??臻g大小最好是memory page大小(通常是4KB)的倍數(shù),一般而言,1M的RAM空間已經(jīng)足夠了。flash中存儲(chǔ)的u-boot可執(zhí)行文件中,代碼段、數(shù)據(jù)段以及BSS段都是首尾相連存儲(chǔ)的,所以在計(jì)算搬移大小的時(shí)候就是利用了用BSS段的首地址減去代碼的首地址,這樣算出來的就是實(shí)際使用的空間。程序用一個(gè)循環(huán)將代碼搬移到0x81180000,即RAM底端1M空間用來存儲(chǔ)代碼。然后程序繼續(xù)將中斷向量表搬到RAM的頂端。由于stage2通常是C語言執(zhí)行代碼,所以還要建立堆棧去。在堆棧區(qū)之前還要將malloc分配的空間以及全局?jǐn)?shù)據(jù)所需的空間空下來,他們的大小是由宏定義給出的,可以在相應(yīng)位置修改?;緝?nèi)存分布圖:

u-boot啟動(dòng)過程分析——基于lpc2210的移植代碼

圖3 搬移后內(nèi)存分布情況圖

接下來是的第二個(gè)階段,是用c代碼寫的,這部分是一些相對(duì)變化不大的部分,我們針對(duì)不同的板子改變它調(diào)用的一些初始化函數(shù),并且通過設(shè)置一些宏定義來改變初始化的流程,所以這些代碼在移植的過程中并不需要修改,也是錯(cuò)誤相對(duì)較少出現(xiàn)的文件。在文件的開始先是定義了一個(gè)函數(shù)指針數(shù)組,通過這個(gè)數(shù)組,程序通過一個(gè)循環(huán)來按順序進(jìn)行常規(guī)的初始化,并在其后通過一些宏定義來初始化一些特定的設(shè)備。在最后程序進(jìn)入一個(gè)循環(huán),main_loop。這個(gè)循環(huán)接收用戶輸入的命令,以設(shè)置參數(shù)或者進(jìn)行啟動(dòng)引導(dǎo)。

本篇文章將分析重點(diǎn)放在了前面的start.s上,是因?yàn)檫@部分無論在移植還是在調(diào)試過程中都是最容易出問題的地方,要解決問題就需要程序員對(duì)代碼進(jìn)行修改,所以在這里簡(jiǎn)單介紹了一下start.s的基本流程,希望能對(duì)大家有所幫助。


上一頁 1 2 下一頁

評(píng)論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉