grub-devel
[Top][All Lists]
Advanced

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

vmlinux and initrd support for the PPC


From: Marco Gerards
Subject: vmlinux and initrd support for the PPC
Date: Sat, 29 Jan 2005 00:10:24 +0000
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)

Hi,

Here is a patch to add vmlinux support and initrd support to the linux
loader of the PPC port.  I have tested the loader with several vmlinux
and vmlinuz kernels and with an initrd.

If I don't hear anything, I will just commit this patch on Monday.

Thanks,
Marco

2005-01-29  Marco Gerards  <address@hidden>

        * include/grub/powerpc/ieee1275/loader.h (grub_load_linux):
        Removed prototype.
        (grub_rescue_cmd_linux): New prototype.
        (grub_rescue_cmd_initrd): Likewise.
        * powerpc/ieee1275/linux.c (grub_linux_boot): Remove struct
        `bi_rec'.
        (grub_linux_release_mem): Release the memory for the initrd.
        (grub_load_linux): Renamed from this...
        (grub_rescue_cmd_linux): ...To this.  Changed all callers.
        Changed `entry' not to be static.  Loop over memory regions to
        find another one when the default fails.
        (grub_rescue_cmd_initrd): New function.
        (grub_linux_init): Remove function.
        (grub_linux_fini): Likewise.
        (GRUB_MOD_INIT): Register `initrd'.
        (GRUB_MOD_FINI): Unregister `initrd'.
        * powerpc/ieee1275/linux_normal.c (grub_linux_normal_init):
        Function removed.
        (grub_linux_normal_fini): Likewise.
        (GRUB_MOD_INIT): Register `initrd'.
        (GRUB_MOD_FINI): Unregister `initrd'.


Index: include/grub/powerpc/ieee1275/loader.h
===================================================================
RCS file: /cvsroot/grub/grub2/include/grub/powerpc/ieee1275/loader.h,v
retrieving revision 1.3
diff -u -p -r1.3 loader.h
--- include/grub/powerpc/ieee1275/loader.h      27 Jul 2004 17:47:37 -0000      
1.3
+++ include/grub/powerpc/ieee1275/loader.h      29 Jan 2005 00:06:26 -0000
@@ -22,7 +22,8 @@
 
 /* The symbol shared between the normal mode and rescue mode
    loader.  */
-void grub_load_linux (int argc, char *argv[]);
+void grub_rescue_cmd_linux (int argc, char *argv[]);
+void grub_rescue_cmd_initrd (int argc, char *argv[]);
 
 void grub_linux_init (void);
 void grub_linux_fini (void);
Index: loader/powerpc/ieee1275/linux.c
===================================================================
RCS file: /cvsroot/grub/grub2/loader/powerpc/ieee1275/linux.c,v
retrieving revision 1.4
diff -u -p -r1.4 linux.c
--- loader/powerpc/ieee1275/linux.c     29 Oct 2004 02:45:14 -0000      1.4
+++ loader/powerpc/ieee1275/linux.c     29 Jan 2005 00:06:27 -0000
@@ -50,13 +50,6 @@ grub_linux_boot (void)
   grub_ieee1275_phandle_t chosen;
   grub_size_t actual;
   
-  struct bi_rec
-  {
-    unsigned long tag;
-    unsigned long size;
-    unsigned long data[0];
-  };
-  
   grub_ieee1275_finddevice ("/chosen", &chosen);
   
   /* Set the command line arguments.  */
@@ -79,7 +72,12 @@ grub_linux_release_mem (void)
   if (linux_addr && grub_ieee1275_release (linux_addr, linux_size))
     return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not release memory");
   
+  if (initrd_addr && grub_ieee1275_release (initrd_addr, initrd_size))
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not release memory");
+  
   linux_addr = 0;
+  initrd_addr = 0;
+  
   return GRUB_ERR_NONE;
 }
 
@@ -97,14 +95,15 @@ grub_linux_unload (void)
 }
 
 void
-grub_load_linux (int argc, char *argv[])
+grub_rescue_cmd_linux (int argc, char *argv[])
 {
   grub_file_t file = 0;
   Elf32_Ehdr ehdr;
   Elf32_Phdr *phdrs = 0;
   int i;  
   int offset = 0;
-  static grub_addr_t entry;
+  grub_addr_t entry;
+  int found_addr = 0;
   int size;
   
   grub_dl_ref (my_mod);
@@ -188,13 +187,22 @@ grub_load_linux (int argc, char *argv[])
   /* Reserve memory for the kernel.  */
   linux_size += 0x100000;
   
-  if (grub_claimmap (entry, linux_size) == -1)
+  /* For some vmlinux kernels the address set above won't work.  Just
+     try some other addresses just like yaboot does.  */
+  for (linux_addr = entry; linux_addr < entry + 200 * 0x100000; linux_addr += 
0x100000)
+    {
+      found_addr = grub_claimmap (linux_addr, linux_size);
+      if (found_addr != -1)
+       break;
+    }
+
+  if (found_addr == -1)
     {
       grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not claim memory");
       goto fail;
     }
-  linux_addr = entry;
-
+  entry = linux_addr;
+  
   /* Load every loadable segment in memory.  */
   for (i = 0; i < ehdr.e_phnum; i++)
     {
@@ -257,28 +265,66 @@ grub_load_linux (int argc, char *argv[])
   return;
 }
 
-
-GRUB_MOD_INIT
+void
+grub_rescue_cmd_initrd (int argc, char *argv[])
 {
-  grub_rescue_register_command ("linux", grub_load_linux,
-                               "load a linux kernel");
-  my_mod = mod;
-}
+  grub_file_t file = 0;
+  grub_ssize_t size;
+  grub_addr_t addr;
+  
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified");
+      goto fail;
+    }
+  
+  if (!loaded)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first.");
+      goto fail;
+    }
 
-GRUB_MOD_FINI
-{
-  grub_rescue_unregister_command ("linux");
+  file = grub_file_open (argv[0]);
+  if (! file)
+    goto fail;
+  
+  addr = linux_addr + linux_size;
+  size = grub_file_size (file);
+  
+  if (grub_claimmap (addr, size) == -1)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not claim memory");
+      goto fail;
+    }
+  
+  if (grub_file_read (file, (void *) addr, size) != size)
+    {
+      grub_ieee1275_release (addr, size);
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
+  
+  initrd_addr = addr;
+  initrd_size = size;
+  
+ fail:
+  if (file)
+    grub_file_close (file);
 }
 
-void
-grub_linux_init (void)
+
+
+GRUB_MOD_INIT
 {
-  grub_rescue_register_command ("linux", grub_load_linux,
+  grub_rescue_register_command ("linux", grub_rescue_cmd_linux,
                                "load a linux kernel");
+  grub_rescue_register_command ("initrd", grub_rescue_cmd_initrd,
+                               "load an initrd");
+  my_mod = mod;
 }
 
-void
-grub_linux_fini (void)
+GRUB_MOD_FINI
 {
   grub_rescue_unregister_command ("linux");
+  grub_rescue_unregister_command ("initrd");
 }
Index: loader/powerpc/ieee1275/linux_normal.c
===================================================================
RCS file: /cvsroot/grub/grub2/loader/powerpc/ieee1275/linux_normal.c,v
retrieving revision 1.1
diff -u -p -r1.1 linux_normal.c
--- loader/powerpc/ieee1275/linux_normal.c      27 Jul 2004 17:47:37 -0000      
1.1
+++ loader/powerpc/ieee1275/linux_normal.c      29 Jan 2005 00:06:28 -0000
@@ -31,33 +31,31 @@ static grub_err_t
 grub_cmd_linux (struct grub_arg_list *state  __attribute__ ((unused)),
                int argc, char **args)
 {
-  grub_load_linux (argc, args);
+  grub_rescue_cmd_linux (argc, args);
   return GRUB_ERR_NONE;
 }
 
-GRUB_MOD_INIT
-{
-  (void) mod;
-  grub_register_command ("linux", grub_cmd_linux, GRUB_COMMAND_FLAG_BOTH,
-                        "linux [KERNELARGS...]",
-                        "Loads linux", options);
-}
-
-GRUB_MOD_FINI
+static grub_err_t
+grub_cmd_initrd (struct grub_arg_list *state  __attribute__ ((unused)),
+                int argc, char **args)
 {
-  grub_unregister_command ("linux");
+  grub_rescue_cmd_initrd (argc, args);
+  return GRUB_ERR_NONE;
 }
 
-void
-grub_linux_normal_init (void)
+GRUB_MOD_INIT
 {
+  (void) mod;
   grub_register_command ("linux", grub_cmd_linux, GRUB_COMMAND_FLAG_BOTH,
                         "linux [KERNELARGS...]",
                         "Loads linux", options);
+  grub_register_command ("initrd", grub_cmd_initrd, GRUB_COMMAND_FLAG_BOTH,
+                        "initrd FILE",
+                        "Loads initrd", options);
 }
 
-void
-grub_linux_normal_fini (void)
+GRUB_MOD_FINI
 {
   grub_unregister_command ("linux");
+  grub_unregister_command ("initrd");
 }





reply via email to

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