uboot1.3.4的SD卡烧写cmd_fastboot.c解读

1750阅读 0评论2015-05-06 l658775
分类:嵌入式

     交叉工具链:arm-2009q3
     环境:ubuntu+sourceInsight
    目标板:CPU:  S5PV210@1000MHz(OK)
        APLL = 1000MHz, HclkMsys = 200MHz, PclkMsys = 100MHz
        MPLL = 667MHz, EPLL = 80MHz
        HclkDsys = 166MHz, PclkDsys = 83MHz
        HclkPsys = 133MHz, PclkPsys = 66MHz
        SCLKA2M  = 200MHz
        Serial = CLKUART 
        Board:   SMDKV210
        DRAM:    512 MB
        Flash:   8 MB
       SD/MMC:  1910MB
        NAND:    256 MB 

          运行uboot命令help sdfuse 可知道:
            sdfuse info                             - print primitive infomation.
            sdfuse flashall                         - flash boot.img, system.img,
                                                           erase userdata, cache, and reboot.
            sdfuse flash [ ] - write a file to a partition.
            sdfuse erase                - erase (format) a partition.

          sdfuse命令的源码在common/cmd_fastboot.c下实现。
          命令的构造:
                    U_BOOT_CMD(
                        sdfuse, 4, 1, do_sdfuse,
                        "sdfuse  - read images from FAT partition of SD card and write them to booting device.\n",
                        "info                             - print primitive infomation.\n"
                        "sdfuse flashall                         - flash boot.img, system.img,\n"
                        "                                          erase userdata, cache, and reboot.\n"
                        "sdfuse flash [ ] - write a file to a partition.\n"
                        "sdfuse erase                - erase (format) a partition.\n"
                    );
             分析函数实现do_sdfuse:               

点击(此处)折叠或打开

  1. /* SD Fusing : read images from FAT partition of SD Card, and write it to boot device.
  2.  *
  3.  * NOTE
  4.  * - sdfuse is not a original code of fastboot
  5.  * - Fusing image from SD Card is not a original part of Fastboot protocol.
  6.  * - This command implemented at this file to re-use an existing code of fastboot */
  7. int do_sdfuse (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  8. {
  9.     int ret = 1;
  10.     int enable_reset = 0;

  1.     //1.寻找mmc设备

  1.     struct mmc *mmc = find_mmc_device(CFG_FASTBOOT_SDFUSE_MMCDEV);

  1. //2.初始化mmc

  1.     if (mmc_init(mmc)) {
  2.         printf("sdmmc init is failed.\n");
  3.     }

  1. //3.static struct cmd_fastboot_interface interface

  1.     interface.nand_block_size    = CFG_FASTBOOT_PAGESIZE * 64;
  2.     interface.transfer_buffer    = (unsigned char *) CFG_FASTBOOT_TRANSFER_BUFFER;
  3.     interface.transfer_buffer_size    = CFG_FASTBOOT_TRANSFER_BUFFER_SIZE;

  4.     printf("[Fusing Image from SD Card.]\n");

  1. //4.读取分区信息

  1.     if (set_partition_table())
  2.         return 1;

  3. //5.help sdfuse 可以知道命令分为:
  4. //sdfuse info
  5. //sdfuse flashall
  6. //sdfuse flash <partition> [ <filename> ]
  7. //sdfuse erase <partition>

  1. //执行sdfuse info命令

  1.     if ((argc == 2) && !strcmp(argv[1], "info"))
  2.     {
  3.         printf("sdfuse will read images from the followings:\n");
  4.         printf(" sd/mmc device : mmc %d:%d\n",
  5.             CFG_FASTBOOT_SDFUSE_MMCDEV, CFG_FASTBOOT_SDFUSE_MMCPART);

  1.         //images所在的目录CFG_FASTBOOT_SDFUSE_DIR

  1.         printf(" directory : %s\n", CFG_FASTBOOT_SDFUSE_DIR);
  2.         printf(" booting device : %s\n",
  3. #if defined(CFG_FASTBOOT_ONENANDBSP)
  4.             "OneNAND"
  5. #elif defined(CFG_FASTBOOT_NANDBSP)
  6.             "NAND"
  7. #elif defined(CFG_FASTBOOT_SDMMCBSP)
  8.             "MoviNAND"
  9. #else
  10. #error "Unknown booting device!"
  11. #endif
  12. #if defined(CONFIG_FUSED)
  13.             " (on eFused Chip)"
  14. #endif
  15.         );
  16.         return 0;
  17.     }
  18.     else if ((argc == 2) && !strcmp(argv[1], "flashall"))
    1. //执行sdfuse flashall命令

  19.     {
  20.     //sdfuse flashhall -flash boot.img, system.img,erase userdata, cache, and reboot
  21.         LCD_turnon();

  22.         if (update_from_sd("boot", "boot.img"))
  23.             goto err_sdfuse;
  24.         if (update_from_sd("system", "system.img"))
  25.             goto err_sdfuse;
  26.         if (update_from_sd("userdata", NULL))
  27.             goto err_sdfuse;
  28.         if (update_from_sd("cache", NULL))
  29.             goto err_sdfuse;

  30.         enable_reset = 1;
  31.         ret = 0;
  32.     }
  33.     else if ((argc == 4) && !strcmp(argv[1], "flash"))
  34.     {
    1. //执行sdfuse flash命令

  35.         LCD_turnon();

  36.         if (update_from_sd(argv[2], argv[3]))
  37.             goto err_sdfuse;

  38.         ret = 0;
  39.     }
  40.     else if ((argc == 3) && !strcmp(argv[1], "erase"))
  41.     {
    1. //执行sdfuse erase命令

  42.         LCD_turnon();

  43.         if (update_from_sd(argv[2], NULL))
  44.             goto err_sdfuse;

  45.         ret = 0;
  46.     }
  47.     else
  48.     {
  49.         printf("Usage:\n%s\n", cmdtp->usage);
  50.         return 1;
  51.     }



  52. err_sdfuse:
  53.     LCD_setfgcolor(0x000010);
  54.     LCD_setleftcolor(0x000010);
  55.     LCD_setprogress(100);

  56.     if (enable_reset)
  57.         do_reset (NULL, 0, 0, NULL);

  58.     return ret;
  59. }
            从源代码可知,do_sdfuse会调用set_partition_table获取分区信息:

点击(此处)折叠或打开

  1. ....................

  2. if (ptable_default_size >= sizeof(fastboot_ptentry))
  3.     {
  4.         printf("Fastboot: employ default partition information\n");
  5.         //memcpy(ptable, ptable_default, ptable_default_size);

  1.         //内存拷贝默认的分区信息到ptable

  1.         memcpy((void*)ptable, (void*)&ptable_default, ptable_default_size);
  2.         pcount = ptable_default_size / sizeof(fastboot_ptentry);
  3.     }
  4. .......................
       这里set_partition_table获取的是板的默认分区ptable_default,一个在cpu/s5pc11x/fastboot.c下定义为fastboot_ptentry类型的结构体数组
      然后在当前函数下使用 fastboot_flash_dump_ptn();打印分区信息到串口

        SD卡烧写的目标文件需要放在指定的目录下。在cmd_fastboot.c下有个宏:
        //镜像所在目录
        #define CFG_FASTBOOT_SDFUSE_DIR "/lucasSdfuse"

        烧写的主要函数是update_from_sd (char *part, char *file),它接受两个字符串指针,分别是分区名称和目标文件名。烧写的过程是先从SD卡读取file,然后调用static int rx_handler (const unsigned char *buffer, unsigned int buffer_size)烧写。具体的烧写动作如同nand erase 然后 nand write
       通过do_sdfuse函数,我们就实现了sdfuse flash bootloader u-boot.bin这样的烧写过程。

------自定义一键烧写命令

        在cmd_fastboot.c末尾添加一个自定义命令:
点击(此处)折叠或打开
  1. U_BOOT_CMD(
  2.     alfred,1,1,do_Alfred_Sdfuse,
  3.     "alfred auto burning uboot kernel system \n",
  4.     "alfred auto burning uboot kernel system\n"
  5. )
        编写do_Alfred_Sdfuse函数:

点击(此处)折叠或打开

  1. int do_Alfred_Sdfuse (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  2. {
  3.         if(argc > 1){
  4.             //实现的效果是在uboot输入alfred这个命令就可以自动执行
  5.             //sdfuse flash bootloader u-boot.bin
  6.             //sdfuse flash kernel Kernel.img
  7.             //sdfuse flash system System.img
  8.             //所以只需要一个命令参数
  9.             return 1;
  10.         }

  11.         int ret = 1;
  12.             
  13.         
  14.         //1.寻找mmc设备
  15.         struct mmc *mmc = find_mmc_device(CFG_FASTBOOT_SDFUSE_MMCDEV);
  16.     
  17.     //2.初始化mmc
  18.         if (mmc_init(mmc)) {
  19.             printf("sdmmc init is failed.\n");
  20.         }
  21.     
  22.     //3.static struct cmd_fastboot_interface interface
  23.         interface.nand_block_size    = CFG_FASTBOOT_PAGESIZE * 64;
  24.         interface.transfer_buffer    = (unsigned char *) CFG_FASTBOOT_TRANSFER_BUFFER;
  25.         interface.transfer_buffer_size    = CFG_FASTBOOT_TRANSFER_BUFFER_SIZE;
  26.     
  27.         printf("[Fusing Image from SD Card.]\n");
  28.     
  29.     //4.读取分区信息
  30.         if (set_partition_table())
  31.             return 1;

  32.         
  33.         //sdfuse flash uboot filename
  34.         //sdfuse flash kernel filename
  35.         //sdfuse flash system filename

  36.         //char *des[] = {"bootloader","kernel","system"};
  37.             
  38.         char *des[] = {ptable[0].name,ptable[2].name,ptable[4].name};//通过分区表ptable获取分区名
  39.         char *src[] = {"u-boot.bin","Kernel.img","System.img"};

  40.         int t = 0,count=sizeof(des)/sizeof(des[t]);
  41.         
  42.         if(count != sizeof(src)/sizeof(src[t])){
  43.             return 1;
  44.         }
  45.         for(t=0; t < count; t++){//循环烧写目标文件
  46.             printf("des=%s*************src=%s\n",des[t],src[t]);
  47.             LCD_turnon();
  48.             
  49.             if (update_from_sd(des[t], src[t])){
  50.                 goto err_sdfuse;
  51.             }
  52.             printf("*******************************\n");
  53.         }
  54.                     
  55.         ret = 0;
  56.             
  57.     err_sdfuse:
  58.         LCD_setfgcolor(0x000010);
  59.         LCD_setleftcolor(0x000010);
  60.         LCD_setprogress(100);
  61.         
  62.         return ret;
  63.     }
            重新烧写uboot,然后启动uboot,输入alfred




          






           
上一篇:Uncompressing Linux... done, booting the kernel
下一篇:C语言typeof详解