uboot移植之命令烧写uboot,zImage.img,root .

 
  1. /**************uboot下用命令下载uboot,内核和文件系统********************/  
  2.   
  3. /* 
  4. 先将内核zImage用mkimage转换成uImage(叫zIMage.img) 
  5. mkimage 工具是uboot提供,在uboot源码的tools/ 
  6. 在内核源码的arch/arm/boot/下执行如下命令 
  7. */  
  8. mkimage -n 'tekkaman' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage zImage.img  
  9. /* 
  10. Usage: mkimage -l image 
  11.           -l ==> list image header information 
  12.        mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image 
  13.           -A ==> set architecture to 'arch' 
  14.           -O ==> set operating system to 'os' 
  15.           -T ==> set image type to 'type' 
  16.           -C ==> set compression type 'comp' 
  17.           -a ==> set load address to 'addr' (hex) 
  18.           -e ==> set entry point to 'ep' (hex) 
  19.           -n ==> set image name to 'name' 
  20.           -d ==> use image data from 'datafile' 
  21.           -x ==> set XIP (execute in place) 
  22. */  
  23.   
  24. //或者在制作内核时用   
  25. make uImage //这样生成的uImage和用mkimage工具将zImage转换成的uImage的格式一样,均可被uboot引导。  
  26. mv uImage zImage.img //为了和下面的命令统一,将uImage改名叫zImga.img  
  27. //但在试验中发现这样制作的uImage有时uboot引导不起来  
  28. /***********************参数修改************************************/  
  29. mini2440  
  30.   
  31. setenv ipaddr 192.168.1.230  
  32. setenv serverip 192.168.1.103  
  33. setenv gatewayip 192.168.1.1  
  34.   
  35.   
  36. /*bootargs  uboot传递给内核de*/  
  37. setenv bootargs  console=ttySAC0 noinitrd root=/dev/mtdblock3 init=/linuxrc  
  38.   
  39. /*bootcmd  uboot要执行的任务*/  
  40. setenv bootcmd tftp 0x30008000 zImage.img\;bootm 0x30008000     /*从tftp服务器下载内核到sdram,然后启动*/  
  41. setenv bootcmd nboot 30008000 0 0x60000\;bootm 0x30008000   /*从nand读取内核到sdram,然后启动*/  
  42. setenv bootcmd nand read 30008000 0x60000 0x500000\;bootm 0x30008000  /*从nand读取内核到sdram,然后启动*/  
  43.   
  44. saveenv  
  45.   
  46. /**********************从服务器烧写文件到nand*************************************/  
  47.   
  48. //download uboot   
  49. tftp 0x30008000 u-boot.bin      //从ftp服务器将u-boot.bin文件读到内存0x30008000处  
  50. nand erase 0 0x40000            //清除nandflash的0-0x40000的数据  
  51. nand write 0x30008000  0  0x40000   //从内存0x30008000写入nandflash的0开始处,大小0x40000  
  52.   
  53. /*nand的0x40000--0x60000是参数区 
  54. 从板子启动现象判断参数区和kernel去有没重叠的方法:上电按空格进入nand的uboot,如果没有提示using default param并且 
  55. 执行命令nboot 30008000 0 0x60000\;bootm 0x30008000可以成功进入内核,说明ok 
  56. */  
  57. //dowload kernel   
  58. tftp 0x30008000 zImage.img      //从ftp服务器将zImage.img文件读到内存0x30008000处  
  59. nand erase 0x60000 500000       //清除nandflash的0x60000-0x560000的数据  
  60. nand write 0x30008000 0x060000 0x500000 //从内存0x30008000写入nandflash的0x60000开始处,大小0x500000  
  61.   
  62.   
  63. //dowload rootfs   
  64. tftp 0x30008000 root            //从ftp服务器将ysffs文件读到内存0x30008000处  
  65. nand erase 0x560000             //清除nandflash的0x560000到结尾的数据      
  66.   
  67. //nand write 0x30008000 0x560000 0x6000000    直接写在nand上不行,需专门的命令向nand写yaffs文件,因为读写的时候还要有其他动作  
  68. //nand read 0x30008000 0x560000 0x6000000     直接从nand读不行,需专门的命令从nand读yaffs文件  
  69.   
  70. nand write.yaffs 0x30008000 0x560000 0x3b36dc0  //从内存0x30008000写入nandflash的0x560000开始处,大小0x3b36dc0  
  71.   
  72. /*在只有64MB的sdram系统上,用tftp 0x30008000 root 加载的yaffs文件不得大于33f80000-30008000=3F7 8000=63.46875MB,否则会覆盖掉处于33f80000的uboot 
  73. 在试验中发现只能指定size为0x3b36dc0,否则出错,现还不知原因 
  74. 可参考http://bbs.huiwen.com/thread-426-1-1.html 
  75. */  
  76.   
  77. /***********************************************************/  
/**************uboot下用命令下载uboot,内核和文件系统********************/ /* 先将内核zImage用mkimage转换成uImage(叫zIMage.img) mkimage 工具是uboot提供,在uboot源码的tools/ 在内核源码的arch/arm/boot/下执行如下命令 */ mkimage -n 'tekkaman' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage zImage.img /* 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'           -O ==> set operating system to 'os'           -T ==> set image type to 'type'           -C ==> set compression type 'comp'           -a ==> set load address to 'addr' (hex)           -e ==> set entry point to 'ep' (hex)           -n ==> set image name to 'name'           -d ==> use image data from 'datafile'           -x ==> set XIP (execute in place) */ //或者在制作内核时用 make uImage //这样生成的uImage和用mkimage工具将zImage转换成的uImage的格式一样,均可被uboot引导。 mv uImage zImage.img //为了和下面的命令统一,将uImage改名叫zImga.img //但在试验中发现这样制作的uImage有时uboot引导不起来 /***********************参数修改************************************/ mini2440 setenv ipaddr 192.168.1.230 setenv serverip 192.168.1.103 setenv gatewayip 192.168.1.1 /*bootargs uboot传递给内核de*/ setenv bootargs console=ttySAC0 noinitrd root=/dev/mtdblock3 init=/linuxrc /*bootcmd uboot要执行的任务*/ setenv bootcmd tftp 0x30008000 zImage.img\;bootm 0x30008000 /*从tftp服务器下载内核到sdram,然后启动*/ setenv bootcmd nboot 30008000 0 0x60000\;bootm 0x30008000 /*从nand读取内核到sdram,然后启动*/ setenv bootcmd nand read 30008000 0x60000 0x500000\;bootm 0x30008000 /*从nand读取内核到sdram,然后启动*/ saveenv /**********************从服务器烧写文件到nand*************************************/ //download uboot tftp 0x30008000 u-boot.bin //从ftp服务器将u-boot.bin文件读到内存0x30008000处 nand erase 0 0x40000 //清除nandflash的0-0x40000的数据 nand write 0x30008000 0 0x40000 //从内存0x30008000写入nandflash的0开始处,大小0x40000 /*nand的0x40000--0x60000是参数区 从板子启动现象判断参数区和kernel去有没重叠的方法:上电按空格进入nand的uboot,如果没有提示using default param并且 执行命令nboot 30008000 0 0x60000\;bootm 0x30008000可以成功进入内核,说明ok */ //dowload kernel tftp 0x30008000 zImage.img //从ftp服务器将zImage.img文件读到内存0x30008000处 nand erase 0x60000 500000 //清除nandflash的0x60000-0x560000的数据 nand write 0x30008000 0x060000 0x500000 //从内存0x30008000写入nandflash的0x60000开始处,大小0x500000 //dowload rootfs tftp 0x30008000 root //从ftp服务器将ysffs文件读到内存0x30008000处 nand erase 0x560000 //清除nandflash的0x560000到结尾的数据 //nand write 0x30008000 0x560000 0x6000000 直接写在nand上不行,需专门的命令向nand写yaffs文件,因为读写的时候还要有其他动作 //nand read 0x30008000 0x560000 0x6000000 直接从nand读不行,需专门的命令从nand读yaffs文件 nand write.yaffs 0x30008000 0x560000 0x3b36dc0 //从内存0x30008000写入nandflash的0x560000开始处,大小0x3b36dc0 /*在只有64MB的sdram系统上,用tftp 0x30008000 root 加载的yaffs文件不得大于33f80000-30008000=3F7 8000=63.46875MB,否则会覆盖掉处于33f80000的uboot 在试验中发现只能指定size为0x3b36dc0,否则出错,现还不知原因 可参考http://bbs.huiwen.com/thread-426-1-1.html */ /***********************************************************/上面将
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本来就是用来引导内核的,内核怎么表现,它就跟着怎么变就行了)
view plain copy to clipboard print ?
  1. static struct mtd_partition friendly_arm_default_nand_part[] = {  
  2.     [0] = {  
  3.         .name   = "supervivi",  
  4.         .size   = 0x00040000,  
  5.         .offset = 0,  
  6.     },  
  7.     [1] = {  
  8.         .name   = "param",  
  9.         .offset = 0x00040000,  
  10.         .size   = 0x00020000,  
  11.     },  
  12.     [2] = {  
  13.         .name   = "Kernel",  
  14.         .offset = 0x00060000,  
  15.         .size   = 0x00500000,  
  16.     },  
  17.     [3] = {  
  18.         .name   = "root",  
  19.         .offset = 0x00560000,  
  20.         .size   = 1024 * 1024 * 1024, //   
  21.     },  
  22.     [4] = {  
  23.         .name   = "nand",  
  24.         .offset = 0x00000000,  
  25.         .size   = 1024 * 1024 * 1024, //   
  26.     }  
  27. };  
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的标记列表,和nandflash上的param存储区的内容不一样
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的设置堆栈的代码中可以看出

你可能感兴趣的:(bootloader,Nand,驱动)