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