rootfs.jffs2 文件系统不适合 mtd3

rootfs.jffs2 文件系统不适合 mtd3

我有一个文件系统,我试图将其放入闪存 mtd3 分区中。我首先使用uboot启动,然后run sdboot使用SD卡启动,如下所示:

U-Boot-PetaLinux>
U-Boot-PetaLinux> printenv mtdparts
mtdparts=mtdparts=0:5M(boot),128K(bootenv),10752K(image),4M(spare)
U-Boot-PetaLinux>run sdboot

现在我已经有了一个正在运行的linux系统。

.
.
.
.
root@Xilinx-ZC702-14_7:/mnt/flashboot# nandwrite -p /dev/mtd3 rootfs.jffs2
Image 3513340 bytes, NAND page 1 bytes, OOB area 0 bytes, device size 393216 bytes
nandwrite: error!: Input file does not fit into device
           error 0 (Success)
nandwrite: error!: Data was only partially written due to error
           error 0 (Success)

那么为什么它显示:

nandwrite:错误!:输入文件不适合设备

您可以在第一行看到我的环境变量,我已经给出了足够的 4MB 空间,那么为什么大小为 3513340 字节(3.35 MB)的图像不适合设备?而这又是从哪里来的

设备大小 393216 字节来了?

附加信息

#cat /proc/cmdline
console=ttyPS0,115200

MTD信息:

Count of MTD devices:           4
Present MTD devices:            mtd0, mtd1, mtd2, mtd3
Sysfs interface supported:      yes

分区

root@Xilinx-ZC702-14_7:/# cat /proc/mtd
dev: size erasesize name
mtd0: 00500000 00010000 "boot"
mtd1: 00020000 00010000 "bootenv"
mtd2: 00a80000 00010000 "image"
mtd3: 00060000 00010000 "spare"

还可以看出:

root@Xilinx-ZC702-14_7:/mnt/flash# mtdinfo /dev/mtd0
mtd0
Name:                           boot
Type:                           nor
Eraseblock size:                65536 bytes, 64.0 KiB
Amount of eraseblocks:          80 (5242880 bytes, 5.0 MiB)
Minimum input/output unit size: 1 byte
Sub-page size:                  1 byte
Character device major/minor:   90:0
Bad blocks are allowed:         false
Device is writable:             true

root@Xilinx-ZC702-14_7:/mnt/flash# mtdinfo /dev/mtd1
mtd1
Name:                           bootenv
Type:                           nor
Eraseblock size:                65536 bytes, 64.0 KiB
Amount of eraseblocks:          2 (131072 bytes, 128.0 KiB)
Minimum input/output unit size: 1 byte
Sub-page size:                  1 byte
Character device major/minor:   90:2
Bad blocks are allowed:         false
Device is writable:             true

root@Xilinx-ZC702-14_7:/mnt/flash# mtdinfo /dev/mtd2
mtd2
Name:                           image
Type:                           nor
Eraseblock size:                65536 bytes, 64.0 KiB
Amount of eraseblocks:          168 (11010048 bytes, 10.5 MiB)
Minimum input/output unit size: 1 byte
Sub-page size:                  1 byte
Character device major/minor:   90:4
Bad blocks are allowed:         false
Device is writable:             true

root@Xilinx-ZC702-14_7:/mnt/flash# mtdinfo /dev/mtd3
mtd3
Name:                           spare
Type:                           nor
Eraseblock size:                65536 bytes, 64.0 KiB
Amount of eraseblocks:          6 (393216 bytes, 384.0 KiB)
Minimum input/output unit size: 1 byte
Sub-page size:                  1 byte
Character device major/minor:   90:6
Bad blocks are allowed:         false
Device is writable:             true

系统

在 ARM Cortex A9 上运行的 petalinux

http://www.wiki.xilinx.com/Linux

https://github.com/Xilinx

设备树 http://git.yoctoproject.org/cgit/cgit.cgi/meta-xilinx/plain/conf/machine/boards/zedboard/zedboard-zynq7-board.dtsi

配置工具中的分区 这是我在构建 image.ub 之前使用的配置工具。查看jffs2的大小,它大于rootfs.jffs2文件的实际大小。

在此输入图像描述

/sys/class/mtd

root@Xilinx-ZC702-14_7:/sys/class/mtd# ls -ld *
lrwxrwxrwx    1 root     root             0 Jan  1 00:00 mtd0 -> ../../devices/amba.0/e000d000.ps7-qspi/spi_master/spi32766/spi32766.0/mtd/mtd0
lrwxrwxrwx    1 root     root             0 Jan  1 00:00 mtd0ro -> ../../devices/amba.0/e000d000.ps7-qspi/spi_master/spi32766/spi32766.0/mtd/mtd0ro
lrwxrwxrwx    1 root     root             0 Jan  1 00:00 mtd1 -> ../../devices/amba.0/e000d000.ps7-qspi/spi_master/spi32766/spi32766.0/mtd/mtd1
lrwxrwxrwx    1 root     root             0 Jan  1 00:00 mtd1ro -> ../../devices/amba.0/e000d000.ps7-qspi/spi_master/spi32766/spi32766.0/mtd/mtd1ro
lrwxrwxrwx    1 root     root             0 Jan  1 00:00 mtd2 -> ../../devices/amba.0/e000d000.ps7-qspi/spi_master/spi32766/spi32766.0/mtd/mtd2
lrwxrwxrwx    1 root     root             0 Jan  1 00:00 mtd2ro -> ../../devices/amba.0/e000d000.ps7-qspi/spi_master/spi32766/spi32766.0/mtd/mtd2ro
lrwxrwxrwx    1 root     root             0 Jan  1 00:00 mtd3 -> ../../devices/amba.0/e000d000.ps7-qspi/spi_master/spi32766/spi32766.0/mtd/mtd3
lrwxrwxrwx    1 root     root             0 Jan  1 00:00 mtd3ro -> ../../devices/amba.0/e000d000.ps7-qspi/spi_master/spi32766/spi32766.0/mtd/mtd3ro
root@Xilinx-ZC702-14_7:/sys/class/mtd#

司机

root@Xilinx-ZC702-14_7:~# ls /sys/bus/*/drivers

/sys/bus/amba/drivers:

/sys/bus/clocksource/drivers:

/sys/bus/cpu/drivers:

/sys/bus/hid/drivers:
hid-generic

/sys/bus/i2c/drivers:
at24     dummy    pca954x

/sys/bus/mdio_bus/drivers:
Generic PHY

/sys/bus/mmc/drivers:
mmcblk

/sys/bus/platform/drivers:
alarmtimer       vexpress-sysreg  xilinx-gpio      xusbps-dr
of-flash         xadcps           xilinx_emaclite  xusbps-ehci
physmap-flash    xdevcfg          xqspips          xusbps-otg
sdhci-zynq       xemacps          xslcr            xusbps-udc
uio_pdrv_genirq  xgpiops          xsmcps           xwdtps
vexpress-reset   xi2cps           xuartps          zynq_remoteproc

/sys/bus/rpmsg/drivers:
rpmsg_proto          rpmsg_server_sample

/sys/bus/scsi/drivers:
ch    osst  sd    sr    st

/sys/bus/sdio/drivers:

/sys/bus/serio/drivers:

/sys/bus/spi/drivers:
m25p80

/sys/bus/usb/drivers:
hub          usb          usb-storage  usbfs        usbhid

/sys/bus/virtio/drivers:
virtio_rpmsg_bus
root@Xilinx-ZC702-14_7:~#

毫米卡驱动程序

root@Xilinx-ZC702-14_7:/# cd /sys/bus/mmc/drivers/mmcblk/
root@Xilinx-ZC702-14_7:/sys/bus/mmc/drivers/mmcblk# ls
bind       mmc0:1234  uevent     unbind
root@Xilinx-ZC702-14_7:/sys/bus/mmc/drivers/mmcblk# cd mmc0\:1234/
root@Xilinx-ZC702-14_7:/sys/devices/amba.0/e0100000.ps7-sdio/mmc_host/mmc0/mmc0:1234# ls
cid                   hwrev                 scr
csd                   manfid                serial
date                  name                  subsystem
driver                oemid                 type
erase_size            power                 uevent
fwr

解决方案

我通过使用配置工具并进行以下先前未选择的选择来解决它。

File systems  ---> 
-*- Native language support  --->
    <*>   Codepage 437 (United States, Canada)
    ...
    <*>   NLS ISO 8859-1  (Latin 1; Western European Languages)
    ... 

答案1

首先,我认为mtdparts环境变量没有传达任何关于实际分区大小的有意义的信息。mtdparts应该是内核启动参数,而不是环境变量。 PetaLinux 可能会在引导期间将这些值放入环境中。然而,即使这样,它的格式似乎也是错误的。要查看内核启动参数,您可以执行以下操作cat /proc/cmdline

要找出内核尝试创建的分区大小,您可以/proc/mtd根据其他问题进行查看。要找出实际创建的块设备的大小(以字节为单位),您可以这样做blockdev --getsize64 /dev/mtd3(需要root权限)。一切顺利的话两人应该很匹配!

现在,假设分区大小太小,您将需要增加分区的大小(这就是另一个问题所问的!)。在启动时指定mtdparts参数是执行此操作的正确方法。从drivers/mtd/cmdlinepart.c内核源代码中(请注意,这提供了比drivers/mtd/Kconfig之前使用的几乎相同的片段稍多的信息),这是正确的格式规范:

 * The format for the command line is as follows:
 *
 * mtdparts=<mtddef>[;<mtddef]
 * <mtddef>  := <mtd-id>:<partdef>[,<partdef>]
 * <partdef> := <size>[@<offset>][<name>][ro][lk]
 * <mtd-id>  := unique name used in mapping driver/device (mtd->name)
 * <size>    := standard linux memsize OR "-" to denote all remaining space
 *              size is automatically truncated at end of device
 *              if specified or trucated size is 0 the part is skipped
 * <offset>  := standard linux memsize
 *              if omitted the part will immediately follow the previous part
 *              or 0 if the first part
 * <name>    := '(' NAME ')'
 *              NAME will appear in /proc/mtd
 *
 * <size> and <offset> can be specified such that the parts are out of order
 * in physical memory and may even overlap.
 *
 * The parts are assigned MTD numbers in the order they are specified in the
 * command line regardless of their order in physical memory.
 *
 * Examples:
 *
 * 1 NOR Flash, with 1 single writable partition:
 * edb7312-nor:-
 *
 * 1 NOR Flash with 2 partitions, 1 NAND with one
 * edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home)

具体是什么意思standard linux memsize还不清楚。Documentation/kernel-parameters.txt给出以下段落:

Finally, the [KMG] suffix is commonly described after a number of kernel
parameter values. These 'K', 'M', and 'G' letters represent the _binary_
multipliers 'Kilo', 'Mega', and 'Giga', equalling 2^10, 2^20, and 2^30
bytes respectively. Such letter suffixes can also be entirely omitted.

这是预期使用的大写字母,但是k示例中使用的小写字母是否指定相同或不同的幂K没有提及(最好忽略这一点并根据事物的外观使用大写字母)。

从你的问题来看,这mtdparts=mtdparts=部分似乎是错误的。通常,对于环境变量,变量的名称根本不是变量值的一部分。似乎0也不是有效的mtd-id.

你给的其他一切mtdparts似乎都很好。应仔细选择分区的大小,使其与擦除块的大小相同,但考虑/proc/mtd到您的其他问题的擦除块大小为 64KiB,情况似乎就是这样。

寻找正确的mtd-id

似乎没有方法可以在运行的系统上确定这一点。虽然可以在 下找到有关 mtd 设备的各种信息/sys/class/mtd,但该信息目前不可用。该mtdinfo命令似乎除了读取和格式化这些信息之外没有做任何事情,所以这也没有多大用处

但是,考虑到所使用的驱动程序,应该可以通过查看内核源代码来找到这一点。为此,您可以使用以下命令查看最新的稳定源代码树:

git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git

或者您可能更喜欢使用发行版中所用内核版本的代码。请注意,设备本身可能没有足够的空间来下载约 1.4 GB 的内容。从源树的根内部,以下命令显示了设置值的大部分位置mtd->name(请注意,代码不必使用mtd结构的名称,但通常会使用):

grep -rE 'mtd(\.|->|-)name[[:space:]]*='

在大多数情况下,它要么硬编码在驱动程序中,要么信息位于文件中.dts。这也说明我们要找的司机很可能是在下drivers/mtd。进一步挖掘,使用如下命令:

for drv in a bunch of drivers; do
  find . -iname "*$drv*"
done | grep mtd

显示 mtd 驱动程序是m25p80.这适用于通过 SPI 通信的各种闪存设备(这解释了为什么寻找 PCI 相关的东西没有帮助)。查看源文件drivers/mtd/devices/m25p80.c,我们看到mtd->name在以下代码片段中设置:

  if (data && data->name)
    flash->mtd.name = data->name;
  else
    flash->mtd.name = dev_name(&spi->dev);

不幸的是,该驱动程序没有使用单一的特定名称,而是在其他地方定义了名称并取决于所使用的硬件。进一步挖掘,我们发现这data是一个flash_platform_data结构。寻找它的定义,我们在以下位置得到了这样的评论include/linux/spi/flash.h

 * struct flash_platform_data: board-specific flash data
 * @name: optional flash device name (eg, as used with mtdparts=)
 * @parts: optional array of mtd_partitions for static partitioning
 * @nr_parts: number of mtd_partitions for static partitoning
 * @type: optional flash device type (e.g. m25p80 vs m25p64), for use
 *  with chips that can't be queried for JEDEC or other IDs
 *
 * Board init code (in arch/.../mach-xxx/board-yyy.c files) can
 * provide information about SPI flash parts (such as DataFlash) to
 * help set up the device and its appropriate default partitioning.
 *
 * Note that for DataFlash, sizes for pages, blocks, and sectors are
 * rarely powers of two; and partitions should be sector-aligned.

似乎是mtd-id特定于主板而不是闪存本身。给出了该结构的用法,-A 2在匹配后打印 2 行并显示大部分使用的名称:

grep -rA 2 '[[:space:]]flash_platform_data'

文件名也反映了板的名称,所以希望你的板在那里。很多只是用作m25p80mtd-id所以这可能就是这样。

如果失败,代码片段的另一个分支将追溯到init_name设备的,尽管我不知道如何找到它(dmesg?)。

假设m25p80mtd-id,内核参数应该是:

mtdparts=m25p80:5M(boot),128K(bootenv),10752K(image),4M(spare)

剩下的就是重新配置 U Boot,并将其添加到bootargs参数中。重新启动,希望您应该拥有所需的分区大小。

相关内容