diff mbox series

[8/8] doc: blkmap: Add introduction and examples

Message ID 20230201181016.4145834-9-tobias@waldekranz.com
State Superseded
Delegated to: Tom Rini
Headers show
Series blk: blkmap: Composable virtual block devices | expand

Commit Message

Tobias Waldekranz Feb. 1, 2023, 6:10 p.m. UTC
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

Comments

Simon Glass Feb. 1, 2023, 8:21 p.m. UTC | #1
On Wed, 1 Feb 2023 at 11:10, Tobias Waldekranz <tobias@waldekranz.com> wrote:
>
> 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

Reviewed-by: Simon Glass <sjg@chromium.org>

Nice feature!
Heinrich Schuchardt Feb. 1, 2023, 9:14 p.m. UTC | #2
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
diff mbox series

Patch

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}
+
+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}
+
+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