Hell[o]

Attached rest of my grub changes.

affs: As mentioned on grub_ofdisk_open() the total_sectors value is
hosed on ieee1275 then we can not use it here. Anyway the code is
still a bit broken :( I will try to fix it in a free time in future.

Read: Fixed grub_ofdisk_read() for old versions of OF and fixed a read
error check. Not tested, but should be fine I hope.

ofboot: Added ofboot commands to boot using interface from firmware.
This allows us to boot MorphOS for example. As a addon I introduced a
command to execute a forth script before real boot which can be used
for example on efika to execute a device-tree fixup before boot linux.

A small example:

menuentry "MorphOS (Normal)" {
        ofboot    $mos_img $mos_3d ramdebug logserver
}

menuentry "Gentoo (2.6.22-gentoo-r8)" {
        set       root=(ide0,11)
        ofrun    efika.forth
        linux     /vmlinuz-2.6.22-gentoo-r8 video=radeonfb root=/dev/sda7
        initrd    /initrd-2.6.22-gentoo-r8.img
}

-- 
--- Marcin 'Morgoth' Kurek ---
diff -urN grub2.org/fs/affs.c grub2/fs/affs.c
--- grub2.org/fs/affs.c	2007-08-02 20:40:36.000000000 +0200
+++ grub2/fs/affs.c	2007-09-15 10:23:35.550133111 +0200
@@ -25,6 +25,7 @@
 #include <grub/dl.h>
 #include <grub/types.h>
 #include <grub/fshelp.h>
+#include <grub/partition.h>
 
 /* The affs bootblock.  */
 struct grub_affs_bblock
@@ -97,6 +98,9 @@
   struct grub_fshelp_node diropen;
   grub_disk_t disk;
 
+  /* Size in sectors */
+  grub_uint64_t len;
+
   /* Blocksize in sectors.  */
   int blocksize;
 
@@ -170,10 +174,17 @@
   int checksumr = 0;
   int blocksize = 0;
 
+
   data = grub_malloc (sizeof (struct grub_affs_data));
   if (!data)
     return 0;
 
+  /* total_sectors are not valid on ieee1275 */
+  if(disk->partition)
+    data->len = grub_partition_get_len (disk->partition);
+  else
+    data->len = disk->total_sectors;
+
   /* Read the bootblock.  */
   grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock),
 		  (char *) &data->bblock);
@@ -194,12 +205,6 @@
       goto fail;
     }
 
-  /* Read the bootblock.  */
-  grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock),
-		  (char *) &data->bblock);
-  if (grub_errno)
-    goto fail;
-
   /* No sane person uses more than 8KB for a block.  At least I hope
      for that person because in that case this won't work.  */
   rootblock = grub_malloc (GRUB_DISK_SECTOR_SIZE * 16);
@@ -209,7 +214,7 @@
   rblock = (struct grub_affs_rblock *) rootblock;
 
   /* Read the rootblock.  */
-  grub_disk_read (disk, (disk->total_sectors >> 1) + blocksize, 0,
+  grub_disk_read (disk, (data->len >> 1) + blocksize, 0,
 		  GRUB_DISK_SECTOR_SIZE * 16, (char *) rootblock);
   if (grub_errno)
     goto fail;
@@ -241,7 +246,7 @@
   data->disk = disk;
   data->htsize = grub_be_to_cpu32 (rblock->htsize);
   data->diropen.data = data;
-  data->diropen.block = (disk->total_sectors >> 1);
+  data->diropen.block = (data->len >> 1);
 
   grub_free (rootblock);
 
@@ -522,7 +527,7 @@
     {
       /* The rootblock maps quite well on a file header block, it's
 	 something we can use here.  */
-      grub_disk_read (data->disk, disk->total_sectors >> 1,
+      grub_disk_read (data->disk, data->len >> 1,
 		      data->blocksize * (GRUB_DISK_SECTOR_SIZE
 					 - GRUB_AFFS_FILE_LOCATION),
 		      sizeof (file), (char *) &file);
diff -urN grub2.org/disk/ieee1275/ofdisk.c grub2/disk/ieee1275/ofdisk.c
--- grub2.org/disk/ieee1275/ofdisk.c	2007-07-22 01:32:20.000000000 +0200
+++ grub2/disk/ieee1275/ofdisk.c	2007-10-15 21:45:40.998210358 +0200
@@ -124,7 +124,7 @@
 grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
 		  grub_size_t size, char *buf)
 {
-  grub_ssize_t status, actual;
+  grub_ssize_t status = 0, actual = 0;
   unsigned long long pos;
 
   grub_dprintf ("disk",
@@ -139,9 +139,10 @@
     return grub_error (GRUB_ERR_READ_ERROR,
 		       "Seek error, can't seek block %llu",
 		       sector);
+  size *= 512UL;
   grub_ieee1275_read ((grub_ieee1275_ihandle_t) disk->data, buf,
-		      size * 512UL, &actual);
-  if (actual != actual)
+		      size, &actual);
+  if (actual != size)
     return grub_error (GRUB_ERR_READ_ERROR, "Read error on block: %llu",
 		       sector);
     
diff -urN grub2.org/conf/powerpc-ieee1275.rmk grub2/conf/powerpc-ieee1275.rmk
--- grub2.org/conf/powerpc-ieee1275.rmk	2007-10-03 10:45:57.000000000 +0200
+++ grub2/conf/powerpc-ieee1275.rmk	2007-10-03 16:41:03.000000000 +0200
@@ -101,6 +101,8 @@
 
 # Modules.
 pkgdata_MODULES = halt.mod \
+	_ofboot.mod \
+	ofboot.mod \
 	_linux.mod \
 	linux.mod \
 	normal.mod \
@@ -109,6 +111,16 @@
         _multiboot.mod \
         multiboot.mod
 
+# For _ofboot.mod.
+_ofboot_mod_SOURCES = loader/powerpc/ieee1275/ofboot.c
+_ofboot_mod_CFLAGS = $(COMMON_CFLAGS)
+_ofboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ofboot.mod.
+ofboot_mod_SOURCES = loader/powerpc/ieee1275/ofboot_normal.c
+ofboot_mod_CFLAGS = $(COMMON_CFLAGS)
+ofboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For _linux.mod.
 _linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c
 _linux_mod_CFLAGS = $(COMMON_CFLAGS)
diff -urN grub2.org/include/grub/powerpc/ieee1275/loader.h grub2/include/grub/powerpc/ieee1275/loader.h
--- grub2.org/include/grub/powerpc/ieee1275/loader.h	2007-07-22 01:32:24.000000000 +0200
+++ grub2/include/grub/powerpc/ieee1275/loader.h	2007-10-03 16:07:43.000000000 +0200
@@ -23,10 +23,16 @@
    loader.  */
 void grub_rescue_cmd_linux (int argc, char *argv[]);
 void grub_rescue_cmd_initrd (int argc, char *argv[]);
+void grub_rescue_cmd_ofboot (int argc, char *argv[]);
+void grub_rescue_cmd_ofrun (int argc, char *argv[]);
 
 void grub_linux_init (void);
 void grub_linux_fini (void);
+void grub_ofboot_init (void);
+void grub_ofboot_fini (void);
 void grub_linux_normal_init (void);
 void grub_linux_normal_fini (void);
+void grub_ofboot_normal_init (void);
+void grub_ofboot_normal_fini (void);
 
 #endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff -urN grub2.org/loader/powerpc/ieee1275/ofboot.c grub2/loader/powerpc/ieee1275/ofboot.c
--- grub2.org/loader/powerpc/ieee1275/ofboot.c	1970-01-01 01:00:00.000000000 +0100
+++ grub2/loader/powerpc/ieee1275/ofboot.c	2007-10-03 16:09:51.000000000 +0200
@@ -0,0 +1,140 @@
+/* ofboot.c - OF boot */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003, 2004, 2005, 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/rescue.h>
+#include <grub/misc.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/machine/loader.h>
+
+static grub_dl_t my_mod;
+
+static grub_err_t
+grub_ofboot_boot (void)
+{
+  grub_err_t err;
+
+  err = grub_ieee1275_interpret("go", 0);
+
+  return err;
+}
+
+static grub_err_t
+grub_ofboot_unload (void)
+{
+  grub_dl_unref (my_mod);
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_ofboot_prepare (int argc, char *argv[])
+{
+  int i;
+  int size;
+  char *dest;
+  char *ofboot_args = 0;
+
+  grub_err_t err;
+  grub_ieee1275_cell_t res;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
+      goto out;
+    }
+
+  size = sizeof("load") + 1;
+  for (i = 0; i < argc; i++)
+    size += grub_strlen (argv[i]) + 1;
+
+  ofboot_args = grub_malloc (size);
+  if (! ofboot_args)
+    goto out;
+
+  dest = grub_stpcpy (ofboot_args, "load");
+  for (i = 0; i < argc; i++)
+    {
+      *dest++ = ' ';
+      dest = grub_stpcpy (dest, argv[i]);
+    }
+
+  err = grub_ieee1275_interpret(ofboot_args, &res);
+  if (err || res)
+  {
+    grub_error (GRUB_ERR_UNKNOWN_OS, "Failed to \"load\"");
+    goto out;
+  }
+
+  err = grub_ieee1275_interpret("init-program", &res);
+  if (err || res)
+  {
+    grub_error (GRUB_ERR_UNKNOWN_OS, "Failed to \"init-program\"");
+    goto out;
+  }
+
+out:
+  if(ofboot_args)
+    grub_free (ofboot_args);
+
+  return grub_errno;
+}
+
+void
+grub_rescue_cmd_ofrun (int argc, char *argv[])
+{
+  grub_ofboot_prepare (argc, argv);
+
+  if (grub_errno == GRUB_ERR_NONE)  
+      grub_ofboot_boot ();
+}
+
+void
+grub_rescue_cmd_ofboot (int argc, char *argv[])
+{
+  grub_dl_ref (my_mod);
+
+  /* Release the previously used memory.  */
+  grub_loader_unset ();
+
+  grub_ofboot_prepare (argc, argv);
+
+  if (grub_errno == GRUB_ERR_NONE)
+      grub_loader_set (grub_ofboot_boot, grub_ofboot_unload, 1);
+  else
+      grub_ofboot_unload ();
+}
+
+
+
+GRUB_MOD_INIT(ofboot)
+{
+  grub_rescue_register_command ("ofboot", grub_rescue_cmd_ofboot,
+				"load using OF interface");
+  grub_rescue_register_command ("ofrun", grub_rescue_cmd_ofrun,
+				"load&run using OF interface");
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(ofboot)
+{
+  grub_rescue_unregister_command ("ofrun");
+  grub_rescue_unregister_command ("ofboot");
+}
diff -urN grub2.org/loader/powerpc/ieee1275/ofboot_normal.c grub2/loader/powerpc/ieee1275/ofboot_normal.c
--- grub2.org/loader/powerpc/ieee1275/ofboot_normal.c	1970-01-01 01:00:00.000000000 +0100
+++ grub2/loader/powerpc/ieee1275/ofboot_normal.c	2007-10-03 16:08:59.000000000 +0200
@@ -0,0 +1,60 @@
+/* ofboot_normal.c - OF boot */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/machine/loader.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static grub_err_t
+grub_cmd_ofboot (struct grub_arg_list *state  __attribute__ ((unused)),
+		int argc, char **args)
+{
+  grub_rescue_cmd_ofboot (argc, args);
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_ofrun (struct grub_arg_list *state  __attribute__ ((unused)),
+		int argc, char **args)
+{
+  grub_rescue_cmd_ofrun (argc, args);
+  return GRUB_ERR_NONE;
+}
+
+GRUB_MOD_INIT(ofboot_normal)
+{
+  (void) mod;
+  grub_register_command ("ofboot", grub_cmd_ofboot, GRUB_COMMAND_FLAG_BOTH,
+			 "ofboot [ARGS...]",
+			 "Loads using OF interface", options);
+  grub_register_command ("ofrun", grub_cmd_ofrun, GRUB_COMMAND_FLAG_BOTH,
+			 "ofrun [ARGS...]",
+			 "Loads&Run using OF interface", options);
+}
+
+GRUB_MOD_FINI(ofboot_normal)
+{
+  grub_unregister_command ("ofrun");
+  grub_unregister_command ("ofboot");
+}
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to