u-boot之怎么实现分区

发布时间:2024-08-29  

启动参数bootcmd=nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0中kernel在哪定义,为什么可以直接引用?针对这个问题展开思考最终定位到了MTD分区的实现。 在u-boot之start_armboot函数分析中提到过实现nand flash的分区。执行run_command('mtdparts default', 0)可以实现分区功能,run_command函数在u-boot之内核是怎么启动的已经详细介绍过,现在只是说明mtdparts命令的执行函数do_jffs2_mtdparts,它位于Cmd_jffs2.c (common)文件下。


1、环境变量的初始化


2、mtdparts default命令分析(实现分区)


3、nand read.jffs2 0x30007FC0 kernel命令中kernel的值


1、环境变量的初始化


环境变量的初始化在u-boot之start_armboot函数分析的时候已经粗略的提及过,但是没有具体分析,现在接着详细分析下,首先是在初始化数组中初始化的环境变量:


env_init,        /* initialize environment *///初始化环境变量,采用默认环境变量  by andy

具体的函数为:


    int env_init(void)

{

#if defined(ENV_IS_EMBEDDED)//ENV_IS_EMBEDDED表示环境变量存放在ram中,不存储在flash上

/****此处省略******/

#else /* ENV_IS_EMBEDDED */

    gd->env_addr  = (ulong)&default_environment[0];//取得默认的环境变量地址 

    gd->env_valid = 1;                             //环境变量已经存在标志

#endif /* ENV_IS_EMBEDDED */


    return (0);

}


接着继续重新定位环境变量,函数如下


/* initialize environment */

    env_relocate ();//初始化环境变量,crc有效的话从nand中读取存储的环境变量,否则采用默认的环境变量

对env_relocate分析


void env_relocate (void)

{

    DEBUGF ('%s[%d] offset = 0x%lxn', __FUNCTION__,__LINE__,

        gd->reloc_off);


#ifdef ENV_IS_EMBEDDED

/*******省略*********/

#else

    /*

     * We must allocate a buffer for the environment

     */

    env_ptr = (env_t *)malloc (CFG_ENV_SIZE);//在RAM中为环境变量的存放分配一个堆区 

    DEBUGF ('%s[%d] malloced ENV at %pn', __FUNCTION__,__LINE__,env_ptr);

#endif


    /*

     * After relocation to RAM, we can always use the 'memory' functions

     */

    env_get_char = env_get_char_memory;//得到环境变量的地址的函数


    if (gd->env_valid == 0) {//如果环境变量在一开始初始化的时候无效,重新定位默认环境变量

#if defined(CONFIG_GTH)    || defined(CFG_ENV_IS_NOWHERE)    /* Environment not changable */

        puts ('Using default environmentnn');

#else

        puts ('*** Warning - bad CRC, using default environmentnn');

        SHOW_BOOT_PROGRESS (-1);

#endif


        if (sizeof(default_environment) > ENV_SIZE)

        {

            puts ('*** Error - default environment is too largenn');

            return;

        }


        memset (env_ptr, 0, sizeof(env_t));

        memcpy (env_ptr->data,

            default_environment,

            sizeof(default_environment));

#ifdef CFG_REDUNDAND_ENVIRONMENT

        env_ptr->flags = 0xFF;

#endif

        env_crc_update ();

        gd->env_valid = 1;

    }

    else {

        env_relocate_spec ();//从nand中取出有效的数据,如果无效,还是使用默认的环境变量

    }

    gd->env_addr = (ulong)&(env_ptr->data);//取得首个环境变量的地址env_ptr为一个结构体,包含了crc、flags、以及data指针

}


2、mtdparts default命令分析(实现分区)


跟着do_jffs2_mtdparts函数往里看,setenv为设置环境变量函数。


    if (argc == 2) {//如果参数个数为2个

        if (strcmp(argv[1], 'default') == 0) {           //默认参数

            setenv('mtdids', (char *)mtdids_default);    //设置mtdids环境变量

            setenv('mtdparts', (char *)mtdparts_default);//设置mtdparts环境变量

            setenv('partition', NULL);                   //设置partition环境变量


            mtdparts_init();//分区初始化  by andy

            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();

        }

    }


继续往里看mtdparts_init函数,这函数比较复杂,先看一下它的调用层次。


mtdparts_init();//分区初始化  by andy

        parse_mtdids(ids);    //添加mtdids到mtdids链表 nand0=nandflash0

        parse_mtdparts(parts);//添加分区parts

            devices_init();//0初始化成功,主要是做了删除所有分区设备的工作 

                device_parse(p, &p, &dev);//添加分区设备,返回的设备为dev,p为从环境变量取得的字符串

                        id_find_by_mtd_id(mtd_id, mtd_id_len - 1);//找到parse_mtdids(ids);中添加的mtdids以及名称nandflash0

                        while (p && (*p != '') && (*p != ';')) {

                        {

                            part_parse(p, &p, &part);//分区解析,填充part,添加解析过后的part的链表。这个函数解析MTDPARTS_DEFAULT然后分区

                        }


总的来说就是根据MTDIDS_DEFAULT 与MTDPARTS_DEFAULT解析它们然后进行分区


#define MTDIDS_DEFAULT 'nand0=nandflash0'//分区设备为nand

#define MTDPARTS_DEFAULT 'mtdparts=nandflash0:256k@0(bootloader),' //bootloader分区

                            '128k(params),'                        //参数分区

                            '2m(kernel),'                          //内核分区

                            '-(root)'                               //用户分区

 


3、nand read.jffs2 0x30007FC0 kernel中kernel的值


实现了分区之后就可以调用分区的名称了,kernel就是其中一个分区的名称。同样的切换到nand命令的运行函数do_nand。同样对它进行层次分析,找到kernel。


do_nand

    arg_off_size(argc - 3, argv + 3, nand, &off, &size)//5个参数分别代表参数个数、参数位于的地址、分区设备结构地址、返回的偏移值、返回的大小

        find_dev_and_part(argv[0], &dev, &pnum, &part)//查找有哪个设备存在argv[0]分区,即kernel分区,找到分区信息存放在part中

        *off  = part->offset;//找到了nand设备,取得偏移值

        *size = part->size;  //取得大小


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    装机、做系统必备:秒懂MBRGPT分区表;很多网友询问MBRGPT的问题,涉及到硬盘操作系统的安装,其实除了MBRGPT分区表,UEFI BIOS也是和操作系统紧密联系在一起的,下面我们就来聊聊硬盘......
    的价格爆降。但与此同时,固态硬盘的读写性能也不能太差,所以像“缓存”这种“花小钱办大事”的方案就逐渐多了起来。 结语 1、目前机械硬盘在大容量存储方面价格优势还是十分明显的。而对于小容量存储,固态硬盘与机械硬盘......
    3(300E5K)进行实际体验一下。 在进行体验之前,首先介绍一下三星300E5K的硬盘情况。该机搭载了一块容量为256GB的固态硬盘,为三星自家产品,属于OEM版本。三星的固态硬盘无论是性能还是......
    选型的设备涉及零下工作环境,或者超过零上70℃的环境,那么就很有必要优先考虑选择宽温固态硬盘。 广告 以车载计算机为例,无论是载人汽车,还是用于物流运输的无人驾驶汽车,都有可能会在温度为零下的雪地中前进,或者......
    现微小的震动和噪音,而固态硬盘是没有这些问题的。 用户选择 对速度需求:如果你对存储速度有特殊的要求,那么你就选择SSD。 游戏玩家:玩游戏的都知道SSD是必备的,所以SSD对于玩游戏的人来说还是喜爱有加。 工作......
    生产工艺以及用户对读写速度的追求,越来越多的中高端SSD开始选择PCI-E接口来进行SSD与主板的对接。在本篇文章中笔者将详细介绍SATA通道与PCI-E通道固态硬盘的优缺点,让大家在装机选择固态硬盘时做到心中有数,按需......
    是果断下了单! 目前固态硬盘领域其实存在着很强的竞争,一方面是新势力崛起,另一方面是老品牌推陈出新,各有各的优势。在这样的形势下,其实我是选择相信品牌的,Lexar雷克沙是知名消费类存储品牌,旗下......
    笔记本电脑加硬盘,选机械硬盘还是固态硬盘?; 大存储时代,手机内存已经是动辄512GB、甚至1TB,很多人难免会对的存储容量产生焦虑。 为什么笔记本电脑需要升级硬盘......
    大小从512B-64MB依次向上增加。从测试结果可以看出,科赋CRAS C710 M.2固态硬盘在文件读写方面的表现还是非常稳定的,读取最高速度可达1.92 GB/s、写入速度最高可达1.59 GB......
    黯淡的时候,这则消息确实来得令人震惊。 不得不说,在固态硬盘价格高居不下的形势下,人们选择相对廉价的机械硬盘也是无奈之举。这个状况已经持续了好几年,大家总是盼着固态硬盘真正平民化的那天大家都可以彻底抛弃机械硬盘......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>