8)實現(xiàn)u-boot引導Linux內核啟動。
在前面幾節(jié)中,我們講了u-boot對Nor Flash和Nand Flash的啟動支持,那現(xiàn)在我們就再來探討一下u-boot怎樣來引導Linux內核的啟動。
①、機器碼的確定
通常,在u-boot和kernel中都會有一個機器碼(即:MACH_TYPE),只有這兩個機器碼一致時才能引導內核,否則就會出現(xiàn)如下mach的錯誤信息:(如果沒有錯誤信息則不需要一下修改,我的就沒有,這些錯誤是摘錄的)
首先,確定u-boot中的MACH_TYPE。在u-boot的include/asm-arm/mach-types.h文件中針對不同的CPU定義了非常多的MACH_TYPE,可以找到下面這個定義:
- #define MACH_TYPE_SMDK2440 1008
那么我們就修改u-boot的MACH_TYPE代碼引用部分,確定u-boot的MACH_TYPE。如下:
- #vim board/samsung/yyq2440/yyq2440.c //修改board_init函數(shù)
- /* arch number of SMDK2410-Board */
- //gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
- 改為:
- gd->bd->bi_arch_number = MACH_TYPE_SMDK2440;
其次,確定kernel中的MACH_TYPE。在kernel的arch/arm/tools/mach-types文件中也針對不同的CPU定義了非常多的MACH_TYPE,也可以找到下面這個定義:
- smdk2440 MACH_SMDK2440 SMDK2440 1008
那么我們就修改kernel的MACH_TYPE代碼引用部分,確定kernel的MACH_TYPE。如下:
- #vim arch/arm/mach-s3c2440/mach-smdk2440.c //修改文件最后面
- //MACHINE_START(S3C2440, "SMDK2440")
- 改為:
- MACHINE_START(SMDK2440, "SMDK2440")
- #gedit arch/arm/kernel/head.S //在ENTRY(stext)下添加如下代碼(紅色部分)
- ENTRY(stext)
- mov r0, #0
- mov r1, #0x3f0 //上面的MACH_TYPE值1008換成十六進制就是0x3f0
- ldr r2, =0x30000100
- msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- .......
分別重新編譯u-boot和kernel。u-boot下載后,記得要saveenv;kernel用tftp下載到內存后使用go命令來測試引導內核,結果可以引導了。如下。

②、準備能被u-boot直接引導的內核uImage
通常,kernel的啟動需要u-boot提供一些參數(shù)信息,比如ramdisk在RAM中的地址。經過編譯后的u-boot在根目錄下的tools目錄中,會有個叫做mkimage的工具,他可以給zImage添加一個header,也就是說使得通常我們編譯的內核zImage添加一個數(shù)據(jù)頭信息部分,我們把添加頭后的image通常叫uImage,uImage是可以被u-boot直接引導的內核鏡像。
mkimage工具的使用介紹如下:
- 使用: 中括號括起來的是可選的
- mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image
- 選項:
- -A:set architecture to 'arch' //用于指定CPU類型,比如ARM
- -O:set operating system to 'os' //用于指定操作系統(tǒng),比如Linux
- -T:set image type to 'type' //用于指定image類型,比如Kernel
- -C:set compression type 'comp' //指定壓縮類型
- -a:set load address to 'addr' (hex) //指定image的載入地址
- -e:set entry point to 'ep' (hex) //內核的入口地址,一般為image的載入地址+0x40(信息頭的大。
- -n:set image name to 'name' //image在頭結構中的命名
- -d:use image data from 'datafile' //無頭信息的image文件名
- -x:set XIP (execute in place)
先將u-boot下的tools中的mkimage復制到主機的/usr/local/bin目錄下,這樣就可以在主機的任何目錄下使用該工具了,F(xiàn)在我們進入kernel生成目錄(一般是arch/arm/boot目錄),然后執(zhí)行如下命令,就會在該目錄下生成一個uImage.img的鏡像文件,把他復制到tftp目錄下,這就是我們所說的uImage。
- [skywalker@bogon tools]$ sudo cp mkimage /usr/local/bin/
- [skywalker@bogon tools]$ cd ..
- [skywalker@bogon u-boot-2009.08]$ mkimage -n 'linux-2.6.33.7' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage uImage.img
- Image Name: linux-2.6.33.7
- Created: Fri Mar 4 20:35:51 2011
- Image Type: ARM Linux Kernel Image (uncompressed)
- Data Size: 2026844 Bytes = 1979.34 kB = 1.93 MB
- Load Address: 30008000
- Entry Point: 30008000
- [skywalker@bogon u-boot-2009.08]$
③、Nand Flash的分區(qū)。我們查看內核在arch/arm/plat-s3c24xx/common-smdk.c中的分區(qū)情況如下:
- [0] = {
- .name = "boot",
- .size = 0x00020000,
- .offset = 0
- },
- [1] = {
- .name = "bootParam",
- .size = 0x00060000,
- .offset = 0x00020000,
- },
- [2] = {
- .name = "Kernel",
- .size = 0x00300000,
- .offset = 0x00500000,
- },
- [3] = {
- .name = "fs_yaffs",
- .size = 0x03c00000,
- .offset = 0x00800000,
- },
- [4] = {
- .name = "eboot",
- .size = 0x00080000,
- .offset = 0x04400000,
- },
- [5] = {
- .name = "WINCE",
- .size = 0x03b80000,
- .offset = 0x04480000,
- }
④、設置修改u-boot的啟動參數(shù),在u-boot命令行下輸入。設置啟動參數(shù),意思是將nand中0x500000(offset)-0x00800000(offset+size)(和kernel分區(qū)一致)的內容讀到內存0x31000000中,然后用bootm命令來執(zhí)行
- U-Boot 2009.08 ( 3.. 03 2011 - 20:48:30)
- DRAM: 64 MB
- Flash: 512 kB
- NAND: NAND_ECC_NONE selected by board driver. This is not recommended !!
- 128 MiB
- In: serial
- Out: serial
- Err: serial
- Net: dm9000 ' - try 'help'
- [yyq2440] # set bootcmd 'nand read 0x31000000 0x500000 0x800000;bootm 0x3100000
- [yyq2440] # saveenv
Saving Environment to NAND... Erasing Nand... Erasing at 0x2 -- 262144% complete. Writing to Nand... done [yyq2440] #
⑤、把uImage.img用tftp下載到內存中,然后再固化到Nand Flash中,操作和執(zhí)行圖如下:
- [yyq2440] # tftp 0x30000000 uImage.img
- dm9000 i/o: 0x20000000, id: 0x90000a46
- DM9000: running in 16 bit mode
- MAC: 08:00:3e:26:0a:5b
- operating at 100M full duplex mode
- Using dm9000 device
- TFTP from server 192.168.7.11; our IP address is 192.168.7.1
- Filename 'uImage.img'.
- Load address: 0x30000000
- Loading: T T T T T T T #################################T######################
- ##T T ###############################################################
- ##T T #########
- done
- Bytes transferred = 2026908 (1eed9c hex)
- [yyq2440] #
在執(zhí)行擦除和燒寫的時候,卻出現(xiàn)了壞塊的提示,并失敗。
- [yyq2440] # nand erase 0x500000 0x800000
-
- NAND erase: device 0 offset 0x500000, size 0x800000
- Skipping bad block at 0x00000000
- Skipping bad block at 0x00000000
- Skipping bad block at 0x00000000
- Skipping bad block at 0x00000000
- Skipping bad block at 0x00000000
- Skipping bad block at 0x00000000
- Skipping bad block at 0x00000000
- Skipping bad block at 0x00000000
- Skipping bad block at 0x00000000
- Skipping bad block at 0x00000000
- Skipping bad block at 0x00000000
- Skipping bad block at 0x00000000
- Skipping bad block at 0x00000000
- Skipping bad block at 0x00000000
- Skipping bad block at 0x00000000
- Erasing at 0x8 -- 13500416% complete.
- OK
- [yyq2440] # nand write 0x30000000 0x500000 0x800000
- NAND write: device 0 offset 0x500000, size 0x800000
- Skip bad block 0x00000000
- Skip bad block 0x00000000
- Skip bad block 0x00000000
- Skip bad block 0x00000000
- Skip bad block 0x00000000
- Skip bad block 0x00000000
- Skip bad block 0x00000000
- Skip bad block 0x00000000
- Skip bad block 0x00000000
- Skip bad block 0x00000000
- Skip bad block 0x00000000
- Skip bad block 0x00000000
- Skip bad block 0x00000000
- Skip bad block 0x00000000
- Skip bad block 0x00000000
- NAND write to offset ffffffff failed 13631488
- 6422528 bytes written: ERROR
- [yyq2440] #
這個時候我擦除了整塊的nandflash就好了。
- [yyq2440] # nand scrub
-
- NAND scrub: device 0 whole chip
- Warning: scrub option will erase all factory set bad
- There is no reliable way to recover them.
- Use this command only for testing purposes if you
- are sure of what you are
-
- Really scrub this NAND flash? <y/N>
- Erasing at 0x8 -- 24117248% complete..
- NAND 128MiB 3,3V 8-bit: MTD Erase failure: -5
- Erasing at 0x8000000 -- 52297728% complete.
- NAND 128MiB 3,3V 8-bit: MTD Erase failure: -5
- Erasing at 0x8000000 -- 134086656% complete.
- OK
- [yyq2440] # tftp 0x30000000 uImage.img
- dm9000 i/o: 0x20000000, id: 0x90000a46
- DM9000: running in 16 bit mode
- MAC: 08:00:3e:26:0a:5b
- operating at 100M full duplex mode
- Using dm9000 device
- TFTP from server 192.168.7.11; our IP address is 192.168.7.1
- Filename 'uImage.img'.
- Load address: 0x30000000
- Loading: #T T T T T ###################################T #######################
- ###T T ####T ###########################################T #############
- ##T T #######
- done
- Bytes transferred = 2026908 (1eed9c hex)
- [yyq2440] # nand erase 0x500000 0x800000
-
- NAND erase: device 0 offset 0x500000, size 0x800000
- Erasing at 0x8 -- 13500416% complete.
- OK
- [yyq2440] # nand write 0x30000000 0x500000 0x800000
-
- NAND write: device 0 offset 0x500000, size 0x800000
- 8388608 bytes written: OK
- [yyq2440] #
最后,我們重新啟動開發(fā)板,可以看到,內核被u-boot成功引導起來了,如圖:
- U-Boot 2009.08 ( 3.. 03 2011 - 20:48:30)
-
- DRAM: 64 MB
- Flash: 512 kB
- NAND: NAND_ECC_NONE selected by board driver. This is not recommended !!
- 128 MiB
- In: serial
- Out: serial
- Err: serial
- Net: dm9000
- Hit any key to stop autoboot: 0
-
- NAND read: device 0 offset 0x500000, size 0x800000
- 8388608 bytes read: OK
- ## Booting kernel from Legacy Image at 31000000 ...
- Image Name: linux-2.6.33.7
- Created: 2011-03-04 12:35:51 UTC
- Image Type: ARM Linux Kernel Image (uncompressed)
- Data Size: 2026844 Bytes = 1.9 MB
- Load Address: 30008000
- Entry Point: 30008000
- Verifying Checksum ... OK
- Loading Kernel Image ... OK
- OK
-
- Starting kernel ...
-
- Uncompressing Linux... done, booting the kernel.
- Linux version 2.6.33.7 (skywalker@localhost.localdomain) (gcc version 4.3.2 (So1
- CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=00007177
- CPU: VIVT data cache, VIVT instruction cache
- Machine: SMDK2410
- Warning: bad configuration page, trying to continue
- Memory policy: ECC disabled, Data cache writeback
- CPU S3C2440A (id 0x32440001)
2011-03-04 |