mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-31 04:53:01 +02:00
The blkmap patches were not included in the original U-Boot Secure
Boot changeset.
Fixes: d243c80 ("aarch64: Convenience target to configure a QEMU compatible U-Boot")
338 lines
9.1 KiB
Diff
338 lines
9.1 KiB
Diff
From c20dd0f17a128e65c1f376bf0e1cad9cec1d0336 Mon Sep 17 00:00:00 2001
|
|
From: Tobias Waldekranz <tobias@waldekranz.com>
|
|
Date: Thu, 16 Feb 2023 15:10:49 +0100
|
|
Subject: [PATCH v2 6/9] cmd: blkmap: Add blkmap command
|
|
|
|
Add a frontend for the blkmap subsystem. In addition to the common
|
|
block device operations, this allows users to create and destroy
|
|
devices, and map in memory and slices of other block devices.
|
|
|
|
With that we support two primary use-cases:
|
|
|
|
- Being able to "distro boot" from a RAM disk. I.e., from an image
|
|
where the kernel is stored in /boot of some filesystem supported
|
|
by U-Boot.
|
|
|
|
- Accessing filesystems not located on exact partition boundaries,
|
|
e.g. when a filesystem image is wrapped in an FIT image and stored
|
|
in a disk partition.
|
|
|
|
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
|
---
|
|
MAINTAINERS | 1 +
|
|
cmd/Kconfig | 19 +++++
|
|
cmd/Makefile | 1 +
|
|
cmd/blkmap.c | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
disk/part.c | 1 +
|
|
5 files changed, 255 insertions(+)
|
|
create mode 100644 cmd/blkmap.c
|
|
|
|
diff --git a/MAINTAINERS b/MAINTAINERS
|
|
index 3e47c9b34c..316b85fed7 100644
|
|
--- a/MAINTAINERS
|
|
+++ b/MAINTAINERS
|
|
@@ -796,6 +796,7 @@ F: tools/binman/
|
|
BLKMAP
|
|
M: Tobias Waldekranz <tobias@waldekranz.com>
|
|
S: Maintained
|
|
+F: cmd/blkmap.c
|
|
F: drivers/block/blkmap.c
|
|
F: include/blkmap.h
|
|
|
|
diff --git a/cmd/Kconfig b/cmd/Kconfig
|
|
index 2caa4af71c..3dd3cdc656 100644
|
|
--- a/cmd/Kconfig
|
|
+++ b/cmd/Kconfig
|
|
@@ -1959,6 +1959,25 @@ config CMD_BLOCK_CACHE
|
|
during development, but also allows the cache to be disabled when
|
|
it might hurt performance (e.g. when using the ums command).
|
|
|
|
+config CMD_BLKMAP
|
|
+ bool "blkmap - Composable virtual block devices"
|
|
+ depends on BLKMAP
|
|
+ default y if BLKMAP
|
|
+ help
|
|
+ Create virtual block devices that are backed by various sources,
|
|
+ e.g. RAM, or parts of an existing block device. Though much more
|
|
+ rudimentary, it borrows a lot of ideas from Linux's device mapper
|
|
+ subsystem.
|
|
+
|
|
+ Example use-cases:
|
|
+ - Treat a region of RAM as a block device, i.e. a RAM disk. This let's
|
|
+ you extract files from filesystem images stored in RAM (perhaps as a
|
|
+ result of a TFTP transfer).
|
|
+ - Create a virtual partition on an existing device. This let's you
|
|
+ access filesystems that aren't stored at an exact partition
|
|
+ boundary. A common example is a filesystem image embedded in an FIT
|
|
+ image.
|
|
+
|
|
config CMD_BUTTON
|
|
bool "button"
|
|
depends on BUTTON
|
|
diff --git a/cmd/Makefile b/cmd/Makefile
|
|
index 36d2daf22a..837eee39b1 100644
|
|
--- a/cmd/Makefile
|
|
+++ b/cmd/Makefile
|
|
@@ -27,6 +27,7 @@ obj-$(CONFIG_CMD_BCB) += bcb.o
|
|
obj-$(CONFIG_CMD_BDI) += bdinfo.o
|
|
obj-$(CONFIG_CMD_BIND) += bind.o
|
|
obj-$(CONFIG_CMD_BINOP) += binop.o
|
|
+obj-$(CONFIG_CMD_BLKMAP) += blkmap.o
|
|
obj-$(CONFIG_CMD_BLOBLIST) += bloblist.o
|
|
obj-$(CONFIG_CMD_BLOCK_CACHE) += blkcache.o
|
|
obj-$(CONFIG_CMD_BMP) += bmp.o
|
|
diff --git a/cmd/blkmap.c b/cmd/blkmap.c
|
|
new file mode 100644
|
|
index 0000000000..b34c013072
|
|
--- /dev/null
|
|
+++ b/cmd/blkmap.c
|
|
@@ -0,0 +1,233 @@
|
|
+// SPDX-License-Identifier: GPL-2.0+
|
|
+/*
|
|
+ * Copyright (c) 2023 Addiva Elektronik
|
|
+ * Author: Tobias Waldekranz <tobias@waldekranz.com>
|
|
+ */
|
|
+
|
|
+#include <blk.h>
|
|
+#include <blkmap.h>
|
|
+#include <common.h>
|
|
+#include <command.h>
|
|
+#include <malloc.h>
|
|
+#include <dm/device.h>
|
|
+
|
|
+static int blkmap_curr_dev;
|
|
+
|
|
+struct map_ctx {
|
|
+ struct udevice *dev;
|
|
+ lbaint_t blknr, blkcnt;
|
|
+};
|
|
+
|
|
+typedef int (*map_parser_fn)(struct map_ctx *ctx, int argc, char *const argv[]);
|
|
+
|
|
+struct map_handler {
|
|
+ const char *name;
|
|
+ map_parser_fn fn;
|
|
+};
|
|
+
|
|
+int do_blkmap_map_linear(struct map_ctx *ctx, int argc, char *const argv[])
|
|
+{
|
|
+ struct blk_desc *lbd;
|
|
+ int err, ldevnum;
|
|
+ lbaint_t lblknr;
|
|
+
|
|
+ if (argc < 4)
|
|
+ return CMD_RET_USAGE;
|
|
+
|
|
+ ldevnum = dectoul(argv[2], NULL);
|
|
+ lblknr = dectoul(argv[3], NULL);
|
|
+
|
|
+ lbd = blk_get_devnum_by_uclass_idname(argv[1], ldevnum);
|
|
+ if (!lbd) {
|
|
+ printf("Found no device matching \"%s %d\"\n",
|
|
+ argv[1], ldevnum);
|
|
+ return CMD_RET_FAILURE;
|
|
+ }
|
|
+
|
|
+ err = blkmap_map_linear(ctx->dev, ctx->blknr, ctx->blkcnt,
|
|
+ lbd->bdev, lblknr);
|
|
+ if (err) {
|
|
+ printf("Unable to map \"%s %d\" at block 0x" LBAF ": %d\n",
|
|
+ argv[1], ldevnum, ctx->blknr, err);
|
|
+
|
|
+ return CMD_RET_FAILURE;
|
|
+ }
|
|
+
|
|
+ printf("Block 0x" LBAF "+0x" LBAF " mapped to block 0x" LBAF " of \"%s %d\"\n",
|
|
+ ctx->blknr, ctx->blkcnt, lblknr, argv[1], ldevnum);
|
|
+ return CMD_RET_SUCCESS;
|
|
+}
|
|
+
|
|
+int do_blkmap_map_mem(struct map_ctx *ctx, int argc, char *const argv[])
|
|
+{
|
|
+ phys_addr_t addr;
|
|
+ int err;
|
|
+
|
|
+ if (argc < 2)
|
|
+ return CMD_RET_USAGE;
|
|
+
|
|
+ addr = hextoul(argv[1], NULL);
|
|
+
|
|
+ err = blkmap_map_pmem(ctx->dev, ctx->blknr, ctx->blkcnt, addr);
|
|
+ if (err) {
|
|
+ printf("Unable to map %#llx at block 0x" LBAF ": %d\n",
|
|
+ (unsigned long long)addr, ctx->blknr, err);
|
|
+ return CMD_RET_FAILURE;
|
|
+ }
|
|
+
|
|
+ printf("Block 0x" LBAF "+0x" LBAF " mapped to %#llx\n",
|
|
+ ctx->blknr, ctx->blkcnt, (unsigned long long)addr);
|
|
+ return CMD_RET_SUCCESS;
|
|
+}
|
|
+
|
|
+struct map_handler map_handlers[] = {
|
|
+ { .name = "linear", .fn = do_blkmap_map_linear },
|
|
+ { .name = "mem", .fn = do_blkmap_map_mem },
|
|
+
|
|
+ { .name = NULL }
|
|
+};
|
|
+
|
|
+static int do_blkmap_map(struct cmd_tbl *cmdtp, int flag,
|
|
+ int argc, char *const argv[])
|
|
+{
|
|
+ struct map_handler *handler;
|
|
+ struct map_ctx ctx;
|
|
+
|
|
+ if (argc < 5)
|
|
+ return CMD_RET_USAGE;
|
|
+
|
|
+ ctx.dev = blkmap_from_label(argv[1]);
|
|
+ if (!ctx.dev) {
|
|
+ printf("\"%s\" is not the name of any known blkmap\n", argv[1]);
|
|
+ return CMD_RET_FAILURE;
|
|
+ }
|
|
+
|
|
+ ctx.blknr = hextoul(argv[2], NULL);
|
|
+ ctx.blkcnt = hextoul(argv[3], NULL);
|
|
+ argc -= 4;
|
|
+ argv += 4;
|
|
+
|
|
+ for (handler = map_handlers; handler->name; handler++) {
|
|
+ if (!strcmp(handler->name, argv[0]))
|
|
+ return handler->fn(&ctx, argc, argv);
|
|
+ }
|
|
+
|
|
+ printf("Unknown map type \"%s\"\n", argv[0]);
|
|
+ return CMD_RET_USAGE;
|
|
+}
|
|
+
|
|
+static int do_blkmap_create(struct cmd_tbl *cmdtp, int flag,
|
|
+ int argc, char *const argv[])
|
|
+{
|
|
+ const char *label;
|
|
+ int err;
|
|
+
|
|
+ if (argc != 2)
|
|
+ return CMD_RET_USAGE;
|
|
+
|
|
+ label = argv[1];
|
|
+
|
|
+ err = blkmap_create(label, NULL);
|
|
+ if (err) {
|
|
+ printf("Unable to create \"%s\": %d\n", label, err);
|
|
+ return CMD_RET_FAILURE;
|
|
+ }
|
|
+
|
|
+ printf("Created \"%s\"\n", label);
|
|
+ return CMD_RET_SUCCESS;
|
|
+}
|
|
+
|
|
+static int do_blkmap_destroy(struct cmd_tbl *cmdtp, int flag,
|
|
+ int argc, char *const argv[])
|
|
+{
|
|
+ struct udevice *dev;
|
|
+ const char *label;
|
|
+ int err;
|
|
+
|
|
+ if (argc != 2)
|
|
+ return CMD_RET_USAGE;
|
|
+
|
|
+ label = argv[1];
|
|
+
|
|
+ dev = blkmap_from_label(label);
|
|
+ if (!dev) {
|
|
+ printf("\"%s\" is not the name of any known blkmap\n", label);
|
|
+ return CMD_RET_FAILURE;
|
|
+ }
|
|
+
|
|
+ err = blkmap_destroy(dev);
|
|
+ if (err) {
|
|
+ printf("Unable to destroy \"%s\": %d\n", label, err);
|
|
+ return CMD_RET_FAILURE;
|
|
+ }
|
|
+
|
|
+ printf("Destroyed \"%s\"\n", label);
|
|
+ return CMD_RET_SUCCESS;
|
|
+}
|
|
+
|
|
+static int do_blkmap_get(struct cmd_tbl *cmdtp, int flag,
|
|
+ int argc, char *const argv[])
|
|
+{
|
|
+ struct udevice *dev;
|
|
+ const char *label;
|
|
+ int err;
|
|
+
|
|
+ if (argc < 3)
|
|
+ return CMD_RET_USAGE;
|
|
+
|
|
+ label = argv[1];
|
|
+
|
|
+ dev = blkmap_from_label(label);
|
|
+ if (!dev) {
|
|
+ printf("\"%s\" is not the name of any known blkmap\n", label);
|
|
+ return CMD_RET_FAILURE;
|
|
+ }
|
|
+
|
|
+ if (!strcmp(argv[2], "dev")) {
|
|
+ if (argc == 3) {
|
|
+ printf("%d\n", dev_seq(dev));
|
|
+ } else {
|
|
+ err = env_set_hex(argv[3], dev_seq(dev));
|
|
+ if (err)
|
|
+ return CMD_RET_FAILURE;
|
|
+ }
|
|
+ } else {
|
|
+ return CMD_RET_USAGE;
|
|
+ }
|
|
+
|
|
+ return CMD_RET_SUCCESS;
|
|
+}
|
|
+
|
|
+static int do_blkmap_common(struct cmd_tbl *cmdtp, int flag,
|
|
+ int argc, char *const argv[])
|
|
+{
|
|
+ /* The subcommand parsing pops the original argv[0] ("blkmap")
|
|
+ * which blk_common_cmd expects. Push it back again.
|
|
+ */
|
|
+ argc++;
|
|
+ argv--;
|
|
+
|
|
+ return blk_common_cmd(argc, argv, UCLASS_BLKMAP, &blkmap_curr_dev);
|
|
+}
|
|
+
|
|
+U_BOOT_CMD_WITH_SUBCMDS(
|
|
+ blkmap, "Composeable virtual block devices",
|
|
+ "info - list configured devices\n"
|
|
+ "blkmap part - list available partitions on current blkmap device\n"
|
|
+ "blkmap dev [<dev>] - show or set current blkmap device\n"
|
|
+ "blkmap read <addr> <blk#> <cnt>\n"
|
|
+ "blkmap write <addr> <blk#> <cnt>\n"
|
|
+ "blkmap get <label> dev [<var>] - store device number in variable\n"
|
|
+ "blkmap create <label> - create device\n"
|
|
+ "blkmap destroy <label> - destroy device\n"
|
|
+ "blkmap map <label> <blk#> <cnt> linear <interface> <dev> <blk#> - device mapping\n"
|
|
+ "blkmap map <label> <blk#> <cnt> mem <addr> - memory mapping\n",
|
|
+ U_BOOT_SUBCMD_MKENT(info, 2, 1, do_blkmap_common),
|
|
+ U_BOOT_SUBCMD_MKENT(part, 2, 1, do_blkmap_common),
|
|
+ U_BOOT_SUBCMD_MKENT(dev, 4, 1, do_blkmap_common),
|
|
+ U_BOOT_SUBCMD_MKENT(read, 5, 1, do_blkmap_common),
|
|
+ U_BOOT_SUBCMD_MKENT(write, 5, 1, do_blkmap_common),
|
|
+ U_BOOT_SUBCMD_MKENT(get, 5, 1, do_blkmap_get),
|
|
+ U_BOOT_SUBCMD_MKENT(create, 2, 1, do_blkmap_create),
|
|
+ U_BOOT_SUBCMD_MKENT(destroy, 2, 1, do_blkmap_destroy),
|
|
+ U_BOOT_SUBCMD_MKENT(map, 32, 1, do_blkmap_map));
|
|
diff --git a/disk/part.c b/disk/part.c
|
|
index d449635254..35300df590 100644
|
|
--- a/disk/part.c
|
|
+++ b/disk/part.c
|
|
@@ -140,6 +140,7 @@ void dev_print(struct blk_desc *dev_desc)
|
|
case UCLASS_NVME:
|
|
case UCLASS_PVBLOCK:
|
|
case UCLASS_HOST:
|
|
+ case UCLASS_BLKMAP:
|
|
printf ("Vendor: %s Rev: %s Prod: %s\n",
|
|
dev_desc->vendor,
|
|
dev_desc->revision,
|
|
--
|
|
2.34.1
|
|
|