Description: Support long Linux command lines Author: Vladimir Serbinenko Origin: upstream, http://bzr.sv.gnu.org/r/grub/branches/longlinuxcmd/ Forwarded: not-needed Applied-Upstream: http://bazaar.launchpad.net/~vcs-imports/grub/grub2-bzr/revision/3303 Last-Update: 2011-05-19 Index: b/grub-core/loader/i386/linux.c =================================================================== --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -57,7 +57,6 @@ #endif #define GRUB_LINUX_CL_OFFSET 0x1000 -#define GRUB_LINUX_CL_END_OFFSET 0x2000 static grub_dl_t my_mod; @@ -74,6 +73,7 @@ static grub_uint32_t initrd_pages; static struct grub_relocator *relocator = NULL; static void *efi_mmap_buf; +static grub_size_t maximal_cmdline_size; #ifdef GRUB_MACHINE_EFI static grub_efi_uintn_t efi_mmap_size; #else @@ -189,7 +189,7 @@ grub_err_t err; /* Make sure that each size is aligned to a page boundary. */ - real_size = GRUB_LINUX_CL_END_OFFSET; + real_size = GRUB_LINUX_CL_OFFSET + maximal_cmdline_size; prot_size = page_align (prot_size); mmap_size = find_mmap_size (); @@ -662,6 +662,14 @@ goto fail; } + if (grub_le_to_cpu16 (lh.version) >= 0x0206) + maximal_cmdline_size = grub_le_to_cpu32 (lh.cmdline_size) + 1; + else + maximal_cmdline_size = 256; + + if (maximal_cmdline_size < 128) + maximal_cmdline_size = 128; + setup_sects = lh.setup_sects; /* If SETUP_SECTS is not set, set it to the default (4). */ @@ -675,7 +683,7 @@ goto fail; params = (struct linux_kernel_params *) real_mode_mem; - grub_memset (params, 0, GRUB_LINUX_CL_END_OFFSET); + grub_memset (params, 0, GRUB_LINUX_CL_OFFSET + maximal_cmdline_size); grub_memcpy (¶ms->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1); params->ps_mouse = params->padding10 = 0; @@ -870,7 +878,7 @@ grub_create_loader_cmdline (argc, argv, (char *)real_mode_mem + GRUB_LINUX_CL_OFFSET + sizeof (LINUX_IMAGE) - 1, - GRUB_LINUX_CL_END_OFFSET - GRUB_LINUX_CL_OFFSET + maximal_cmdline_size - (sizeof (LINUX_IMAGE) - 1)); len = prot_size; Index: b/grub-core/loader/i386/pc/linux.c =================================================================== --- a/grub-core/loader/i386/pc/linux.c +++ b/grub-core/loader/i386/pc/linux.c @@ -39,7 +39,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define GRUB_LINUX_CL_OFFSET 0x9000 -#define GRUB_LINUX_CL_END_OFFSET 0x90FF static grub_dl_t my_mod; @@ -49,6 +48,7 @@ static grub_addr_t grub_linux_real_target; static char *grub_linux_real_chunk; static grub_size_t grub_linux16_prot_size; +static grub_size_t maximal_cmdline_size; static grub_err_t grub_linux16_boot (void) @@ -128,15 +128,20 @@ setup_sects = lh.setup_sects; linux_mem_size = 0; + maximal_cmdline_size = 256; + if (lh.header == grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE) && grub_le_to_cpu16 (lh.version) >= 0x0200) { grub_linux_is_bzimage = (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL); lh.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE; + if (grub_le_to_cpu16 (lh.version) >= 0x0206) + maximal_cmdline_size = grub_le_to_cpu32 (lh.cmdline_size) + 1; + /* Put the real mode part at as a high location as possible. */ grub_linux_real_target = grub_mmap_get_lower () - - GRUB_LINUX_SETUP_MOVE_SIZE; + - (GRUB_LINUX_CL_OFFSET + maximal_cmdline_size); /* But it must not exceed the traditional area. */ if (grub_linux_real_target > GRUB_LINUX_OLD_REAL_MODE_ADDR) grub_linux_real_target = GRUB_LINUX_OLD_REAL_MODE_ADDR; @@ -153,7 +158,8 @@ { lh.cl_magic = grub_cpu_to_le16 (GRUB_LINUX_CL_MAGIC); lh.cl_offset = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET); - lh.setup_move_size = grub_cpu_to_le16 (GRUB_LINUX_SETUP_MOVE_SIZE); + lh.setup_move_size = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET + + maximal_cmdline_size); } } else @@ -185,12 +191,13 @@ goto fail; } - if (grub_linux_real_target + GRUB_LINUX_SETUP_MOVE_SIZE + if (grub_linux_real_target + GRUB_LINUX_CL_OFFSET + maximal_cmdline_size > grub_mmap_get_lower ()) { grub_error (GRUB_ERR_OUT_OF_RANGE, "too small lower memory (0x%x > 0x%x)", - grub_linux_real_target + GRUB_LINUX_SETUP_MOVE_SIZE, + grub_linux_real_target + GRUB_LINUX_CL_OFFSET + + maximal_cmdline_size, (int) grub_mmap_get_lower ()); goto fail; } @@ -263,7 +270,8 @@ grub_relocator_chunk_t ch; err = grub_relocator_alloc_chunk_addr (relocator, &ch, grub_linux_real_target, - GRUB_LINUX_SETUP_MOVE_SIZE); + GRUB_LINUX_CL_OFFSET + + maximal_cmdline_size); if (err) return err; grub_linux_real_chunk = get_virtual_current_address (ch); @@ -294,7 +302,7 @@ grub_create_loader_cmdline (argc, argv, (char *)grub_linux_real_chunk + GRUB_LINUX_CL_OFFSET + sizeof (LINUX_IMAGE) - 1, - GRUB_LINUX_CL_END_OFFSET - GRUB_LINUX_CL_OFFSET + maximal_cmdline_size - (sizeof (LINUX_IMAGE) - 1)); if (grub_linux_is_bzimage) Index: b/include/grub/i386/linux.h =================================================================== --- a/include/grub/i386/linux.h +++ b/include/grub/i386/linux.h @@ -41,7 +41,6 @@ #define GRUB_LINUX_VID_MODE_ASK 0xFFFD #define GRUB_LINUX_VID_MODE_VESA_START 0x0300 -#define GRUB_LINUX_SETUP_MOVE_SIZE 0x9100 #define GRUB_LINUX_CL_MAGIC 0xA33F #ifdef __x86_64__ @@ -130,6 +129,10 @@ grub_uint16_t pad1; /* Unused */ grub_uint32_t cmd_line_ptr; /* Points to the kernel command line */ grub_uint32_t initrd_addr_max; /* Highest address for initrd */ + grub_uint32_t kernel_alignment; + grub_uint8_t relocatable; + grub_uint8_t pad[3]; + grub_uint32_t cmdline_size; } __attribute__ ((packed)); /* Boot parameters for Linux based on 2.6.12. This is used by the setup