From adf486860fe0d395579be8b01d4fda8b93377768 Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Wed, 8 Jun 2022 16:04:12 +0800 Subject: [PATCH 08/10] linuxefi: Use common grub_initrd_load By using the common initrd loading routine factored out allows to share between features like concatenating initramfs component. For eg. initrdefi /initrd-5.16.15-1-default newc:grub.cfg:/grub2/grub.cfg The file /grub2/grub.cfg read off from root disk will be available to use as /grub.cfg in the target initramfs loaded by grub. Signed-off-by: Michael Chang --- grub-core/loader/i386/efi/linux.c | 87 ++++--------------------------- 1 file changed, 10 insertions(+), 77 deletions(-) --- a/grub-core/loader/i386/efi/linux.c +++ b/grub-core/loader/i386/efi/linux.c @@ -30,6 +30,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -146,44 +147,6 @@ return GRUB_ERR_NONE; } -#define BOUNCE_BUFFER_MAX 0x1000000ull - -static grub_ssize_t -read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len) -{ - grub_ssize_t bufpos = 0; - static grub_size_t bbufsz = 0; - static char *bbuf = NULL; - - if (bbufsz == 0) - bbufsz = MIN(BOUNCE_BUFFER_MAX, len); - - while (!bbuf && bbufsz) - { - bbuf = grub_malloc(bbufsz); - if (!bbuf) - bbufsz >>= 1; - } - if (!bbuf) - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate bounce buffer")); - - while (bufpos < (long long)len) - { - grub_ssize_t sz; - - sz = grub_file_read (file, bbuf, MIN(bbufsz, len - bufpos)); - if (sz < 0) - return sz; - if (sz == 0) - break; - - grub_memcpy(bufp + bufpos, bbuf, sz); - bufpos += sz; - } - - return bufpos; -} - #define LOW_U32(val) ((grub_uint32_t)(((grub_addr_t)(val)) & 0xffffffffull)) #define HIGH_U32(val) ((grub_uint32_t)(((grub_addr_t)(val) >> 32) & 0xffffffffull)) @@ -191,10 +154,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { - grub_file_t *files = 0; - int i, nfiles = 0; + struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; grub_size_t size = 0; - grub_uint8_t *ptr; if (argc == 0) { @@ -208,24 +169,10 @@ goto fail; } - files = grub_calloc (argc, sizeof (files[0])); - if (!files) + if (grub_initrd_init (argc, argv, &initrd_ctx)) goto fail; - for (i = 0; i < argc; i++) - { - files[i] = grub_file_open (argv[i], GRUB_FILE_TYPE_LINUX_INITRD - | GRUB_FILE_TYPE_NO_DECOMPRESS); - if (! files[i]) - goto fail; - nfiles++; - if (grub_add (size, ALIGN_UP (grub_file_size (files[i]), 4), &size)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); - goto fail; - } - } - + size = grub_get_initrd_size (&initrd_ctx); initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); if (initrd_mem == NULL) goto fail; @@ -238,30 +185,16 @@ params->ext_ramdisk_image = HIGH_U32(initrd_mem); #endif - ptr = initrd_mem; - - for (i = 0; i < nfiles; i++) - { - grub_ssize_t cursize = grub_file_size (files[i]); - if (read (files[i], ptr, cursize) != cursize) - { - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), - argv[i]); - goto fail; - } - ptr += cursize; - grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); - ptr += ALIGN_UP_OVERHEAD (cursize, 4); - } + /* FIXME: Use bounce buffers as many UEFI machines apparently can't DMA + * correctly above 4GB + */ + if (grub_initrd_load (&initrd_ctx, initrd_mem)) + goto fail; params->ramdisk_size = size; fail: - for (i = 0; i < nfiles; i++) - grub_file_close (files[i]); - grub_free (files); - + grub_initrd_close (&initrd_ctx); if (initrd_mem && grub_errno) grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, BYTES_TO_PAGES(size));