主题 : tiny6410 uboot tftp 下载 ubi 复制链接 | 浏览器收藏 | 打印
2440
级别: 侠客
UID: 34266
精华: 0
发帖: 68
金钱: 350 两
威望: 70 点
贡献值: 0 点
综合积分: 136 分
注册时间: 2010-12-13
最后登录: 2015-07-01
楼主  发表于: 2012-12-09 22:58

 tiny6410 uboot tftp 下载 ubi

在uboot 源码common/main.c的FriendlyARMMenu函数中增加几个选项用于tftp下载uboot , kernel , ubi
复制代码
  1. printf("[m] medconn Download u-boot.bin by tftp\n");//u-boot.bin
  2. printf("[e] medconn Download zImage by tftp\n");//zImage
  3. printf("[d] medconn Download filesystem.ubi by tftp\n");//filesystem.ubi


复制代码
  1. case 'M': case 'm'://uboot
  2. pos = 0;
  3. max_size = 256 K;
  4. len = 256 K;
  5. FriendlyARMGet_uboot_FromTftpAndWriteNand(max_size, pos, len, "u-boot.bin");
  6. //SetLinuxCommandLine(NULL);
  7. break;
  8. case 'E': case 'e'://kernel
  9. if (NandIsMlc()) {
  10. pos = 4 M;
  11. max_size = 5 M - 128 K;
  12. len = 8 M;
  13. NAND_EraseBlock(1 M / NandBlockSizeInByte);
  14. } else {
  15. pos = 4 * 128 K;
  16. max_size = 5 M - 128 K;
  17. len = 5 M;
  18. }
  19. FriendlyARMGet_kernel_FromTftpAndWriteNand(max_size, pos, len, "zImage");
  20. break;
  21. case 'D': case 'd'://ubi
  22. max_size = 126 M;
  23. len = (unsigned) -2;
  24. if (NandIsMlc()) {
  25. pos = 12 M;
  26. } else {
  27. pos = 5 M + 4 * 128 K;
  28. }
  29. FriendlyARMGet_UBI_FromTftpAndWriteNand(max_size, pos, len, "filesystem.ubi");
  30. SetLinuxCommandLine("init=/linuxrc rootfstype=ubifs root=ubi0:FriendlyARM-root ubi.mtd=2 console=ttySAC0,115200");
  31. break;



复制代码
  1. extern int run_command (const char *cmd, int flag);
  2. int FriendlyARMGet_uboot_FromTftpAndWriteNand(unsigned max_len, unsigned offset, unsigned MaxNandSize, const char *Name)
  3. {
  4. int ret;
  5. unsigned char *RevPtr=(unsigned char *)0xc0000000;//从tftp下载xxx到内存的位置
  6. unsigned RevLen=max_len;////xxx的长度
  7. //offset,从内存取得数据写到nand的偏移位置
  8. printf("Downloading %s from Tftp...\n", Name);
  9. //从tftp下载uboot到内存RevPtr位置处
  10. run_command("tftp c0000000 u-boot.bin",0);
  11. printf("Downloading %s %s\n", Name, ret >= 0 ? "successed" : "failed");
  12. printf("RevPtr= 0x%x, RevLen= 0x%x, nand offset= 0x%x, MaxNandSize=0x%x \n",RevPtr,RevLen,offset,MaxNandSize);
  13. if (ret < 0) {
  14. return ret;
  15. }
  16. ret = FriendlyARMCheckData(RevPtr, RevLen, offset, MaxNandSize);
  17. if (ret < 0) {
  18. return ret;
  19. }
  20. printf("Writing %s into NAND...\n", Name);
  21. if (NandIsMlc() && offset == 0) {
  22. ret = FriendlyARMWriteNandMlcBoot(RevPtr, RevLen, 1);
  23. } else {
  24. //从内存RevPtr位置取RevLen长的的数据写到nand的offset位置处
  25. ret = FriendlyARMWriteNand(RevPtr, RevLen, offset, MaxNandSize);
  26. }
  27. printf("Writing %s %s\n", Name, ret >= 0 ? "successed" : "failed");
  28. return ret;
  29. }
  30. int FriendlyARMGet_kernel_FromTftpAndWriteNand(unsigned max_len, unsigned offset, unsigned MaxNandSize, const char *Name)
  31. {
  32. int ret;
  33. unsigned char *RevPtr=(unsigned char *)0xc0000000;//从tftp下载xxx到内存的位置
  34. unsigned RevLen=max_len;////xxx的长度
  35. //offset,从内存取得数据写到nand的偏移位置
  36. printf("Downloading %s from Tftp...\n", Name);
  37. //从tftp下载kernel到内存RevPtr位置处
  38. ret=run_command("tftp c0000000 zImage",0);
  39. printf("Downloading %s %s\n", Name, ret >= 0 ? "successed" : "failed");
  40. printf("RevPtr= 0x%x, RevLen= 0x%x, nand offset= 0x%x, MaxNandSize=0x%x \n",RevPtr,RevLen,offset,MaxNandSize);
  41. if (ret < 0) {
  42. return ret;
  43. }
  44. ret = FriendlyARMCheckData(RevPtr, RevLen, offset, MaxNandSize);
  45. if (ret < 0) {
  46. return ret;
  47. }
  48. printf("Writing %s into NAND...\n", Name);
  49. if (NandIsMlc() && offset == 0) {
  50. ret = FriendlyARMWriteNandMlcBoot(RevPtr, RevLen, 1);
  51. } else {
  52. //从内存RevPtr位置取RevLen长的的数据写到nand的offset位置处
  53. ret = FriendlyARMWriteNand(RevPtr, RevLen, offset, MaxNandSize);
  54. }
  55. printf("Writing %s %s\n", Name, ret >= 0 ? "successed" : "failed");
  56. return ret;
  57. }
  58. int FriendlyARMGet_UBI_FromTftpAndWriteNand(unsigned max_len, unsigned offset, unsigned MaxNandSize, const char *Name)
  59. {
  60.     int ret;
  61.     unsigned char *RevPtr=(unsigned char *)0xc0000000;//从tftp下载xxx到内存的位置
  62.     unsigned RevLen=max_len;////xxx的长度
  63.     //offset,从内存取得数据写到nand的偏移位置
  64.     printf("Downloading %s from Tftp...\n", Name);
  65. //从tftp下载ubi到内存RevPtr位置处
  66.     ret=run_command("tftp c0000000 filesystem.ubi",0);
  67.     printf("Downloading %s %s\n", Name, ret >= 0 ? "successed" : "failed");
  68.     printf("RevPtr= 0x%x, RevLen= 0x%x, nand offset= 0x%x, MaxNandSize=0x%x \n",RevPtr,RevLen,offset,MaxNandSize);
  69.     if (ret < 0) {
  70.         return ret;
  71.     }
  72.     ret = FriendlyARMCheckData(RevPtr, RevLen, offset, MaxNandSize);
  73.     if (ret < 0) {
  74.         return ret;
  75.     }
  76.     printf("Writing %s into NAND...\n", Name);
  77.     if (NandIsMlc() && offset == 0) {
  78.         ret = FriendlyARMWriteNandMlcBoot(RevPtr, RevLen, 1);
  79.     } else {
  80.         //从内存RevPtr位置取RevLen长的的数据写到nand的offset位置处
  81.         ret = FriendlyARMWriteNand(RevPtr, RevLen, offset, MaxNandSize);
  82.     }
  83.     printf("Writing %s %s\n", Name, ret >= 0 ? "successed" : "failed");
  84.     
  85.     return ret;


说明:
1.友善提供的uboot没有tftp下载功能,只有usb下载功能。所以我就仿照里面的usb下载函数自己写了一个tftp下载函数,具体说是3个,分别用来下载uboot,kernel,ubi.即
FriendlyARMGet_uboot_FromTftpAndWriteNand ,FriendlyARMGet_kernel_FromTftpAndWriteNand,FriendlyARMGet_UBI_FromTftpAndWriteNand
2.友善提供的FriendlyARMGetDataFromUsbAndWriteNand函数是先通过usb把pc上的一个文件加载到内存0xc0000000(是线性地址,uboot开了mmu),然后再调用函数FriendlyARMWriteNand把内存中的相应数据写入nandflash的对应分区。对于SLC 1G的nand,按如下分区下载的


(512KB)
3.基于2,我先用tftp把文件下载到0xc000 0000,然后同样再调用函数FriendlyARMWriteNand把内存中的相应数据写入nandflash的对应分区。但是测得的结果是uboot可以下载并成功运行;kernel也可以下载并成功运行;ubifs可以成功下载,但是启动的结果老是ubifs报错:

Creating 4 MTD partitions on "NAND 1GiB 3,3V 8-bit":
0x000000000000-0x000000080000 : "Bootloader"
0x000000080000-0x000000580000 : "Kernel"
0x000000580000-0x000040000000 : "File System"
UBI: attaching mtd2 to ubi0
UBI: physical eraseblock size:   131072 bytes (128 KiB)
UBI: logical eraseblock size:    129024 bytes
UBI: smallest flash I/O unit:    2048
UBI: sub-page size:              512
UBI: VID header offset:          512 (aligned 512)
UBI: data offset:                2048
UBI: max. sequence number:       19
UBI: attached mtd2 to ubi0
UBI: MTD device name:            "File System"
UBI: MTD device size:            1018 MiB
UBI: number of good PEBs:        8146
UBI: number of bad PEBs:         2
UBI: number of corrupted PEBs:   0
UBI: max. allowed volumes:       128
UBI: wear-leveling threshold:    4096
UBI: number of internal volumes: 1
UBI: number of user volumes:     1
UBI: available PEBs:             0
UBI: total number of reserved PEBs: 8146
UBI: number of PEBs reserved for bad PEB handling: 81
UBI: max/mean erase counter: 9/0
UBI: image sequence number:  1929542009
UBI: background thread "ubi_bgt0d" started, PID 546
...
...
UBIFS: recovery needed
s3c-nand: 1 bit error detected at byte 55, correcting from 0xfa to 0x7a...OK
s3c-nand: 1 bit error detected at byte 397, correcting from 0x00 to 0x02...OK
UBI error: ubi_io_read: error -74 (ECC error) while reading 2048 bytes from PEB 2383:129024, read 2048 bytes
s3c-nand: 1 bit error detected at byte 42, correcting from 0x00 to 0x10...OK
s3c-nand: 1 bit error detected at byte 370, correcting from 0x00 to 0x02...OK
s3c-nand: 1 bit error detected at byte 256, correcting from 0x00 to 0x01...OK
UBI error: ubi_io_read: error -74 (ECC error) while reading 24576 bytes from PEB 325:106496, read 24576 bytes
UBIFS error (pid 685): ubifs_check_node: bad node length 0
one_wire_status: 4
UBIFS error (pid 685): ubifs_check_node: bad node at LEB 323:104448
UBIFS error (pid 685): ubifs_scanned_corruption: corruption at LEB 323:104448
UBIFS error (pid 685): ubifs_recover_leb: LEB 323 scanning failed
mount: mounting ubi0:FriendlyARM-root on /r failed: Structure needs cleaning
/init: line 103: can't open /r/dev/console: no such file
Kernel panic - not syncing: Attempted to kill init!
[<c0176c44>] (unwind_backtrace+0x0/0xe4) from [<c04b2a58>] (panic+0x58/0x174)
[<c04b2a58>] (panic+0x58/0x174) from [<c0188ed0>] (do_exit+0x68/0x5e4)
[<c0188ed0>] (do_exit+0x68/0x5e4) from [<c0189710>] (do_group_exit+0x90/0xc4)
[<c0189710>] (do_group_exit+0x90/0xc4) from [<c0189754>] (sys_exit_group+0x10/0x18)
[<c0189754>] (sys_exit_group+0x10/0x18) from [<c01715e0>] (ret_fast_syscall+0x0/0x30)
one_wire_status: 2

并且有时即使启动成功,ubifs文件系统也变成只读的了。

4.
错误显示ubifs没有正确写入。
我分析可能出错的过程或者在a .tftp下载ubifs到内存时出错,或者在 b.将内存数据写到nand时出错
对于a,通过随机抽取几个使用usb下载到内存里的数据和使用tftp下载到内存里的数据,经对比数据一致。查看方法,在uboot下执行md.l 0xc0000000 len
对于b,使用的是同一个函数FriendlyARMWriteNand将内存数据写到nand,难道还会不一样。并且参数也设的基本一样。
参数max_size和len有什么不同呢?

谢谢。
[ 此帖被shift在2012-12-09 23:03重新编辑 ]
2440
级别: 侠客
UID: 34266
精华: 0
发帖: 68
金钱: 350 两
威望: 70 点
贡献值: 0 点
综合积分: 136 分
注册时间: 2010-12-13
最后登录: 2015-07-01
1楼  发表于: 2012-12-10 20:18