[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[1919] * loader/i386/linux.c (grub_rescue_cmd_initrd): Implement
From: |
Robert Millan |
Subject: |
[1919] * loader/i386/linux.c (grub_rescue_cmd_initrd): Implement a few needed |
Date: |
Wed, 19 Nov 2008 12:11:45 +0000 |
Revision: 1919
http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=1919
Author: robertmh
Date: 2008-11-19 12:11:44 +0000 (Wed, 19 Nov 2008)
Log Message:
-----------
* 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.
Modified Paths:
--------------
trunk/grub2/ChangeLog
trunk/grub2/loader/i386/linux.c
Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog 2008-11-19 12:05:20 UTC (rev 1918)
+++ trunk/grub2/ChangeLog 2008-11-19 12:11:44 UTC (rev 1919)
@@ -1,6 +1,10 @@
2008-11-19 Robert Millan <address@hidden>
* 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 <address@hidden>
Modified: trunk/grub2/loader/i386/linux.c
===================================================================
--- trunk/grub2/loader/i386/linux.c 2008-11-19 12:05:20 UTC (rev 1918)
+++ trunk/grub2/loader/i386/linux.c 2008-11-19 12:11:44 UTC (rev 1919)
@@ -529,8 +529,21 @@
initrd_pages = (page_align (size) >> 12);
lh = (struct linux_kernel_header *) real_mode_mem;
+
+ /* 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;
- addr_max = (grub_cpu_to_le32 (lh->initrd_addr_max) << 10);
if (linux_mem_size != 0 && linux_mem_size < addr_max)
addr_max = linux_mem_size;
@@ -544,18 +557,19 @@
addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
+ page_align (size);
- /* FIXME: This doesn't take addr_max & addr_min into account. */
- addr = (grub_addr_t) grub_malloc (page_align (size));
+ if (addr_max > grub_os_area_addr + grub_os_area_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;
}
initrd_mem = (void *) addr;
- if (! initrd_mem)
- grub_fatal ("cannot allocate pages");
if (grub_file_read (file, initrd_mem, size) != size)
{
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [1919] * loader/i386/linux.c (grub_rescue_cmd_initrd): Implement a few needed,
Robert Millan <=