Ubiformat error sub page cannot be larger than min i o unit

I noticed while looking at one of my firmwares that the files coming out of binwalk were corrupt and in the image was strange filemagic that turned out to be an UBI file system (http://www.dubeiko....

Ah thanks, I forgot how out of date Kali Linux was (and I gave up after finding ./setup.py install didn’t place things in the right folder on Kali Linux even when using —install—layout=deb.. and just assumed it was some Kali quirk as binwalk is sat in /usr/local/bin/binwalk and if I try executing the one that I installed I get plugin errors).

Thank you also for your kind help trying to get the image mounted. I tried it but it still did not work:

# Try mtdram
modprobe mtdram total_size=32000
cat /proc/mtd
flash_erase /dev/mtd0 0 0
ubiformat /dev/mtd0 -f UBI.bin
modprobe ubi
ubiattach -p /dev/mtd0
dmesg

…bad VID header offset 512, expected 64..

flash_erase /dev/mtd0 0 0
ubiformat /dev/mtd0 -f UBI.bin -s 64

ubiformat: error! : sub-page cannot be larger than min. I/O unit

# Try nandsim
modprobe nandsim first_id_byte=0x20 second_id_byte=0x35
cat /proc/mtd
flash_erase /dev/mtd0 0 0
ubiformat /dev/mtd0 -f UBI.bin -s 64

…min. I/O size 512 bytes…
ubiformat: error!: bad UBI magic 00000000, should be 0x55424923
ubiformat: error!: bad EC header at eraseblock 1 of «UBI.bin»

flash_erase /dev/mtd0 0 0
ubiformat /dev/mtd0 -f UBI.bin
flash_erase /dev/mtd0 0 0

I tried all manner of s values, they couldn’t be bigger than the min. I/O size (which was 1 when using mtdram).. previously when I tried nandsim I also looked at all the different NANDs it supported and tried to find one with a smaller block size but couldn’t. I also tried screwing with the -O parameter when using ubiattach, that then moves the error onto «bad data offset 2048, expected 576». It’s definitely a valid file but with me specifying incorrect geometry.

I believe nandsim is for NAND memory and mtdram is for NOR memory.. I seem to get closer with mtdram (it’s reading the file magic and the header correctly!). The original device does not list what model flash it uses (other than that it’s 32MB) and it’s too expensive and in warranty to take apart.

I seem to be in the same place as : https://garage.maemo.org/pipermail/moebian-devel/2010-March/000030.html

Any other suggestions are very welcome (I’ve been Googling for ages and haven’t read anyone having much success with this).

UBI FAQ and HOWTO

Table of contents

  1. How do I enable UBI?
  2. How do I attach an MTD device?
  3. How do I create/delete UBI volumes?
  4. How do I run JFFS2 on top of an UBI volume?
  5. Can I run ext2 on top of UBI?
  6. Can I run squashfs on top of UBI?
  7. Do I have to format my empty flash before running UBI on top of it?
  8. How do I erase flash and preserve erase counters?
  9. How do I create UBI images?
  10. How do I find out min. I/O unit size, sub-page size, and LEB size?
  11. How do I flash UBI images and preserve erase counters?
  12. Can UBI logical eraseblocks be written randomly?
  13. Why UBI does not use OOB area of NAND flashes?
  14. Is UBI tolerant of power failures?
  15. What happens when the PEBs reserved for bad block handling run out?
  16. May UBI be used on MLC flash?
  17. Why does ubiattach on a freshly formatted device fail with «Invalid argument»?
  18. What is a sub-page?
  19. I get «ubi_io_write: error -5 while writing 512 bytes to PEB 5:512»
  20. I get «no VID header found at PEB 7923, only 0xFF bytes»
  21. I get: «ubi_io_read: error -74 (ECC error) while reading 126976 bytes from PEB 47:4096, read 126976 bytes»
  22. How do I force UBI to ignore sub-pages?
  23. How do I implement UBI flasher?
  24. What does the «ubi_bgt0d» thread do?
  25. How do I speed up UBI initialization
  26. Why a dynamic volume is faster to access than a static volume of the
    same size?
  27. How do I debug UBI?
  28. How do I send an UBI bug report?

How do I enable UBI?

In the Linux configuration menu, go to «Device Drivers» ->
«Memory Technology Devices (MTD)» -> «UBI — Unsorted block images«,
and mark the «Enable UBI» check-box. UBI may be either compiled into the
kernel or be built as a kernel module.

How do I attach an MTD device?

Each MTD device has a name and a number, which you may find out by
examining the /proc/mtd file. The preferable way to attach
MTD devices is to attach them by name, not by number, because MTD device
numbers may change if you change the layout of your flash, while the
names will supposedly stay the same.

If UBI is compiled as a kernel module, it is enough to specify the MTD
device name or number to attach in the module arguments, e.g.

$ modprobe ubi mtd=rootfs
$ modprobe ubi mtd=0

loads the UBI kernel module and attaches MTD device named «rootfs» or with
number 3 (mtd3). And

$ modprobe ubi mtd=config mtd=rootfs
$ modprobe ubi mtd=3 mtd=5

command loads UBI kernel module and attaches MTD devices named «config»
and «rootfs», or mtd3 and mtd5.

If UBI is compiled into the kernel, the mtd device to attach may be
specified in the ubi.mtd=kernel boot parameter, e.g.,

ubi.mtd=rootfs
ubi.mtd=0

command makes UBI attach MTD device named «rootfs» or mtd3 when
the kernel is booting. And

ubi.mtd=config ubi.mtd=rootfs
ubi.mtd=3 ubi.mtd=5

command makes UBI attach MTD devices named «config» and «rootfs», or
mtd3 and mtd5.

And finally, MTD devices may be attached or detached at any time with the
ubiattach and ubidetach
utilities; For example,

$ ubiattach /dev/ubi_ctrl -m 3

attaches mtd3. But these utilities will work with kernel
versions starting from version 2.6.25. And someone should
update them and teach to accept MTD device names, not only MTD device
numbers.

How do I create/delete UBI volumes?

Use the ubimkvol and ubirmvol
utilities. For example, the below command
creates an 128MiB volume on UBI device 0:

$ ubimkvol /dev/ubi0 -N rootfs -s 128MiB

and the following command removes it:

$ ubirmvol /dev/ubi0 -n 0

For additional information, use ubimkvol -h and
ubirmvol -h.

How do I run JFFS2 on top of an UBI volume?

There is an additional driver called gluebi which can emulate
fake MTD devices for each UBI volume and JFFS2 can be used with these emulated
MTD devices. Enable gluebi in the UBI configuration menu (the
«MTD devices emulation driver (gluebi)» option).

Note, pre-2.6.31 kernels did not have a separate
gluebi driver and it was built into the UBI driver. The
corresponding UBI configuration menu option was
«Emulate MTD devices«

Can I run ext2 on top of UBI?

UBI is not a block device emulation layer, it is not an FTL. Neither ext2
nor other «traditional» file systems can be run on top of an UBI device.
Please, read the big red note
and overview documentation sections to
realize why.

However, given UBI takes care of many flash complexities, it provides a
bad-block-free block device access on top of UBI volumes. This feature is useful to
mount read-only file systems.

Can I run squashfs on top of UBI?

Yes. UBI allows to create a read-only block device on top of a UBI volume
which is suitable for read-only, block-oriented file systems, such as squashfs.
See the UBI block device section for more details.

Do I have to format my empty flash before running UBI on top of it?

Ideally, yes, but not necessarily.

Roughly speaking, «UBI-formatted MTD device» has each PEB erased and
containing a valid EC header.
However, it is not always possible because many a lot of existing software is
not UBI-aware and cannot preserve erase counters. Often all it can do is to wipe
out the flash. This is why UBI can to deal with empty flash perfectly well — it
just automatically formats it.

So the answer is no, you do not have to. For example, if you wipe out the
flash and try to attach it to UBI — it will work. UBI will just automatically
format the flash. The formatting process takes time, though.

But keep in mind that every time you erase the flash, you lose erase
counters, so you lose wearing information. Doing this over and over again may
wear out some eraseblocks. This is especially dangerous on MLC NAND flashes
which have very low eraseblock life-cycle. Try to use UBI-aware utilities and
flashing programs.

How do I erase flash and preserve erase counters?

Use the ubiformat
utility. Example:

$ ubiformat /dev/mtd0
ubiformat: mtd0 (NAND), size 536870912 bytes (512.0 MiB), 131072 eraseblocks of
131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 4095 -- 100 % complete
ubiformat: 4094 eraseblocks have valid erase counter, mean value is 104
ubiformat: bad eraseblocks: 13, 666
ubiformat: formatting eraseblock 4095 -- 100 % complete

Note! If you use an old kernel, which is older than 2.6.30 and where
MTD does not support sysfs, you have to pass «-s» argument to
ubiformat.

This section has some hints
for those who implement a custom UBI flasher.

How do I create UBI images?

UBI images may be created using the
ubinize utility. This
utility takes the configuration file on input and generates an UBI image on
output. The input configuration file describes all UBI volumes which the
resulting UBI image has to contain. The configuration file has the
ini-file syntax. Here is an example:

$ cat config.ini
[configuration-data-volume]
mode=ubi
image=config_data.img
vol_id=0
vol_size=512KiB
vol_type=static
vol_name=configuration

[rootfs-volume]
mode=ubi
image=rootfs.img
vol_id=1
vol_size=220MiB
vol_type=dynamic
vol_name=rootfs
vol_flags=autoresize

$ ./ubinize -o ubi.img -p 128KiB -m 512 -s 256 config.ini

The config.ini file tells UBIFS to create 2 volumes:

  • static configuration volume of 512KiB in size, assign it ID 0 and
    name «configuration»; the contents of the volume should be taken from
    the config_data.img file;
  • dynamic root file-system volume of 220MiB in size, assign it ID 1
    and name «rootfs»; the contents of the volume should be taken from
    the rootfs.img file; this volume should also have
    «auto-resize» flag which means the size of this volume will be amended
    when UBI runs for the first time; namely, UBI will make this volume
    larger by giving available eraseblocks; this may be very useful in case
    of NAND flash (see here for
    more details).

So in the above example, ubinize basically reads 3 input
files:

  • The config.ini file which describes how many volumes
    should the resulting ubi.img file contain, their sizes,
    names, and so on; it also refers the files containing the data which
    should be put to the volumes; note, if the volume is supposed to be
    empty, just do not specify the image file;
  • the config_data.img image file for the first
    volume;
  • the rootfs.img image file for the second volume.

Users often wonder why ubinize needs a configuration file. The
answer is that one UBI image may contain many UBI volumes with different
characteristics and it is difficult to invent a nice command-line interface for
specifying all those characteristics. Thus a configuration file is used. But
feel free sending a patch which teaches ubinize working without
the configuration file if there is only one volume.

Note, UBI reserves physical flash space for volumes. Namely, UBI
reserves a physical eraseblock for each logical eraseblock. The size if LEB
130560 bytes in our example (found out by running ubinize
with -v option), which means that the configuration volume will
have 5 LEBs ([512 * 1024] / 130560 rounded up) and the root file-system
volume will have at least 1767 LEBs. This means that the MTD device the
ubi.img is going to be flashed to has to have at least 1772
physical eraseblocks, which is about 221MiB. But because of the UBI overhead
(see this section), the MTD device
actually has to be at least 225MiB in size. Of course it may be larger,
in which case the «rootfs» volume will be re-sized and take the rest of the
flash space (because of the auto-resize flag).

The implications of the above paragraph are important. The
vol_size option effectively represents the minimum size of the
flash where the volume will be installed. If you are working with multiple
devices (i.e. you are producing an image to be flashed on various devices,
even when ‘identical’), the amount of usable flash will vary because
some devices have more bad blocks than others. Excluding the
vol_size option will cause vol_size to be automatically
calculated based on the size of the input image, and this will produce
maximum robustness in the face of varying numbers of bad blocks on target
devices. You can combine this with the autoresize functionality so that the
maximum amount of free space is made available upon first mount.

Also, the config_data.img and rootfs.img input
files do not have to be 512KiB and 220MiB respectively, but may be smaller if
they contain less data. In this case the resulting ubi.img file
will also be smaller than 221MiB. All the ubinize utility does is
it takes the image files, splits them to LEB-sized chunks, forms PEB data by
adding UBI headers to these LEB
chunks, and writes the result to the output file. It also writes the
volume table (2 physical
eraseblocks). Thus, ubi.img file size will be small if the input
volume images are small. And ubinize does not do any further
padding.

Please, use the Use the
ubiformat utility to
flash the resulting UBI image. Also, you can find detailed description of how
UBI-aware flashing programs should work in
this section.

How do I find out min. I/O unit size, sub-page size, and LEB size?

If you run kernel version 2.6.30 or later, the easiest
way to find out all these parameters is to run the
mtdinfo
tool, which reports them. Of course, the tool has to be run on the
target.

Otherwise, first find out the physical eraseblock (PEB) size from
the flash manual, or from the /proc/mtd file on the target.

Refer this and
this sections for some hints about
what the min. I/O unit and sub-page sizes may be for you.

The LEB size is defined by:

  • physical eraseblock size;
  • minimum input/output unit size;
  • sub-page size;

Please, read this section for
information about how LEB size is calculated (it is denoted by O
there).

How do I flash UBI images and preserve erase counters?

Use the ubiformat
utility. Example:

$ ubiformat /dev/mtd0 -f ubi.img
ubiformat: mtd0 (NAND), size 536870912 bytes (512.0 MiB), 131072 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 4095 -- 100 % complete
ubiformat: 4094 eraseblocks have valid erase counter, mean value is 105
ubiformat: bad eraseblocks: 13, 666
ubiformat: flashing eraseblock 50 -- 100 % complete
ubiformat: formatting eraseblock 4095 -- 100 % complete

Note, this section has
describes how UBI-aware flasher program has to work.

Important!: even if you do not care about erasecounters, do not use
dd for flashing UBI images to NAND flashes, because
dd does handle bad eraseblocks.

Important!: even if you do not care about erasecounters, do not use
nandwrite for flashing UBI images containing UBIFS file-system to
NAND flashes, read here for
more information.

Can UBI logical eraseblocks be written randomly?

No, the flash chip restrictions have to be taken into account. This is
because UBI logical eraseblocks (LEB) are mapped to physical eraseblocks (PEB),
and an LEB write operation is essentially a write to the corresponding PEB
plus a small offset. The important flash restrictions are:

  1. all writes have to be aligned to the
    min. I/O unit size and be
    multiple of min. I/O unit size;
  2. sometimes it is prohibited to write more then once to the same PEB
    offset (e.g., in case of NAND flash);
  3. many NAND flashes (specifically, MLC NAND flashes) require NAND
    pages to be written sequentially from the beginning of the physical
    eraseblock, to the end of the physical eraseblock; for example, it is
    prohibited to first write to offset 2048, then to offset 0; once offset
    2048 has been written to, it is possible to write only to further
    offsets.

Even if the flash chip is devoid of the last restriction, UBI anyway
requires logical eraseblocks to be written sequentially from the beginning
to the end. This is because UBI calculates data CRC when moving logical
eraseblocks to other physical eraseblocks (see
here for more information),
so a write an offset which is less than the furthest written data offset causes
CRC errors;

Why UBI does not use OOB area of NAND flashes?

Because many flashes (e.g., NOR) do not have OOB and UBI was designed to be
generic. Also, modern MLC NAND flashes use whole OOB area for the ECC
checksum, so there is no room for application data.

But of course, things could be optimized for SLC NAND flashes if UBI used
the space available in the OOB area. This is not implemented, but one could
probably do this.

Is UBI tolerant of power failures?

Yes, UBI is designed to be tolerant of power failures and unclean
reboots.

What happens when the PEBs reserved for bad block handling run out?

By default, about 2% of the whole chip size (20/1024 PEB) are reserved for
bad blocks handling.
If the number of blocks that turn bad exceeds that allocation, an error
message will be printed and UBI will switch to read-only mode.

Note: If at attach time, there’s already more bad blocks than reserved PEBs,
UBI will stay in read-write mode. The switching to read-only mode only occurs
when a new bad block appears.

May UBI be used on MLC flash?

Yes, it may, as long as the flash is supported by the MTD layer. UBI does
not use OOB and it requires data to be written sequentially (see
here). UBI guarantees that the difference
between maximum and minimum erase-counters is withing certain threshold,
which is 4096 by default. Since MLC flashes have quite low eraseblock
life-cycle (about 1000-10000, unlike 100000-1000000 for SLC NAND and NOR
flashes), the threshold has to be set to a lower value (e.g., 256). This may be
done via the Linux kernel configuration menu.

Note, unlike UBI, JFFS2 uses random wear-leveling algorithm, which is in
fact not completely random, because JFFS2 makes it more probable to
garbage collect eraseblocks with more dirty data. This means that JFFS2 is not
really appropriate for MLC flashes. However, it is possible to use JFFS2
file-system on top of UBI (see this
section) to improve wear-leveling.

Why does ubiattach on a freshly formatted device fail with «Invalid argument»?

On NAND devices that support sub-page accesses, ubiformat
may choose a different location for the
VID header to the kernel UBI driver.
This can result in the following error when attaching to a UBI device:

$ ubiformat /dev/mtd0
ubiformat: mtd0 (NAND), size 260046848 bytes (248.0 MiB), 131072 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
[...]
$ ubiattach /dev/ubi_ctrl -m 0
ubiattach: error!: cannot attach mtd0
           error 22 (Invalid argument)

and in dmesg you will see:

UBI error: validate_ec_hdr: bad VID header offset 2048, expected 512
UBI error: validate_ec_hdr: bad EC header
UBI error: ubi_io_read_ec_hdr: validation failed for PEB 0

This happens because ubiformat assumes the flash does not
support sub-pages, because the kernel does not expose sub-page information
to user-space (which should be fixed when sysfs support is added to MTD).
However, the kernel UBI driver assumes sub-pages are supported and sub-page
size is 512 bytes in our example. To fix this, you should override the default
sub-page size that ubiformat uses to what the kernel expects using
the -s option of ubiformat. For example, if you see
the error above in dmesg, you can tell ubiformat to assume
512-byte sub-page by executing:

$ ubiformat /dev/mtd0 -s 512

Or you may pass «-O 512» would have the same effect as
«-s 512» — the VID header would be put at offset 512.

Alternately, you may wish to actually attach to the UBI device by forcing
VID header offset to be 2048 bytes. In other words, you may ask UBI to avoid
using sub-pages. This is not recommended since this will require more storage
overhead, but may be useful if your NAND driver incorrectly reports that it can
handle sub-page accesses when it should not. To do this with
ubiattach, use:

$ ubiattach /dev/ubi_ctrl -m 0 -O 2048

or on the kernel command-line, pass:

ubi.mtd=0,2048

What is a sub-page?

Please, refer to this section.

I get «ubi_io_write: error -5 while writing 512 bytes to PEB 5:512»

If you have a 2048 bytes per NAND page device, and have
CONFIG_MTD_NAND_VERIFY_WRITE enabled in your kernel, you will need
to turn it off. The code did not currently (as of 2.6.26) perform verification
of sub-page writes correctly. As UBI is one of the few users of sub-page
writes, not much else seemed to be affected by this bug. In Linux 3.7,
CONFIG_MTD_NAND_VERIFY_WRITE was removed:

commit 657f28f8811c92724db10d18bbbec70d540147d6
Date:   Tue Aug 14 22:38:45 2012 -0400

    mtd: kill MTD_NAND_VERIFY_WRITE

    "Both UBI and JFFS2 are able to read verify what they wrote already.
    There are also MTD tests which do this verification. So I think there
    is no reason to keep this in the NAND layer, let alone wasting RAM in
    the driver to support this feature. Besides, it does not work for sub-pages
    and many drivers have it broken. It hurts more than it provides benefits."

    So kill MTD_NAND_VERIFY_WRITE entirely.

I get «no VID header found at PEB 7923, only 0xFF bytes»

The messages mean that UBI could not find
VID header in the eraseblock, but
the header supposed to be there. This probably means some corruption.

However, if you have UBI «build» debugging messages enabled,
(CONFIG_MTD_UBI_DEBUG_MSG_BLD=y), you may see a lot of these
messages and they are harmless. They are just debugging messages in this
case.

I see this UBI error: «ubi_io_read: error -74 (ECC error) while reading 126976 bytes from PEB 47:4096, read 126976 bytes»

The -74 error code is -EBADMSG and means an ECC
error. In other words, UBI tried to read some data from the flash, but the
flash driver found that there is an uncorrectable ECC error, and returned
-EBADMSG.

There may be many reasons for this. It may be because your NAND driver is
buggy, or you HW is buggy. We recommend you to validate the driver using the
MTD tests.

The other possibility is that you failed to flash your UBI/UBIFS image
properly. Try to erase your flash, then attach it to UBI/UBIFS without writing
any image, and check if you still have these errors.

If you do not have errors when you mount empty flash, it is probably indeed
related to how you flash the UBI/UBIFS images. One typical problem is related
to ECC calculation algorithm — read
here for more information. Make sure
that you use ubiformat, or make sure
either that your flashing program skips 0xFF properly (see
here) or that your UBIFS image
was generated with the «free space fixup» flag set (see
here).

Another possibility is that your flash reports that it supports
sub-pages, but does not actually support
them properly.

How do I force UBI to ignore sub-pages?»

If your NAND flash supports
sub-pages, UBI will use them. But
sometimes you may want to ask UBI to ignore sub-pages, for example if you have
an UBI image which was made for a similar NAND flash, but without sub-pages, or
if you just want to disable sub-pages for testing purposes. You may do this
by forcing UBI to read/write the VID header from/to the beginning of the second
page, instead of the second sub-page (which is the default behavior). And UBI
uses sub-pages only for VID headers, so this is enough.

If you attach MTD devices using the
ubiattach tool — just
use the --vid-hdr-offset option and specify the second page
offset. For example, if you have 2048-byte NAND pages, use
--vid-hdr-offset 2048. All the below examples also assume
2048-byte NAND pages.

If you do not use ubiattach and instead specify the MTD device
to attach using kernel boot parameters (see
here), then you may put VID header offset
after the MTD device name or number. For example:

$ ubi.mtd=rootfs,2048
$ ubi.mtd=3,2048

will attach MTD device named «rootfs» (or MTD device number 3) and force
UBI to read/write VID headers from/to offset 2048, which is the second NAND
page in the eraseblock.

Similarly, if you use module load parameters, try

$ modprobe ubi mtd=rootfs,2048
$ modprobe ubi mtd=3,2048

And of course, if you have an MTD partition which is already formatted
so that sub-pages are used, which means all VID headers sit at offsets 512
(second sub-page of a 2048-byte NAND page), you cannot force UBI to stop using
sub-pages (it will fail). You may do this only if you are attaching an empty
MTD partition, or if the flash is already formatted so that all VID headers
are at offset 2048. This means that if you use or
ubinize, you should
avoid using the -s parameter.

How do I implement UBI flasher?

Please, read here

What does the «ubi_bgt0d» thread do?

The UBI back-ground thread is a per-UBI device thread which has
«ubi_bgtXd» name, where «X» is the UBI device number. For
example, «ubi_bgt0d» is a background thread corresponding to UBI
device 0.

The UBI background thread is doing background physical eraseblock erasure.
This is an important optimization which greatly improves UBI I/O throughput
(applications do not have to wait for erasure completion). For example,
UBI unmap operation schedules physical
eraseblocks for erasure.

The background thread also
tortures faulty physical
eraseblocks.

The UBI background thread also moves data from more worn-out physical
eraseblocks to less worn out, i.e., performs wear-leveling. It also moves data
from physical eraseblocks which have bit-flips. See the
UBI overview section for some more
information.

Note, UBI may work without the background thread, so the thread is just an
optimization, although a very important one.

How do I speed up UBI initialization

As this section explains, UBI
has scalability limitations imposed by its design, so there is no much you
can do about it but without re-designing. Here are some ideas

  • When UBI attaches an MTD device, it reads a lot of data from the
    media. If you manage to improve read speed on the driver level, you
    will also speed up UBI initialization.
  • The MTD layer supplies upper layers (including UBI) with information
    about bad PEBs. It keeps so-called bad block table in RAM, which is
    usually 1 bit per PEB. When the driver initializes, it has to build
    this table by scanning whole flash media, which normally includes
    reading OOB area of 1st NAND page of each PEB. This takes time and may
    be improved by using on-flash BBT (bad block table). In this case the
    bad PEB map is stored on flash and MTD does not have to do any
    scanning. See the NAND_USE_FLASH_BBT constant in the Linux
    source codes. But note, bad PEB scanning is usually minor comparing to
    the UBI scan time, so on-flash BBT is not probably going to give
    much.
  • UBI scan time linearly depends on the number of PEB to read, which
    means that you may speed it up by merging two or more PEB and treating
    them as one composite PEB. Then from UBI POV PEB size will become
    larger, and the amount of PEBs to Scan will become smaller. The best
    way to do this is probably to teach UBI merging PEBs. It does not have
    to merge adjacent PEB. Instead, UBI can store the paired PEB number in
    the EC header. If one of the PEBs in the pair becomes bad, the pair may
    be «re-constructed» by moving the good PEB somewhere else and
    substituting the bad PEB by a good one from the pool of reserved
    PEBs.
  • Design and implement UBI2. You may teach UBI to store erase
    counters and mapping information in a separate internal volume, instead
    of storing it in each PEB. Then you could implement the «anchor» idea
    to quickly find that internal volume (see
    here). This would solve slow UBI
    attach problem, but not linear memory consumption problem. Later we
    could have UBI3 which could solve more issues. This plan was suggested

    here. Indeed, it is easier to solve one problem at a time.

Why a dynamic volume is faster to access than a static volume of the same size?

Static UBI volumes were originally designed to store blobs of data like
configuration files. Static volumes provide CRC-32 protection for the stored
data, and static volumes know how much data they store. E.g., if you have a
static volume /dev/ubi0_1 of 254KiB in size consisting of 2
127KiB LEBs, and you store a 200KiB file there, and you read whole
/dev/ubi0_1 , you’ll get exactly 200KiB. If
/dev/ubi0_1 was a dynamic volume, you’d read 254KiB. So static
volumes make it easier to store blobs of data.

Thus, static volumes are slower to access (comparing to dynamic
volumes) because UBI has to check the data CRC-32 checksum. And note, it is not
a good idea to use static volumes with R/O UBIFS because UBIFS also protects
all the information it stores in the UBI volume with CRC-32 checksums, and
using static volumes with UBIFS would only slow down UBIFS mount speed.

How do I debug UBI?

Use fake MTD device

When debugging UBI one doesn’t have to use a real embedded platform with real
flash. In many cases, it is easier to use a PC with an MTD device emulator and
run UBI on top of this emulated MTD device. In fact, this is how most of the
UBI development was done.

There are 3 MTD device emulators in Linux kernel available:

  • mtdram which simulates NOR flash in RAM;
  • nandsim which simulates NAND flash in RAM;
  • block2mtd which simulates NOR flash on top of a block
    device;

For example, to get a 32MiB fake NOR flash, run

$ modprobe mtdram total_size=32768

or to get a 64MiB fake NAND flash, run

$ modprobe nandsim second_id_byte=0x36

See here for more information about
the NAND simulator.

To ensure that you have fake MTD devices, run «cat /proc/mtd«.
It should print something like

dev:    size   erasesize  name
mtd0: 02000000 00020000 "mtdram test device"
mtd1: 04000000 00004000 "NAND simulator partition"

The fake MTD devices may further be attached to UBI (see
here).

Debugging messages

Sometimes it is necessary to make UBI print about what it is doing. You may
enable various UBI debugging messages using the «dynamic debug» Linux kernel
infrastructure. Please, refer to the corresponding
UBIFS section for more information. Below
is a similar table for UBI.

Message Type Magic string
All messages (very noisy) ‘format «UBI DBG» +pf’
General messages ‘format «UBI DBG gen» +pf’
EBA messages ‘format «UBI DBG eba» +pf’
Wear-levelling messages ‘format «UBI DBG wl» +pf’
Input/output messages ‘format «UBI DBG io» +pf’
Attach messages ‘format «UBI DBG bld» +pf’

Extra self-checks

UBI contains various internal self-check functions which are often
very useful for debugging or testing. Please, refer to the corresponding
UBIFS self-checks
section for more information, because UBI extra self-checks are very
similar, just a bit simpler. Here is a similar table for UBI.

Check type File name
General checks. chk_gen
I/O checks. Does things like verifying that eraseblocks contain
only 0xFF bytes after erasure, verifies that all writes go to an empty
flash area, verifies each writes by reading the data back and comparing
to the original.
chk_io

Power-cut recovery testing

UBI suppors power-cut emulation for testing which emulates power-cuts after
a random number of writes. When a power-cut is emulated, UBI switches to
read-only mode and disallows any further write to the UBI volume, thus
emulating a power cut. The main idea of this mode is to emulate power cuts in
interesting places, e.g. when writing the vid header.

Use the tst_emulate_power_cut debugfs file to set flags for
when to enable power-cut emulation. Possible flags for power-cut testing
can be seen in the table below.

Use the files tst_emulate_power_cut_min and
tst_emulate_power_cut_max to set the minimum and maximum number
of successful writes, respectively, before a power-cut is emulated.

Note that UBIFS has its own power-cut emulation functions. Please, refere
to the corresponding
Power-cut recovery testing
section.

Emulation type Flag value
Allow power-cut to be emulated during EC header write 1
Allow power-cut to be emulated during VID header write 2

How do I send an UBI bug report?

Basically the same way as an
UBIFS bug report

.

I was trying to read firmware from a NAND chip, and extract its program and data for analyse.

From online I learned, you must create an UBI device with your image file write to it, then you can mount it to your system.

Description

First I read a bin file from FLASH chip. binwalk I get this.

$ binwalk -Me Flash_data.bin 

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
771180        0xBC46C         device tree image (dtb)
772444        0xBC95C         device tree image (dtb)
823236        0xC8FC4         CRC32 polynomial table, little endian
2703360       0x294000        uImage header, header size: 64 bytes, header CRC: 0xF092DEF5, created: 2016-10-04 21:32:58, image size: 2773040 bytes, Data Address: 0x80008000, Entry Point: 0x80008000, data CRC: 0x365DF8B1, OS: Linux, CPU: ARM, image type: OS Kernel Image, compression type: none, image name: "Linux-3.2.0"
2703424       0x294040        Linux kernel ARM boot executable zImage (little-endian)
2722452       0x298A94        gzip compressed data, maximum compression, from Unix, last modified: 1970-01-01 00:00:00 (null date)
8110080       0x7BC000        UBI erase count header, version: 1, EC: 0x2, VID header offset: 0x800, data offset: 0x1000

From its output files, I foun this ubi image file.

$ binwalk 7BC000.ubi 

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             UBI erase count header, version: 1, EC: 0x2, VID header offset: 0x800, data offset: 0x1000
$ file 7BC000.ubi 
7BC000.ubi: UBI image, version 1

Some information about NAND chip:

     PageSize : 2048
    SpareSize : 64
PagesPerBlock : 64
  Blocks Size : 128KB + 4KB
  Total Block : 2048
  Device Size : 256MB + 8192KB8192KB
   Bus Width  : 8

Then I tried to mount it, like this:

$ sudo modprobe mtdblock
$ sudo modprobe nandsim first_id_byte=0x20 second_id_byte=0xac third_id_byte=0x00 fourth_id_byte=0x15
$ mtdinfo /dev/mtd0
mtd0
Name:                           NAND simulator partition 0
Type:                           nand
Eraseblock size:                131072 bytes, 128.0 KiB
Amount of eraseblocks:          4096 (536870912 bytes, 512.0 MiB)
Minimum input/output unit size: 2048 bytes
Sub-page size:                  512 bytes
OOB size:                       64 bytes
Character device major/minor:   90:0
Bad blocks are allowed:         true
Device is writable:             true
$ sudo flash_erase /dev/mtd0 0 0
$ cp 7BC000.ubi test_infile   
$ sudo ubiformat /dev/mtd0 -O 2048 -f test_infile
ubiformat: mtd0 (nand), size 536870912 bytes (512.0 MiB), 4096 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 4095 -- 100 % complete  
ubiformat: 4096 eraseblocks are supposedly empty
ubiformat: error!: file "test_infile" (size 268713984 bytes) is not multiple of eraseblock size (131072 bytes)
           error 0 (Success)

The size of «test_file» is 0x10044000, so I just remove the last 0x4000 bytes, and tried to ubiformat again.

$ dd if=test_infile of=test_infile_dd bs=268697600 count=1
$ sudo ubiformat /dev/mtd0 -O 2048 -f test_infile_dd      
ubiformat: mtd0 (nand), size 536870912 bytes (512.0 MiB), 4096 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 4095 -- 100 % complete  
ubiformat: 4096 eraseblocks are supposedly empty
ubiformat: flashing eraseblock 1 --  0 % complete  ubiformat: error!: bad UBI magic 0xffffffff, should be 0x55424923
ubiformat: error!: bad EC header at eraseblock 1 of "test_infile_dd"

I did some research and found out, in this UBI image, there are many blocks, and every block contains data and OOB.

The reason last command fails because it searchs 0x55424923 at wrong position which is 0x20000, because of OOB, 0x55424923 is actually at 0x21000, so I think perhaps delete all of OOB part from «this_file_dd» might work. The bash command and test as follows.

#!/bin/bash                                                                                
# ./dump.sh
# pagesize 0x20000                                                                         
# oob size 0x01000   

# block 1                                                                                  
dd if=infile of=test_infile_dd_nooob bs=$((0x20000)) count=1

declare -i i=1

# block others                                                                             
while ((i<2048))
  do
    dd if=test_infile of=out bs=$((0x21000)) count=1 skip=$i
    dd if=out of=outfile bs=$((0x20000)) count=1
    cat outfile >> test_infile_dd_nooob
    rm out
    rm outfile
    let i++
done

After remove all OOB, compare 2 file, and noticed that OOB has been remove.

$ xxd test_infile_dd | grep "5542 4923"                                               ⏎
00000000: 5542 4923 0100 0000 0000 0000 0000 0002  UBI#............
00021000: 5542 4923 0100 0000 0000 0000 0000 0002  UBI#............
00042000: 5542 4923 0100 0000 0000 0000 0000 0001  UBI#............
00063000: 5542 4923 0100 0000 0000 0000 0000 0001  UBI#............
00084000: 5542 4923 0100 0000 0000 0000 0000 0001  UBI#............
$ xxd test_infile_dd_nooob | grep "5542 4923" 
00000000: 5542 4923 0100 0000 0000 0000 0000 0002  UBI#............
00020000: 5542 4923 0100 0000 0000 0000 0000 0002  UBI#............
00040000: 5542 4923 0100 0000 0000 0000 0000 0001  UBI#............
00060000: 5542 4923 0100 0000 0000 0000 0000 0001  UBI#............
00080000: 5542 4923 0100 0000 0000 0000 0000 0001  UBI#............

Then ubiformat again, another error about bad UBI magic.

$ sudo ubiformat /dev/mtd0 -O 2048 -f test_infile_dd_nooob 
ubiformat: mtd0 (nand), size 536870912 bytes (512.0 MiB), 4096 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 4095 -- 100 % complete  
ubiformat: 1 eraseblocks have valid erase counter, mean value is 0
ubiformat: 4095 eraseblocks are supposedly empty
ubiformat: warning!: only 1 of 4096 eraseblocks have valid erase counter
ubiformat: erase counter 0 will be used for all eraseblocks
ubiformat: note, arbitrary erase counter value may be specified using -e option
ubiformat: continue? (y/N) y
ubiformat: use erase counter 0 for all eraseblocks
ubiformat: flashing eraseblock 1074 -- 54 % complete  ubiformat: error!: bad UBI magic 00000000, should be 0x55424923
ubiformat: error!: bad EC header at eraseblock 1074 of "test_infile_dd_nooob"

Used ghex to fix wrong EC header in EB-1074, and ubiformat again, same block’s CRC is not right.

sudo ubiformat /dev/mtd0 -O 2048 -f test_infile_dd_nooob -e 10
ubiformat: mtd0 (nand), size 536870912 bytes (512.0 MiB), 4096 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 4095 -- 100 % complete  
ubiformat: 1074 eraseblocks have valid erase counter, mean value is 10
ubiformat: 3022 eraseblocks are supposedly empty
ubiformat: use erase counter 10 for all eraseblocks
ubiformat: flashing eraseblock 1074 -- 54 % complete  ubiformat: error!: bad CRC 0x7d72af58, should be 00000000

ubiformat: error!: bad EC header at eraseblock 1074 of "test_infile_dd_nooob"

Fix CRC and ubiformat again, enable ubi and ubiattach to mtd0, but another error occurs.

sudo ubiformat /dev/mtd0 -O 2048 -f test_infile_dd_nooob -e 10                         ⏎
ubiformat: mtd0 (nand), size 536870912 bytes (512.0 MiB), 4096 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 4095 -- 100 % complete  
ubiformat: 1074 eraseblocks have valid erase counter, mean value is 10
ubiformat: 3022 eraseblocks are supposedly empty
ubiformat: use erase counter 10 for all eraseblocks
ubiformat: flashing eraseblock 1987 -- 100 % complete  
ubiformat: formatting eraseblock 4095 -- 100 % complete 
$ sudo modprobe ubi
$ sudo modprobe ubi mtd=0
$ sudo ubiattach -m 0 -O 2048   
ubiattach: error!: cannot attach mtd0
           error 22 (Invalid argument)

Do dmesg I found this message.

$ sudo dmesg
[ 6974.021149] 0001efa0: 00 00 00 00 00 00 00 00 10 0a 00 00 01 00 00 00 00 0a d9 d5 05 f9 20 a1 63 d7 00 00 00 02 fb d2  ...................... .c.......
[ 6974.021150] 0001efc0: ce 15 00 00 00 0d 00 00 02 00 00 00 04 00 20 00 c7 00 00 00 0d 0d 0d 00 00 00 0b 01 b8 00 03 db  .............. .................
[ 6974.021151] 0001efe0: 03 9d 03 5e 03 20 02 fd 02 d8 02 93 02 4e 02 1b 01 f6 01 b8 20 00 7a 14 08 00 32 3b 81 0e 04 17  ...^. .......N...... .z...2;....
[ 6974.023703] ubi0 error: validate_ec_hdr [ubi]: node with incompatible UBI version found: this UBI version is 1, image version is 0                                                 
[ 6974.023707] ubi0 error: validate_ec_hdr [ubi]: bad EC header
[ 6974.023707] Erase counter header dump:
[ 6974.023708]  magic          0x55424923
[ 6974.023708]  version        0
[ 6974.023709]  ec             10
[ 6974.023709]  vid_hdr_offset 2048
[ 6974.023710]  data_offset    4096
[ 6974.023710]  image_seq      144665903
[ 6974.023711]  hdr_crc        0xb574c34c
[ 6974.023711] erase counter header hexdump:
[ 6974.023713] 00000000: 55 42 49 23 00 00 00 00 00 00 00 00 00 00 00 0a 00 00 08 00 00 00 10 00 08 9f 6d 2f 00 00 00 00  UBI#......................m/....
[ 6974.023713] 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b5 74 c3 4c  .............................t.L
[ 6974.023715] CPU: 4 PID: 14955 Comm: ubiattach Tainted: G        W   E     5.7.0-kali1-amd64 #1 Debian 5.7.6-1kali2
[ 6974.023716] Hardware name: Dell Inc. Inspiron 7472/0GHVRJ, BIOS 1.1.6 06/14/2018
[ 6974.023716] Call Trace:
[ 6974.023722]  dump_stack+0x66/0x90
[ 6974.023725]  validate_ec_hdr+0x8a/0xe0 [ubi]
[ 6974.023729]  ubi_io_read_ec_hdr+0x1e9/0x280 [ubi]
[ 6974.023732]  ubi_attach+0x1d3/0x14c0 [ubi]
[ 6974.023736]  ubi_attach_mtd_dev+0x5b3/0xd30 [ubi]
[ 6974.023741]  ? __get_mtd_device+0x2c/0xa0 [mtd]
[ 6974.023743]  ? _cond_resched+0x15/0x30
[ 6974.023746]  ctrl_cdev_ioctl+0xda/0x1c0 [ubi]
[ 6974.023748]  ksys_ioctl+0x87/0xc0
[ 6974.023749]  __x64_sys_ioctl+0x16/0x20
[ 6974.023751]  do_syscall_64+0x52/0x180
[ 6974.023753]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 6974.023754] RIP: 0033:0x7f3f55902c87
[ 6974.023756] Code: 00 00 00 48 8b 05 09 92 0c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d d9 91 0c 00 f7 d8 64 89 01 48
[ 6974.023756] RSP: 002b:00007ffd4fec6f88 EFLAGS: 00000206 ORIG_RAX: 0000000000000010
[ 6974.023757] RAX: ffffffffffffffda RBX: 00007ffd4fec7020 RCX: 00007f3f55902c87
[ 6974.023758] RDX: 00007ffd4fec6fb0 RSI: 0000000040186f40 RDI: 0000000000000003
[ 6974.023758] RBP: 0000000000000003 R08: 0000000000000001 R09: 0000000000000000
[ 6974.023759] R10: fffffffffffff48e R11: 0000000000000206 R12: 000055c2a393c052
[ 6974.023759] R13: 00007ffd4fec6fb0 R14: 0000000000000000 R15: 0000000000000000
[ 6974.023763] ubi0 error: ubi_io_read_ec_hdr [ubi]: validation failed for PEB 1074
[ 6974.061006] ubi0 error: ubi_attach_mtd_dev [ubi]: failed to attach mtd0, error -22

But I don’t know how to solve this, so I just remove block 1074 from file.

$ dd if=test_infile_dd_nooob of=test_infile_dd_nooob_no1074_1 bs=131072 count=1074
$ dd if=test_infile_dd_nooob of=test_infile_dd_nooob_no1074_2 bs=131072 skip=1075
$ cat test_infile_dd_nooob_no1074_1 test_infile_dd_nooob_no1074_2 > test_infile_dd_nooob_no1074

Then ubiformat and attach again, but there was another error.

$ sudo ubiformat /dev/mtd0 -O 2048 -f test_infile_dd_nooob_no1074 -e 10
ubiformat: mtd0 (nand), size 536870912 bytes (512.0 MiB), 4096 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 4095 -- 100 % complete  
ubiformat: 4096 eraseblocks have valid erase counter, mean value is 10
ubiformat: use erase counter 10 for all eraseblocks
ubiformat: flashing eraseblock 1986 -- 100 % complete  
ubiformat: formatting eraseblock 4095 -- 100 % complete 
$ sudo ubiattach -m 0 -O 2048                                                            ⏎
ubiattach: error!: cannot attach mtd0
           error 22 (Invalid argument)

Check dmesg and found this, this is where I don’t know how to do, I don’t know how I get so many bad blocks.

$ sudo dmesg
ubi0: scanning is finished
[ 7392.005554] ubi0 error: ubi_attach [ubi]: 1205 PEBs are corrupted and preserved
[ 7392.005554] Corrupted PEBs are: 1805 1802 1793 1678 1674 1670 1666 1662 1654 1653 1652 1649 1640 1639 1626 1625 1621 1605 1587 1586 1581 1563 1553 1540 1534 1533 1532 1531 1530 1529 1528 1527 1526 1525 1524 1523 1522 1521 1520 1519 1518 1517 1516 1515 1514 1512 1511 1510 1509 1508 1507 1506 1505 1504 1503 1502 1501 1500 1499 1498 1496 1495 1494 1493 1492 1491 1490 1489 1488 1487 1486 1485 1484 1483 1482 1481 1471 1449 1448 1447 1446 1445 1444 1441 1439 1438 1437 1436 1435 1434 1433 1432 1431 1430 1429 1428 1425 1424 1423 1422 1421 1420 1419 1418 1417 1416 1415 1414 1413 1412 1411 1410 1409 1408 1407 1406 1405 1404 1403 1402 1401 1400 1399 1398 1397 1396 1395 1394 1393 1391 1390 1389 1388 1387 1386 1385 1384 1383 1382 1381 1380 1379 1378 1377 1376 1375 1374 1373 1372 1371 1370 1369 1368 1367 1366 1365 1364 1363 1362 1361 1360 1359 1358 1357 1356 1355 1354 1353 1352 1351 1350 1349 1348 1347 1346 1345 1344 1343 1342 1341 1340 1339 1338 1337 1335 1334 1333 1332 1331 1330 1329 1328 1327 1326                                                                                        
[ 7392.005578]  1325 1324 1323 1322 1321 1294 1275 1274 1273 1264 1230 1223 1221 1219 1214 1211 1210 1207 1204 1203 1202 1201 1200 1199 1198 1197 1196 1195 1194 1193 1192 1191 1190 1189 1188 1187 1186 1185 1184 1183 1182 1181 1180 1179 1178 1177 1176 1175 1174 1173 1172 1165 1164 1163 1157 1147 1144 1143 1142 1141 1140 1139 1138 1137 1136 1134 1133 1132 1131 1130 1129 1128 1127 1126 1125 1124 1123 1122 1121 1120 1119 1118 1117 1116 1115 1114 1112 1111 1110 1109 1108 1106 1105 1098 1085 1053 1052 1044 1016 1003 1002 977 973 972 963 939 938 937 936 935 934 933 932 931 930 929 928 927 926 925 924 923 922 921 920 919 918 917 916 915 914 913 912 911 910 909 908 907 906 905 904 903 902 900 899 898 897 896 895 894 893 892 891 890 889 888 887 886 885 884 883 882 881 880 879 878 877 876 875 874 873 872 871 870 869 868 867 866 865 864 863 862 861 860 859 858 857 856 855 854 853 852 851 850 849 848 847 846 845 844 841 840 839 838 837 836 835 834 833 832 831 830 829 828 827 826 825 824 823 822 821 820
[ 7392.005606]  819 818 817 816 815 814 813 812 811 810 809 808 807 806 805 804 803 802 801 800 799 798 797 796 795 794 793 792 791 790 789 788 787 785 784 782 781 780 779 778 777 776 775 774 773 772 771 770 769 768 767 766 765 764 763 762 761 760 759 758 757 756 755 754 753 752 751 750 749 748 747 746 745 744 743 742 741 740 739 738 737 736 735 734 733 732 731 730 729 727 726 725 724 723 722 721 720 719 718 716 715 714 713 712 711 710 709 708 707 706 705 704 703 702 701 700 699 698 697 696 695 694 693 692 691 690 689 688 687 686 685 684 683 682 681 680 679 678 677 676 675 674 673 672 671 670 668 667 666 665 664 663 662 661 660 659 657 656 655 654 653 652 651 650 649 648 647 646 645 644 643 642 641 640 639 638 637 636 635 634 633 632 631 630 629 628 627 626 625 624 623 622 621 620 619 618 617 616 615 614 613 611 610 609 608 607 606 605 604 602 601 600 599 598 597 596 595 594 593 592 591 589 588 587 586 585 584 583 582 581 580 579 578 577 576 575 574 573 572 571 570 569 568 567 566 565 564 563
[ 7392.005634]  562 561 560 559 558 557 556 554 553 552 551 550 549 548 547 546 545 544 543 541 540 539 538 537 536 535 534 533 532 531 530 529 528 527 526 525 524 523 522 521 520 519 518 517 516 515 514 513 512 511 510 509 508 507 506 505 504 503 502 501 500 498 497 496 495 494 493 492 491 489 488 487 486 485 484 483 482 481 480 479 478 477 476 475 474 473 472 471 470 469 468 467 466 465 464 463 461 460 459 458 457 456 455 454 453 452 451 450 449 448 447 446 445 444 443 441 440 438 437 436 435 434 433 432 431 430 429 428 427 426 425 424 423 422 421 420 419 418 417 416 415 414 413 412 411 410 409 408 407 406 405 404 403 402 401 400 399 398 397 396 395 394 393 392 391 390 389 388 387 386 384 383 382 381 380 379 378 377 376 375 374 373 372 371 370 369 368 367 366 365 364 363 362 361 360 359 358 357 356 355 354 353 352 351 350 349 348 347 346 345 344 343 342 341 340 339 338 337 336 335 333 332 331 330 329 328 327 326 325 324 323 322 321 320 319 318 317 316 315 314 313 312 311 310 309 308 307 306
[ 7392.005661]  305 304 303 302 301 300 295 294 293 292 290 289 288 287 286 285 284 283 282 281 280 279 278 277 276 275 274 273 271 270 269 268 267 266 265 264 263 262 261 260 259 258 257 256 255 254 253 252 251 250 249 248 247 246 245 244 243 242 241 240 239 238 237 236 235 233 231 230 229 228 227 226 225 224 223 222 221 220 219 218 217 216 215 214 213 212 211 210 209 208 207 206 205 204 203 202 201 200 199 198 197 196 195 194 193 192 191 190 189 188 187 186 185 184 183 182 181 180 179 177 176 175 174 172 171 170 169 168 167 166 165 164 163 162 161 160 159 158 157 156 155 154 153 152 151 150 149 148 147 146 145 144 143 142 141 140 139 138 137 136 135 134 133 132 131 130 129 128 127 126 125 124 123 122 121 120 118 117 116 115 114 113 112 111 110 109 108 107 106 105 104 103 102 101 100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30
[ 7392.005690]  29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2
[ 7392.005698] ubi0 error: ubi_attach.cold [ubi]: too many corrupted PEBs, refusing
[ 7392.028819] ubi0 error: ubi_attach_mtd_dev [ubi]: failed to attach mtd0, error -22
[ 7393.182325] systemd-journald[331]: /dev/kmsg buffer overrun, some messages lost.

I read the official documents, it says only in 2 senerios a block will be marked as bad. One is
when write opertion to eraseblock fails, UBI will move data from bad EB to a good EB, and do some tests so it can confirm whether bad EB is really bad; or when erase opertion have EIO error, then EB will be marked as bad block immediately. I am not sure which reason caused so much bad block.

My questions

  • In the progess, is my command doing wrong? If not, how to repair this UBI image so I can read its programs and data?
  • Is there other ways that can get programs and data from this UBI image file?

Tools and versions

  • Kali 2020.3
  • mtd-utils 2.1.1


0

1

Ситуация такая, вот собрал мне buildroot rootfs.ubifs. Надо его залить на плату. Сперва делаем ubi-образ с помощью ubinize

открываем гугл и берем пример:

конфиг

[ubifs]
mode=ubi
image=rootfs.ubifs
vol_id=0
vol_size=200MiB
vol_type=dynamic
vol_name=rootfs
vol_flags=autoresize

/usr/sbin/ubinize -o ubi.img -m 2048 -p 128KiB -s 512 ubinize.cfg

и получаем ошибку

[    9.550000] UBI: attaching mtd4 to ubi0
[    9.560000] UBI error: validate_ec_hdr: bad VID header offset 512, expected 2048
[    9.570000] UBI error: validate_ec_hdr: bad EC header
[    9.580000] Erase counter header dump:
[    9.590000]  magic          0x55424923
[    9.600000]  version        1
[    9.610000]  ec             0
[    9.620000]  vid_hdr_offset 512
[    9.630000]  data_offset    2048
[    9.640000]  image_seq      745861233
[    9.650000]  hdr_crc        0xfb58fdc8
[    9.660000] erase counter header hexdump:
[    9.670000] CPU: 0 PID: 1 Comm: swapper Not tainted 3.10.28-modules #6
[    9.680000] [<c0012498>] (unwind_backtrace+0x0/0x11c) from [<c0010ed0>] (show_stack+0x10/0x14)
[    9.690000] [<c0010ed0>] (show_stack+0x10/0x14) from [<c01cf7c4>] (validate_ec_hdr+0x124/0x14c)
[    9.700000] [<c01cf7c4>] (validate_ec_hdr+0x124/0x14c) from [<c01d0470>] (ubi_io_read_ec_hdr+0x284/0x300)
[    9.710000] [<c01d0470>] (ubi_io_read_ec_hdr+0x284/0x300) from [<c01d546c>] (ubi_attach+0x1a0/0x136c)
[    9.720000] [<c01d546c>] (ubi_attach+0x1a0/0x136c) from [<c01c9fe4>] (ubi_attach_mtd_dev+0x864/0xe8c)
[    9.730000] [<c01c9fe4>] (ubi_attach_mtd_dev+0x864/0xe8c) from [<c046fe00>] (ubi_init+0x1d0/0x2c8)
[    9.740000] [<c046fe00>] (ubi_init+0x1d0/0x2c8) from [<c0008678>] (do_one_initcall+0xb8/0x164)
[    9.750000] [<c0008678>] (do_one_initcall+0xb8/0x164) from [<c0460ac0>] (kernel_init_freeable+0x128/0x1ec)
[    9.760000] [<c0460ac0>] (kernel_init_freeable+0x128/0x1ec) from [<c02c86b4>] (kernel_init+0x8/0xe4)
[    9.770000] [<c02c86b4>] (kernel_init+0x8/0xe4) from [<c000dff8>] (ret_from_fork+0x14/0x3c)
[    9.780000] UBI error: ubi_io_read_ec_hdr: validation failed for PEB 0
[    9.790000] UBI error: ubi_attach_mtd_dev: failed to attach mtd4, error -22
[    9.800000] UBI error: ubi_init: cannot attach mtd4

После чего делаю

/usr/sbin/ubinize -o ubi.img -m 2048 -p 128KiB -s 2048 ubinize.cfg

и получаю ошибку

[   19.640000] UBI: scanning is finished
[   19.730000] UBI: volume 0 ("rootfs") re-sized from 1652 to 7992 LEBs
[   19.740000] UBI: attached mtd4 (name "rootfs", size 1019 MiB) to ubi0
[   19.750000] UBI: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
[   19.760000] UBI: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
[   19.770000] UBI: VID header offset: 2048 (aligned 2048), data offset: 4096
[   19.780000] UBI: good PEBs: 8145, bad PEBs: 11, corrupted PEBs: 0
[   19.790000] UBI: user volume: 1, internal volumes: 1, max. volumes count: 128
[   19.800000] UBI: max/mean erase counter: 1/0, WL threshold: 4096, image sequence number: 1712739736
[   19.810000] UBI: available PEBs: 0, total reserved PEBs: 8145, PEBs reserved for bad PEB handling: 149
[   19.820000] UBI: background thread "ubi_bgt0d" started, PID 565
[   19.830000] UBIFS error (pid 1): validate_sb: LEB size mismatch: 129024 in superblock, 126976 real
[   19.840000] UBIFS error (pid 1): validate_sb: bad superblock, error 1
[   19.850000]  magic          0x6101831
[   19.860000]  crc            0xd3702c3
[   19.870000]  node_type      6 (superblock node)
[   19.880000]  group_type     0 (no node group)
[   19.890000]  sqnum          16002
[   19.900000]  len            4096
[   19.910000]  key_hash       0 (R5)
[   19.920000]  key_fmt        0 (simple)
[   19.930000]  flags          0x0
[   19.940000]    big_lpt      0
[   19.950000]    space_fixup  0
[   19.960000]  min_io_size    2048
[   19.960000]  leb_size       129024
[   19.970000]  leb_cnt        183
[   19.970000]  max_leb_cnt    2048
[   19.980000]  max_bud_bytes  8388608
[   19.990000]  log_lebs       5
[   20.000000]  lpt_lebs       2
[   20.010000]  orph_lebs      1
[   20.020000]  jhead_cnt      1
[   20.030000]  fanout         8
[   20.040000]  lsave_cnt      256
[   20.050000]  default_compr  1
[   20.060000]  rp_size        0
[   20.070000]  rp_uid         0
[   20.080000]  rp_gid         0
[   20.080000]  fmt_version    4
[   20.090000]  time_gran      1000000000
[   20.100000]  UUID           60770486-8BBA-43DB-A8B0-6CA873730EF1

ЧЯДНТ?

I have a custom iMX 6UL board with Barebox (partially) functional. I have on board a Semper s25hs512t Flash being detected (after adding the necessary device id indrivers/mtd/spi-nor/spi-nor.c)

The problem — My board does not have ethernet or removable SD. I need to burn the boot loader/ flash on the s25hs512. I need to format the flash accordingly and copy the files on it.

my dtsi has

&qspi {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_qspi>;
        status = "okay";

        flash0: [email protected] {
                #address-cells = <1>;
                #size-cells = <1>;
                compatible = "spansion,s25hs512t", "jedec,spi-nor";
                spi-max-frequency = <40000000>;
                spi-rx-bus-width = <4>;
                spi-tx-bus-width = <4>;
                reg = <0>;
                spi-mode = <0>;
                m25p,fast-read;
                status = "okay";

                [email protected] {
                        label = "barebox";
                        reg = <0x00000000 0x00100000>;
                };
                [email protected] {
                        label = "barebox-env";
                        reg = <0x00100000 0x00040000>;
                };
                [email protected] {
                        label = "barebox-of";
                        reg = <0x00140000 0x00040000>;
                };
                [email protected] {
                        label = "kernel";
                        reg = <0x00180000 0x00800000>;
                };
                [email protected] {
                        label = "root";
                        reg = <0x00980000 0x03640000>;
                };

        };
};

on boot barebox detects the flash

Board: Freescale i.MX6 UltraLite Caisteal Board
detected i.MX6 UltraLite revision 1.0
i.MX6 UltraLite unique ID: 241e09d4e317402a
m25p80 [email protected]: s25hs512t (65536 Kbytes).  <=====
imx-esdhc [email protected]: registered as mmc1
rng_self_test: RNG software self-test passed
caam [email protected]: Instantiated RNG4 SH0
caam [email protected]: Instantiated RNG4 SH1
malloc space: 0x8eefcf80 -> 0x9ddf9eff (size 239 MiB)
barebox-environment chosen:environment.of: probe failed: No such file or directory

devinfo shows

         `-- [email protected]
            `-- [email protected]
               `-- m25p0
                  `-- 0x00000000-0x03ffffff (    64 MiB): /dev/m25p0
                  `-- m25p0.barebox
                     `-- 0x00000000-0x000fffff (     1 MiB): /dev/m25p0.barebox
                  `-- m25p0.barebox-env
                     `-- 0x00000000-0x0003ffff (   256 KiB): /dev/m25p0.barebox-env
                  `-- m25p0.barebox-of
                     `-- 0x00000000-0x0003ffff (   256 KiB): /dev/m25p0.barebox-of
                  `-- m25p0.kernel
                     `-- 0x00000000-0x007fffff (     8 MiB): /dev/m25p0.kernel
                  `-- m25p0.root
                     `-- 0x00000000-0x0363ffff (  54.3 MiB): /dev/m25p0.root

but when I run ubiformat, I am oddly getting this

[email protected] i.MX6 UltraLite Caisteal Board:/ ubiformat /dev/m25p0.barebox -y
ubiformat: m25p0.barebox (nor), size 1048576 bytes (1 MiB), 4 eraseblocks of 262144 bytes (256 KiB), min. I/O size 1 bytes
libscan: scanning eraseblock 3 -- 100 % complete  
ubiformat: 1 eraseblocks are supposedly empty
ubiformat: warning!: 3 of 4 eraseblocks contain non-ubifs data
ubiformat: warning!: only 0 of 4 eraseblocks have valid erase counter
ubiformat: erase counter 0 will be used for all eraseblocks
ubiformat: note, arbitrary erase counter value may be specified using -e option
ubiformat: use erase counter 0 for all eraseblocks
ubiformat: formatting eraseblock 3 -- 100 % complete  
ERROR: m25p80 [email protected]: flash operation timed out
ERROR: m25p0.barebox: error -110 while writing 262144 bytes to PEB 0:0, written 0 bytes
libubigen: error!: cannot write 262144 bytes
ubiformat: error!: cannot write layout volume
ubiformat: Operation not permitted

Any way ahead from this?

PS : Update
Thanks for help from @TrentP — I am focusing only on formatting the larger partitions so that I can write the kernel and root partition. but I have not been able to mount the ubi partition. I get the following issue (Readonly filesystem)

[email protected] i.MX6 UltraLite Caisteal Board:/ erase /dev/m25p0.kernel 

[email protected] i.MX6 UltraLite Caisteal Board:/ ubiattach /dev/m25p0.kernel 
NOTICE: ubi0: scanning is finished
NOTICE: ubi0: empty MTD device detected
NOTICE: ubi0: registering /dev/m25p0.kernel.ubi
NOTICE: ubi0: attached mtd0 (name "m25p0.kernel", size 8 MiB) to ubi0
NOTICE: ubi0: PEB size: 262144 bytes (256 KiB), LEB size: 262016 bytes
NOTICE: ubi0: min./max. I/O unit sizes: 1/256, sub-page size 1
NOTICE: ubi0: VID header offset: 64 (aligned 64), data offset: 128
NOTICE: ubi0: good PEBs: 32, bad PEBs: 0, corrupted PEBs: 0
NOTICE: ubi0: user volume: 0, internal volumes: 1, max. volumes count: 128
NOTICE: ubi0: max/mean erase counter: 1/0, WL threshold: 65536, image sequence number: 1700878141
NOTICE: ubi0: available PEBs: 28, total reserved PEBs: 4, PEBs reserved for bad PEB handling: 0

[email protected] i.MX6 UltraLite Caisteal Board:/ ubimkvol /dev/m25p0.kernel.ubi kernel 0
NOTICE: ubi0: registering kernel as /dev/m25p0.kernel.ubi.kernel


[email protected] i.MX6 UltraLite Caisteal Board:/ mount -t ubifs /dev/m25p0.kernel.ubi.kernel  /mnt/kernel/
ERROR: UBIFS error (ubi0:0): 9de5a2d5: can't format empty UBI volume: read-only mount
ERROR: ubifs ubifs0: probe failed: Read-only file system
mount: Invalid argument

If I use ubiformat I get this

[email protected] i.MX6 UltraLite Caisteal Board:/ ubiformat /dev/m25p0.kernel -y
ubiformat: m25p0.kernel (nor), size 8388608 bytes (8 MiB), 32 eraseblocks of 262144 bytes (256 KiB), min. I/O size 1 bytes
libscan: scanning eraseblock 31 -- 100 % complete  
ubiformat: warning!: 32 of 32 eraseblocks contain non-ubifs data
ubiformat: warning!: only 0 of 32 eraseblocks have valid erase counter
ubiformat: erase counter 0 will be used for all eraseblocks
ubiformat: note, arbitrary erase counter value may be specified using -e option
ubiformat: use erase counter 0 for all eraseblocks
ubiformat: formatting eraseblock 31 -- 100 % complete  
[email protected] i.MX6 UltraLite Caisteal Board:/ ubiattach /dev/m25p0.kernel 
NOTICE: ubi0: scanning is finished
ERROR: ubi0 error: ubi_read_volume_table: the layout volume was not found
ERROR: ubi0 error: ubi_attach_mtd_dev: failed to attach mtd0, error -22
failed to attach: Invalid argument

devinfo

Parent: m25p0.kernel
Parameters:
  available_pebs: 0 (type: uint32)
  bad_peb_count: 0 (type: uint32)
  good_peb_count: 32 (type: uint32)
  leb_size: 262016 (type: uint32)
  max_erase_counter: 2 (type: uint32)
  mean_erase_counter: 0 (type: uint32)
  min_io_size: 1 (type: uint32)
  peb_size: 262144 (type: uint32)
  reserved_pebs: 32 (type: uint32) <=== why all PEBs are reserved?
  sub_page_size: 1 (type: uint32)
  vid_header_offset: 64 (type: uint32)

Any suggestions on what I am doing wrong. I know its something ridiculously simple. just unknown to me

On an mtd partition with 39 erase blocks (= 4.9 MiB), I tried to format a ubifs. The resulting file system has free space of 2.2M uncompressed data when reserved blocks are reduced to the minimum possible 1 block (I know that’s not good). This means that only 45% of the space is usable for data.

The same area formatted with jffs2 allows me to write 4.6 MB of data which is 93% or more than double the size in a ubifs setup.

The problem is that I can’t use jffs2 because my OOB size of 64 bytes doesn’t provide enough space for both BCH8 and JFFS2 OBB data, as described in a TI warning.

I already read the FAQ chapters
Why does my UBIFS volume have significantly lower capacity than my equivalent JFFS2 volume?
and
Why does df report too little free space?
but I still can’t believe that the overhead is so big.

Is there anything I can do to increase the free space of my (writable) ubifs volume?

Do I save space when I merge ubi0 and ubi1? (more than the reserved blocks?)

This is my setup:

$ mtdinfo -a

mtd10
Name:                           NAND.userdata
Type:                           nand
Eraseblock size:                131072 bytes, 128.0 KiB
Amount of eraseblocks:          39 (5111808 bytes, 4.9 MiB)
Minimum input/output unit size: 2048 bytes
Sub-page size:                  512 bytes
OOB size:                       64 bytes
Character device major/minor:   90:20
Bad blocks are allowed:         true
Device is writable:             true

$ ubinfo -a

ubi1
Volumes count:                           1
Logical eraseblock size:                 129024 bytes, 126.0 KiB
Total amount of logical eraseblocks:     39 (5031936 bytes, 4.8 MiB)
Amount of available logical eraseblocks: 0 (0 bytes)
Maximum count of volumes                 128
Count of bad physical eraseblocks:       0
Count of reserved physical eraseblocks:  1
Current maximum erase counter value:     2
Minimum input/output unit size:          2048 bytes
Character device major/minor:            249:0
Present volumes:                         0

Volume ID:   0 (on ubi1)
Type:        dynamic
Alignment:   1
Size:        34 LEBs (4386816 bytes, 4.2 MiB)
State:       OK
Name:        userdata
Character device major/minor: 249:1

dmesg:
[    1.340937] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xf1
[    1.347903] nand: Micron MT29F1G08ABADAH4
[    1.352108] nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
[    1.359782] nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme

uname -a:
Linux 4.1.18-g543c284-dirty #3 PREEMPT Mon Jun 27 17:02:46 CEST 2016 armv7l GNU/Linux

Create & test ubifs:

# flash_erase /dev/mtd10 0 0
Erasing 128 Kibyte @ 4c0000 -- 100 % complete 
# ubiformat /dev/mtd10 -s 512 -O 512
ubiformat: mtd10 (nand), size 5111808 bytes (4.9 MiB), 39 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 38 -- 100 % complete  
ubiformat: 39 eraseblocks are supposedly empty
ubiformat: formatting eraseblock 38 -- 100 % complete  
# ubiattach -d1 -m10 -b 1
UBI device number 1, total 39 LEBs (5031936 bytes, 4.8 MiB), available 34 LEBs (4386816 bytes, 4.2 MiB), LEB size 129024 bytes (126.0 KiB)
# ubimkvol /dev/ubi1 -N userdata -m
Set volume size to 4386816
Volume ID 0, size 34 LEBs (4386816 bytes, 4.2 MiB), LEB size 129024 bytes (126.0 KiB), dynamic, name "userdata", alignment 1
# mount -t ubifs ubi1:userdata /tmp/1
# df -h /tmp/1
Filesystem      Size  Used Avail Use% Mounted on
-               2.1M   20K  2.0M   2% /tmp/1
# dd if=/dev/urandom of=/tmp/1/bigfile bs=4096
dd: error writing '/tmp/1/bigfile': No space left on device
550+0 records in
549+0 records out
2248704 bytes (2.2 MB) copied, 1.66865 s, 1.3 MB/s
# ls -l /tmp/1/bigfile
-rw-r--r-- 1 root root 2248704 Jan  1 00:07 /tmp/1/bigfile
# sync
# df -h /tmp/1
Filesystem      Size  Used Avail Use% Mounted on
-               2.1M  2.1M     0 100% /tmp/1

Create & test jffs2:

# mkdir /tmp/empty.d
# mkfs.jffs2 -s 2048 -r /tmp/empty.d -o /tmp/empty.jffs2
# flash_erase /dev/mtd10 0 0
Erasing 128 Kibyte @ 4c0000 -- 100 % complete 
# nandwrite /dev/mtd10 /tmp/empty.jffs2
Writing data to block 0 at offset 0x0
# mount -t jffs2 /dev/mtdblock10 /tmp/1
# df -h /tmp/1
Filesystem      Size  Used Avail Use% Mounted on
-               4.9M  384K  4.5M   8% /tmp/1
# dd if=/dev/urandom of=/tmp/1/bigfile bs=4096
dd: error writing '/tmp/1/bigfile': No space left on device
1129+0 records in
1128+0 records out
4620288 bytes (4.6 MB) copied, 4.54715 s, 1.0 MB/s
# ls -l /tmp/1/bigfile
-rw-r--r-- 1 root root 4620288 Jan  1 00:20 /tmp/1/bigfile
# sync
# df -h /tmp/1
Filesystem      Size  Used Avail Use% Mounted on
-               4.9M  4.9M     0 100% /tmp/1

Update:

I did some mass measurements which resulted in the following chart:
enter image description here

So I can formulate my question more specific now:

The «formula» seems to be usable_size_mb = (raw_size_mb - 2.3831) * 0.89423077

In different words: no matter what size my mtd has, there are always 2.38 MB lost, no matter how big our volume is. This is the size of 19 erase blocks. The rest is a filesystem overhead of 10.6% of user data which is a high value but not unexpected for ubifs.

Btw. when doing the tests I got kernel warnings that at least 17 erase blocks are needed (=2.176 MB). But the smallest mtd which successfully ran through the test had 22 blocks (2.816 MB).

Flash super heroEmbedded-oriented filesystems are a scattered world. Flash-optimized filesystems are less so. JFFS2 has been widely used but has several performance issues (mount time, especially, though CONFIG_SUMMARY and sumtool fixes that since 2.6.15). LogFS doesn’t seem to be actively maintained. The most active and promising flash filesystem is UBIFS. It runs on top of UBI (“Unsorted Block Images”), an abstraction layer for MTD devices.

Why flash-oriented filesystems ?

MTDs (Memory Technology Devices) are very different from block devices: instead of a sequence of writable sectors, they contain an array of writable pages, organized in so-called “erase blocks”.

To write on a page that already has data on it, you first have to erase this data. However, it is only possible to erase whole eraseblocks. Only then, you can write your new data (including what you didn’t change). Erasing causes the memory cells to wear out. At some point, they won’t be usable anymore and have to be skipped.

Because it is memory-based, random access is theoretically as fast as sequential access. So, you don’t need to keep the fragments of your files together. It makes it possible to do wear-leveling and thus, “increase” the lifetime of the chip.

A simple way of doing wear-leveling is to keep track of the number of times a block has been erased and use the block that has been the least erased when updating data.

All these constraints make it hard to write a flash filesystem.

UBI intends to deal with all MTD-specific operations while still presenting random-access volumes to the the upper-layer. The first – and as for now, only – implementation using UBI is UBIFS. UBI is a “volume manager” and maps physical erase blocks (PEB) to logical erase blocks (LEB). The LEBs are smaller than the PEBs because of meta-data and headers.

How to use UBI on my board ?

There are mainly 2 ways to do that:

  • On a booted Linux system, approximately the same way you would create a partition on your desktop’s hard drive ;
  • From the bootloader, by flashing a previously prepared UBI image ;

Whatever solution you choose, you need to know the sizes of:

  • the eraseblocks (PEB) ;
  • the pages (or “minimum input/output size”) ;
  • the subpages (it may be the same as the min i/o size) ;

From these details, you can deduce another one: the size of logical erase blocks. It is the size of the PEB minus a data offset which is:

(int((Subpage_size + Page_size) / Page_size))  * Page_size

(subpage+page truncated to page size). This formula makes some assumption but should be correct if the subpage size is more than 8B and the page size more than 64B (see the source for more information). The best way to be sure of this size is to use mtdinfo on linux on the board. mtdinfo is part of the ubi-utils (part of mtd-utils). It’s probably available in your build system.

In both cases, you will also need a UBIFS image. In the way of JFFS2, mkfs.ubifs comes in mtd-utils (thus, you also need them on your desktop. Warning: mtd-utils in Ubuntu 10.10 are reported to be buggy ; if you use this distribution, recompile them from their git tree). Here is an example of how you can invoke it:

# mkfs.ubifs -r </path/to/your/rootfs/tree> -m <min io size>
  -e <LEB size> -c <Eraseblocks count>
  -o </path/to/output/ubifs.img>

Solution A – On a booted Linux system

I think it’s the best method to understand how UBI is structured.

You first need to enable UBI and UBIFS in the kernel and install the mtd-utils package (for Debian and Ubuntu) on your box. You may also compile mtd-utils from its sources.

Once you have your UBIFS image at hand, let’s sing the UBI song:

# ubiformat /dev/mtdX
# ubiattach -p /dev/mtdX
# ubimkvol /dev/ubi0 -N volume_name -s 64MiB
# ubiupdatevol /dev/ubi0_0 /path/to/ubifs.img
# mount -t ubifs ubi0:volume_name /mount/point

Let’s examine each command. ubiformat erases an MTD partition but keeps its erase counters ((‘X’ is the number of the partition you want to use). ubiattach creates a UBI device from the MTD partition. This UBI device is then referred to by UBI as ubi0 (if it is the first device). ubimkvol creates a volume on a UBI device ; this volume is referred to as ubi0_0 (if it is the first volume on the device). ubiupdatevol puts an image on an empty volume. (use ubiupdatevol -t /dev/ubi0_0 to empty a volume). At last, the well-known mount can be invoked using <device>:<volume>

Solution B – Prepare a UBI image ready to be flashed

It is more common to directly flash filesystem images directly from the bootloader. It is made possible by ubinize to prepare a UBI device image containing one or more volumes.

ubinize reads a configuration file (in the very simple INI format) describing the volumes and their configuration. Here is an example of a device with two volumes ; one, named rootfs is read-only (static), the other one, data is read-write (dynamic) ; the autoresize flag makes UBI resize to volume to use the whole unused space at initialization. The name of the sections is totally arbitrary.

[rootfs_volume]
mode=ubi
image=rootfs.ubifs
vol_id=1
vol_type=static
vol_name=rootfs
vol_alignment=1

[rwdata_volume]
mode=ubi
image=data.ubifs
vol_id=2
vol_type=dynamic
vol_name=data
vol_alignment=1
vol_flags=autoresize

Next is the generation of the UBI image. The ubinize utility will need the Physical Erase Block size (PEB) (option -p) and the minimum I/O size (-m):

# ubinize -vv -o <output image> -m <min io size>
  -p <PEB size>KiB <configuration file>

Your image is ready. You may now want to boot on the rootfs UBIFS partition. Keep on reading, then.

Use a UBIFS partition as root partition

Some options need to be passed to the kernel to boot on a ubi volume and on a UBIFS partition:

ubi.mtd=<mtd partition number>
root=<ubi device>:<volume>
rootfstype=ubifs

For instance, with the previous examples and assuming the UBI device has been created/flashed on /dev/mtd1:

ubi.mtd=1 root=ubi0:rootfs rootfstype=ubifs

Conclusion

Creating and using a UBIFS filesystem is not as easy as with JFFS2 but UBI/UBIFS is designed to be more robust and UBI will ease the development of new filesystems. The authors of UBI have pointed some memory usage scalability problems but if a second version of UBI were written, filesystems on top of it would not need to be modified.

Troubleshooting

In case your system is missing the /dev/ubi_ctrl, /dev/ubi0 or /dev/ubi0_X device files, we advise you to recompile your kernel with DEVTMPFS and DEVTMPFS_MOUNT. This way, all the devices existing on your system will appear in /dev.

If you get write errors (code -74 or -5, probably), check that CONFIG_MTD_NAND_VERIFY_WRITE (respectively, ONENAND) is disabled : verifying subpages writes isn’t supported yet.

Sources

The primary place for information about MTD support in Linux is infradead.org. There also is a mailing list which you can also subscribe to.

The kernel sources under drivers/mtd and fs/ubisfs are also very helpful.

modinfo ubi
filename: /lib/modules/4.8.0-58-generic/kernel/drivers/mtd/ubi/ubi.ko
license: GPL
author: Artem Bityutskiy
description: UBI — Unsorted Block Images
version: 1
srcversion: F48B37AF1AFBE3F312DCCAA
depends: mtd
intree: Y
vermagic: 4.8.0-58-generic SMP mod_unload modversions
parm: block:Attach block devices to UBI volumes. Parameter format: block=<path|dev,num|dev,name>.
Multiple «block» parameters may be specified.
UBI volumes may be specified by their number, name, or path to the device node.
Examples
Using the UBI volume path:
ubi.block=/dev/ubi0_0
Using the UBI device, and the volume name:
ubi.block=0,rootfs
Using both UBI device number and UBI volume number:
ubi.block=0,0

parm: mtd:MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num]]].
Multiple «mtd» parameters may be specified.
MTD devices may be specified by their number, name, or path to the MTD character device node.
Optional «vid_hdr_offs» parameter specifies UBI VID header position to be used by UBI. (default value if 0)
Optional «max_beb_per1024» parameter specifies the maximum expected bad eraseblock per 1024 eraseblocks. (default value (20) if 0)
Optional «ubi_num» parameter specifies UBI device number which have to be assigned to the newly created UBI device (assigned automatically by default)

Example 1: mtd=/dev/mtd0 — attach MTD device /dev/mtd0.
Example 2: mtd=content,1984 mtd=4 — attach MTD device with name «content» using VID header offset 1984, and MTD device number 4 with default VID header offset.
Example 3: mtd=/dev/mtd1,0,25 — attach MTD device /dev/mtd1 using default VID header offset and reserve 25*nand_size_in_blocks/1024 erase blocks for bad block handling.
Example 4: mtd=/dev/mtd1,0,0,5 — attach MTD device /dev/mtd1 to UBI 5 and using default values for the other fields.
(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device).
parm: fm_autoconvert:Set this parameter to enable fastmap automatically on images without a fastmap. (bool)
parm: fm_debug:Set this parameter to enable fastmap debugging by default. Warning, this will make fastmap slow! (bool)

Понравилась статья? Поделить с друзьями:
  • Ubidetach error cannot detach
  • Uawea game error
  • Uathelper packaging windows 64 bit logoutputdevice error begin stack for uat
  • Uathelper packaging windows 64 bit error unable to compile source files
  • Uathelper packaging windows 64 bit error cook failed