bug-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

PATCH: Fix for multiple initrd files


From: Dave Cinege
Subject: PATCH: Fix for multiple initrd files
Date: Thu, 28 Jun 2001 21:33:01 -0400

Okuji,

Back in January I wrote a patch that basically did this, and you
replied with a better version. I've finally gotten around to testing,
fixing, and making ready your patch.

This patch fixes GRUB's initrd loading behavior. Each 'initrd' call is
now loaded 'inline' instead of replacing the previous file.
This allows one to load an initrd image that is split across several
devices (or floppies, using 'pause'). It also allows kernel patches
like initrd_dynamic to load multiple tgz archives to construct a
root.

Example:
kernel (fd0)/linux load_ramdisk=1 blah blah
initrd (fd0)/img1.bin
pause Insert disk2 and hit enter
initrd (fd0)/img2.bin
pause Insert disk3 and hit enter
initrd (fd0)/img3.bin

Diff'ed against CVS 20010622 boot.c. It's quite straight forward
and safe. Please include it for 0.5.97 release. (After you fix that nogunzip
for initrd. ; > )

Dave
--- boot.c.orig Thu Jun 28 20:09:27 2001
+++ boot.c      Thu Jun 28 21:13:38 2001
@@ -630,9 +630,10 @@
 int
 load_initrd (char *initrd)
 {
+
   int len;
   unsigned long moveto;
-  struct linux_kernel_header *lh;
+  struct linux_kernel_header *lh = (struct linux_kernel_header *) LINUX_SETUP;
   
   if (! grub_open (initrd))
     return 0;
@@ -644,23 +645,39 @@
       return 0;
     }
 
-  moveto = ((mbi.mem_upper + 0x400) * 0x400 - len) & 0xfffff000;
-  if (moveto + len >= LINUX_INITRD_MAX_ADDRESS)
-    moveto = (LINUX_INITRD_MAX_ADDRESS - len) & 0xfffff000;
+  /* Load multiple files one after the other. Allows initrd images
+     to span several devices (discs), and also allows multiple 
+     archives to be used with the initrd_dynamic kernel patch. */
+  if (lh->ramdisk_size != 0)
+    {
+      moveto = (lh->ramdisk_image - len) & 0xfffff000;
+      grub_memmove ((void *) moveto, (void *) lh->ramdisk_image,
+                  lh->ramdisk_size);
+      lh->ramdisk_image = moveto;
+      
+      moveto += lh->ramdisk_size;
+      grub_memmove ((void *) moveto, (void *) cur_addr, len);
+      lh->ramdisk_size += len;
+    }
+  else
+    {
+      moveto = ((mbi.mem_upper + 0x400) * 0x400 - len) & 0xfffff000;
+      if (moveto + len >= LINUX_INITRD_MAX_ADDRESS)
+        moveto = (LINUX_INITRD_MAX_ADDRESS - len) & 0xfffff000;
   
-  /* XXX: Linux 2.3.xx has a bug in the memory range check, so avoid
-     the last page.
-     XXX: Linux 2.2.xx has a bug in the memory range check, which is
-     worse than that of Linux 2.3.xx, so avoid the last 64kb. *sigh*  */
-  moveto -= 0x10000;
-  memmove ((void *) RAW_ADDR (moveto), (void *) cur_addr, len);
+      /* XXX: Linux 2.3.xx has a bug in the memory range check, so avoid
+         the last page.
+         XXX: Linux 2.2.xx has a bug in the memory range check, which is
+         worse than that of Linux 2.3.xx, so avoid the last 64kb. *sigh*  */
+      moveto -= 0x10000;
+      memmove ((void *) RAW_ADDR (moveto), (void *) cur_addr, len);
 
-  printf ("   [Linux-initrd @ 0x%x, 0x%x bytes]\n", moveto, len);
+      /* FIXME: Should check if the kernel supports INITRD.  */
+      lh->ramdisk_image = RAW_ADDR (moveto);
+      lh->ramdisk_size = len;
+    }
 
-  /* FIXME: Should check if the kernel supports INITRD.  */
-  lh = (struct linux_kernel_header *) LINUX_SETUP;
-  lh->ramdisk_image = RAW_ADDR (moveto);
-  lh->ramdisk_size = len;
+  printf ("   [Linux-initrd @ 0x%x, 0x%x (%d) bytes]\n", moveto, len, len );
 
   grub_close ();
   return 1;

reply via email to

[Prev in Thread] Current Thread [Next in Thread]