• 移植u-boot-1.1.6之mtdparts分区


    和u-boot高版本不同,mtdparts命令没有cmd_mtdparts这么一个单独的文件来实现。

    不过,搜索uboot可以在cmd_jffs2.c里面看到如下代码:

     1 U_BOOT_CMD(
     2     mtdparts,    6,    0,    do_jffs2_mtdparts,
     3     "mtdparts- define flash/nand partitions
    ",
     4     "
    "
     5     "    - list partition table
    "
     6     "mtdparts delall
    "
     7     "    - delete all partitions
    "
     8     "mtdparts del part-id
    "
     9     "    - delete partition (e.g. part-id = nand0,1)
    "
    10     "mtdparts add <mtd-dev> <size>[@<offset>] [<name>] [ro]
    "
    11         
    12 
    13         ...

    可知mtdpart命令是在do_jffs2_mtdparts函数里面实现的。

    再看do_jffs2_mtdparts函数:

    int do_jffs2_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
    {
        if (argc == 2) {                   //这里先检测参数的个数,注意,我们通常使用mtdpart命令时是不带参数,下面会在这里做修改
            if (strcmp(argv[1], "default") == 0) {
                setenv("mtdids", (char *)mtdids_default);  //mtdids使用mtdids_default
                setenv("mtdparts", (char *)mtdparts_default);  //mtdparts使用mtdparts,以上两个默认配置都是在配置文件里面实现的,如smdk2410.h
                setenv("partition", NULL);
    
                mtdparts_init();
                return 0;
            } else if (strcmp(argv[1], "delall") == 0) {
                /* this may be the first run, initialize lists if needed */
                mtdparts_init();
    
                setenv("mtdparts", NULL);
    
                /* devices_init() calls current_save() */
                return devices_init();
            }
        }
    
            ...

    此外,在cmd_jffs2.c文件的开头,注意有几个宏定义:

    #include <linux/ctype.h>
    
    #if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
    
    #include <cramfs/cramfs_fs.h>
    
    #if (CONFIG_COMMANDS & CFG_CMD_NAND)
    #ifdef CFG_NAND_LEGACY
    #include <linux/mtd/nand_legacy.h>
    #else /* !CFG_NAND_LEGACY */

    #ifdef CONFIG_JFFS2_CMDLINE
    /* default values for mtdids and mtdparts variables */
    #if defined(MTDIDS_DEFAULT)
    static const char *const mtdids_default = MTDIDS_DEFAULT;
    #else
    #warning "MTDIDS_DEFAULT not defined!"
    static const char *const mtdids_default = NULL;
    #endif

    还有

    static int part_validate_nand(struct mtdids *id, struct part_info *part)
    {
    #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND)
        /* info for NAND chips */
        nand_info_t *nand;

    这里需要定义三个宏还有默认配置:

    
    
    #define CONFIG_JFFS2_CMDLINE 1
    #define CONFIG_JFFS2_NAND    1
    
    #define MTDIDS_DEFAULT "nand0=nandflash0"
    #define MTDPARTS_DEFAULT "mtdparts=nandflash0:256k@0(bootloader)," 
                                "128k(params)," 
                                "2m(kernel)," 
                                "-(root)"
    
    
    1 #define CONFIG_COMMANDS  
    2                         CFG_CMD_JFFS2    | 

    以上,编译通过后,并不能立刻启动内核,注意此时的启动参数:

    #define CONFIG_BOOTCOMMAND "nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0"  //因为kernel还没有被识别

    这里应该改成:

    #define CONFIG_BOOTCOMMAND "nand read.jffs2 0x30007FC0 0x60000 0x200000; bootm 0x30007FC0"

    //这里是内核已经被烧写到Nand里面去了,然后使用nand read命令读到sdram的30007fc0地址处,内核在nand里面的地址是0x60000,大小是2M

    这里还是不能使用mtdpart命令,原因是上面提到过mtdpart参数的问题

    因为我们不使用参数,那么:

     1 if (argc == 2) {
     2         if (strcmp(argv[1], "default") == 0) {
     3             setenv("mtdids", (char *)mtdids_default);
     4             setenv("mtdparts", (char *)mtdparts_default);
     5             setenv("partition", NULL);
     6 
     7             mtdparts_init();
     8             return 0;
     9         } else if (strcmp(argv[1], "delall") == 0) {
    10             /* this may be the first run, initialize lists if needed */
    11             mtdparts_init();
    12 
    13             setenv("mtdparts", NULL);
    14 
    15             /* devices_init() calls current_save() */
    16             return devices_init();
    17         }
    18     }
    19 
    20     /* make sure we are in sync with env variables */
    21     if (mtdparts_init() != 0)
    22         return 1;
    23 
    24     if (argc == 1) {
    25         list_partitions();
    26         return 0;
    27     }

    那么,以下四个函数没有执行:

    setenv("mtdids", (char *)mtdids_default);
    setenv("mtdparts", (char *)mtdparts_default);
    setenv("partition", NULL);

    mtdparts_init();  //其中,主要是这个没有被执行

    处理措施:有两种

    第一个,把参数解析那个去掉,直接执行mtdparts_init()函数,代码如下:

     1 int do_jffs2_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
     2 {
     3                 //by Flinn
     4         setenv("mtdids", (char *)mtdids_default);
     5         setenv("mtdparts", (char *)mtdparts_default);
     6         setenv("partition", NULL);
     7 
     8         mtdparts_init();
     9     if (argc == 2) {
    10         if (strcmp(argv[1], "default") == 0) {
    11             //setenv("mtdids", (char *)mtdids_default);
    12             //setenv("mtdparts", (char *)mtdparts_default);
    13             //setenv("partition", NULL);
    14 
    15             //mtdparts_init();
    16             return 0;
    17         } else if (strcmp(argv[1], "delall") == 0) {
    18             /* this may be the first run, initialize lists if needed */
    19             mtdparts_init();
    20 
    21             setenv("mtdparts", NULL);
    22 
    23             /* devices_init() calls current_save() */
    24             return devices_init();
    25         }
    26     }    

    第二种,如韦东山所做,在main.c的main_loop函数里面添加:

     1 #ifdef CONFIG_JFFS2_CMDLINE
     2     extern int mtdparts_init(void);  //先执行init函数
     3     if (!getenv("mtdparts"))
     4     {
     5         run_command("mtdparts default", 0);  //再调用默认配置
     6     }
     7     else
     8     {
     9         mtdparts_init();
    10     }
    11 #endif

    以上两种办法都是可以的。

  • 相关阅读:
    IT职场求生法则
    设计模式六大原则
    非win7系统访问win7系统发布的网站
    C#自定义导出Excel
    js操作table元素,表格的行列新增、删除汇集
    一个真正合格的程序员应该具备的素质
    项目心得
    项目心得1
    Spring boot 使用profile完成不同环境的maven打包功能
    关于std容器类的内存使用
  • 原文地址:https://www.cnblogs.com/hulig7/p/4746832.html
Copyright © 2020-2023  润新知