XiaomiRouter自学之路(14-Openwrt文件系统读取失败问题解决)

news/2024/7/21 12:19:09 标签: kernel, 文件系统

文件系统读取失败问题解决">XiaomiRouter自学之路(14-Openwrt文件系统读取失败问题解决)

在11-Openwrt配置编译烧录中,我们将编译好的openwrt-ramips-mt7620-xiaomi-miwifi-mini-squashfs-sysupgrade.bin烧录进去后,发现系统可以正常启动,但是出现了Kernel panic,Unable to mount root fs on unknown-block(0,0),貌似文件系统出现了问题。

查看openwrt的启动信息,找到MTD分区信息的位置,如下:

[    0.710000] 7 ofpart partitions found on MTD device spi32766.0
[    0.710000] Creating 7 MTD partitions on "spi32766.0":
[    0.720000] 0x000000000000-0x000000030000 : "u-boot"
[    0.730000] 0x000000030000-0x000000040000 : "u-boot-env"
[    0.730000] 0x000000040000-0x000000050000 : "factory"
[    0.740000] 0x000000050000-0x000000fd0000 : "firmware"
[    0.920000] 0x000000fd0000-0x000000fe0000 : "crash"
[    0.930000] 0x000000fe0000-0x000000ff0000 : "reserved"
[    0.930000] 0x000000ff0000-0x000001000000 : "Bdata"
[    0.940000] gsw: setting port4 to ephy mode
[    0.950000] ralink_soc_eth 10100000.ethernet eth0 (uninitialized): port 1 link up (10Mbps/Half duplex)
[    0.960000] ralink_soc_eth 10100000.ethernet: loaded mt7620 driver
[    0.960000] ralink_soc_eth 10100000.ethernet eth0: ralink at 0xb0100000, irq 5
[    0.970000] rt2880_wdt 10000120.watchdog: Initialized
[    0.980000] TCP: cubic registered
[    0.980000] NET: Registered protocol family 17
[    0.990000] bridge: automatic filtering via arp/ip/ip6tables has been deprecated. Update your scripts to load br_netfilter if you need this.
[    1.000000] 8021q: 802.1Q VLAN Support v1.8
[    1.010000] VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6
[    1.020000] Please append a correct "root=" boot option; here are the available partitions:
[    1.020000] 1f00             192 mtdblock0  (driver?)
[    1.030000] 1f01              64 mtdblock1  (driver?)
[    1.030000] 1f02              64 mtdblock2  (driver?)
[    1.040000] 1f03           15872 mtdblock3  (driver?)
[    1.040000] 1f04              64 mtdblock4  (driver?)
[    1.050000] 1f05              64 mtdblock5  (driver?)
[    1.060000] 1f06              64 mtdblock6  (driver?)
[    1.060000] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
[    1.060000] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

可以看到分成7个partition,对于partition的添加我在Linux mtd system里面已经有说了三种方式,这边使用的是dts添加的方式,该dts文件为target/linux/ramips/dts/XIAOMI-MIWIFI-MINI.dts,打开dts可以看到有如下内容:

m25p80@0 {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "w25q128";
        reg = <0 0>;
        linux,modalias = "m25p80", "w25q128";
        spi-max-frequency = <10000000>;

        partition@0 {
            label = "u-boot";
            reg = <0x0 0x30000>;
        };

        partition@30000 {
            label = "u-boot-env";
            reg = <0x30000 0x10000>;
            read-only;
        };

        factory: partition@40000 {
            label = "factory";
            reg = <0x40000 0x10000>;
            read-only;
        };

        partition@50000 {
            label = "firmware";
            reg = <0x50000 0xf80000>;
        };

        partition@fd0000 {
            label = "crash";
            reg = <0xfd0000 0x10000>;
        };

        partition@fe0000 {
            label = "reserved";
            reg = <0xfe0000 0x10000>;
            read-only;
        };

        partition@ff0000 {
            label = "Bdata";
            reg = <0xff0000 0x10000>;
        };
    };

直接观察这7个分区,好像没看到linux和rootfs,其实这两部分被cat连接成一个.img文件,存放在firmware分区里面,对于openwrt的firmware生成过程后期会专门写一篇文章介绍。

既然分区文件系统什么都有了为什么rootfs没有引导成功呢?再查看下u-boot下个文件所存到的地址是否与kernel下的地址一致呢?

在08-U-boot启动数值具体说明里面有提到U-boot下文件的存储位置,在include/configs/rt2880.h中有如下定义:

#define CFG_BOOTLOADER_SIZE 0x20000
#define CFG_CONFIG_SIZE     0x10000
#define CFG_FACTORY_SIZE    0x10000

#define CFG_ENV_ADDR        (CFG_FLASH_BASE + CFG_BOOTLOADER_SIZE)
#define CFG_FACTORY_ADDR    (CFG_FLASH_BASE + CFG_BOOTLOADER_SIZE + CFG_CONFIG_SIZE)
#define CFG_KERN_ADDR       (CFG_FLASH_BASE + (CFG_BOOTLOADER_SIZE + CFG_CONFIG_SIZE + CFG_FACTORY_SIZE))
#ifdef DUAL_IMAGE_SUPPORT
#define CFG_KERN2_ADDR      (CFG_FLASH2_BASE + (CFG_BOOTLOADER_SIZE + CFG_CONFIG_SIZE + CFG_FACTORY_SIZE))

发现u-boot阶段对u-boot的大小定义为0x20000,而kernel那边对u-boot的大小定义却为0x30000,地址已经错位了,我们将u-boot下的CFG_BOOTLOADER_SIZE改成0x30000后,对u-boot、openwrt进行重新烧录测试。

重新烧录后,可以观察到一切都正常,可以引导文件系统了,启动完按下Enter键进入命令行模式,如下:

BusyBox v1.23.2 (2017-02-21 05:58:37 PST) built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 CHAOS CALMER (Chaos Calmer, r49389)
 -----------------------------------------------------
  * 1 1/2 oz Gin            Shake with a glassful
  * 1/4 oz Triple Sec       of broken ice and pour
  * 3/4 oz Lime Juice       unstrained into a goblet.
  * 1 1/2 oz Orange Juice
  * 1 tsp. Grenadine Syrup
 -----------------------------------------------------
root@OpenWrt:/# 
root@OpenWrt:/# ls
bin      etc      mnt      proc     root     sys      usr      www
dev      lib      overlay  rom      sbin     tmp      var

现在已经可以正常引导了,试着去分析下是为什么会出现内核正常启动,可是文件系统引导不成功呢?

看下新的启动信息中MTD的分区信息有了一些信息,如下:

[    0.700000] m25p80 spi32766.0: w25q128 (16384 Kbytes)
[    0.710000] 7 ofpart partitions found on MTD device spi32766.0
[    0.710000] Creating 7 MTD partitions on "spi32766.0":
[    0.720000] 0x000000000000-0x000000030000 : "u-boot"
[    0.730000] 0x000000030000-0x000000040000 : "u-boot-env"
[    0.730000] 0x000000040000-0x000000050000 : "factory"
[    0.740000] 0x000000050000-0x000000fd0000 : "firmware"
[    0.860000] 2 uimage-fw partitions found on MTD device firmware
[    0.870000] 0x000000050000-0x0000001668b5 : "kernel"
[    0.870000] 0x0000001668b5-0x000000fd0000 : "rootfs"
[    0.880000] mtd: device 5 (rootfs) set to be root filesystem
[    0.890000] 1 squashfs-split partitions found on MTD device rootfs
[    0.890000] 0x000000360000-0x000000fd0000 : "rootfs_data"
[    0.900000] 0x000000fd0000-0x000000fe0000 : "crash"
[    0.910000] 0x000000fe0000-0x000000ff0000 : "reserved"
[    0.910000] 0x000000ff0000-0x000001000000 : "Bdata"
[    0.920000] gsw: setting port4 to ephy mode

可以看到中间多了一些信息,上面有说过firmware里面其实包含了kernel和rootfs两个部分,所以其实是有两个partition在里面,内核在调用add_mtd_partitions()函数里面会调用mtd分离函数mtd_partition_split(),看下函数的原型:

static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part)
{
    static int rootfs_found = 0;

    if (rootfs_found)
        return;

    if (!strcmp(part->mtd.name, "rootfs")) {
        int num = run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS);

        if (num <= 0 && config_enabled(CONFIG_MTD_ROOTFS_SPLIT))
            split_rootfs_data(master, part);

        rootfs_found = 1;
    }

    if (!strcmp(part->mtd.name, SPLIT_FIRMWARE_NAME) &&
        config_enabled(CONFIG_MTD_SPLIT_FIRMWARE))
        split_firmware(master, part);

    arch_split_mtd_part(master, part->mtd.name, part->offset,
                part->mtd.size);
}

该函数会先判断有没有rootfs该partition,如果有直接对该partition进行解析,如果没有那就说明在firmware里面,所以会先调用split_firmware()函数,简单说明该函数就是将firmware里面的kernel和rootfs分离出来,再对rootfs的partition进行解析。

该函数具体做了以下几件事:

  • 找type为MTD_PARSER_TYPE_FIRMWARE的分区解析器来分析。
  • “uimage-fw” 解析器读出 firmware 分区的头部,成功找到一个 uImage。
  • 跃过uImage,紧接着成功找到 squashfs 的头信息,于是找到了格式为 squashfs 的 rootfs。
  • 解析器在找到一个分区后,会调用 __mtd_add_partition() 将此分区添加到系统中。
  • __mtd_add_partition() 最后又调用 mtd_partition_split(),因为此时 rootfs已经找到,所以会调用 split_rootfs_data() 找 rootfs_data 分区。
  • rootfs 为 squashfs 分区,该格式的文件系统只读,且头信息里有标记分区大小。所以很容易就可以找到 rootfs_data 的起始位置。

通过上面这么一分析其实我们就大概知道没有引导文件系统的原因了:

1.kernel能够启动那是因为kernel的启动与mtd分区是没有关系的,只跟u-boot的引导地址有关,又因为在u-boot阶段,kernel所存储的位于与启动的引导地址肯定是一致的,所以kernel正常启动。

2.rootfs的启动与mtd分区是有关的,因为后面是通过读取分区块的内容来载入数据的,所以当所存放的地址和所要取的地址错误时,调用split_firmware()函数没能找出rootfs所处的位置,没能为rootfs建立分区块,所以会提示Unable to mount root fs on unknown-block(0,0)无法挂载rootfs文件系统

Openwrt文件系统读取失败问题解决的分析就到这边,有感悟时会持续会更新。

注:以上内容都是本人在学习过程积累的一些心得,难免会有参考到其他文章的一些知识,如有侵权,请及时通知我,我将及时删除或标注内容出处,如有错误之处也请指出,进行探讨学习。文章只是起一个引导作用,详细的数据解析内容还请查看XiaomiRouter相关教程,感谢您的查阅。


http://www.niftyadmin.cn/n/1535329.html

相关文章

天地在我心

歌曲&#xff1a;天地在我心 歌曲出自动画电影《宝莲灯》 作词&#xff1a;刘欢&#xff1b;作曲&#xff1a;郑方、刘欢&#xff1b;演唱&#xff1a;刘欢。 天上的星星多么美丽&#xff0c; 可是没有你&#xff0c;一切都没生机&#xff0c; 每一个孤独的深夜里&#xff0c; …

7-Linux profile and inittab file

Linux profile and inittab file /etc/profile文件是每个用户登录时都会运行的环境变量设置&#xff0c;属于系统级别的环境变量&#xff0c;设置在里面的东西对所有用户适用。/etc/inittab文件是系统初始化进入busybox后跑的一个配置文件。 下面通过具体例子&#xff0c;来分析…

theMatrix代码雨效果

做了一个代码雨效果放在个人主页: https://lanleilin.github.io/lanGallery/index.html 代码&#xff1a; <!DOCTYPE html> <html><head><title>The Matrix</title><script type"text/javascript" src"../js/jquery.min.js&q…

Eclipse + MinGW下编译调试c++程序

作为编程人员&#xff0c;程序的调试是一项基本功。在不使用IDE的时候&#xff0c;程序的调试多数是通过日志或者输入语句&#xff08;System.out.println&#xff09;的方式。可以把程序运行的轨迹或者程序运行过程中的状态显示给用户&#xff0c;用户据此对程序进行分析调试。…

8-Linux spi system

Linux spi system SPI是由Motorola提出的一种全双工同步串行通信接口&#xff0c;通信波特率可以高达5Mbps&#xff0c;但具体速度大小取决于SPI硬件,SPI接口具有全双工操作&#xff0c;操作简单&#xff0c;数据传输速率较高的优点&#xff0c;但也存在没有指定的流控制&#…

Html(1)——常用标签

Html常用标签 一.基本标签 <!DOCTYPE html>:引用官方的DTD文件——对标签的使用进行了一定的约束 <html>:根元素标签&#xff0c;成对出现&#xff0c;代表一个html文档的开始和结束 <head>:头部标签&#xff0c;成对出现 <body>:主体标签&#xff0c;…

1-SIM卡复位ATR解析

激活时序 在激活过程结束&#xff08;接口设备中 RST 处于 L 状态&#xff0c;VCC 上电&#xff0c;I/O 进入接收模式&#xff0c;CLK 已被提供了一个匹配并稳定的时钟信号&#xff09;时&#xff0c;卡片已就绪&#xff0c;可以进行冷复位。卡片在冷复位之前的内部状态不做规定…

项目的开发部署思路:

项目的开发部署思路&#xff1a; 需求分析&#xff0c;明确边界&#xff0c;业务重点 项目开发&#xff0c;完成基本的功能&#xff0c;进行迭代开发&#xff0c;不断完善 交流使用&#xff0c;完善体系转载于:https://www.cnblogs.com/Erma/p/7289714.html