uboot 移植全過程---基于ARM9 2410
uboot@localhost ~]#mkdir -p dev_home/uboot?
[uboot@localhost ~]#cd dev_home/uboot?
從下面地址下載u-boot 的源代碼。??
[uboot@localhost uboot]#tar -xjvf u-boot-1.1.4.tar.bz2?
[uboot@localhost uboot]#cd u-boot-1.1.4?
1.3 u-boot 體系結構?
1.3.1 u-boot 目錄結構?
1. 目錄樹?
[uboot@localhost u-boot-1.1.4]#tree -L 1 -d?
.?
|-- board?
|-- common?
|-- cpu?
|-- disk?
|-- doc?
|-- drivers?
|-- dtt?
|-- examples?
|-- fs?
|-- include?
|-- lib_arm?
|-- lib_generic?
|-- lib_i386?
|-- lib_m68k?
|-- lib_microblaze?
|-- lib_mips?
|-- lib_nios?
|-- lib_nios2?
|-- lib_ppc?
|-- net?
|-- post?
|-- rtc?
`-- tools?
2. board:和一些已有開發板有關的文件. 每一個開發板都以一個子目錄出現在當前目錄中,比如說:SMDK2410, 子目錄中存放與開發板相關的配置文件.?
3. common:實現u-boot 命令行下支持的命令,每一條命令都對應一個文件。例如bootm 命令對應就是 cmd_bootm.c 。?
4. cpu:與特定CPU 架構相關目錄,每一款U-boot 下支持的CPU 在該目錄下對應一個子目錄,比如有子目錄 arm920t 等。?
5. disk:對磁盤的支持。?
5. doc:文檔目錄。U-boot 有非常完善的文檔,推薦大家參考閱讀。?
6. drivers:U-boot 支持的設備驅動程序都放在該目錄,比如各種網卡、支持CFI 的Flash 、串口和USB 等。?
7. fs: 支持的文件系統,U-boot 現在支持cramfs 、fat 、fdos 、jffs2 和registerfs 。?
8. include:U-boot 使用的頭文件,還有對各種硬件平臺支持的匯編文件,系統的配置文件和對文件系統支持的文件。該目錄下configs? 目錄有與開發板相關的配置頭文件,如smdk2410.h 。該目錄下的asm? 目錄有與CPU 體?
系結構相關的頭文件,asm 對應的是asm-arm.?
9. lib_xxxx: 與體系結構相關的庫文件。如與ARM 相關的庫放在lib_arm 中。?
10. net:與網絡協議棧相關的代碼,BOOTP 協議、TFTP 協議、RARP 協議和NFS 文件系統的實現。?
11. tools:生成U-boot 的工具,如:mkimage, crc 等等。?
2 uboot 的啟動過程及工作原理?
2.1 啟動模式介紹?
大多數 Boot Loader 都包含兩種不同的操作模式:"啟動加載"模式和"下載"模式,這種區別僅對于開發人員才有意義。但從最終用戶的角度看,Boot Loader 的作用就是用來加載操作系統,而并不存在所謂的啟動加 載模式與下載工作模式的區別。?
??? 啟動加載 (Boot loading)模式:這種模式也稱為" 自主"?????? (Autonomous)模式。也即 Boot Loader 從目標機上的某個固態存儲設備上將操作系統加載到 RAM 中運行,整個過程并沒有用戶的介入。這種模式是 Boot Loader 的正常工作模式,因此成都網站設計公司在嵌入式產品發布的時侯,Boot Loader 顯然必須工作在這種模式下。?
? 下載 (Downloading)模式:在這種模式下,目標機上的 Boot Loader 將通過串口連接或網絡連接等通信手 段從主機 (Host)下載文件,比如:下載內核映像和根文件系統映像等。從主機下載的文件通常首先被 Boot Loader 保存到目標機的 RAM 中,然后再被 BootLoader 寫到目標機上的FLASH 類固態存儲設備中。Boot oader 的這種模式通常在第一次安裝內核與根文件系統時被使用;此外,以后的系統更新也會使用 Boot Loader 的這種工作模式。工作于這種模式下的 Boot Loader 通常都會向它的終端用戶提供一個簡單的命令? 接口。?
?? U-Boot 這樣功能強大的 Boot Loader 同時支持這兩種工作模式,而且允許用戶在這兩種工作模式之間進?
切換。?
??? 大多數bootloader 都分為階段 1(stage1)和階段2(stage2)兩大部分,u-boot 也不例外。依賴于CPU 體系結構 的代碼 (如CPU 初始化代碼等)通常都放在階段 1 中且通常用匯編語言實現,而階段2 則通常用C 語言來實 現,這樣可以實現復雜的功能,而且有更好的可讀性和移植性。
2.2 階段1 介紹?
u-boot 的stage1 代碼通常放在start.s 文件中,它用匯編語言寫成,其主要代碼部分如下:?
2.2.1 定義入口?
由于一個可執行的Image 必須有一個入口點,并且只能有一個全局入口,通常這個入口放在ROM(Flash)的0x0?
地址,因此,必須通知編譯器以使其知道這個入口,該工作可通過修改連接器腳本來完成。?
??? 1. board/crane2410/u-boot.lds:? ENTRY(_start) ==> cpu/arm920t/start.S: .globl _start?
???? 2. uboot 代碼區 (TEXT_BASE = 0x33F80000)定義在board/crane2410/config.mk?
2.2.2 設置異常向量?
_start: b?????? reset????????????????????????? @ 0x00000000?
??????? ldr???? pc, _undefined_instruction???? @ 0x00000004?
??????? ldr???? pc, _software_interrupt??????? @ 0x00000008?
??????? ldr???? pc, _prefetch_abort??????????? @ 0x0000000c?
??????? ldr???? pc, _data_abort??????????????? @ 0x00000010?
??????? ldr???? pc, _not_used????????????????? @ 0x00000014?
??????? ldr???? pc, _irq?????????????????????? @ 0x00000018?
??????? ldr???? pc, _fiq?????????????????????? @ 0x0000001c?
????? 當發生異常時,執???cpu/arm920t/interrupts.c 中定義的中斷處理函數。?
2.2.3 設置 CPU 的模式為SVC模式?
?????? ?mrs???? r0,cpsr?
??????? bic???? r0,r0,#0x1f?
??????? orr???? r0,r0,#0xd3?
??????? msr???? cpsr,r0?
2.2.4 關閉看門狗?
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)?
??????? ldr???? r0, =pWTCON?
??????? mov???? r1, #0x0???? @ 根據三星手冊進行調置。?
??????? str???? r1, [r0]?
2.2.5 禁掉所有中斷?
?????? ?mov???? r1, #0xffffffff?
??????? ldr???? r0, =INTMSK?
??????? str???? r1, [r0]?
# if defined(CONFIG_S3C2410)?
??????? ldr???? r1, =0x3ff?
??????? ldr???? r0, =INTSUBMSK?
??????? str???? r1, [r0]?
.2.6 設置以 CPU 的頻率?
默認頻率為 FCLK:HCLK:PCLK = 1:2:4,默認FCLK的值為120 MHz,該值為S3C2410手冊的推薦值。?
??????? ldr???? r0, =CLKDIVN?
??????? mov???? r1, #3?
??????? str???? r1, [r0]?
2.2.7 設置 CP15?
設置CP15, 失效指令(I)Cache 和數據(D)Cache 后, 禁止MMU 與Cache 。?
cpu_init_crit:?
??????? mov???? r0, #0?
??????? mcr???? p15, 0, r0, c7, c7, 0?? /* 失效I/D cache, 見S3C2410手冊附錄的2-16 */?
??????? mcr???? p15, 0, r0, c8, c7, 0?? /* 失效TLB, 見S3C2410手冊附錄的2-18 */?
/*?
???????? * 禁止 MMU 和caches, 詳見S3C2410手冊附錄2-11?
???????? */?
??????? mrc???? p15, 0, r0, c1, c0, 0?
??????? bic???? r0, r0, #0x00002300???? /* 清除 bits 13, 9:8 (--V- --RS)?
???????????????????????????????? * Bit 8: Disable System Protection?
???????????????????????????????? * Bit 7: Disable ROM Protection?
???????????????????????????????? * Bit 13: 異常向量表基地址: 0x0000 0000?
???????????????????????????????? */?
??????? bic???? r0, r0, #0x00000087???? /* 清除 bits 7, 2:0 (B--- -CAM)?
???????????????????????????????? * Bit 0: MMU disabled?
???????????????????????????????? * Bit 1: Alignment Fault checking disabled?
???????????????????????????????? * Bit 2: Data cache disabled?
???????????????????????????????? * Bit 7: 0 = Little-endian operation?
???????????????????????????????? */?
??????? orr???? r0, r0, #0x00000002????? /* set bit 2 (A) Align, 1 = Fault checking enabled */?
??????? orr???? r0, r0, #0x00001000???? /* set bit 12 (I) I-Cache, 1 = Instruction cache enabled ?
*/?
??????? mcr???? p15, 0, r0, c1, c0, 0?
2.2.8 配置內存區控制寄存器?
配置內存區控制寄存器,寄存器的具體值通常由開發板廠商或硬件工程師提供. 如果您對總線周期及外圍?
芯片非常熟悉, 也可以自己確定, 在U-BOOT 中的設置文件是board/crane2410/lowlevel_init.S, 該文件包含?
lowleve_init 程序段. 詳細寄存器設置及值的解釋見3.2.2 啟動AXD 配置開發板一節中的第5 點.?
????? mov???? ip, lr?
??????? bl????? lowlevel_init?
??????? mov???? lr, ip?
2.2.9 安裝 U-BOOT使的棧空間?
??? 下面這段代碼只對不是從Nand Flash 啟動的代碼段有意義,對從Nand Flash 啟動的代碼,沒有意義。因為?
從Nand Flash 中把UBOOT 執行代碼搬移到RAM,由2.1.9 中代碼完成.?
#ifndef CONFIG_SKIP_RELOCATE_UBOOT?
...?
#endif?
stack_setup:?
?????? ldr???? r0, _TEXT_BASE????????????? /* 代碼段的起始地址??? */?
?????? sub???? r0, r0, #CFG_MALLOC_LEN???? /* 分配的動態內存區??? */?
?????? sub???? r0, r0, #CFG_GBL_DATA_SIZE?? /* UBOOT開發板全局數據存放? */?
#ifdef CONFIG_USE_IRQ?
?????? /* 分配IRQ和FIQ棧空間 */?
?????? sub???? r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)?
#endif?
?????? sub???? sp, r0, #12???????????????? /* 留下3個字為Abort??? */?
2.2.10 BSS段清 0?
clear_bss:?
?????? ldr???? r0, _bss_start?????? /* BSS段的起始地址?? */?
?????? ldr???? r1, _bss_end???????? /* BSS段的結束地址?? */?
?????? mov???? r2, #0x00000000???????????? /* BSS段置0?????????????????? */?
clbss_l:str??? r2, [r0]???????????? /* 循環清除BSS段 */?
?????? add???? r0, r0, #4?
?????? cmp???? r0, r1?
?????? ble???? clbss_l?
2.2.11 搬移 Nand Flash代碼?
從Nand Flash 中, 把數據拷貝到RAM, 是由copy_myself 程序段完成, 該程序段詳細解釋見:第七部分的3.1 節.?
#ifdef CONFIG_S3C2410_NAND_BOOT?
?????? bl??? copy_myself?
???? ?@ jump to ram?
?????? ldr?? r1, =on_the_ram?
?????? add? pc, r1, #0?
?????? nop?
?????? nop?
1:??? b???? 1b????????? @ infinite loop?
on_the_ram:?
#endif?
2.2.12 進入 C代碼部分?
??????? ldr???? pc, _start_armboot?
??????? _start_armboot: .word start_armboot?
2.3 階段2 的C 語言代碼部分 ?
lib_arm/board.c 中的start armboot 是C 語言開始的函數,也是整個啟動代碼中C 語言的主函數,同時還是整個?
u-boot(armboot)的主函數,該函數主要完成如下操作:?
2.3.1調用一系列的初始化函數?
1. 指定初始函數表:?
init_fnc_t *init_sequence[] = {?
?????? cpu_init,???????????? /* cpu的基本設置????????? */?
?????? board_init,?????????? /* 開發板的基本初始化???? */?
?????? interrupt_init,?????? /* 初始化中斷???????????? */?
?????? env_init,???????????? /* 初始化環境變量???????? */?
?????? init_baudrate,??????? /* 初始化波特率?????????? */?
?????? serial_init,????????? /* 串口通訊初始化???????? */?
?????? console_init_f,?????? /* 控制臺初始化第一階段?? */?
?????? display_banner,?????? /* 通知代碼已經運行到該處 */?
?????? dram_init,??????????? /* 配制可用的內存區?????? */?
?????? display_dram_config,?
#if defined(CONFIG_VCMA9) || defined (CONFIG_CMC_PU2)?
?????? checkboard,?
#endif?
?????? NULL,?
};?
執行初始化函數的代碼如下:?
?????? for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {?
?????????????? if ((*init_fnc_ptr)() != 0) {?
????????????????????? hang ();?
?????????????? }?
?????? }?
2. 配置可用的Flash 區?
?? flash_init ()?? ?
?? ?
3. 初始化內存分配函數?
?? mem_malloc_init()? ?
4. nand flash 初始化?
?#if (CONFIG_COMMANDS & CFG_CMD_NAND)?
????????? puts ("NAND:");?
????????? nand_init();????????????? /* 初始化 NAND */?
見第七部分3.2.3 節中的第3 點nand_init()函數.?
5. 初始化環境變量??
? env_relocate ();?
6. 外圍設備初始化?
?? devices_init()?
7. I2C 總線初始化?
? i2c_init();?
8. LCD 初始化?
? drv_lcd_init();?
9. VIDEO 初始化?
? drv_video_init();?
10. 鍵盤初始化?
? drv_keyboard_init();?
11. 系統初始化?
? drv_system_init();?
2.3.2 初始化網絡設備?
初始化相關網絡設備,填寫IP 、MAC 地址等。?
1. 設置IP 地址?
??????? /* IP Address */?
??????? gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");?
??????? /* MAC Address */?
??????? {?
??????????????? int i;?
??????????????? ulong reg;?
??????????????? char *s, *e;?
??????????????? uchar tmp[64];?
??????????????? i = getenv_r ("ethaddr", tmp, sizeof (tmp));?
??????????????? s = (i > 0) ? tmp : NULL;?
??????????????? for (reg = 0; reg < 6; ++reg) {?
??????????????????????? gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;?
??????????????????????? if (s)?
??????????????????????????????? s = (*e) ? e + 1 : e;?
??????????????? }?
??????? }?
2.3.3 進入主 UBOOT命令?
進入命令循環 (即整個boot 的工作循環),接受用戶從串口輸入的命令,然后進行相應的工作。?
??????? for (;;) {?
??????????????? main_loop (); /* 在common/main.c */?
??????? }?
2.4 代碼搬運?
為了支持NAND flash 起動,S3C2410 內建了內部的4k 的SRAM 緩存 “Steppingstone” 。當起動時,NAND?
flash 最初的4k 字節將被讀入”Steppingstone”然后開始執? 起動代碼。通常起動代碼會把NAND flash 中的內容?
拷到SDRAM 中以便執行主代碼。?
使用硬件的ECC, NAND flash 中的數據的有效性將會得到檢測。?
功能?
??? 1. NAND flash 模式:支持讀/刪除/編程 NAND Flash?
??? 2.? 自動起動模式:在復位時起動代碼將被讀入”Steppingstone”中,然后開始執? 起動代碼。?
??? 3. 硬件ECC 檢測模塊(硬件檢測,軟件糾正)?
??? 4. “Steppingstone” 4-KB 內部SRAM 在起動后可以另外使用。?
3 uboot 的移植過程?
3.1 環境?
? 1. 工作用戶?
??? uboot?
? 2. u-boot 版本 1.1.4?
??? 獲取u-boot1.1.4請看 1.2?
? 3. 工具鏈2.95.3?
3.2 步驟?
我們為開發板取名叫: crane2410, 并在u-boot 中建立自己的開發板類型?
3.2.1 修改 Makefile?
[uboot@localhost uboot]#vi Makefile?
#為crane2410 建立編譯項?
crane2410_config : unconfig?
?? @./mkconfig $(@:_config=) arm arm920t crane2410 NULL s3c24x0?
各項的意思如下:?
??? arm:????? CPU 的架構(ARCH)?
??? arm920t:? CPU 的類型(CPU) ,其對應于cpu/arm920t 子目錄。?
??? crane2410: 開發板的型號(BOARD) ,對應于board/crane2410? 目錄。?
??? NULL:???? 開發者/或經銷商(vender) 。?
??? s3c24x0:? 片上系統(SOC) 。?
?
評論
查看更多