#endif
#define GRUB_LINUX_CL_OFFSET 0x1000
-#define GRUB_LINUX_CL_END_OFFSET 0x2000
static grub_dl_t my_mod;
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
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 ();
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). */
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;
/* Copy kernel parameters. */
for (i = 1;
i < argc
- && dest + grub_strlen (argv[i]) + 1 < ((char *) real_mode_mem
- + GRUB_LINUX_CL_END_OFFSET);
+ && dest + grub_strlen (argv[i]) + 2 < ((char *) real_mode_mem
+ + GRUB_LINUX_CL_OFFSET
+ + maximal_cmdline_size);
i++)
{
*dest++ = ' ';
#include <grub/i386/floppy.h>
#define GRUB_LINUX_CL_OFFSET 0x9000
-#define GRUB_LINUX_CL_END_OFFSET 0x90FF
static grub_dl_t my_mod;
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)
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;
{
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
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;
}
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);
/* Copy kernel parameters. */
for (i = 1;
i < argc
- && dest + grub_strlen (argv[i]) + 1 < (grub_linux_real_chunk
- + GRUB_LINUX_CL_END_OFFSET);
+ && dest + grub_strlen (argv[i]) + 2 < (grub_linux_real_chunk
+ + GRUB_LINUX_CL_OFFSET
+ + maximal_cmdline_size);
i++)
{
*dest++ = ' ';
#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__
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