* loader/i386/linux.c (grub_rescue_cmd_initrd): Implement a few needed
constraints to initrd allocation (based on code from loader/i386/pc/linux.c). Without them, initrd was allocated too high for Linux to find it.
This commit is contained in:
parent
ebaaf49b02
commit
9290711060
2 changed files with 25 additions and 7 deletions
|
@ -1,6 +1,10 @@
|
||||||
2008-11-19 Robert Millan <rmh@aybabtu.com>
|
2008-11-19 Robert Millan <rmh@aybabtu.com>
|
||||||
|
|
||||||
* loader/i386/pc/linux.c (grub_rescue_cmd_initrd): Fix a typo.
|
* loader/i386/pc/linux.c (grub_rescue_cmd_initrd): Fix a typo.
|
||||||
|
* loader/i386/linux.c (grub_rescue_cmd_initrd): Implement a few needed
|
||||||
|
constraints to initrd allocation (based on code from
|
||||||
|
loader/i386/pc/linux.c). Without them, initrd was allocated too high
|
||||||
|
for Linux to find it.
|
||||||
|
|
||||||
2008-11-14 Robert Millan <rmh@aybabtu.com>
|
2008-11-14 Robert Millan <rmh@aybabtu.com>
|
||||||
|
|
||||||
|
|
|
@ -530,7 +530,20 @@ grub_rescue_cmd_initrd (int argc, char *argv[])
|
||||||
|
|
||||||
lh = (struct linux_kernel_header *) real_mode_mem;
|
lh = (struct linux_kernel_header *) real_mode_mem;
|
||||||
|
|
||||||
addr_max = (grub_cpu_to_le32 (lh->initrd_addr_max) << 10);
|
/* Get the highest address available for the initrd. */
|
||||||
|
if (grub_le_to_cpu16 (lh->version) >= 0x0203)
|
||||||
|
{
|
||||||
|
addr_max = grub_cpu_to_le32 (lh->initrd_addr_max);
|
||||||
|
|
||||||
|
/* XXX in reality, Linux specifies a bogus value, so
|
||||||
|
it is necessary to make sure that ADDR_MAX does not exceed
|
||||||
|
0x3fffffff. */
|
||||||
|
if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS)
|
||||||
|
addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
|
||||||
|
|
||||||
if (linux_mem_size != 0 && linux_mem_size < addr_max)
|
if (linux_mem_size != 0 && linux_mem_size < addr_max)
|
||||||
addr_max = linux_mem_size;
|
addr_max = linux_mem_size;
|
||||||
|
|
||||||
|
@ -544,18 +557,19 @@ grub_rescue_cmd_initrd (int argc, char *argv[])
|
||||||
addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
|
addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
|
||||||
+ page_align (size);
|
+ page_align (size);
|
||||||
|
|
||||||
/* FIXME: This doesn't take addr_max & addr_min into account. */
|
if (addr_max > grub_os_area_addr + grub_os_area_size)
|
||||||
addr = (grub_addr_t) grub_malloc (page_align (size));
|
addr_max = grub_os_area_addr + grub_os_area_size;
|
||||||
|
|
||||||
if (addr == 0)
|
/* Put the initrd as high as possible, 4KiB aligned. */
|
||||||
|
addr = (addr_max - size) & ~0xFFF;
|
||||||
|
|
||||||
|
if (addr < addr_min)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, "no free pages available");
|
grub_error (GRUB_ERR_OUT_OF_RANGE, "The initrd is too big");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
initrd_mem = (void *) addr;
|
initrd_mem = (void *) addr;
|
||||||
if (! initrd_mem)
|
|
||||||
grub_fatal ("cannot allocate pages");
|
|
||||||
|
|
||||||
if (grub_file_read (file, initrd_mem, size) != size)
|
if (grub_file_read (file, initrd_mem, size) != size)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue