lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240923105937.4374-4-ansuelsmth@gmail.com>
Date: Mon, 23 Sep 2024 12:59:32 +0200
From: Christian Marangi <ansuelsmth@...il.com>
To: Jens Axboe <axboe@...nel.dk>,
	Jonathan Corbet <corbet@....net>,
	Ulf Hansson <ulf.hansson@...aro.org>,
	Rob Herring <robh@...nel.org>,
	Krzysztof Kozlowski <krzk+dt@...nel.org>,
	Conor Dooley <conor+dt@...nel.org>,
	Christian Marangi <ansuelsmth@...il.com>,
	INAGAKI Hiroshi <musashino.open@...il.com>,
	Daniel Golle <daniel@...rotopia.org>,
	Christian Brauner <brauner@...nel.org>,
	Al Viro <viro@...iv.linux.org.uk>,
	Ming Lei <ming.lei@...hat.com>,
	Li Lingfeng <lilingfeng3@...wei.com>,
	Christian Heusel <christian@...sel.eu>,
	linux-block@...r.kernel.org,
	linux-doc@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	linux-mmc@...r.kernel.org,
	devicetree@...r.kernel.org,
	Miquel Raynal <miquel.raynal@...tlin.com>,
	Lorenzo Bianconi <lorenzo@...nel.org>
Subject: [RFC PATCH 3/4] block: add support for partition table defined in OF

Add support for partition table defined in Device Tree. Similar to how
it's done with MTD, add support for defining a fixed partition table in
device tree.

A common scenario for this is fixed block (eMMC) embedded devices that
have no MBR or GPT partition table to save storage space. Bootloader
access the block device with absolute address of data.

This is to complete the functionality with an equivalent implementation
with providing partition table with bootargs, for case where the booargs
can't be modified and tweaking the Device Tree is the only solution to
have an usabe partition table.

The implementation follow the fixed-partitions parser used on MTD
devices where a "partitions" node is expected to be declared in the OF
node of the disk device (mmc-card for eMMC for example) and each child
node declare a label and a reg with offset and size. Eventually is also
possible to declare the read-only property to flag the partition as
read-only.

The driver scan the disk name and check if it's suffixed with boot0 or
boot1. This is to handle the additional disk provided by eMMC or UFS
devices in general. If this suffix is detected, "partitions-boot0" or
"partitions-boot1" are used instead of the generic "partitions"

Signed-off-by: Christian Marangi <ansuelsmth@...il.com>
---
 block/partitions/Kconfig  |  8 ++++
 block/partitions/Makefile |  1 +
 block/partitions/of.c     | 85 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 94 insertions(+)
 create mode 100644 block/partitions/of.c

diff --git a/block/partitions/Kconfig b/block/partitions/Kconfig
index 7aff4eb81c60..8534f7544f26 100644
--- a/block/partitions/Kconfig
+++ b/block/partitions/Kconfig
@@ -270,4 +270,12 @@ config CMDLINE_PARTITION
 	  Say Y here if you want to read the partition table from bootargs.
 	  The format for the command line is just like mtdparts.
 
+config OF_PARTITION
+	bool "Command line partition support" if PARTITION_ADVANCED
+	depends on OF
+	help
+	  Say Y here if you want to enable support for partition table
+	  defined in Device Tree. (mainly for eMMC)
+	  The format for the command line is just like MTD fixed-partition schema.
+
 endmenu
diff --git a/block/partitions/Makefile b/block/partitions/Makefile
index a7f05cdb02a8..25d424922c6e 100644
--- a/block/partitions/Makefile
+++ b/block/partitions/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_CMDLINE_PARTITION) += cmdline.o
 obj-$(CONFIG_MAC_PARTITION) += mac.o
 obj-$(CONFIG_LDM_PARTITION) += ldm.o
 obj-$(CONFIG_MSDOS_PARTITION) += msdos.o
+obj-$(CONFIG_OF_PARTITION) += of.o
 obj-$(CONFIG_OSF_PARTITION) += osf.o
 obj-$(CONFIG_SGI_PARTITION) += sgi.o
 obj-$(CONFIG_SUN_PARTITION) += sun.o
diff --git a/block/partitions/of.c b/block/partitions/of.c
new file mode 100644
index 000000000000..1c420b7f53c0
--- /dev/null
+++ b/block/partitions/of.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/blkdev.h>
+#include <linux/of.h>
+#include "check.h"
+
+#define BOOT0_STR	"boot0"
+#define BOOT1_STR	"boot1"
+
+static struct device_node *get_partitions_node(struct device_node *disk_np,
+					       const char *disk_name)
+{
+	const char *node_name = "partitions";
+
+	/* Check if we are parsing boot0 or boot1 */
+	if (!memcmp(disk_name + strlen(disk_name) - strlen(BOOT0_STR),
+		    BOOT0_STR, sizeof(BOOT0_STR)))
+		node_name = "partitions-boot0";
+	if (!memcmp(disk_name + strlen(disk_name) - strlen(BOOT1_STR),
+		    BOOT1_STR, sizeof(BOOT1_STR)))
+		node_name = "partitions-boot1";
+
+	return of_get_child_by_name(disk_np, node_name);
+}
+
+static void add_of_partition(struct parsed_partitions *state, int slot,
+			     struct device_node *np)
+{
+	struct partition_meta_info *info;
+	char tmp[sizeof(info->volname) + 4];
+	int a_cells, s_cells;
+	const char *partname;
+	const __be32 *reg;
+	u64 offset, size;
+	int len;
+
+	reg = of_get_property(np, "reg", &len);
+
+	a_cells = of_n_addr_cells(np);
+	s_cells = of_n_size_cells(np);
+
+	offset = of_read_number(reg, a_cells);
+	size = of_read_number(reg + a_cells, s_cells);
+
+	put_partition(state, slot, offset, size);
+
+	if (of_property_read_bool(pp, "read-only"))
+		state->parts[slot].flags |= ADDPART_FLAG_READONLY;
+
+	info = &state->parts[slot].info;
+	partname = of_get_property(np, "label", &len);
+	strscpy(info->volname, partname, sizeof(info->volname));
+
+	snprintf(tmp, sizeof(tmp), "(%s)", info->volname);
+	strlcat(state->pp_buf, tmp, PAGE_SIZE);
+}
+
+int of_partition(struct parsed_partitions *state)
+{
+	struct device_node *disk_np, *partitions_np, *np;
+	struct device *ddev = disk_to_dev(state->disk);
+	int slot = 1;
+
+	disk_np = of_node_get(ddev->parent->of_node);
+	if (!disk_np)
+		return 0;
+
+	partitions_np = get_partitions_node(disk_np,
+					    state->disk->disk_name);
+	if (!partitions_np)
+		return 0;
+
+	for_each_child_of_node(partitions_np, np) {
+		if (slot >= state->limit)
+			return -1;
+
+		add_of_partition(state, slot, np);
+
+		slot++;
+	}
+
+	strlcat(state->pp_buf, "\n", PAGE_SIZE);
+
+	return 1;
+}
-- 
2.45.2


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ