-
使用nor的supervivi烧写uboot到nand:
-
进入supervivi,选择a,absolute user application
-
-
-
-
-
-
-
-
mkimage -n 'tekkaman' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage zImage.img
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
make uImage
-
mv uImage zImage.img
-
-
-
mini2440
-
-
setenv ipaddr 192.168.1.230
-
setenv serverip 192.168.1.103
-
setenv gatewayip 192.168.1.1
-
-
-
-
setenv bootargs console=ttySAC0 noinitrd root=/dev/mtdblock3 init=/linuxrc
-
-
-
setenv bootcmd tftp 0x30008000 zImage.img\;bootm 0x30008000
-
setenv bootcmd nboot 30008000 0 0x60000\;bootm 0x30008000
-
setenv bootcmd nand read 30008000 0x60000 0x500000\;bootm 0x30008000
-
-
saveenv
-
-
-
-
-
tftp 0x30008000 u-boot.bin
-
nand erase 0 0x40000
-
nand write 0x30008000 0 0x40000
-
-
-
-
-
-
-
-
-
-
-
-
-
-
tftp 0x30008000 zImage.img
-
nand erase 0x60000 500000
-
nand write 0x30008000 0x060000 0x500000
-
-
-
-
tftp 0x30008000 root
-
nand erase 0x560000
-
-
-
-
-
nand write.yaffs 0x30008000 0x560000 0x3b36dc0
-
-
-
-
-
-
-
上面将
uboot 下载到nand的起始位置为0 (--0x40000) 256KB
kernel下载到nand的起始位置为0x60000 (--0x560000) 5MB
root 下载到nand的起始位置为0x560000 (--0x10560000) 250+MB
而nand上0x40000--0x60000是保存着nand的一些参数(128KB),起始地址0x40000由CONFIG_ENV_OFFSET指定,在mini2440.h中定义。所以用uboot写内核到nand时不要写到0x400000的位置而把参数给覆盖掉
既然uboot已经将这些root 下载到nand的0x560000位置上了,内核怎么知道yaffs文件系统处于nand的0x5600000上呢?当然是uboot传递给内核的参数,如下
console=ttySAC0 noinitrd root=/dev/mtdblock3 init=/linuxrc,
uboot没有直接告诉内核 文件系统在0x560000,而是指定了mtdblock3
内核怎么知道mtdblock3在哪呢?恩,mtdblock3本来就是内核里的名词,内核当然知道了,内核可以查看nandflsh的分区表,定义在kernel/arch/arm/mach-s3c2440/mach-mini2440.c,如下,内核会得知nand的mtdblock3起始位置是0x560000,然后去这个位置加载yaffs文件系统,而这个位置处刚好放着yaffs文件系统,即前面的命令
nand write.yaffs 0x30008000 0x560000 0x3b36dc0 (实际试验中我将yaffs下载到nand的0x580000处,内核也能顺利加载yaffs)
相反,uboot并不知道mtdblcok3为何东东,对uboot来讲它只是一个字符串,
所以一般先在内核的nand分区表中划分一个开始于a位置的分区p,在uboot中若将文件系统下载到nand的a位置,然后uboot传递参数p给内核以使内核顺利找到位置a来加载yaffs(内核的分区表先定,用uboot命令参照内核分区表去下载内核和文件系统到nand正确的位置。uboot本来就是用来引导内核的,内核怎么表现,它就跟着怎么变就行了)
-
static struct mtd_partition friendly_arm_default_nand_part[] = {
-
[0] = {
-
.name = "supervivi",
-
.size = 0x00040000,
-
.offset = 0,
-
},
-
[1] = {
-
.name = "param",
-
.offset = 0x00040000,
-
.size = 0x00020000,
-
},
-
[2] = {
-
.name = "Kernel",
-
.offset = 0x00060000,
-
.size = 0x00500000,
-
},
-
[3] = {
-
.name = "root",
-
.offset = 0x00560000,
-
.size = 1024 * 1024 * 1024,
-
},
-
[4] = {
-
.name = "nand",
-
.offset = 0x00000000,
-
.size = 1024 * 1024 * 1024,
-
}
-
};
下面是nand的布局
uboot在启动之后加载内核之前的sdram空间处于如下布局
①此处param区存放着uboot传递给kernel的标记列表,(是uboot传递给内核的,内核去读取),和nandflash上的param存储区(是uboot自己的)的内容不一样
nandflash的param存储区存放的是如
bootargs=console=ttySAC0 noinitrd root=/dev/mtdblock3 init=/linuxrc
bootcmd=tftp zImage.img;bootm
bootdelay=1
baudrate=115200
ethaddr=08:08:11:18:12:27
ipaddr=192.168.1.2
serverip=192.168.1.103
gatewayip=192.168.1.1
netmask=255.255.255.0
tekkaman=bmp d 70000
stdin=serial
stdout=serial
stderr=serial
ethact=dm9000
这样的东东
sdram中param存储区是下面形式的东东
params->hdr.tag = ATAG_MEM;//标记类型:内存标记,hdr是struct tag_header类型结构体,为tag一成员
params->hdr.size = tag_size (tag_mem32);//标记大小
params->u.mem.start = bd->bi_dram[i].start;//内存起始地址,u是union类型,为tag一成员
params->u.mem.size = bd->bi_dram[i].size;//内存结束地址
params = tag_next (params);
params->hdr.tag = ATAG_CMDLINE;//标记类型:命令字符串 //这个tag的内容是使用nand上param区的bootcmd=tftp zImage.img;bootm填充的
params->hdr.size =
(sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2;
strcpy (params->u.cmdline.cmdline, p);
params = tag_next (params);
而内核在启动时,会使用和uboot存储tag时所用的一样的数据类型即struct tag去读这些tag
②uboot代码段前面有malloc内存区和堆栈,从uboot/cpu/arm920t/start.S的设置堆栈的代码中可以看出
阅读(4303) | 评论(0) | 转发(0) |