![rootfs.jffs2 文件系统不适合 mtd3](https://linux22.com/image/51659/rootfs.jffs2%20%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%E4%B8%8D%E9%80%82%E5%90%88%20mtd3.png)
我有一个文件系统,我试图将其放入闪存 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
配置工具中的分区 这是我在构建 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'
文件名也反映了板的名称,所以希望你的板在那里。很多只是用作m25p80
,mtd-id
所以这可能就是这样。
如果失败,代码片段的另一个分支将追溯到init_name
设备的,尽管我不知道如何找到它(dmesg
?)。
假设m25p80
是mtd-id
,内核参数应该是:
mtdparts=m25p80:5M(boot),128K(bootenv),10752K(image),4M(spare)
剩下的就是重新配置 U Boot,并将其添加到bootargs
参数中。重新启动,希望您应该拥有所需的分区大小。