uboot_disk_write() is currently lacking the write support to storage devices because, historically, those devices did not implement block_write() in U-Boot.
The solution has been tested using a patched U-Boot loading and booting GRUB in a QEMU vexpress-a9 environment. The disk write operations were triggered with GRUB's save_env command. Signed-off-by: Cristian Ciocaltea <cristian.ciocal...@gmail.com> Reviewed-by: Daniel Kiper <daniel.ki...@oracle.com> --- Changes since v1: * Fix compiler error when building with '-Werror=discarded-qualifiers': passing argument 2 of 'grub_uboot_dev_write' discards 'const' qualifier from pointer target type grub-core/disk/uboot/ubootdisk.c | 22 ++++++++++++++++------ grub-core/kern/uboot/uboot.c | 16 ++++++++++++++++ include/grub/uboot/uboot.h | 3 ++- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/grub-core/disk/uboot/ubootdisk.c b/grub-core/disk/uboot/ubootdisk.c index a5ce07a99..584a9cbdf 100644 --- a/grub-core/disk/uboot/ubootdisk.c +++ b/grub-core/disk/uboot/ubootdisk.c @@ -264,13 +264,23 @@ uboot_disk_read (struct grub_disk *disk, } static grub_err_t -uboot_disk_write (struct grub_disk *disk __attribute__ ((unused)), - grub_disk_addr_t sector __attribute__ ((unused)), - grub_size_t size __attribute__ ((unused)), - const char *buf __attribute__ ((unused))) +uboot_disk_write (struct grub_disk *disk, + grub_disk_addr_t offset, grub_size_t numblocks, const char *buf) { - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "attempt to write (not supported)"); + struct ubootdisk_data *d; + int retval; + + d = disk->data; + + retval = grub_uboot_dev_write (d->dev, buf, numblocks, offset); + grub_dprintf ("ubootdisk", + "retval=%d, numblocks=%d, sector=%llu\n", + retval, numblocks, (grub_uint64_t) offset); + + if (retval != 0) + return grub_error (GRUB_ERR_IO, "U-Boot disk write error"); + + return GRUB_ERR_NONE; } static struct grub_disk_dev grub_ubootdisk_dev = { diff --git a/grub-core/kern/uboot/uboot.c b/grub-core/kern/uboot/uboot.c index cf0168e62..3631c044e 100644 --- a/grub-core/kern/uboot/uboot.c +++ b/grub-core/kern/uboot/uboot.c @@ -243,6 +243,22 @@ grub_uboot_dev_read (struct device_info *dev, void *buf, grub_size_t blocks, return retval; } +int +grub_uboot_dev_write (struct device_info *dev, const void *buf, + grub_size_t blocks, grub_uint32_t start) +{ + int retval; + + if (!OPEN_DEV (dev)) + return -1; + + if (!grub_uboot_syscall (API_DEV_WRITE, &retval, dev, buf, + &blocks, &start)) + return -1; + + return retval; +} + int grub_uboot_dev_recv (struct device_info *dev, void *buf, int size, int *real_size) diff --git a/include/grub/uboot/uboot.h b/include/grub/uboot/uboot.h index c122de6ab..353ad51c0 100644 --- a/include/grub/uboot/uboot.h +++ b/include/grub/uboot/uboot.h @@ -72,7 +72,8 @@ int EXPORT_FUNC (grub_uboot_dev_enum) (void); struct device_info * EXPORT_FUNC (grub_uboot_dev_get) (int index); int EXPORT_FUNC (grub_uboot_dev_open) (struct device_info *dev); int EXPORT_FUNC (grub_uboot_dev_close) (struct device_info *dev); -int grub_uboot_dev_write (struct device_info *dev, void *buf, int *len); +int grub_uboot_dev_write (struct device_info *dev, const void *buf, + grub_size_t blocks, grub_uint32_t start); int grub_uboot_dev_read (struct device_info *dev, void *buf, grub_size_t blocks, grub_uint32_t start, grub_size_t * real_blocks); int EXPORT_FUNC (grub_uboot_dev_recv) (struct device_info *dev, void *buf, -- 2.17.1 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel