U-boot
源代碼下載:ftp://ftp.denx.de/pub/u-boot/
啟動過程分析:1.小于8Kb的程序:IROM從nand讀8K數(shù)據(jù)到ISRAM中運行;
2.大于8kb程序(主要指u-boot):IROM從nand讀前8k數(shù)據(jù)到SRAM中主要做兩件事:
第一:初始化DRAM;
第二:將剩下的代碼搬運到DRAM運行。
3.在DRAM中就可以引導系統(tǒng)啟動了。
BL0:IROM,出廠已固化代碼
BL1:ISRAM的前16kb,u-boot-spl.bin
BL2:ISRAM的后80kb,u-boot.bin
ISRAM是內(nèi)置內(nèi)存,不用初始化就可以使用;
DRAM是外接內(nèi)存,需要初始化才能使用。
uboot有兩種模式:
1.啟動加載模式:存儲在nand上,上電將操作系統(tǒng)加載到DRAM運行。正常啟動時的模式,自動加載linux內(nèi)核。
2.下載模式:調(diào)試模式,通過網(wǎng)絡或串口從主機獲得文件,控制啟動流程。按下任意鍵進入下載模式。
bootloader有兩個階段:
1.第一階段代碼用匯編:arch/arm/cpu/armv7/start.S和board/samsung/smart210/lowlevel_init.S,從ISRAM運行。
第一:建立中斷向量表和異常向量表
第二:獲取啟動參數(shù),設(shè)置SVC32模式,拷貝前8k代碼到ISRAM。
第三:cpu_init_crit:
關(guān)I/D cache,關(guān)看門狗,清TLB,關(guān)MMU等
第四:cpu_init_crit調(diào)用lowlevel_init.S:
設(shè)置TCPZ,禁止中斷,初始化系統(tǒng)時鐘、內(nèi)存、串口、nand等
第五:設(shè)置棧,判斷啟動開關(guān),sd卡啟動就跳轉(zhuǎn)到board_init_f,nand啟動就跳轉(zhuǎn)到board_init_f_nand。
第六:搬運代碼,從sd卡或nand到DRAM(內(nèi)存)。
第七:初始化棧,清bss段,跳轉(zhuǎn)到board_init_r,完了啟動過程結(jié)束。
2.第二階段代碼用c:arch/arm/lib/board.c和common/main.c,從內(nèi)存運行。
board_init_f:
為gd數(shù)據(jù)結(jié)構(gòu)分配地址并清零;
執(zhí)行init_fnc_ptr函數(shù)指針數(shù)組中的各個初始化函數(shù);
分配DRAM高64kb為TLB,用于uboot;
分配DRAM下一個單元為uboot代碼段,數(shù)據(jù)段,bss段;
開辟malloc空間存放bd,gd,3個字大小的異常堆空間;
將relocate地址傳給gd結(jié)構(gòu)體變量,用于返回start.S。
board_init_r:在內(nèi)存中運行
對gd,bd數(shù)據(jù)結(jié)構(gòu)賦值初始化;
各種外設(shè)初始化;
進入main_loop,(main_loop函數(shù)在common/main.c中定義,進入main.c)
common/main.c:引導內(nèi)核
u-boot源代碼支持一部分官方的評估開發(fā)板,不需要修改u-boot。由于我們用的cpu和官方的測試版的cpu相同,所以cpu部分u-boot不需要修改,其他部分需要修改。SMDK指三星的評估板
移植關(guān)心的文件夾:
board文件夾 :和開發(fā)板相關(guān)的,是移植需要修改的。
arch/arm/文件夾 :和處理器相關(guān)的,主流的cpu都是支持的.
lib文件夾 :u-boot的通用的自己的庫。
arch/arm/lib文件夾 :根據(jù)arm處理器創(chuàng)建的庫。
include/configs文件夾:里面是頭文件,需要修改。
drivers文件夾 :驅(qū)動文件夾.
common文件夾 :u-boot核心代碼。
net文件夾 :網(wǎng)絡協(xié)議相關(guān)代碼。
tools文件夾 :u-boot提供的編譯運行等輔助工具。
1.u-boot啟動過程:
start.S :arch/arm/cpu/armv7/start.S,程序的入口;
board.c :arch/arm/lib/board.c,不用修改,可以用于所有arm;
main.c :common/main.c,與硬件無關(guān),不用修改,所有開發(fā)板通用,用來啟動內(nèi)核。
arch/arm/cpu/armv7/start.S調(diào)用board/samsung/smart210/lowlevel_init.s進行初始化(主要初始化內(nèi)存DRAM)。
arch/arm/lib/board.c初始化和硬件相關(guān)的函數(shù),調(diào)用相關(guān)的初始化函數(shù)進行初始化開發(fā)板上資源。
common/main.c是整個u-boot程序的主函數(shù),主要負責運行維護uboot的shell命令行。
2.添加和開發(fā)板相關(guān)的程序和頭文件
在boart/sumsung/下面新建一個文件夾smart210
參考board/sumsung/smdkv210文件夾中的文件修改成smart210可用文件。
第一、修改arch/arm/cpu/armv7/start.S
#include
#include
#include
定義代碼段的鏈接地址
.globl _TEXT_BASE
_TEXT_BASE:
.word CONFIG_SYS_TEXT_BASE
定義當前程序的開始地址,一般是在DRAM中
.globl _armboot_start
_armboot_start:
.word _start
#endif
第二、修改board/samsung/smart210/lowlevel_init.S
#include
#include "smart210_val.h"
第二、修改和開發(fā)板相關(guān)的代碼
board/sumsung/smart210/smart210.c
參看smdkc100,主要進行一些cpu控制器和資源的初始化工作。
#include
include/s5pc110.h包含下面兩個
include/s5pc110.h
arch/arm/include/asm/arch/hardware.h(arch是arch-s5pc1xx的鏈接)
第四、include/configs/smart210.h
配置文件,添加需要的宏定義。
#defineCONFIG_SAMSUNG 1
#define CONFIG_S5P 1
#define CONFIG_S5PC110 1
#define CONFIG_SMART210 1
#define CONFIG_MACH_TYPE MACH_TYPE_SMART210
#define CONFIG_SYS_TEXT_BASE 0x23E00000 //定義代碼段的鏈接地址
#defineMACH_TYPE_SMART210 3466
配合文件中主要有另類宏:
1.CONFIG_開頭的用于cpu、soc、board等的時鐘設(shè)置、設(shè)備驅(qū)動等。
2.CFG_開頭的用于malloc緩沖池的大小、uboot提示符、uboot下載文件時的默認地址、flash的其實地址等。
3.uboot的配置和編譯:
添加目標板的信息到/boards.cfg:
# Target ARCH CPU Boardname Vendor SoC Options
webee210 arm armv7 webee210 samsung s5pc1xx
make distclean #清除之前編譯結(jié)果
make clean
修改/Makefile文件:
unconfig:
@rm -f $(obj)include/config.h $(obj)include/config.mk \
$(obj)board*/config.tmp \
$(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep \
$(obj)board/$(VENDOR)/$(BOARD)/config.mk
smart210_config: unconfig
@$(MKCONFIG) $(@:_config=) arm armv7 smart210samsung s5pc1xx
@echo"TEXT_BASE = 0xc3e00000" >$(obj)board/samsung/smart210/config.mk
make smart210_config
$(@:_config=)表示$@這個目標的_config換成空,得到開發(fā)板名稱smart210.
執(zhí)行make smart210_config實際上調(diào)用uboot根目錄下mkconfig(注意這個腳本的權(quán)限)這個shell腳本,該腳本將開發(fā)板六個信息寫入include/config.mk文件和include/config.h文件中.
include/config.mk:
ARCH = arm
CPU =armv7
BOARD = smart210
VENDOR = samsung
SOC =s5pc1xx
OPTIONS =
include/config.h:
#define CONFIG_BOARDDIR board/samsung/smart210
#include
#include
#include
#include
修改board/sumsung/smart210/Makefile
因為在這個文件夾添加了開發(fā)板相關(guān)的程序,所有需要修改相應的Makefile文件。
參考smdk2410的Makefile
COBJS :=smart210.o
arch/arm/config.mk已經(jīng)配置好交叉編譯:
CROSS_COMPILE ?= arm-linux-
arch/arm/cpu/armv7/u-boot.lds定義了起始地址和入口函數(shù):
. =0x00000000;
. = ALIGN(4);
.text :
{
arch/arm/cpu/armv7/start.o (.text)
*(.text)
}
include/configs/smart210.h定義了定義了TEXT_BASE:
#defineCONFIG_SYS_TEXT_BASE 0x23E00000
make
執(zhí)行/Makefile文件,完成了uboot的編譯。
生成以下的文件:
u-boot.bin:二進制可執(zhí)行文件可以直接燒寫
u-boot.elf:elf格式的可執(zhí)行文件
u-boot.srec:motorolas-record格式的可執(zhí)行文件
u-boot.lds
u-boot.map
4.燒寫uboot到開發(fā)板的nand有兩種方法:
第一、先燒寫到SD卡,
注意手冊給的sd卡的分區(qū):(512b為一個block)
512b(保留區(qū),0block)+8kb(BL1,1-16block)+16Kb(EN環(huán)境變量,17-48block)+512kb(BL2,也就是u-boot.bin,從49block開始)+linux內(nèi)核+根文件系統(tǒng)
cat /proc/partitions #找出SD卡對應的設(shè)備,一般為/dev/sdb
dmesg | tail
sudo dd bs=512 if=/dev/zero of=/dev/sdbcount=2400
sudo dd bs=512 iflag=dsync oflag=dsync if=spl/smart210-spl.binof=/dev/sdb seek=1
sudo dd ba=512 iflag=dsync oflay=dsyncif=smart210-uboot.bin of=/dev/sdb seek=49
再使用uboot命令,燒寫到nand:
tftp 21000000 smart210-uboot.bin
nand erase.chip
nand write 21000000 0 3c1f4
第二、使用jtag直接燒寫到nand中
5.uboot常用命令:
bdinfo:打印目標板配置信息
flinfo:獲取可用的flash信息
help:打印幫助信息
base:打印或設(shè)置地址偏移
crc:crc32的校驗和計算,用于計算某一段存儲區(qū)的校驗和。
cmp:測試兩個存儲器區(qū)域是否相同。
cp:拷貝存儲區(qū)。
md:存儲區(qū)顯示,顯示某些區(qū)域的值。
mm:存儲區(qū)修改,修改累加地址的值。
mtest:存儲區(qū)測試,測試寫操作是夠成功,只能測試rom。
mw:內(nèi)存填充,
nm:內(nèi)存修改,修改同一地址的值。
era:擦除flash存儲器某個區(qū)域
erase all:擦除整個存儲器
protect:使能或禁止flash保護功能,更改某一區(qū)域的只讀屬性。
bootm:從存數(shù)器啟動應用程序鏡像
go:開始某地址處的應用程序。
loadb:經(jīng)由串口線加載二進制文件(kermit模式)
tftpboot:使用tftp協(xié)議由網(wǎng)絡加載映像文件
printenv:打印環(huán)境變量,ipaddr,hostname,netmask。
setenv:設(shè)置環(huán)境變量
saveenv:保存環(huán)境變量到存儲器(sd和nand)
bootm工作原理:
用于啟動操作系統(tǒng)鏡像,從鏡像頭獲取操作系統(tǒng)類型,所使用的文件壓縮方法,加載和入口點地址等信息。加載鏡像文件到指定的存儲器,甚至解壓。也可以傳遞要求的啟動參數(shù)并在入口點啟動操作系統(tǒng)。第一個參數(shù)是待加載的映像的存儲地址,之后可以添加操作系統(tǒng)需要的參數(shù)。
bootm用于linux操作系統(tǒng):
傳遞一個可選的參數(shù),作為initrd ramdisk映像的起始地址,bootm命令有三個步驟組成:
1.linux內(nèi)核映像被解壓縮并拷貝到DRAM
2.ramdisk映像被加載到DRAM
3.控制權(quán)交給linux內(nèi)核,并傳遞ramdisk映像的位置和大小信息。
5.怎樣用u-boot來啟動linux內(nèi)核(前提是內(nèi)核已經(jīng)燒寫到nand)
nand read 讀入的內(nèi)存目的地址 讀入的nand的地址 讀入的大小
bootm 內(nèi)核的入口地址
|