
Am 1. Februar 2023 19:10:16 MEZ schrieb Tobias Waldekranz tobias@waldekranz.com:
Explain block maps by going through two common use-cases.
Signed-off-by: Tobias Waldekranz tobias@waldekranz.com
MAINTAINERS | 1 + doc/usage/blkmap.rst | 109 +++++++++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + 3 files changed, 111 insertions(+) create mode 100644 doc/usage/blkmap.rst
diff --git a/MAINTAINERS b/MAINTAINERS index c420c8e1f9..de0e41487d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -790,6 +790,7 @@ BLKMAP M: Tobias Waldekranz tobias@waldekranz.com S: Maintained F: cmd/blkmap.c +F: doc/usage/blkmap.rst F: drivers/block/blkmap.c F: include/blkmap.h F: test/py/tests/test_blkmap.py diff --git a/doc/usage/blkmap.rst b/doc/usage/blkmap.rst new file mode 100644 index 0000000000..1cf6d97c1b --- /dev/null +++ b/doc/usage/blkmap.rst @@ -0,0 +1,109 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. +.. Copyright (c) 2023 Addiva Elektronik +.. Author: Tobias Waldekranz tobias@waldekranz.com
+Block Maps (blkmap) +===================
+Block maps are a way of looking at various sources of data through the +lens of a regular block device. It lets you treat devices that are not +block devices, like RAM, as if they were. It also lets you export a +slice of an existing block device, which does not have to correspond +to a partition boundary, as a new block device.
+This is primarily useful because U-Boot's filesystem drivers only +operate on block devices, so a block map lets you access filesystems +wherever they might be located.
+The implementation is loosely modeled on Linux's "Device Mapper" +subsystem, see `kernel documentation`_ for more information.
+.. _kernel documentation: https://docs.kernel.org/admin-guide/device-mapper/index.html
+Example: Netbooting an Ext4 Image +---------------------------------
+Say that our system is using an Ext4 filesystem as its rootfs, where +the kernel is stored in ``/boot``. This image is then typically stored +in an eMMC partition. In this configuration, we can use something like +``load mmc 0 ${kernel_addr_r} /boot/Image`` to load the kernel image +into the expected location, and then boot the system. No problems.
+Now imagine that during development, or as a recovery mechanism, we +want to boot the same type of image by downloading it over the +network. Getting the image to the target is easy enough:
+::
- dhcp ${ramdisk_addr_r} rootfs.ext4
+But now we are faced with a predicament: how to we extract the kernel +image? Block maps to the rescue!
+We start by creating a new device:
+::
- blkmap create 0
+Before setting up the mapping, we figure out the size of the +downloaded file, in blocks:
+::
- setexpr fileblks ${filesize} + 0x1ff
- setexpr fileblks ${filesize} / 0x200
+Then we can add a mapping to the start of our device, backed by the +memory at `${loadaddr}`:
+::
- blkmap map 0 0 ${fileblks} mem ${fileaddr}
This is way too complicated. Just accept the file size here.
How can we handle images assuming a different block size then?
+Now we can access the filesystem via the virtual device:
+::
- load blkmap 0 ${kernel_addr_r} /boot/Image
+Example: Accessing a filesystem inside an FIT image +---------------------------------------------------
+In this example, an FIT image is stored in an eMMC partition. We would +like to read the file ``/etc/version``, stored inside a Squashfs image +in the FIT. Since the Squashfs image is not stored on a partition +boundary, there is no way of accessing it via ``load mmc ...``.
+What we can to instead is to first figure out the offset and size of +the filesystem:
+::
- mmc dev 0
- mmc read ${loadaddr} 0 0x100
- fdt addr ${loadaddr}
- fdt get value squashaddr /images/ramdisk data-position
- fdt get value squashsize /images/ramdisk data-size
- setexpr squashblk ${squashaddr} / 0x200
- setexpr squashsize ${squashsize} + 0x1ff
- setexpr squashsize ${squashsize} / 0x200
+Then we can create a block map that maps to that slice of the full +partition:
+::
- blkmap create 0
- blkmap map 0 0 ${squashsize} linear mmc 0 ${squashblk}
We are the requirements on alignment?
Best regards
Heinrich
+Now we can access the filesystem:
+::
- load blkmap 0 ${loadaddr} /etc/version
diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 3804046835..856a3da28e 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -4,6 +4,7 @@ Use U-Boot .. toctree:: :maxdepth: 1
- blkmap dfu environment fdt_overlays