doc: blkmap: Add introduction and examples
authorTobias Waldekranz <tobias@waldekranz.com>
Thu, 16 Feb 2023 15:33:54 +0000 (16:33 +0100)
committerTom Rini <trini@konsulko.com>
Wed, 5 Apr 2023 14:54:47 +0000 (10:54 -0400)
Explain block maps by going through two common use-cases.

Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
MAINTAINERS
doc/usage/blkmap.rst [new file with mode: 0644]
doc/usage/index.rst

index ec8b149..4c17c6c 100644 (file)
@@ -797,6 +797,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/dm/blkmap.c
diff --git a/doc/usage/blkmap.rst b/doc/usage/blkmap.rst
new file mode 100644 (file)
index 0000000..dbfa8e5
--- /dev/null
@@ -0,0 +1,111 @@
+.. 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 netboot
+
+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 netboot 0 ${fileblks} mem ${fileaddr}
+
+Now we can access the filesystem via the virtual device:
+
+::
+
+   blkmap get netboot dev devnum
+   load blkmap ${devnum} ${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 sq
+   blkmap map sq 0 ${squashsize} linear mmc 0 ${squashblk}
+
+Now we can access the filesystem:
+
+::
+
+   blkmap get sq dev devnum
+   load blkmap ${devnum} ${loadaddr} /etc/version
index bc85e1d..729541b 100644 (file)
@@ -4,6 +4,7 @@ Use U-Boot
 .. toctree::
    :maxdepth: 1
 
+   blkmap
    dfu
    environment
    fdt_overlays