[U-Boot] [PATCH 1/2] common: Generic file system firmware loader

tien.fong.chee at intel.com tien.fong.chee at intel.com
Wed Nov 1 09:18:21 UTC 2017


From: Tien Fong Chee <tien.fong.chee at intel.com>

Generic firmware loader framework contains some common functionality
which is factored out from splash loader. It is reusable by any
specific driver file system firmware loader. Specific driver file system
firmware loader handling can be defined with both weak function
fsloader_preprocess and fs_loading.

Signed-off-by: Tien Fong Chee <tien.fong.chee at intel.com>
---
 common/Makefile   |   1 +
 common/load_fs.c  | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/load_fs.h |  38 ++++++++++
 3 files changed, 256 insertions(+)
 create mode 100644 common/load_fs.c
 create mode 100644 include/load_fs.h

diff --git a/common/Makefile b/common/Makefile
index 801ea31..89f9365 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -130,3 +130,4 @@ obj-$(CONFIG_CMD_DFU) += dfu.o
 obj-y += command.o
 obj-y += s_record.o
 obj-y += xyzModem.o
+obj-y += load_fs.o
diff --git a/common/load_fs.c b/common/load_fs.c
new file mode 100644
index 0000000..112b4f6
--- /dev/null
+++ b/common/load_fs.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2017 Intel Corporation <www.intel.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <fs.h>
+#include <load_fs.h>
+#include <nand.h>
+#include <sata.h>
+#include <spi.h>
+#include <spi_flash.h>
+#include <usb.h>
+
+int flash_select_fs_dev(struct flash_location *location)
+{
+	int res;
+
+	switch (location->storage) {
+	case FLASH_STORAGE_MMC:
+		res = fs_set_blk_dev("mmc", location->devpart, FS_TYPE_ANY);
+		break;
+	case FLASH_STORAGE_USB:
+		res = fs_set_blk_dev("usb", location->devpart, FS_TYPE_ANY);
+		break;
+	case FLASH_STORAGE_SATA:
+		res = fs_set_blk_dev("sata", location->devpart, FS_TYPE_ANY);
+		break;
+	case FLASH_STORAGE_NAND:
+		if (location->ubivol != NULL)
+			res = fs_set_blk_dev("ubi", NULL, FS_TYPE_UBIFS);
+		else
+			res = -ENODEV;
+		break;
+	default:
+		error("Error: unsupported location storage.\n");
+		return -ENODEV;
+	}
+
+	if (res)
+		error("Error: could not access storage.\n");
+
+	return res;
+}
+
+#ifndef CONFIG_SPL_BUILD
+#ifdef CONFIG_USB_STORAGE
+static int flash_init_usb(void)
+{
+	int err;
+
+	err = usb_init();
+	if (err)
+		return err;
+
+#ifndef CONFIG_DM_USB
+	err = usb_stor_scan(1) < 0 ? -ENODEV : 0;
+#endif
+
+	return err;
+}
+#else
+static inline int flash_init_usb(void)
+{
+	error("Error: Cannot load flash image: no USB support\n");
+	return -ENOSYS;
+}
+#endif
+#endif
+
+#ifdef CONFIG_SATA
+static int flash_init_sata(void)
+{
+	return sata_probe(0);
+}
+#else
+static inline int flash_init_sata(void)
+{
+	error("Error: Cannot load flash image: no SATA support\n");
+	return -ENOSYS;
+}
+#endif
+
+#ifdef CONFIG_CMD_UBIFS
+static int flash_mount_ubifs(struct flash_location *location)
+{
+	int res;
+	char cmd[32];
+
+	sprintf(cmd, "ubi part %s", location->mtdpart);
+	res = run_command(cmd, 0);
+	if (res)
+		return res;
+
+	sprintf(cmd, "ubifsmount %s", location->ubivol);
+	res = run_command(cmd, 0);
+
+	return res;
+}
+
+static inline int flash_umount_ubifs(void)
+{
+	return run_command("ubifsumount", 0);
+}
+#else
+static inline int flash_mount_ubifs(struct flash_location *location)
+{
+	error("Error: Cannot load flash image: no UBIFS support\n");
+	return -ENOSYS;
+}
+
+static inline int flash_umount_ubifs(void)
+{
+	error("Error: Cannot unmount UBIFS: no UBIFS support\n");
+	return -ENOSYS;
+}
+#endif
+
+/**
+ * fsloader_preprocess - Any prepocessing before calling filesystem loader such
+ *			 getting filename, and flash partition information.
+ *
+ * @locations:		An array of supported flash locations. Contains default
+ *			flash setting for the file image.
+ * @file_info:		Description and attributes to the image.
+ *			Could be structure pointer, and any type pointer.
+ * @filename:		Image filename in flashes. Storing the file image name
+ *			to this pointer after retriving the name from DTB,
+ *			or environment or source code.
+ * @load_addr:		Target location image loaded to.
+ *
+ * @return:		If 0, processing is succesfull. Filename pointer
+ *			contains valid filename.
+ *			If -ve, processing is failed.
+ */
+__weak int fsloader_preprocess(struct flash_location *location,
+			       void *file_info, char **filename,
+			       u32 load_addr)
+{
+	return 0;
+}
+
+/*
+ * fs_loading - Place for implementing whatever specific driver to
+ *		the target HW such as program raw binary file to FPGA.
+ *
+ * @locations:		An array of supported flash locations. Contains default
+ *			flash setting for the file image.
+ * @file_info:		Description and attributes to the image.
+ *			Could be structure pointer, and any type pointer.
+ * @filename:		Image filename in flashes.
+ * @load_addr:		Target location image loaded to.
+ * @bsize:		Size of target location.
+ *
+ * @return:		If 0, loading is succesfull. filename pointer contains
+ *			valid filename.
+ *			If non-zero, loading is failed.
+ */
+__weak int fs_loading(struct flash_location *location, void *file_info,
+		      char *filename, u32 load_addr, size_t bsize)
+{
+	return 0;
+}
+
+/*
+ * flash_load_fs - Generic filesystem firmware loader, this should be called
+ *		   for any loader with filesystem.
+ *
+ * @locations:		An array of supported flash locations. Contains default
+ *			flash setting for the file image.
+ * @file_info:		Description and attributes to the file image.
+ *			Could be structure pointer, and any type pointer.
+ * @load_addr:		Target location file image loaded to.
+ * @bsize:		Size of target location.
+ *
+ * @return:		If 0, loading is succesfull.
+ *			If non-zero, loading is failed.
+ */
+int flash_load_fs(struct flash_location *location, void *file_info,
+		   u32 load_addr, size_t bsize)
+{
+	int res = 0;
+	char *flash_file = NULL;
+
+	res = fsloader_preprocess(location, file_info, &flash_file,
+				  load_addr);
+
+	if (res)
+		goto out;
+
+#ifndef CONFIG_SPL_BUILD
+	/* Loading from USB is not supported yet in SPL */
+	if (location->storage == FLASH_STORAGE_USB)
+		res = flash_init_usb();
+#endif
+
+	if (location->storage == FLASH_STORAGE_SATA)
+		res = flash_init_sata();
+
+	if (location->ubivol != NULL)
+		res = flash_mount_ubifs(location);
+
+	if (res)
+		return res;
+
+	res = fs_loading(location, file_info, flash_file, load_addr,
+			 bsize);
+
+out:
+	if (location->ubivol != NULL)
+		flash_umount_ubifs();
+
+	return res;
+}
+
diff --git a/include/load_fs.h b/include/load_fs.h
new file mode 100644
index 0000000..dbde8d0
--- /dev/null
+++ b/include/load_fs.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 Intel Corporation <www.intel.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+
+#ifndef _LOAD_FS_H_
+#define _LOAD_FS_H_
+
+enum flash_storage {
+	FLASH_STORAGE_NAND,
+	FLASH_STORAGE_SF,
+	FLASH_STORAGE_MMC,
+	FLASH_STORAGE_USB,
+	FLASH_STORAGE_SATA,
+};
+
+enum flash_flags {
+	FLASH_STORAGE_RAW, /* Stored in raw memory */
+	FLASH_STORAGE_FS,  /* Stored within a file system */
+	FLASH_STORAGE_FIT, /* Stored inside a FIT image */
+};
+
+struct flash_location {
+	char *name;
+	enum flash_storage storage;
+	enum flash_flags flags;
+	u32 offset;	/* offset from start of storage */
+	char *devpart;  /* Use the load command dev:part conventions */
+	char *mtdpart;	/* MTD partition for ubi part */
+	char *ubivol;	/* UBI volume-name for ubifsmount */
+};
+
+int flash_load_fs(struct flash_location *location, void *file_info,
+		  u32 load_addr, size_t bsize);
+int flash_select_fs_dev(struct flash_location *location);
+#endif
-- 
2.2.0



More information about the U-Boot mailing list