移植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

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

原文地址:https://www.cnblogs.com/hulig7/p/4746832.html