Generic firmware loader
v9 cover Generic firmware loader
From: Tien Fong Chee <[email protected]>
This patchset contains generic firmware loader which is very close to Linux firmware loader but for U-Boot framework. Generic firmware loader can be used load whatever into target location, and then consumer driver would use it to program whatever, ie. the FPGA. This version mainly resolved comments from Marek Vasut in [v8].
This series is working on top of u-boot.git -
http://git.denx.de/u-boot.git .
[v8]: https://www.mail-archive.com/u-boot at lists.denx.de/msg278735.html
v8 -> v9 changes:
-----------------
- Swap these two -- mount first and umount seconds.
- Removed #ifdef CONFIG_SPL.
- Adding depends on SPL to config GENERIC_FIRMWARE_LOADER at Kconfig.
- Set mode=0 to usb_stor_scan.
- Sata device number be pulled from devpart in default_locations table.
- Removed debug for CONFIG_SPL.
- Adding UBI to default_location table.
Patchset history
----------------
[v1]: https://www.mail-archive.com/u-boot at lists.denx.de/msg271905.html [v2]: https://www.mail-archive.com/u-boot at lists.denx.de/msg271979.html [v3]: https://www.mail-archive.com/u-boot at lists.denx.de/msg272039.html [v4]: https://www.mail-archive.com/u-boot at lists.denx.de/msg272432.html [v5]: https://www.mail-archive.com/u-boot at lists.denx.de/msg272771.html [v6]: https://www.mail-archive.com/u-boot at lists.denx.de/msg273961.html [v7]: https://www.mail-archive.com/u-boot at lists.denx.de/msg276775.html
Tien Fong Chee (4):
spl: Remove static declaration on spl_mmc_find_device function
cmd: ubifs: Move ubifs_initialized checking into cmd_ubifs_umount()
cmd: ubifs: Factor out some checking codes into cmd_ubifs_mount()
common: Generic firmware loader for file system
cmd/ubifs.c | 40 ++--- common/Kconfig | 10 ++ common/Makefile | 1 + common/fs_loader.c | 365 +++++++++++++++++++++++++++++++++++++++++++++ common/spl/spl_mmc.c | 2 +- doc/README.firmware_loader | 83 +++++++++++ include/fs_loader.h | 28 ++++ include/spl.h | 2 + include/ubi_uboot.h | 2 + 9 files changed, 515 insertions(+), 18 deletions(-) create mode 100644 common/fs_loader.c create mode 100644 doc/README.firmware_loader create mode 100644 include/fs_loader.h
Signature · 1 line
2.2.0
PATCH v9 1/4 spl: Remove static declaration on spl_mmc_find_device function
From: Tien Fong Chee <[email protected]>
This patch removes the static declation on spl_mmc_find_device_function so this function is accessible by the caller from other file. This patch is required for later patch.
--- common/spl/spl_mmc.c | 2 +- include/spl.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-)
common/spl/spl_mmc.c +1 -1
@@ -114,7 +114,7 @@ static int spl_mmc_get_device_index(u32 boot_device)return -ENODEV ; } -static int spl_mmc_find_device (struct mmc **mmcp,u32 boot_device) +int spl_mmc_find_device (struct mmc **mmcp,u32 boot_device) {#if CONFIG_IS_ENABLED (DM_MMC )struct udevice *dev;
include/spl.h +2 -0
@@ -12,6 +12,7 @@/* Platform-specific defines */ #include <linux/compiler.h> #include <asm/spl.h> +#include <mmc.h> /* Value in r0 indicates we booted from U-Boot */ #define UBOOT_NOT_LOADED_FROM_SPL 0x13578642
@@ -83,6 +84,7 @@ void preloader_console_init(void);u32 spl_boot_device (void );u32 spl_boot_mode (const u32 boot_device);void spl_set_bd (void ); +int spl_mmc_find_device (struct mmc **mmcp,u32 boot_device);/** * spl_set_header_raw_uboot() - Set up a standard SPL image structure
Signature · 1 line
2.2.0
PATCH v9 2/4 cmd: ubifs: Move ubifs_initialized checking into cmd_ubifs_umount()
In reply to tien.fong.chee at intel.comFrom: Tien Fong Chee <[email protected]>
cmd_ubifs_umount() function would be called directly instead of involving whole command machinery in generic firmware loader, so checking on ubifs_initialized status need to be done in cmd_ubifs_umount() without breaking original functionality design.
--- cmd/ubifs.c | 18 +++++++++--------- include/ubi_uboot.h | 1 + 2 files changed, 10 insertions(+), 9 deletions(-)
cmd/ubifs.c +9 -9
@@ -51,11 +51,18 @@ int ubifs_is_mounted(void)return ubifs_mounted; } -void cmd_ubifs_umount (void ) +int cmd_ubifs_umount (void ) { +if (ubifs_initialized ==0 ) { +printf ("No UBIFS volume mounted!\n" ); +return -1 ; + } +uboot_ubifs_umount (); ubifs_mounted =0 ; ubifs_initialized =0 ; + +return 0 ; } static int do_ubifs_umount(cmd_tbl_t *cmdtp, int flag, int argc,
@@ -64,14 +71,7 @@ static int do_ubifs_umount(cmd_tbl_t *cmdtp, int flag, int argc,if (argc !=1 )return CMD_RET_USAGE ; -if (ubifs_initialized ==0 ) { -printf ("No UBIFS volume mounted!\n" ); -return -1 ; - } - -cmd_ubifs_umount (); - -return 0 ; +return cmd_ubifs_umount (); } static int do_ubifs_ls(cmd_tbl_t *cmdtp, int flag, int argc,
include/ubi_uboot.h +1 -0
@@ -75,5 +75,6 @@ extern int ubi_volume_write(char *volume, void *buf, size_t size);extern int ubi_volume_read (char *volume,char *buf,size_t size);extern struct ubi_device *ubi_devices[]; +int cmd_ubifs_umount (void );#endif
Signature · 1 line
2.2.0
PATCH v9 3/4 cmd: ubifs: Factor out some checking codes into cmd_ubifs_mount()
In reply to tien.fong.chee at intel.comFrom: Tien Fong Chee <[email protected]>
cmd_ubifs_mount() function would be called directly instead of involving whole command machinery for mounting ubifs in generic firmware loader, so some checking codes need to be factored out into cmd_ubifs_mount() without breaking original functionality design.
--- cmd/ubifs.c | 22 ++++++++++++++-------- include/ubi_uboot.h | 1 + 2 files changed, 15 insertions(+), 8 deletions(-)
cmd/ubifs.c +14 -8
@@ -20,16 +20,10 @@static int ubifs_initialized;static int ubifs_mounted; -static int do_ubifs_mount (cmd_tbl_t *cmdtp,int flag,int argc, -char *const argv[]) +int cmd_ubifs_mount (char *vol_name) { -char *vol_name;int ret; -if (argc !=2 ) -return CMD_RET_USAGE ; - - vol_name = argv[1 ];debug ("Using volume %s\n" , vol_name);if (ubifs_initialized ==0 ) {
@@ -43,7 +37,19 @@ static int do_ubifs_mount(cmd_tbl_t *cmdtp, int flag, int argc, ubifs_mounted =1 ; -return 0 ; +return ret; +} +static int do_ubifs_mount (cmd_tbl_t *cmdtp,int flag,int argc, +char *const argv[]) +{ +char *vol_name; + +if (argc !=2 ) +return CMD_RET_USAGE ; + + vol_name = argv[1 ]; + +return cmd_ubifs_mount (vol_name); }int ubifs_is_mounted (void )
include/ubi_uboot.h +1 -0
@@ -75,6 +75,7 @@ extern int ubi_volume_write(char *volume, void *buf, size_t size);extern int ubi_volume_read (char *volume,char *buf,size_t size);extern struct ubi_device *ubi_devices[]; +int cmd_ubifs_mount (char *vol_name);int cmd_ubifs_umount (void );#endif
Signature · 1 line
2.2.0
PATCH v9 4/4 common: Generic firmware loader for file system
In reply to tien.fong.chee at intel.comFrom: Tien Fong Chee <[email protected]>
This is file system generic loader which can be used to load the file image from the storage into target such as memory. The consumer driver would then use this loader to program whatever, ie. the FPGA device.
--- common/Kconfig | 10 ++ common/Makefile | 1 + common/fs_loader.c | 365 +++++++++++++++++++++++++++++++++++++++++++++ doc/README.firmware_loader | 83 +++++++++++ include/fs_loader.h | 28 ++++ 5 files changed, 487 insertions(+) create mode 100644 common/fs_loader.c create mode 100644 doc/README.firmware_loader create mode 100644 include/fs_loader.h
common/Kconfig +10 -0
@@ -560,6 +560,16 @@ config DISPLAY_BOARDINFO when U-Boot starts up. The board function checkboard() is called to do this. +config GENERIC_FIRMWARE_LOADER + bool "Enable generic firmware loader driver for file system" + depends on SPL + help + This is file system generic loader which can be used to load + the file image from the storage into target such as memory. + + The consumer driver would then use this loader to program whatever, + ie. the FPGA device. + menu "Start-up hooks" config ARCH_EARLY_INIT_R
common/Makefile +1 -0
@@ -134,3 +134,4 @@ obj-$(CONFIG_$(SPL_)LOG) += log.o obj-$(CONFIG_$(SPL_)LOG_CONSOLE) += log_console.o obj-y += s_record.o obj-y += xyzModem.o +obj-$(CONFIG_GENERIC_FIRMWARE_LOADER) += fs_loader.o
common/fs_loader.c new file +365 -0
365 lines not on this page · raw message
doc/README.firmware_loader new file +83 -0
83 lines not on this page · raw message
include/fs_loader.h new file +28 -0
@@ -0,0 +1,28 @@ +/* +* Copyright (C) 2018 Intel Corporation <www.intel.com> +* +* SPDX-License-Identifier: GPL-2.0 +*/ +#ifndef _FS_LOADER_H_ +#define _FS_LOADER_H_ + +#include <linux/types.h> + +struct firmware { +size_t size;/* Size of a file */ +const u8 *data;/* Buffer for file */ +void *priv;/* Firmware loader private fields */ +}; + +struct device_location { +char *name;/* Such as mmc, usb,and sata. */ +char *devpart;/* Use the load command dev:part conventions */ +char *mtdpart;/* MTD partition for ubi part */ +char *ubivol;/* UBI volume-name for ubifsmount */ +}; + +int request_firmware_into_buf (struct firmware **firmware_p, +const char *name, +struct device_location *location, +void *buf,size_t size,u32 offset); +#endif
Signature · 1 line
2.2.0
PATCH v9 4/4 common: Generic firmware loader for file system
Hi,
Quoted 143 lines · On Tue, 27 Feb 2018 13:21:57 +0800 tien.fong.chee at intel.com wrote:
From: Tien Fong Chee <[email protected]>
This is file system generic loader which can be used to load the file image from the storage into target such as memory. The consumer driver would then use this loader to program whatever, ie. the FPGA device.
Signed-off-by Tien Fong Chee <[email protected]>Reviewed-by Lothar Waßmann <[email protected]>--- common/Kconfig | 10 ++ common/Makefile | 1 + common/fs_loader.c | 365 +++++++++++++++++++++++++++++++++++++++++++++ doc/README.firmware_loader | 83 +++++++++++ include/fs_loader.h | 28 ++++ 5 files changed, 487 insertions(+) create mode 100644 common/fs_loader.c create mode 100644 doc/README.firmware_loader create mode 100644 include/fs_loader.hcommon/Kconfig +10
-0@@ -560,6 +560,16 @@ config DISPLAY_BOARDINFO when U-Boot starts up. The board function checkboard() is called to do this. +config GENERIC_FIRMWARE_LOADER + bool "Enable generic firmware loader driver for file system" + depends on SPL + help + This is file system generic loader which can be used to load + the file image from the storage into target such as memory. + + The consumer driver would then use this loader to program whatever, + ie. the FPGA device. + menu "Start-up hooks" config ARCH_EARLY_INIT_Rcommon/Makefile +1
-0@@ -134,3 +134,4 @@ obj-$(CONFIG_$(SPL_)LOG) += log.o obj-$(CONFIG_$(SPL_)LOG_CONSOLE) += log_console.o obj-y += s_record.o obj-y += xyzModem.o +obj-$(CONFIG_GENERIC_FIRMWARE_LOADER) += fs_loader.ocommon/fs_loader.c new file +86
-0@@ -0,0 +1,365 @@ +/* +* Copyright (C) 2018 Intel Corporation <www.intel.com> +* +* SPDX-License-Identifier: GPL-2.0 +*/ + +#include <common.h> +#include <errno.h> +#include <fs.h> +#include <fs_loader.h> +#include <nand.h> +#include <sata.h> +#include <spi.h> +#include <spi_flash.h> +#include <spl.h> +#include <linux/string.h> +#ifdef CONFIG_CMD_UBIFS +#include <ubi_uboot.h> +#include <ubifs_uboot.h> +#endif +#include <usb.h> + +struct firmware_priv { +const char *name;/* Filename */ +u32 offset;/* Offset of reading a file */ +}; + +static struct device_location default_locations[] = { + { + .name ="mmc" , + .devpart ="0:1" , + }, + { + .name ="usb" , + .devpart ="0:1" , + }, + { + .name ="sata" , + .devpart ="0:1" , + }, + { + .name ="ubi" , + .mtdpart ="UBI" , + .ubivol ="ubi0" , + }, +}; + +/* USB build is not supported yet in SPL */ +#ifndef CONFIG_SPL_BUILD +#ifdef CONFIG_USB_STORAGE +static int init_usb (void ) +{ +int err; + + err =usb_init (); +if (err) +return err; + +#ifndef CONFIG_DM_USB + err =usb_stor_scan (0 ); +if (err) +return err; +#endif + +return err; +} +#else +static int init_usb (void ) +{ +debug ("Error: Cannot load flash image: no USB support\n" ); +return -ENOSYS ; +} +#endif +#endif + +#ifdef CONFIG_SATA +static int init_storage_sata (struct device_location *location) +{ +char *dup_str =NULL ; +const char *dev_str, *part_str; +int dev; + +/* Get device ID */ + part_str =strchr (location->devpart,':' ); +if (part_str) { + dup_str =strdup (location->devpart);
common/fs_loader.c line 96
Quoted 10 lines
common/fs_loader.c new file +10
-0+ dup_str[part_str - location->devpart] =0 ; + dev_str = dup_str; + part_str++; + }else { + dev_str = location->devpart; + } + + dev = (int )simple_strtoul (dev_str,NULL ,10 ); + +return sata_probe (dev);
You are leaking the strdup() memory.
Furthermore, there is no need to mess around with the 'devpart' string like this. simple_strtoul() will convert the string up to the first non-digit character and return the position of this char in the second argument (if that's non-null). Thus you can easily check for a valid numerical argument.
Quoted 20 lines
common/fs_loader.c new file +20
-0+static void set_storage_devpart (char *name,char *devpart) +{ +size_t i; + +for (i =0 ; i <ARRAY_SIZE (default_locations); i++) { +if (!strcmp (default_locations[i].name, name)) + default_locations[i].devpart = devpart; + } +} + +static void set_storage_mtdpart (char *name,char *mtdpart) +{ +size_t i; + +for (i =0 ; i <ARRAY_SIZE (default_locations); i++) { +if (!strcmp (default_locations[i].name, name)) + default_locations[i].mtdpart = mtdpart; + } +} +
common/fs_loader.c line 238
Quoted 10 lines
common/fs_loader.c new file +10
-0+static void set_storage_ubivol (char *name,char *ubivol) +{ +size_t i; + +for (i =0 ; i <ARRAY_SIZE (default_locations); i++) { +if (!strcmp (default_locations[i].name, name)) + default_locations[i].ubivol = ubivol; + } +} +
The arguments to these functions could well be const.
Lothar Waßmann
Chee
PATCH v9 4/4 common: Generic firmware loader for file system
Quoted 156 lines · Lothar Waßmann
Hi,
Quoted 153 lines · On Tue, 27 Feb 2018 13:21:57 +0800 tien.fong.chee at intel.com wrote:
From: Tien Fong Chee <[email protected]>
This is file system generic loader which can be used to load the file image from the storage into target such as memory. The consumer driver would then use this loader to program whatever, ie. the FPGA device.
Signed-off-by Tien Fong Chee <[email protected]>Reviewed-by Lothar Waßmann <[email protected]>---
common/Kconfig | 10 ++
common/Makefile | 1 +
common/fs_loader.c | 365
+++++++++++++++++++++++++++++++++++++++++++++
doc/README.firmware_loader | 83 +++++++++++
include/fs_loader.h | 28 ++++5 files changed, 487 insertions(+)create mode 100644
common/fs_loader.c
create mode 100644 doc/README.firmware_loader
create mode 100644include/fs_loader.hcommon/Kconfig +0
-0@@ -560,6 +560,16 @@ config DISPLAY_BOARDINFO when U-Boot starts up. The board function checkboard()is called
to do this.common/Kconfig +2
-0+config GENERIC_FIRMWARE_LOADER + bool "Enable generic firmware loader driver for filesystem"
common/Kconfig +3
-0+ depends on SPL + help + This is file system generic loader which can be used toload
common/Kconfig +1
-0+ the file image from the storage into target such asmemory.
common/Kconfig +2
-0+ + The consumer driver would then use this loader toprogram whatever,
common/Kconfig +2
-0+ ie. the FPGA device. +menu "Start-up hooks"
configARCH_EARLY_INIT_Rcommon/Makefile +0
-0@@ -134,3 +134,4 @@ obj-$(CONFIG_$(SPL_)LOG) += log.oobj-$(CONFIG_$(SPL_)LOG_CONSOLE) += log_console.o obj-y += s_record.o
obj-y += xyzModem.ocommon/Makefile +1
-0+obj-$(CONFIG_GENERIC_FIRMWARE_LOADER) += fs_loader.ocommon/fs_loader.c new file +90
-0@@ -0,0 +1,365 @@ +/* +* Copyright (C) 2018 Intel Corporation <www.intel.com> +* +* SPDX-License-Identifier: GPL-2.0 +*/ + +#include <common.h> +#include <errno.h> +#include <fs.h> +#include <fs_loader.h> +#include <nand.h> +#include <sata.h> +#include <spi.h> +#include <spi_flash.h> +#include <spl.h> +#include <linux/string.h> +#ifdef CONFIG_CMD_UBIFS +#include <ubi_uboot.h> +#include <ubifs_uboot.h> +#endif +#include <usb.h> + +struct firmware_priv { +const char *name;/* Filename */ +u32 offset;/* Offset of reading a file */ +}; + +static struct device_location default_locations[] = { + { + .name ="mmc" , + .devpart ="0:1" , + }, + { + .name ="usb" , + .devpart ="0:1" , + }, + { + .name ="sata" , + .devpart ="0:1" , + }, + { + .name ="ubi" , + .mtdpart ="UBI" , + .ubivol ="ubi0" , + }, +}; + +/* USB build is not supported yet in SPL */ +#ifndef CONFIG_SPL_BUILD +#ifdef CONFIG_USB_STORAGE +static int init_usb (void ) +{ +int err; + + err =usb_init (); +if (err) +return err; + +#ifndef CONFIG_DM_USB + err =usb_stor_scan (0 ); +if (err) +return err; +#endif + +return err; +} +#else +static int init_usb (void ) +{ +debug ("Error: Cannot load flash image: no USB support\n" ); +return -ENOSYS ; +} +#endif +#endif + +#ifdef CONFIG_SATA +static int init_storage_sata (struct device_location *location) +{ +char *dup_str =NULL ; +const char *dev_str, *part_str; +int dev; + +/* Get device ID */ + part_str =strchr (location->devpart,':' ); +if (part_str) { + dup_str =strdup (location->devpart); + dup_str[part_str - location->devpart] =0 ; + dev_str = dup_str; + part_str++; + }else {
Quoted 8 lines
common/fs_loader.c line 96
Quoted 7 lines
common/fs_loader.c new file +6
-0+ dev_str = location->devpart; + } + + dev = (int )simple_strtoul (dev_str,NULL ,10 ); + +return sata_probe (dev);You are leaking the
strdup()memory.
Good catch!!
Quoted 8 lines
Furthermore, there is no need to mess around with the 'devpart' string
like this.simple_strtoul()will convert the string up to the first non-digit character and return the position of this char in the second
argument (if that's non-null). Thus you can easily check for a valid numerical argument.
Okay, i would try with simple_strtoul().
Quoted 24 lines
Quoted 24 lines
common/fs_loader.c new file +23
-0+static void set_storage_devpart (char *name,char *devpart) +{ +size_t i; + +for (i =0 ; i <ARRAY_SIZE (default_locations); i++) { +if (!strcmp (default_locations[i].name, name)) + default_locations[i].devpart = devpart; + } +} + +static void set_storage_mtdpart (char *name,char *mtdpart) +{ +size_t i; + +for (i =0 ; i <ARRAY_SIZE (default_locations); i++) { +if (!strcmp (default_locations[i].name, name)) + default_locations[i].mtdpart = mtdpart; + } +} + +static void set_storage_ubivol (char *name,char *ubivol) +{ +size_t i;
Quoted 9 lines
common/fs_loader.c line 238
Quoted 7 lines
common/fs_loader.c new file +7
-0+ +for (i =0 ; i <ARRAY_SIZE (default_locations); i++) { +if (!strcmp (default_locations[i].name, name)) + default_locations[i].ubivol = ubivol; + } +} +The arguments to these functions could well be const.
Okay. noted.
Quoted 3 lines
Lothar Waßmann