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