說一下uboot分析與移植:
1、下載、建立source insight工程、編譯、燒寫、如果無執行分析原因
tar xjf u-boot-2012.04.01.tar.bz2
cd u-boot-2012.04.01
make smdk2410_config
make
2. 分析u-boot: 通過連結命令分析組成檔案、閱讀程式碼分析啟動過程
a. 初始化硬體:關看門狗、設定時鐘、設定SDRAM、初始化NAND FLASH
b. 如果bootloader比較大,要把它重定位到SDRAM
c. 把核心從NAND FLASH讀到SDRAM
d. 設定"要傳給核心的引數"
e. 跳轉執行核心
2.1 set the cpu to SVC32 mode
2.2 turn off the watchdog
2.3 mask all IRQs by setting all bits in the INTMR
2.4 設定時鐘比例
2.5 設定記憶體控制器
2.6 設定棧,呼叫C函式board_init_f
2.7 呼叫函式陣列init_sequence裡的各個函式
2.7.1 board_early_init_f : 設定系統時鐘、設定GPIO
......
2.8 重定位程式碼:
2.8.1 從NOR FLASH把程式碼複製到SDRAM
2.8.2 程式的連結地址是0,訪問全域性變數、靜態變數、呼叫函式時是使"基於0地址編譯得到的地址"
現在把程式複製到了SDRAM
需要修改程式碼,把"基於0地址編譯得到的地址"改為新地址
2.8.3 程式裡有些地址在連結時不能確定,要到執行前才能確定:fixabs
2.9 clear_bss
2.10 呼叫C函式board_init_r:第2階段的程式碼
可以修改配置定義CONFIG_S3C2440
3. 修改U-BOOT程式碼
3.1 建一個單板
cd board/samsung/
cp smdk2410 smdk2440 -rf
cd ../../include/configs/
cp smdk2410.h smdk2440.h
修改boards.cfg:
仿照
smdk2410 arm arm920t - samsung s3c24x0
新增:
smdk2440 arm arm920t - samsung s3c24x0
3.2 燒寫看結果
3.3 除錯:
a. 閱讀程式碼發現不足:UBOOT裡先以60MHZ的時鐘計算引數來設定記憶體控制器,但是MPLL還未設定
處理措施: 把MPLL的設定放到start.S裡,取消board_early_init_f裡對MPLL的設定
編譯出來的uboot非常大,可以先燒寫主光盤裡的u-boot.bin到nor,然後用這個uboot來燒寫新的uboot
3.4 亂碼,檢視串列埠波特率的設定,發現在get_HCLK裡沒有定義CONFIG_S3C2440
處理措施:include/configs/smdk2440.h: 去掉CONFIG_S3C2410
#define CONFIG_S3C2440
//#define CONFIG_CMD_NAND
3.5 修改UBOOT支援NAND啟動
原來的程式碼在連結時加了"-pie"選項, 使得u-boot.bin裡多了"*(.rel*)", "*(.dynsym)"
使得程式非常大,不利於從NAND啟動(重定位之前的啟動程式碼應該少於4K)
3.5.1 去掉 "-pie"選項
arch/arm/config.mk:75:LDFLAGS_u-boot += -pie 去掉這行
3.5.2 參考"畢業班第1課"的start.S, init.c來修改程式碼
把init.c放入board/samsung/smdk2440目錄, 修改Makefile
修改CONFIG_SYS_TEXT_BASE為0x33f80000
修改start.S
3.5.3 修改board_init_f, 把relocate_code去掉
3.5.4 修改連結指令碼: 把start.S, init.c, lowlevel.S等檔案放在最前面
./arch/arm/cpu/u-boot.lds:
board/samsung/smdk2440/libsmdk2440.o
3.6 修改UBOOT支援NOR FLASH
drivers\mtd\jedec_flash.c 加上新的型號
#define CONFIG_SYS_MAX_FLASH_SECT (128)
修復了重定時留下來的BUG:SP要重新設定
3.7 修改UBOOT支援NAND FLASH
修改:include/configs/smdk2440.h: #define CONFIG_CMD_NAND
把drivers\mtd\nand\s3c2410_nand.c複製為s3c2440_nand.c
分析過程:
nand_init
nand_init_chip
board_nand_init
設定nand_chip結構體, 提供底層的操作函式
nand_scan
nand_scan_ident
nand_set_defaults
chip->select_chip = nand_select_chip;
chip->cmdfunc = nand_command;
chip->read_byte = busw ? nand_read_byte16 : nand_read_byte;
nand_get_flash_type
chip->select_chip
chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
nand_command() // 即可以用來發命令,也可以用來發列地址(頁內地址)、行地址(哪一頁)
chip->cmd_ctrl
s3c2440_hwcontrol
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
*maf_id = chip->read_byte(mtd);
*dev_id = chip->read_byte(mtd);
3.8 修改UBOOT支援DM9000網絡卡
eth_initialize
board_eth_init
cs8900_initialize
*** ERROR: `ethaddr' not set
set ipaddr 192.168.1.17
set ethaddr 00:0c:29:4d:e4:f4
set serverip 192.168.1.3
4. 易用性修裁剪及製作補丁
核心打印出來的分割槽資訊
0x00000000-0x00040000 : "bootloader"
0x00040000-0x00060000 : "params"
0x00060000-0x00260000 : "kernel"
0x00260000-0x10000000 : "root"
nand erase 60000 200000
nand write 30000000 60000 200000
tftp 30000000 uImage
nand erase.part kernel
nand write 30000000 kernel
附筆者的學習筆記,字寫的不好勿怪,將就看吧:
1).uboot介紹以及最終目的:
2).分析makefile找到第一個執行的檔案:
3).原始碼分析:
4)uboot中命令實現:
5)uboot啟動核心:
4N3C)Z6`2I(80LK4771NS7.png)