Long Linux command line support.

* grub-core/loader/i386/linux.c (GRUB_LINUX_CL_END_OFFSET): Removed.
	(maximal_cmdline_size): New variable.
	(allocate_pages): Use maximal_cmdline_size.
	(grub_cmd_linux): Set and use maximal_cmdline_size.
	* grub-core/loader/i386/pc/linux.c (GRUB_LINUX_CL_END_OFFSET): Removed.
	(allocate_pages): Use maximal_cmdline_size.
	(grub_cmd_linux): Set and use maximal_cmdline_size.
	* include/grub/i386/linux.h (GRUB_LINUX_SETUP_MOVE_SIZE): Removed.
	(linux_kernel_header): Add fields kernel_alignment, relocatable, pad
	and cmdline_size.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-05-18 09:56:33 +02:00
commit 05caa461e8
4 changed files with 46 additions and 12 deletions

View file

@ -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 struct grub_relocator *relocator = NULL;
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 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
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 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
{
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 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
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_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
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_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
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)