參看BLOG:http://blog.csdn.net/linuxdianc/article/details/5026426#
BootLoader
軟件層次
一個嵌入式系統(tǒng)從軟件角度來看分為三個層次:
1. 引導(dǎo)加載程序
包括固化在固件(fireware)中的boot程序(可選
)(比如CMOS中的BIOS),和BootLoader(比如grub)兩大部分2.Linux內(nèi)核
特定嵌入式平臺的定制內(nèi)核
3.文件系統(tǒng)
包括了系統(tǒng)命令和應(yīng)用程序
PC機的引導(dǎo)加載程序由BIOS(其本質(zhì)是一段固件程序)和GRUB和 LILO一起組成。BIOS在完成硬件檢測和資源分配后,將硬盤中的引導(dǎo)程序讀到系統(tǒng)內(nèi)存中然后將控制權(quán)交給引導(dǎo)程序。引導(dǎo)程序的主要任務(wù)是將內(nèi)核從硬盤上讀到內(nèi)存中,然后跳轉(zhuǎn)到內(nèi)核的入口點去運行,即啟動操作系統(tǒng)
定義
在嵌入式系統(tǒng)中,通常沒有想BIOS那樣的固件程序,因此整個系統(tǒng)的加載啟動任務(wù)就完全由BootLoader來完成。比如在一個基于ARM7TDMI core的嵌入式系統(tǒng)中,系統(tǒng)在上電或復(fù)位時都從地址0x00000000開始執(zhí)行。而在這個地址處安排的通常就是系統(tǒng)的BootLoader程序
簡單地說,BootLoader就是在操作系統(tǒng)運行之前運行的一段小程序。通過這段小程序,可以初始化硬件設(shè)備,從而將系統(tǒng)的軟硬件環(huán)境帶到一個合適的狀態(tài),以便為最終調(diào)用操作系統(tǒng)做好準(zhǔn)備。
安裝
系統(tǒng)加電或復(fù)位后,所有的CPU通常都從CPU制造商預(yù)先安排地址開始執(zhí)行。比如,S3C6410在復(fù)位后從地址0x00000000起開始執(zhí)行。而嵌入式系統(tǒng)則將固態(tài)存儲設(shè)備(比如:FLASH)安排在這個地址上,而bootloader程序又安排在固態(tài)存儲器的最前端,這樣就能保證在系統(tǒng)加電后,CPU首先執(zhí)行BootLoader程序
流程
BootLoader的啟動過程可分為單階段(Single-Stage)和多階段(Muti-Stage)兩種,通常多階段的BootLoader具有更復(fù)雜的功能,更好的可移植性。從固態(tài)存儲設(shè)備上啟動的BootLoader大多采用兩階段,即啟動過程可以分為stage1和stage2:stage1完成初始化硬件,為stage2準(zhǔn)備內(nèi)存空間,并將stage2復(fù)制到內(nèi)存中,設(shè)置堆棧,然后跳轉(zhuǎn)到stage2.
BootLoader的stage1通常包括以下步驟:
----硬件設(shè)備初始化
----為加載BootLoader的stage2準(zhǔn)備RAM空間
----拷貝BootLoader的stage2到RAM空間中
----設(shè)置好堆棧(目的是為stage2中的C程序的運行搭建環(huán)境)
----跳轉(zhuǎn)到stage2的C入口點
該階段的程序主要是由匯編代碼寫成
BootLoader的stage2通常包括以下步驟:
----初始化本階段要使用的硬件設(shè)備(板載硬件,比如串口、網(wǎng)口)
----將內(nèi)核映像和根文件系統(tǒng)映像從flash上讀到RAM中
----調(diào)用內(nèi)核
該階段的程序主要是由C代碼寫成
工作模式
大多數(shù)BootLoader都包含兩種不同的工作模式:“啟動模式”和“下載模式”,這種區(qū)別僅對于開發(fā)人員才有意義,從最終用戶的角度來看,BootLoader的作用就是用來加載操作系統(tǒng),而不存在所謂的啟動模式與下載模式。
啟動模式:處理器一旦上電后,不需要干預(yù)便能自動地啟動bootloader,并通過bootloader啟動內(nèi)核
下載模式:CPU上電后,目標(biāo)機上的BootLoader將通過串口或網(wǎng)絡(luò)等通信手段從主機(Host)下載文件,然后控制啟動流程(常用于開發(fā)時)。
所以,用戶常見的是啟動模式
交叉工具鏈
工具鏈:gcc、gdb、ld等工具的集合便是工具鏈(sets)
交叉:軟件產(chǎn)生于宿主機,運行于目標(biāo)機的開發(fā)模式
安裝
進行嵌入式開發(fā)前,首先需安裝交叉工具鏈,步驟如下:
1.解壓工具鏈到某一目錄下,例:
tar xvzf arm-linux-gcc-4.5.1-v6-vfp.tgz –C/ (-C表示解壓到后面指定的目錄。如果沒有-C則是默認(rèn)解壓到當(dāng)前目錄。解壓后可以進入/4.5.1/bin/,可見很多工具)
2.修改/etc/profile,添加
export PATH=$PATH: /4.5.1/bin(如果不修改/etc/profile,那么每次運行工具如arm-linux-gcc則必須使用全路徑:/4.5.1/bin/arm-linux-gcc)
3.讓第二步對環(huán)境變量的修改生效
運行source /etc/profile
上述三步驟之后,可以在任何目錄下運行arm-linux-gcc
http://blog.csdn.net/yinjiabin/article/details/7369071
http://blog.csdn.net/dreambegin/article/details/6794673
工具使用
----編譯器:arm-linux-gcc
arm-linux-gcc hello.c –o hello
和gcc的用法完全一樣,不過gcc編譯的運行在X86上,而arm-linux-gcc編譯的運行在arm上
----反匯編工具:arm-linux-objdump
arm-linux-objdum –D –S hello
將二進制文件編程匯編代碼
arm-linux-objdum–D –S hello > log 導(dǎo)出到log文件中
----ELF文件查看工具:arm-linux-readelf
arm-linux-readelf –a hello
查看的信息中,常用的是:Data項的大小端模式
Machine項
arm-linux-readelf –d hello 查看hello使用的動態(tài)庫
UBoot
用于多種嵌入式CPU(MIPS、X86、ARM、XScale等)的bootloader程序,UBoot不僅支持嵌入式Linux系統(tǒng)的引導(dǎo),還支持VxWorks,QNX等多種嵌入式操作系統(tǒng)。
U-BOOT啟動流程
開發(fā)板上電后,執(zhí)行U-BOOT的第一條指令,然后順序執(zhí)行U-BOOT啟動函數(shù)??匆幌?/span>board/smdk2410/u-boot.lds這個鏈接腳本,可以知道目標(biāo)程序的各部分鏈接順序,第一個喲鏈接的是cpu/arm920t/start.o,那么U-BOOT的入口指令一定位于這個程序中
下載
從下面地址可以下載到uboot的源代碼:
目錄結(jié)構(gòu)
進入到UBOOT目錄,可以得到如下的目錄結(jié)構(gòu):
|--board
|--common
|--cpu
|--disk
|--doc
|--drivers
|--dtt
|--examples
|--fs
|--include
----board:和開發(fā)板有關(guān)的文件。每一個開發(fā)板都以一個子目錄出現(xiàn)在當(dāng)前目錄中,比如:smdk2410,子目錄中存放于開發(fā)板相關(guān)的文件
----common:實現(xiàn)Uboot支持的命令
----cpu:與特定CPU架構(gòu)相關(guān)的代碼,每一款Uboot下支持的CPU在該目錄下對應(yīng)一個子目錄,比如有子目錄arm920t等
----disk:對磁盤的支持
----doc:文檔目錄,uboot有非常完善的文檔,推薦閱讀
----drivers:uboot支持的設(shè)備驅(qū)動程序都放在該目錄,比如各種網(wǎng)卡、支持CFI的Flash、串口、USB等
.....
----tools:uboot的工具,如:mkimage、crc等等
編譯
Uboot的Makefile從功能上可以分成兩個部分:
1.執(zhí)行每種board相關(guān)的配置
2.編譯生成uboot.bin文件
uboot.bin的生成也分為兩步,以mini2440開發(fā)板為例來說明,如下(申明:該演示所使用的u-boot為經(jīng)過移植后的u-boot,未經(jīng)移植的u-boot并不支持該6410開發(fā)板,移植過程將在嵌入式linux系統(tǒng)移植專題班講解):
可以在/4.5.1/根目錄下查看Makefile,來知道uboot支持哪些開發(fā)板(比如在這里可以查看smdk6410):
1. 選擇要使用的board:
$make mini2440_config
2. 編譯生成u-boot.bin:
#makeCROSS_COMPILE=arm-linux-
編譯好后有個uboot.bin文件。之后將該文件燒寫到開發(fā)板中去
UBoot命令
常用命令
盡管UBOOT提供了豐富的命令集,但不同的單板所支持的命令并不一定一樣(可配置),help命令可用于查看當(dāng)前單板所支持的命令。
不同的board支持的命令不一定一樣(可配置)
環(huán)境變量相關(guān)
print(Printenv) 查看環(huán)境變量
——用法:
printenv:
-print values of all environment variables
printenv name ...
-print value of environment variable `name`
setenv:添加、修改、刪除環(huán)境變量(存在于內(nèi)存中,只在本次單板開機中有效)
——用法:
setenv name value...
-set environment variable `name` to `value...`
setenv name
-delete environment varible `name`
saveenv保存環(huán)境變量(存在于flash中)。將當(dāng)前定義的所有變量及其值存入flash中
文件下載
tftp:通過網(wǎng)絡(luò)下載文件(開發(fā)板必須有ip地址ipaddr和serverip)可以通過ping serverip看網(wǎng)絡(luò)是否連通
注意:使用tftp,需要先配置好網(wǎng)絡(luò)
如:
Uboot>setenv ethaddr 12:34:45:78:9A:BC
Uboot>setenv ipaddr 192.168.1.1
Uboot>setenv serverip 192.168.1.254(tftp服務(wù)器的地址)
例:
Uboot>tftp c0800000 uImage
把serber(ip=環(huán)境變量中設(shè)置的serverip)中服務(wù)目錄下的uImage通過TFTP讀入到0xc0800000處
loadb:通過串口下載(速度慢,少用)
內(nèi)存操作
md顯示內(nèi)存區(qū)的內(nèi)容。
md采用十六進制和ASCII碼兩種形式來顯示存儲單元的內(nèi)容。這條命令還可以采用長度標(biāo)識符 .l ,.w和.b;
md[.b , .w , .l]address
如:
md.w 100000
00100000:(顯示的內(nèi)容)
00100010:(顯示的內(nèi)容)
mm:修改內(nèi)存,地址自動遞增
mm [.b , .w ,.l] address
mm提供了一種互動修改存儲器內(nèi)容的方法。它會顯示地址和當(dāng)前值,然后提示用戶輸入。如果你輸入了一個合法的十六進制數(shù),這個新的值將會被寫入該地址。然后提示下一個地址。如果你沒有輸入任何值,只是按了一下回車,那么該地址的內(nèi)容保持不變。如果想結(jié)束輸入,則輸入空格,然后回車
如:mm 100000
00100000:(顯示的內(nèi)容)
00100004:(顯示的內(nèi)容)
FLASH操作
flinfo:查看flash扇區(qū)信息
用法:Uboot>flinfo
protect :flash寫保護
打開或關(guān)閉扇區(qū)寫保護
——用法:
protect off all
關(guān)閉所有扇區(qū)的寫保護
protect on all
打開所有扇區(qū)的寫保護
protect off start end
關(guān)閉從start到end扇區(qū)的寫保護(start為要關(guān)閉的第1個扇區(qū)的起始地址,end為要關(guān)閉的最后一個扇區(qū)的結(jié)束地址)
protect on start end
打開從start 到end 扇區(qū)的寫保護
erase:擦除flash扇區(qū)
——用法:
erase start end
擦除從start 到end的扇區(qū),start為要擦除的第1個扇區(qū)的起始地址,end為要擦除的最后一個扇區(qū)的結(jié)束地址(在使用cp命令向NOR型flash寫入數(shù)據(jù)之前必須先使用erase命令擦除flash,因為nor flash按字節(jié)寫入時,無法寫入1,所以必須通過擦除來寫入1)
如:erase 30000 1effff
cp:數(shù)據(jù)拷貝
——用法:
cp[.b , .w , .l]saddress daddress len(默認(rèn)是.l,即32位的拷貝)
cp提供了一種內(nèi)存與內(nèi)存,內(nèi)存與flash之間數(shù)據(jù)拷貝的方法
例:
cp.b 31000000 50000 d0000
將內(nèi)存地址0x31000000處的數(shù)據(jù)(長度為0xd0000)拷貝到地址0x50000處(flash中)
cp.b 32000000 120000 c0000
將內(nèi)存地址0x32000000處的數(shù)據(jù)(長度為0xc0000)拷貝到地址0x120000處(flash中)
注意:必須先用erase命令擦除flash,才能用cp命令執(zhí)行成功
執(zhí)行程序
go:執(zhí)行內(nèi)存中的二進制代碼,一個簡單的跳轉(zhuǎn)到指定地址
——go addr [arg...]
-start application at address `addr` , passing `arg` as arguments
bootm:執(zhí)行內(nèi)存中的二進制代碼
——bootm [addr[arg...]]
-boot application image stored in memory passing arguments `arg..`;when booting a linux kernel , `arg`can be the address of an initrd image
bootm要求所有可執(zhí)行的二進制代碼前部有固定格式的文件頭,那么如何做這個文件頭呢?——uboot下tools中有個mkimage工具可以
注意:bootm可以沒有addr地址,這時它自動執(zhí)行個默認(rèn)的地址
開發(fā)板信息
bdinfo——顯示開發(fā)板信息
bdinfo命令(簡寫為bdi)將在終端顯示諸如內(nèi)存地址和大小、時鐘頻率、MAC地址等信息。這些信息在傳遞給linux內(nèi)核一些參數(shù)時可能會用到
自動啟動
1.設(shè)置自動啟動——通過設(shè)置環(huán)境變量:
比如:Mini2440=>setenv bootcmd tftp 31000000 uImage \; bootm 31000000
Mini2440=>saveenv
——執(zhí)行了兩個操作并保存
聯(lián)系客服