最近一直在做U-boot-2009.08和Linux-2.6.32.2的内核的移植,今天终于可以使用自己移植的U-Boot-2009.08引导自己修改的Linux-2.6.33.2内核了,还有移植的Yaffs2文件系统,真是太高兴的,现在在把这近两个月内,断断续续的移植做个最后的终结吧!在这个过程中也有想放弃的时候,不过现在都过来了,哈哈!遇到困难不要放弃,也许当时解决不了,不过可以先放一放,很可能过几天,从新分析时,会发现问题的所在。这也是我经常不是解决问题的办法的办法!下面开始这篇文章了:
1、机器码的确认:
U-Boot和Linux中都有一个机器码,只有当这两个机器码一致的时候,才能够正确的引导Linux内核。在这个版本中的U-boot和Linux中,对MINI2440的板子支持的都很好了,也有了官方的机器码,只要添加上就可以了。在U-Boot中我们可以看到,在u-boot-2009.08/include/asm-arm/mach-types.h文件中的1985行附近的位置
#define MACH_TYPE_Q2440 1997 #define MACH_TYPE_QQ2440 1998 #define MACH_TYPE_MINI2440 1999 //mini2440的机器码 #define MACH_TYPE_COLIBRI300 2000 #define MACH_TYPE_JADES 2001
|
而在内核中的kernel/linux-2.6.32.2/arch/arm/tools/mach-typs.h文件中的1989行附近的位置
f5d8231_4_v2 MACH_F5D8231_4_V2 F5D8231_4_V2 1996 q2440 MACH_Q2440 Q2440 1997 qq2440 MACH_QQ2440 QQ2440 1998 mini2440 MACH_MINI2440 MINI2440 1999 //Linux中的MINI2440的机器码 colibri300 MACH_COLIBRI300 COLIBRI300 2000 jades MACH_JADES JADES 2001
|
从这里我们可以知道MINI2440的机器码就是1999,那么我们就需要修改U-Boot中的机器码,以便和Linux中的机器码一致。在文件u-boot-2009.08/board/frankzfz/mini2440/mini2440.c目录可能会不一样,这是我自己建立的一个目录,大约在127行附近的位置。在board_init()函数中。
gpio->GPHUP = 0x000007FF; /* arch number of SMDK2410-Board */ #if defined(CONFIG_S3C2440) gd->bd->bi_arch_number = MACH_TYPE_MINI2440; //为u-boot添加机器码 //gd->bd->bi_arch_number = MACH_TYPE_SMDK2410; #endif
|
还有一个地方也已经在另一篇文章《移植Linux内核》中做了说明,也就是在kernel/linux-2.6.32.2/arch/arm/mach-s3c2440/mach-mini2440.c文件中的230行附近中的MACHINE_START,修改成如下:
MACHINE_START(MINI2440, "FriendlyARM MINI2440 development board")
|
2、用u-boot引导Linux的镜象文件uImage
通常,kernel的启动需要u-boot提供一些参数信息,比如ramdisk在RAM中的地址。经过编译后的u-boot在根目录下的tools目录中,会有个叫做mkimage的工具,他可以给zImage添加一个header,也就是说使得通常我们编译的内核zImage添加一个数据头信息部分,我们把添加头后的image通常叫uImage,uImage是可以被u-boot直接引导的内核镜像。我们如何使用这个工具生成我们需要的uImage格式的镜像文件呢?
1)编译u-boot成功后会在u-boot-2009.08/tools下生成mkimage的可执行的文件,为了我们在任何地方都可以使用这个命令,首先我们可以把这个可执行文件复制到/usr/local/bin.这样就可以在任意的目录下执行这个命令了。复制完以后我们在终端下输入“mkimage”,并按下回车。可以看到下面的输出的信息,说明我们已经可以使用改命令了。
Usage: mkimage -l image -l ==> list image header information 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' //用于指定操作系统,比如Linux -T ==> set image type to 'type' //用于指定image类型,比如Kernelramdisk -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) //设置执行位置即不进行文件的拷贝,在当前位置执行 mkimage [-D dtc_options] -f fit-image.its fit-image
|
对于ARM Linux我们可以这样使用各个参数:
对于ARM linux内核映象用法: -A arm -------- 架构是arm -O linux -------- 操作系统是linux -T kernel -------- 类型是kernel -C none/bzip/gzip -------- 压缩类型 -a 20008000 ---- image的载入地址(hex),通常为0xX00008000 -e 200080XX---- 内核的入口地址(hex),XX为0x40或者0x00 -n linux-XXX --- image的名字,任意 -d nameXXX ---- 无头信息的image文件名,你的源内核文件 uImageXXX ---- 加了头信息之后的image文件名,任意取
|
现在我们可以进入kernel/linux-2.6.32.2/arch/arm/boot目录了,然后执行下面的命令,就会在改目录下面生成uImage.img格式的,u-boot可以引导的内核镜象。
mkimage -n 'linux-2.6.32.2' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage uImage.img
|
现在我们可以把生成的uImage.img格式的镜像文件复制到tftp目录下,使用tftp进行下载了:不过现在下载到以后复制到Nand Flash中u-boot还是无法引导内核,还是需要在u-boot中一些配置。
在u-boot-2009.08/include/configs/mini2440.h文件中
#define CONFIG_BOOTDELAY 3 //自动启动前延时3秒,不过这个要和下面的另一个配置一
// 起定义后才会其作用
|
配置命令行的参数
#define CONFIG_BOOTARGS "noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200 mem=64M"
//只有这个宏定义了以后 上面的哪个宏的定义才会生效,否则还是会直接的出现命令行的提示符,不会引导内核的。 root=/dev/mtdblock3 这是有我们Linux中的nand Flash分区所决定的,我的NandFlash的第四个分区为根文件系统所以是mtdblock3,如果不是的话请修改
我的NandFlash的情况是这样的
"U-boot",0x00000000 -- 0x00040000, "param", 0x00040000-- 0x00060000,
"Kernel", 0x00060000--- 0x00560000, "root", 0x00560000---结束
|
还要在该文件中增加下面两个宏的定义:
#define CONFIG_SETUP_MEMORY_TAGS 1 //向内核传递内存分布信息 #define CONFIG_INITRD_TAG #define CONFIG_CMDLINE_TAG 1 //向内核传递命令行参数
|
在该文件中添加下面的定义
#define CONFIG_MTD_NAND_YAFFS2 1 #define MTDIDS_DEFAULT "nand0=nandflash0" #define MTDPARTS_DEFAULT "mtdparts=nandflash0:256k(bootloader),"\ "128k(params),"\ "5m(kernel),"\ "-(root)" //这里要和Linux内核中的分区信息相一致
|
下面的这两个定义也要和分区相一致
#define CONFIG_ENV_OFFSET 0x40000 //将环境变量保存在Nand中的0x30000位置 #define CONFIG_ENV_SIZE 0x20000 //Total Size of Environment Sector
|
为了使u-boot可以自行引导Linux内核,我们还需要添加下面的这句话。
#define CONFIG_BOOTCOMMAND "nand read 0x32000000 0x60000 0x560000;bootm 0x32000000"
//这个宏定义的意思是将nand中0x60000-0x560000(和kernel分区一致)的内容读到内存0x32000000中,然后用bootm命令来执行
|
3、下载系统到内存
我们先把内核下载到内存中,然后我们执行bootm命令(同一个地址)看能不能启动系统。在U-Boot下执行:
tftp 0x31000000 uImage.img (或uImage)
在提示下载完成后再执行:
bootm 0x31000000
如果成功则证明我们的设置没有问题。
4、下载固化
在前面我们看到了NandFlash的分区信息。下面我们使用命令,把我们的Linux内核和制作的根文件系统下载到NandFlash中,以便以开始启动就可以引导Linux内核。
起始地址 结束地址
uboot : 0x00000000 0x00040000 0
param : 0x00040000 0x00060000 0 kernel : 0x00060000 0x00560000 0
root : 0x00560000 0x07FFFFFF 0
这是NandFlash的分区情况;
在u-boot下输入tftp 0x30000000 uImage.img(或uImage),稍等即可下载uImage到内存中。
接着执行 nand erase 0x60000 0x500000 删除掉kernel空间原有的数据。
执行 nand write 0x30000000 0x50000 0x500000,将内存中的kernel烧入nand flash。
接下来,输入tftp 30000000 rootfs.img,将根文件系统镜象下载到内存中。
再输入nand erase 0x560000 0x07FFFFFF 将root空间内原有数据删除。
再输入nand write.yaffs2 0x30000000 0x560000 0x6ffcc0,其中0x6ffcc0是文件系统镜象的size,一定不能写错,它可以tftp下载完毕后看到。
nand erase[clean][off size] 擦除NANDFlash。加上“clean”时,表示在每个块的第一个扇区的OOB区加写入清除的标记:off size表示要擦除的开始偏移地址和长度,如果省略off size 擦除整个NandFlash。现在可以从新启动开发板,从NandFlash启动可以看到启动的信息了。
下载Linux 镜像
[U-Boot@mini2440]#tftp 0x30000000 uImage.img dm9000 i/o: 0x20000300, 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 10.27.10.48; our IP address is 10.27.10.23 Filename 'uImage.img'. Load address: 0x30000000 Loading: ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################### done Bytes transferred = 2092996 (1fefc4 hex) [U-Boot@mini2440]#nand erase 0x60000 0x500000 NAND erase: device 0 offset 0x60000, size 0x500000 Erasing at 0x54000002800000 -- 0% complete. OK [U-Boot@mini2440]#nand write 0x30000000 0x60000 0x500000 NAND write: device 0 offset 0x60000, size 0x500000 5242880 bytes written: OK
|
下载根文件系统
[U-Boot@mini2440]#tftp 30000000 rootfs.img dm9000 i/o: 0x20000300, 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 10.27.10.48; our IP address is 10.27.10.23 Filename 'rootfs.img'. Load address: 0x30000000 Loading: ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# #### done Bytes transferred = 7339200 (6ffcc0 hex) [U-Boot@mini2440]#nand erase 0x560000 NAND erase: device 0 offset 0x560000, size 0x7aa0000 Erasing at 0x7fe000007aa0000 -- 0% complete. OK [U-Boot@mini2440]#nand write.yaffs2 0x30000000 0x560000 0x6ffcc0 NAND write: device 0 offset 0x560000, size 0x6ffcc0 skip first good block 56000000020000 Writing at 0xc4000000020000 --100% is complete 7116800 bytes written: OK
|
引导Linux内核启动
U-Boot 2009.08 ( 410-15 16:39
|