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. /***********************************************************/  
  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 下載到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本來就是用來引導內核的,內核怎麼表現,它就跟着怎麼變就行了)
  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. };  
  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. };  

下面是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的設置堆棧的代碼中可以看出
發佈了70 篇原創文章 · 獲贊 21 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章