最新消息:20190717 VPS服务器:Vultr新加坡,WordPress主题:大前端D8,统一介绍入口:关于

【解答】内核kernel以及根文件系统rootfs是如何映射到对应的nand flash的地址的

工作和技术 crifan 1541浏览 0评论

【解答】内核kernel以及根文件系统rootfs是如何映射到对应的nand flash的地址的

【某人问题 内核在启动的过程中,是如何完成将本地的flash设备映射成文件系统的?
我用的是ramdisk.image.gz,烧写在flash的0x10140000处
我不太明白内核在启动过程中式如何将这个文件映射成/目录及各子目录的?
如果ramdisk.image.gz在flash中的位置发生了变化,应该如何修改内核啊?

【解答】
没理解错的话,ramdisk.image.gz应该是你的内核的压缩镜像。

你的问题,要分2方面和你解释:

1.将这个文件映射成/目录及各子目录的
不是将这个文件映射根目录成及各子目录的,
而是对应的根文件系统,简称rootfs(root file system),
对应着/根目录及其各个子目录和文件。

发现要解释清楚,要简单说清楚整个系统启动的过程:
【系统启动过程简介】
初始化代码读取uboot到内存里面,然后跳转到uboot那里去执行uboot,
uboot初始化必要的硬件,加载一些驱动,其中包括nand flash的驱动,
然后根据你的uboot里面设置的一个启动命令:

nand read 0x30007FC0 0x100000 0x200000;bootm 0x30007FC0
意思就是,先去读取nand flash,从0x100000开始,长度为0x200000的数据到memory的0x30007FC0处,
然后bootm表示从memory的0x30007FC0开始运行。
也就是去运行你的内核镜像了。
此处也就是你的ramdisk.image.gz。
而你的地址是0x10140000,所以,上面中的启动命令,至少0x100000要改成你的地址0x10140000。
然后,内核会自己解压缩,然后执行,
初始化硬件,
加载驱动模块,
最后去挂载rootfs,
而此文件系统是什么格式的,是从uboot里面定义的:
#define CONFIG_BOOTARGS   "root=/dev/mtdblock2 rw init=/linuxrc console=ttyS0,115200 mem=16M rootfstype=yafffs2"

(如果uboot支持变量修改及存储saveenv的话,那么就以当前最新的变量为准)
并在从uboot掉转到内核运行时候,传递给内核的,
这样内核在加载rootfs的时候,才知道,要以什么格式,比如上面的yaffs2格式,
去加载此文件系统。
此文件系统,也是你实现自己用相应的文件系统制作工具,制作的,然后烧写到对应的位置的。
上面中root=/dev/mtdblock2,表示,要去/dev/mtdblock2,也就是你的mtd的第3个分区,去加载。
而这里的mtd的第3个分区具体对应的nand flash中的的地址,
是你在内核中,一般是在core.c自己定义的的nand flash的分区。
一般是uboot是第一个分区,内核kernel是第二个,然后就是rootfs是第三个分区,也就是/dev/mtdblock2。
随便网上给你找个别人的分区:
static struct mtd_partition rm9200_partitions[3] =
{
        {        /* uboot 256K */
                .name = "uboot",
                .size = 0x40000,
                .offset = 0
        },
        {        /* kernel 1.768M */
                .name = "kernel",
                .size = 0x1C0000,
                .offset = 0x40000
        },
        {        /* rootfs 2M */
                .name = "rootfs",
                .size = 0x200000,
                .offset = 0x200000
        },
};

如果按照上面分区,定义的/dev/mtdblock2的起始地址是0x200000=2M的位置,
然后,内核启动挂载rootfs的时候,就是,以上面从uboot传过来的参数中yaffs2格式,
到nand flash 的2M的地址读取并加载rootfs,加载完成后,这样,里面对应的,你说的根目录,以及所有的文件,文件夹就都可以识别了。
然后才会去读取并运行初始化脚本相关的东西,最后初始化console控制台,然后你才能看到那个常见的#,才可以输入命令,比如ls,才可以和系统交互。

所以,你说的位置或地址如何映射成/根目录的,实际就是这个rootfs,对应着mtdblock2,
对应的某个nand flash上的地址,比如此处的2M的地方。而不是内核kernel这个文件映射的。

内核kernel,对应着是分区里面的mtdblock1,比如上面的地址0x40000。

2.
如果ramdisk.image.gz在flash中的位置发生了变化,应该如何修改内核啊?
如果地址变化了,那么
uboot中定义的启动参数:
nand read 0x30007FC0 0x100000 0x200000;bootm 0x30007FC0
中的0x100000就要换成你的新的地址就可以了。

转载请注明:在路上 » 【解答】内核kernel以及根文件系统rootfs是如何映射到对应的nand flash的地址的

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

网友最新评论 (4)

  1. 谢谢博主的耐心解答!
    有问题还会请教你的。
    RayZuo10年前 (2009-08-26)回复
  2. 回复RayZuo:我那段话的前提是,你之前通过某种方式,已经把yaffs2格式的rootfs,烧写到对应你的那个地址(你的2M的位置)了。“否也把此块(blockmtd2)格式化成了yaffs2”,此处没有任何额外操作,仅仅是按照yaffs2格式去读取对应数据加载而已。你所说的,格式化,对于yaffs2格式来说,在烧写rootfs到对应区域之前,只是需要擦除对应的nand flash 的块即可。然后就可以讲对应生成的rootfs烧写到对应区域即可。然后,kernel启动后,才会去根据传入的参数去对应blockmtd读取rootfs。
    againinput410年前 (2009-08-26)回复
  3. 我的问题是因为在你的原文中有这么一句

    “... 内核启动挂载rootfs的时候,就是,以上面从uboot传过来的参数中yaffs2格式,到nand flash 的2M的地址读取并加载rootfs,

    加载完成后,这样,里面对应的,你说的根目录,以及所有的文件,文件夹就都可以识别了...
    RayZuo10年前 (2009-08-26)回复
  4. 请教博主一个问题:
    从nand 2M地址处(0x20_0000)开始的blockmtd2,在以yaffs2文件格式读取并加载rootfs时,是否也把此块(blockmtd2)格式化成了yaffs2?


    谢谢博主!
    RayZuo10年前 (2009-08-26)回复
56 queries in 0.266 seconds, using 18.94MB memory