On 17-08-2026 17:55, Heinrich Schuchardt wrote:
On 8/17/26 17:00, Mike Looijmans wrote:
What I'm trying to accomplish is to be able to read the kernel directly from a squashfs partition in SPI NOR flash.

This should have been simple, as SPI-NOR is an MTD device, and MTD_BLOCK translates that to a block device, and squashfs needs a block device.

The issue is that MTD_BLOCK adds some hooks, in particular "mtd_bind()" but the only point where that ever gets called is from drivers/mtd/nand/ spi/core.c

So even though one activates CONFIG_MTD_BLOCK, no mtd device or partition ever gets registered as a block device (unless you happen to have a spi-nand controller, which, contrary to spi-nor, would be unsuitable for a squashfs filesystem...)

I tried doing the obvious, that is, copy and adapt the spi-nand code into the spi-nor driver, see attached patch, but that doesn't have any effect whatsoever.

I tried similar things a few months ago, and also had a discussion here on the list, but that sort of faded out without any further results...


spi_flash_std_bind() is called before spi_flash_std_probe(). Setting plat->mtd in spi_flash_std_probe() will have no effect in the bind method.

Tried putting something together in an updated patch. Seems to have some effect now. Some block device registers now, but there's no working link to the partitioning:



zynq-uboot> lsblk
Block Driver          Devices
-----------------------------
mmc_blk             : mmc 0
mtd_blk             : mtd 0
ubi_blk             : mtd 1
usb_storage_blk     : <none>
zynq-uboot> dm tree
 Class     Seq    Probed  Driver                Name
-----------------------------------------------------------
 root          0  [ + ]   root_driver           root_driver
 simple_bus    0  [ + ]   simple_bus            |-- axi
 gpio          0  [   ]   gpio_zynq             |   |-- gpio@e000a000
 i2c           0  [   ]   i2c_cdns              |   |-- i2c@e0004000
 i2c           1  [   ]   i2c_cdns              |   |-- i2c@e0005000
 gpio          1  [   ]   pca953x               |   |   `-- gpio@41
 serial        0  [ + ]   serial_zynq           |   |-- serial@e0000000
 spi           0  [   ]   zynq_qspi             |   |-- spi@e000d000
 spi_flash     0  [   ]   jedec_spi_nor         |   |   `-- flash@0
 blk           0  [   ]   mtd_blk               |   |       |-- [email protected]
 blk           1  [   ]   ubi_blk               |   |       `-- [email protected]
 mmc           0  [ + ]   arasan_sdhci          |   |-- mmc@e0100000
 blk           2  [   ]   mmc_blk               |   |   |-- [email protected]  bootdev       0  [   ]   mmc_bootdev           |   |   `-- [email protected]
 simple_bus    1  [ + ]   simple_bus            |   |-- slcr@f8000000
 clk           0  [ + ]   zynq_clk              |   |   `-- clkc@100
 timer         0  [   ]   arm_twd_timer         |   |-- timer@f8f00600
 usb           0  [   ]   ehci_zynq             |   `-- usb@e0002000
 bootstd       0  [   ]   bootstd_drv           `-- bootstd
 bootmeth      0  [   ]   bootmeth_extlinux         `-- extlinux
zynq-uboot> ls mtd 0
** Bad device specification mtd 0 **
Couldn't find partition mtd 0


--
Mike Looijmans
System Expert

TOPIC Embedded Products B.V.
Materiaalweg 4, 5681 RJ Best
The Netherlands

T: +31 (0) 499 33 69 69
E: [email protected]
W: www.topic.nl


From 2e822bce1ffeba2b0009e886319383e3eb910a1d Mon Sep 17 00:00:00 2001
From: Mike Looijmans <[email protected]>
Date: Tue, 25 Mar 2025 16:03:03 +0100
Subject: [PATCH] spi/sf_probe.c: Register stuff at ubi/mtd in bind

Doesn't work, see mail list
Creates block devices, but they don't work
Have to set CONFIG_SYS_MALLOC_F_LEN=0x900 to prevent allocation error
---
 drivers/mtd/spi/sf_probe.c  | 27 +++++++++++++++++++++++++++
 include/linux/mtd/spi-nor.h |  3 +++
 2 files changed, 30 insertions(+)

diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 7100b64bf22..6a6fc0a9185 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -7,14 +7,17 @@
  * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc.
  */
 
+#include <blk.h>
 #include <dm.h>
 #include <errno.h>
+#include <linux/mtd/mtd.h>
 #include <linux/mtd/spi-nor.h>
 #include <log.h>
 #include <malloc.h>
 #include <spi.h>
 #include <spi_flash.h>
 #include <spi-mem.h>
+#include <ubi_uboot.h>
 
 #include "sf_internal.h"
 
@@ -219,6 +222,29 @@ int spi_flash_std_probe(struct udevice *dev)
 	return spi_flash_probe_slave(flash);
 }
 
+int spi_flash_std_bind(struct udevice *dev)
+{
+#ifndef CONFIG_XPL_BUILD
+	struct spi_flash *flash = dev_get_uclass_priv(dev);
+	int ret;
+
+	if (blk_enabled()) {
+		if (CONFIG_IS_ENABLED(MTD_BLOCK)) {
+			// Workaround for mtd_bid requiring a "**" instead of a "*"
+			flash->mtd_p = &flash->mtd;
+			ret = mtd_bind(dev, &flash->mtd_p);
+			if (ret)
+				return ret;
+		}
+
+		if (CONFIG_IS_ENABLED(UBI_BLOCK))
+			return ubi_bind(dev);
+	}
+#endif
+
+	return 0;
+}
+
 static int spi_flash_std_remove(struct udevice *dev)
 {
 	struct spi_flash *flash = dev_get_uclass_priv(dev);
@@ -256,6 +282,7 @@ U_BOOT_DRIVER(jedec_spi_nor) = {
 	.id		= UCLASS_SPI_FLASH,
 	.of_match	= spi_flash_std_ids,
 	.probe		= spi_flash_std_probe,
+	.bind		= spi_flash_std_bind,
 	.remove		= spi_flash_std_remove,
 	.priv_auto	= sizeof(struct spi_nor),
 	.ops		= &spi_flash_std_ops,
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 4eef4ab0488..08b318725bf 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -556,6 +556,9 @@ struct spi_flash {
  */
 struct spi_nor {
 	struct mtd_info		mtd;
+#ifndef CONFIG_XPL_BUILD
+	struct mtd_info		*mtd_p;
+#endif
 	struct udevice		*dev;
 	struct spi_slave	*spi;
 	const struct flash_info	*info;
-- 
2.43.0

Reply via email to