From a377d1896004cf46ece8105fa7c4c55a9d5655e2 Mon Sep 17 00:00:00 2001 From: proski Date: Wed, 2 Jul 2008 19:14:55 +0000 Subject: [PATCH 01/52] Add grub-editenv to ignored files git-svn-id: svn://svn.savannah.gnu.org/grub/trunk/grub2@1674 d0de0278-0dc1-4c01-8a07-af38b3205e46 From d3ab74c94d69cd5e8b9fe8c3529129de7fae9501 Mon Sep 17 00:00:00 2001 From: proski Date: Wed, 2 Jul 2008 19:16:49 +0000 Subject: [PATCH 02/52] Ignore "cpu" and "machine" symlinks git-svn-id: svn://svn.savannah.gnu.org/grub/trunk/grub2@1675 d0de0278-0dc1-4c01-8a07-af38b3205e46 From fd4370fc338ab1d9b2a475b248b3627f17281990 Mon Sep 17 00:00:00 2001 From: phcoder Date: Fri, 28 Aug 2009 20:09:44 +0200 Subject: [PATCH 03/52] Move grub_usb_get_string. --- ChangeLog | 7 +++++++ bus/usb/usb.c | 36 ---------------------------------- commands/usbtest.c | 48 +++++++++++++++++++++++++++++++++++++++++++--- include/grub/usb.h | 3 --- 4 files changed, 52 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index b657885fe..3e8d2533b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-08-28 Vladimir Serbinenko + + * bus/usb/usb.c (grub_usb_get_string): Move from here ... + * commands/usbtest.c (grub_usb_get_string): ... move here. + (usb_print_str): Fix error handling. + * include/grub/usb.h (grub_usb_get_string): Remove. + 2009-08-28 Vladimir Serbinenko * kern/file.c (grub_file_read): Check offset. diff --git a/bus/usb/usb.c b/bus/usb/usb.c index 310b8cc6a..8289185da 100644 --- a/bus/usb/usb.c +++ b/bus/usb/usb.c @@ -155,42 +155,6 @@ grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr) return NULL; } -grub_usb_err_t -grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid, - char **string) -{ - struct grub_usb_desc_str descstr; - struct grub_usb_desc_str *descstrp; - grub_usb_err_t err; - - /* Only get the length. */ - err = grub_usb_control_msg (dev, 1 << 7, - 0x06, (3 << 8) | index, - langid, 1, (char *) &descstr); - if (err) - return err; - - descstrp = grub_malloc (descstr.length); - if (! descstrp) - return GRUB_USB_ERR_INTERNAL; - err = grub_usb_control_msg (dev, 1 << 7, - 0x06, (3 << 8) | index, - langid, descstr.length, (char *) descstrp); - - *string = grub_malloc (descstr.length / 2); - if (! *string) - { - grub_free (descstrp); - return GRUB_USB_ERR_INTERNAL; - } - - grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, descstrp->length / 2 - 1); - (*string)[descstr.length / 2 - 1] = '\0'; - grub_free (descstrp); - - return GRUB_USB_ERR_NONE; -} - grub_usb_err_t grub_usb_device_initialize (grub_usb_device_t dev) { diff --git a/commands/usbtest.c b/commands/usbtest.c index 018c1a25b..1c49d8104 100644 --- a/commands/usbtest.c +++ b/commands/usbtest.c @@ -59,18 +59,60 @@ static const char *usb_devspeed[] = "High" }; +static grub_usb_err_t +grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid, + char **string) +{ + struct grub_usb_desc_str descstr; + struct grub_usb_desc_str *descstrp; + grub_usb_err_t err; + + /* Only get the length. */ + err = grub_usb_control_msg (dev, 1 << 7, + 0x06, (3 << 8) | index, + langid, 1, (char *) &descstr); + if (err) + return err; + + descstrp = grub_malloc (descstr.length); + if (! descstrp) + return GRUB_USB_ERR_INTERNAL; + err = grub_usb_control_msg (dev, 1 << 7, + 0x06, (3 << 8) | index, + langid, descstr.length, (char *) descstrp); + + *string = grub_malloc (descstr.length / 2); + if (! *string) + { + grub_free (descstrp); + return GRUB_USB_ERR_INTERNAL; + } + + grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, descstrp->length / 2 - 1); + (*string)[descstr.length / 2 - 1] = '\0'; + grub_free (descstrp); + + return GRUB_USB_ERR_NONE; +} + static void usb_print_str (const char *description, grub_usb_device_t dev, int idx) { char *name; + grub_usb_err_t err; /* XXX: LANGID */ if (! idx) return; - grub_usb_get_string (dev, idx, 0x0409, &name); - grub_printf ("%s: `%s'\n", description, name); - grub_free (name); + err = grub_usb_get_string (dev, idx, 0x0409, &name); + if (err) + grub_printf ("Error %d retrieving %s\n", err, description); + else + { + grub_printf ("%s: `%s'\n", description, name); + grub_free (name); + } } static int diff --git a/include/grub/usb.h b/include/grub/usb.h index 8dd3b6e2e..dc90e7879 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -64,9 +64,6 @@ grub_usb_err_t grub_usb_clear_halt (grub_usb_device_t dev, int endpoint); grub_usb_err_t grub_usb_set_configuration (grub_usb_device_t dev, int configuration); -grub_usb_err_t grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, - int langid, char **string); - void grub_usb_controller_dev_register (grub_usb_controller_dev_t usb); void grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb); From b8dae8de40888ec7ef446dc14649f649733db06d Mon Sep 17 00:00:00 2001 From: phcoder Date: Fri, 28 Aug 2009 20:58:50 +0200 Subject: [PATCH 04/52] utf16_to_utf8 --- fs/fat.c | 1 + fs/hfsplus.c | 1 + fs/iso9660.c | 1 + fs/jfs.c | 1 + fs/ntfs.c | 1 + include/grub/charset.h | 84 ++++++++++++++++++++++++++++++++++++++++ include/grub/misc.h | 3 -- kern/efi/efi.c | 1 + kern/misc.c | 62 ----------------------------- loader/efi/chainloader.c | 1 + 10 files changed, 91 insertions(+), 65 deletions(-) create mode 100644 include/grub/charset.h diff --git a/fs/fat.c b/fs/fat.c index 8440e43fa..e4a072952 100644 --- a/fs/fat.c +++ b/fs/fat.c @@ -25,6 +25,7 @@ #include #include #include +#include #define GRUB_FAT_DIR_ENTRY_SIZE 32 diff --git a/fs/hfsplus.c b/fs/hfsplus.c index 5e0ab093f..3c2e0c7bd 100644 --- a/fs/hfsplus.c +++ b/fs/hfsplus.c @@ -28,6 +28,7 @@ #include #include #include +#include #define GRUB_HFSPLUS_MAGIC 0x482B #define GRUB_HFSPLUSX_MAGIC 0x4858 diff --git a/fs/iso9660.c b/fs/iso9660.c index 9b7ce765b..976222a45 100644 --- a/fs/iso9660.c +++ b/fs/iso9660.c @@ -26,6 +26,7 @@ #include #include #include +#include #define GRUB_ISO9660_FSTYPE_DIR 0040000 #define GRUB_ISO9660_FSTYPE_REG 0100000 diff --git a/fs/jfs.c b/fs/jfs.c index b73f9bdd4..589b6ae5a 100644 --- a/fs/jfs.c +++ b/fs/jfs.c @@ -24,6 +24,7 @@ #include #include #include +#include #define GRUB_JFS_MAX_SYMLNK_CNT 8 #define GRUB_JFS_FILETYPE_MASK 0170000 diff --git a/fs/ntfs.c b/fs/ntfs.c index 3ff487c6e..ab75ccc63 100644 --- a/fs/ntfs.c +++ b/fs/ntfs.c @@ -24,6 +24,7 @@ #include #include #include +#include static grub_dl_t my_mod; diff --git a/include/grub/charset.h b/include/grub/charset.h new file mode 100644 index 000000000..b1db51f24 --- /dev/null +++ b/include/grub/charset.h @@ -0,0 +1,84 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 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 . + */ + +#ifndef GRUB_CHARSET_HEADER +#define GRUB_CHARSET_HEADER 1 + +/* Convert UTF-16 to UTF-8. */ +static inline grub_uint8_t * +grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src, + grub_size_t size) +{ + grub_uint32_t code_high = 0; + + while (size--) + { + grub_uint32_t code = *src++; + + if (code_high) + { + if (code >= 0xDC00 && code <= 0xDFFF) + { + /* Surrogate pair. */ + code = ((code_high - 0xD800) << 12) + (code - 0xDC00) + 0x10000; + + *dest++ = (code >> 18) | 0xF0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + else + { + /* Error... */ + *dest++ = '?'; + } + + code_high = 0; + } + else + { + if (code <= 0x007F) + *dest++ = code; + else if (code <= 0x07FF) + { + *dest++ = (code >> 6) | 0xC0; + *dest++ = (code & 0x3F) | 0x80; + } + else if (code >= 0xD800 && code <= 0xDBFF) + { + code_high = code; + continue; + } + else if (code >= 0xDC00 && code <= 0xDFFF) + { + /* Error... */ + *dest++ = '?'; + } + else + { + *dest++ = (code >> 12) | 0xE0; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + } + } + + return dest; +} + +#endif diff --git a/include/grub/misc.h b/include/grub/misc.h index a63a0b442..51a4650c8 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -177,9 +177,6 @@ int EXPORT_FUNC(grub_sprintf) (char *str, const char *fmt, ...) __attribute__ (( int EXPORT_FUNC(grub_vsprintf) (char *str, const char *fmt, va_list args); void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn)); void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn)); -grub_uint8_t *EXPORT_FUNC(grub_utf16_to_utf8) (grub_uint8_t *dest, - grub_uint16_t *src, - grub_size_t size); grub_ssize_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest, grub_size_t destsize, const grub_uint8_t *src, diff --git a/kern/efi/efi.c b/kern/efi/efi.c index 8e09a90c0..7be7882a3 100644 --- a/kern/efi/efi.c +++ b/kern/efi/efi.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include diff --git a/kern/misc.c b/kern/misc.c index 1c38fe661..b5e41d1aa 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -837,68 +837,6 @@ grub_sprintf (char *str, const char *fmt, ...) return ret; } -/* Convert UTF-16 to UTF-8. */ -grub_uint8_t * -grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src, - grub_size_t size) -{ - grub_uint32_t code_high = 0; - - while (size--) - { - grub_uint32_t code = *src++; - - if (code_high) - { - if (code >= 0xDC00 && code <= 0xDFFF) - { - /* Surrogate pair. */ - code = ((code_high - 0xD800) << 12) + (code - 0xDC00) + 0x10000; - - *dest++ = (code >> 18) | 0xF0; - *dest++ = ((code >> 12) & 0x3F) | 0x80; - *dest++ = ((code >> 6) & 0x3F) | 0x80; - *dest++ = (code & 0x3F) | 0x80; - } - else - { - /* Error... */ - *dest++ = '?'; - } - - code_high = 0; - } - else - { - if (code <= 0x007F) - *dest++ = code; - else if (code <= 0x07FF) - { - *dest++ = (code >> 6) | 0xC0; - *dest++ = (code & 0x3F) | 0x80; - } - else if (code >= 0xD800 && code <= 0xDBFF) - { - code_high = code; - continue; - } - else if (code >= 0xDC00 && code <= 0xDFFF) - { - /* Error... */ - *dest++ = '?'; - } - else - { - *dest++ = (code >> 12) | 0xE0; - *dest++ = ((code >> 6) & 0x3F) | 0x80; - *dest++ = (code & 0x3F) | 0x80; - } - } - } - - return dest; -} - /* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string. Return the number of characters converted. DEST must be able to hold diff --git a/loader/efi/chainloader.c b/loader/efi/chainloader.c index 01acc4135..9c833e9b9 100644 --- a/loader/efi/chainloader.c +++ b/loader/efi/chainloader.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include From 49ffc6c6273eec1af1b28395ff56b898e1612731 Mon Sep 17 00:00:00 2001 From: phcoder Date: Fri, 28 Aug 2009 20:59:54 +0200 Subject: [PATCH 05/52] finished merge --- commands/usbtest.c | 1 + 1 file changed, 1 insertion(+) diff --git a/commands/usbtest.c b/commands/usbtest.c index 1c49d8104..3405c3b4d 100644 --- a/commands/usbtest.c +++ b/commands/usbtest.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include From 74f391dded3f4d86c5f75192b8049b0c047f5615 Mon Sep 17 00:00:00 2001 From: phcoder Date: Fri, 28 Aug 2009 21:17:23 +0200 Subject: [PATCH 06/52] Changelog --- ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3e8d2533b..6e424b3fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-08-28 Vladimir Serbinenko + + * kern/misc.c (grub_utf16_to_utf8): Move from here ... + * include/grub/charset.h (grub_utf16_to_utf8): ... to here. Inlined. + All users updated. + * include/grub/misc.h (grub_utf16_to_utf8): Removed. + 2009-08-28 Vladimir Serbinenko * bus/usb/usb.c (grub_usb_get_string): Move from here ... From 965632c10f764c63b70c17bd3f4cd5e8acba5ade Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 30 Aug 2009 14:26:41 +0200 Subject: [PATCH 07/52] snow32 support. --- include/grub/i386/xnu.h | 2 +- include/grub/xnu.h | 2 ++ loader/xnu.c | 47 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/include/grub/i386/xnu.h b/include/grub/i386/xnu.h index 68674e605..57ba0f0b6 100644 --- a/include/grub/i386/xnu.h +++ b/include/grub/i386/xnu.h @@ -64,7 +64,7 @@ struct grub_xnu_boot_params /* Size of grub_efi_uintn_t in bits. */ grub_uint8_t efi_uintnbits; } __attribute__ ((packed)); -#define GRUB_XNU_BOOTARGS_VERMINOR 4 +#define GRUB_XNU_BOOTARGS_VERMINOR 5 #define GRUB_XNU_BOOTARGS_VERMAJOR 1 extern grub_uint32_t grub_xnu_entry_point; diff --git a/include/grub/xnu.h b/include/grub/xnu.h index c3902e670..67d78d92c 100644 --- a/include/grub/xnu.h +++ b/include/grub/xnu.h @@ -76,6 +76,8 @@ struct grub_xnu_extheader grub_uint32_t infoplistsize; grub_uint32_t binaryaddr; grub_uint32_t binarysize; + grub_uint32_t nameaddr; + grub_uint32_t namesize; } __attribute__ ((packed)); struct grub_xnu_devtree_key *grub_xnu_create_key (struct grub_xnu_devtree_key **parent, diff --git a/loader/xnu.c b/loader/xnu.c index aac4ae372..1f29b69a1 100644 --- a/loader/xnu.c +++ b/loader/xnu.c @@ -494,6 +494,34 @@ grub_xnu_register_memory (char *prefix, int *suffix, return GRUB_ERR_NONE; } +static inline char * +get_name_ptr (char *name) +{ + char *p = name, *p2; + /* Skip Info.plist. */ + p2 = grub_strrchr (p, '/'); + if (!p2) + return name; + if (p2 == name) + return name + 1; + p = p2 - 1; + + p2 = grub_strrchr (p, '/'); + if (!p2) + return name; + if (p2 == name) + return name + 1; + if (grub_memcmp (p2, "/Contents/", sizeof ("/Contents/") - 1) != 0) + return p2 + 1; + + p = p2 - 1; + + p2 = grub_strrchr (p, '/'); + if (!p2) + return name; + return p2 + 1; +} + /* Load .kext. */ static grub_err_t grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) @@ -505,6 +533,18 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) int neededspace = sizeof (*exthead); char *buf; grub_size_t infoplistsize = 0, machosize = 0; + char *name, *nameend; + int namelen; + + name = get_name_ptr (infoplistname); + nameend = grub_strchr (name, '/'); + + if (nameend) + namelen = nameend - name; + else + namelen = grub_strlen (name); + + neededspace += namelen + 1; if (! grub_xnu_heap_size) return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded"); @@ -581,9 +621,16 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) } grub_file_close (infoplist); buf[infoplistsize] = 0; + buf += infoplistsize + 1; } grub_errno = GRUB_ERR_NONE; + exthead->nameaddr = (buf - grub_xnu_heap_start) + grub_xnu_heap_will_be_at; + exthead->namesize = namelen + 1; + grub_memcpy (buf, name, namelen); + buf[namelen] = 0; + buf += namelen + 1; + /* Announce to kernel */ return grub_xnu_register_memory ("Driver-", &driversnum, exthead, neededspace); From 72db7c22f3e1a8541517906ff8beef63a34f7ce8 Mon Sep 17 00:00:00 2001 From: phcoder Date: Wed, 2 Sep 2009 02:52:10 +0200 Subject: [PATCH 08/52] crashing snow64 --- conf/i386-efi.rmk | 5 +- conf/i386-pc.rmk | 5 +- conf/x86_64-efi.rmk | 5 +- include/grub/i386/macho.h | 35 ++++++ include/grub/macho.h | 17 +++ include/grub/machoload.h | 23 +++- loader/macho.c | 236 +------------------------------------- loader/xnu.c | 145 +++++++++++++++++++++-- 8 files changed, 214 insertions(+), 257 deletions(-) diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index 18a9a636b..4eb3853f1 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -196,8 +196,9 @@ fixvideo_mod_CFLAGS = $(COMMON_CFLAGS) fixvideo_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += xnu.mod -xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c\ - loader/macho.c loader/xnu.c loader/i386/xnu_helper.S +xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c \ + loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c \ + loader/i386/xnu_helper.S xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 8d7d9fca9..a617e1b78 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -242,8 +242,9 @@ linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += xnu.mod -xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/pc/xnu.c\ - loader/macho.c loader/xnu.c loader/i386/xnu_helper.S +xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/pc/xnu.c \ + loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c \ + loader/i386/xnu_helper.S xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk index 1a4cf89ed..5087465b4 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -195,8 +195,9 @@ fixvideo_mod_CFLAGS = $(COMMON_CFLAGS) fixvideo_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += xnu.mod -xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c\ - loader/macho.c loader/xnu.c loader/i386/xnu_helper.S +xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c \ + loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c \ + loader/i386/xnu_helper.S xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/include/grub/i386/macho.h b/include/grub/i386/macho.h index 61e72a71b..f22c21190 100644 --- a/include/grub/i386/macho.h +++ b/include/grub/i386/macho.h @@ -1,3 +1,26 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 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 . + */ + +#ifndef GRUB_CPU_MACHO_H +#define GRUB_CPU_MACHO_H 1 + +#include + #define GRUB_MACHO_CPUTYPE_IS_HOST32(x) ((x)==0x00000007) #define GRUB_MACHO_CPUTYPE_IS_HOST64(x) ((x)==0x01000007) @@ -9,3 +32,15 @@ struct grub_macho_thread32 grub_uint32_t entry_point; grub_uint8_t unknown2[20]; } __attribute__ ((packed)); + + +struct grub_macho_thread64 +{ + grub_uint32_t cmd; + grub_uint32_t cmdsize; + grub_uint8_t unknown1[0x88]; + grub_uint64_t entry_point; + grub_uint8_t unknown2[0x20]; +} __attribute__ ((packed)); + +#endif diff --git a/include/grub/macho.h b/include/grub/macho.h index 0604100e9..82145835f 100644 --- a/include/grub/macho.h +++ b/include/grub/macho.h @@ -102,6 +102,23 @@ struct grub_macho_segment32 grub_uint32_t flags; } __attribute__ ((packed)); +/* 64-bit segment command. */ +struct grub_macho_segment64 +{ +#define GRUB_MACHO_CMD_SEGMENT64 0x19 + grub_uint32_t cmd; + grub_uint32_t cmdsize; + grub_uint8_t segname[16]; + grub_uint64_t vmaddr; + grub_uint64_t vmsize; + grub_uint64_t fileoff; + grub_uint64_t filesize; + grub_macho_vmprot_t maxprot; + grub_macho_vmprot_t initprot; + grub_uint32_t nsects; + grub_uint32_t flags; +} __attribute__ ((packed)); + #define GRUB_MACHO_CMD_THREAD 5 #endif diff --git a/include/grub/machoload.h b/include/grub/machoload.h index a80bac68c..8410162fb 100644 --- a/include/grub/machoload.h +++ b/include/grub/machoload.h @@ -46,17 +46,28 @@ grub_macho_t grub_macho_file (grub_file_t); grub_err_t grub_macho_close (grub_macho_t); int grub_macho_contains_macho32 (grub_macho_t); -grub_err_t grub_macho32_size (grub_macho_t macho, grub_addr_t *segments_start, - grub_addr_t *segments_end, int flags); -grub_uint32_t grub_macho32_get_entry_point (grub_macho_t macho); +grub_err_t grub_macho_size32 (grub_macho_t macho, grub_uint32_t *segments_start, + grub_uint32_t *segments_end, int flags); +grub_uint32_t grub_macho_get_entry_point32 (grub_macho_t macho); + +int grub_macho_contains_macho64 (grub_macho_t); +grub_err_t grub_macho_size64 (grub_macho_t macho, grub_uint64_t *segments_start, + grub_uint64_t *segments_end, int flags); +grub_uint64_t grub_macho_get_entry_point64 (grub_macho_t macho); /* Ignore BSS segments when loading. */ #define GRUB_MACHO_NOBSS 0x1 -grub_err_t grub_macho32_load (grub_macho_t macho, char *offset, int flags); +grub_err_t grub_macho_load32 (grub_macho_t macho, char *offset, int flags); +grub_err_t grub_macho_load64 (grub_macho_t macho, char *offset, int flags); /* Like filesize and file_read but take only 32-bit part for current architecture. */ -grub_size_t grub_macho32_filesize (grub_macho_t macho); -grub_err_t grub_macho32_readfile (grub_macho_t macho, void *dest); +grub_size_t grub_macho_filesize32 (grub_macho_t macho); +grub_err_t grub_macho_readfile32 (grub_macho_t macho, void *dest); +grub_size_t grub_macho_filesize64 (grub_macho_t macho); +grub_err_t grub_macho_readfile64 (grub_macho_t macho, void *dest); + +void grub_macho_parse32 (grub_macho_t macho); +void grub_macho_parse64 (grub_macho_t macho); #endif /* ! GRUB_MACHOLOAD_HEADER */ diff --git a/loader/macho.c b/loader/macho.c index bd460b810..a23f5b206 100644 --- a/loader/macho.c +++ b/loader/macho.c @@ -30,239 +30,6 @@ #include #include -#define min(a,b) (((a) < (b)) ? (a) : (b)) - -/* 32-bit. */ - -int -grub_macho_contains_macho32 (grub_macho_t macho) -{ - return macho->offset32 != -1; -} - -static void -grub_macho_parse32 (grub_macho_t macho) -{ - struct grub_macho_header32 head; - - /* Is there any candidate at all? */ - if (macho->offset32 == -1) - return; - - /* Read header and check magic*/ - if (grub_file_seek (macho->file, macho->offset32) == (grub_off_t) -1 - || grub_file_read (macho->file, &head, sizeof (head)) - != sizeof(head)) - { - grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header."); - macho->offset32 = -1; - return; - } - if (head.magic != GRUB_MACHO_MAGIC32) - { - grub_error (GRUB_ERR_BAD_OS, "Invalid Mach-O 32-bit header."); - macho->offset32 = -1; - return; - } - - /* Read commands. */ - macho->ncmds32 = head.ncmds; - macho->cmdsize32 = head.sizeofcmds; - macho->cmds32 = grub_malloc(macho->cmdsize32); - if (! macho->cmds32) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "not enough memory to read commands"); - return; - } - if (grub_file_read (macho->file, macho->cmds32, - (grub_size_t) macho->cmdsize32) - != (grub_ssize_t) macho->cmdsize32) - { - grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header."); - macho->offset32 = -1; - } -} - -typedef int NESTED_FUNC_ATTR (*grub_macho_iter_hook_t) -(grub_macho_t , struct grub_macho_cmd *, - void *); - -static grub_err_t -grub_macho32_cmds_iterate (grub_macho_t macho, - grub_macho_iter_hook_t hook, - void *hook_arg) -{ - grub_uint8_t *hdrs = macho->cmds32; - int i; - if (! macho->cmds32) - return grub_error (GRUB_ERR_BAD_OS, "Couldn't find 32-bit Mach-O"); - for (i = 0; i < macho->ncmds32; i++) - { - struct grub_macho_cmd *hdr = (struct grub_macho_cmd *) hdrs; - if (hook (macho, hdr, hook_arg)) - break; - hdrs += hdr->cmdsize; - } - - return grub_errno; -} - -grub_size_t -grub_macho32_filesize (grub_macho_t macho) -{ - if (grub_macho_contains_macho32 (macho)) - return macho->end32 - macho->offset32; - return 0; -} - -grub_err_t -grub_macho32_readfile (grub_macho_t macho, void *dest) -{ - grub_ssize_t read; - if (! grub_macho_contains_macho32 (macho)) - return grub_error (GRUB_ERR_BAD_OS, - "Couldn't read architecture-specific part"); - - if (grub_file_seek (macho->file, macho->offset32) == (grub_off_t) -1) - { - grub_error_push (); - return grub_error (GRUB_ERR_BAD_OS, - "Invalid offset in program header."); - } - - read = grub_file_read (macho->file, dest, - macho->end32 - macho->offset32); - if (read != (grub_ssize_t) (macho->end32 - macho->offset32)) - { - grub_error_push (); - return grub_error (GRUB_ERR_BAD_OS, - "Couldn't read architecture-specific part"); - } - return GRUB_ERR_NONE; -} - -/* Calculate the amount of memory spanned by the segments. */ -grub_err_t -grub_macho32_size (grub_macho_t macho, grub_addr_t *segments_start, - grub_addr_t *segments_end, int flags) -{ - int nr_phdrs = 0; - - /* Run through the program headers to calculate the total memory size we - should claim. */ - auto int NESTED_FUNC_ATTR calcsize (grub_macho_t _macho, - struct grub_macho_cmd *phdr, void *_arg); - int NESTED_FUNC_ATTR calcsize (grub_macho_t UNUSED _macho, - struct grub_macho_cmd *hdr0, void UNUSED *_arg) - { - struct grub_macho_segment32 *hdr = (struct grub_macho_segment32 *) hdr0; - if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT32) - return 0; - if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS)) - return 0; - - nr_phdrs++; - if (hdr->vmaddr < *segments_start) - *segments_start = hdr->vmaddr; - if (hdr->vmaddr + hdr->vmsize > *segments_end) - *segments_end = hdr->vmaddr + hdr->vmsize; - return 0; - } - - *segments_start = (grub_uint32_t) -1; - *segments_end = 0; - - grub_macho32_cmds_iterate (macho, calcsize, 0); - - if (nr_phdrs == 0) - return grub_error (GRUB_ERR_BAD_OS, "No program headers present"); - - if (*segments_end < *segments_start) - /* Very bad addresses. */ - return grub_error (GRUB_ERR_BAD_OS, "Bad program header load addresses"); - - return GRUB_ERR_NONE; -} - -/* Load every loadable segment into memory specified by `_load_hook'. */ -grub_err_t -grub_macho32_load (grub_macho_t macho, char *offset, int flags) -{ - grub_err_t err = 0; - auto int NESTED_FUNC_ATTR do_load(grub_macho_t _macho, - struct grub_macho_cmd *hdr0, - void UNUSED *_arg); - int NESTED_FUNC_ATTR do_load(grub_macho_t _macho, - struct grub_macho_cmd *hdr0, - void UNUSED *_arg) - { - struct grub_macho_segment32 *hdr = (struct grub_macho_segment32 *) hdr0; - - if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT32) - return 0; - - if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS)) - return 0; - if (! hdr->vmsize) - return 0; - - if (grub_file_seek (_macho->file, hdr->fileoff - + _macho->offset32) == (grub_off_t) -1) - { - grub_error_push (); - grub_error (GRUB_ERR_BAD_OS, - "Invalid offset in program header."); - return 1; - } - - if (hdr->filesize) - { - grub_ssize_t read; - read = grub_file_read (_macho->file, offset + hdr->vmaddr, - min (hdr->filesize, hdr->vmsize)); - if (read != (grub_ssize_t) min (hdr->filesize, hdr->vmsize)) - { - /* XXX How can we free memory from `load_hook'? */ - grub_error_push (); - err=grub_error (GRUB_ERR_BAD_OS, - "Couldn't read segment from file: " - "wanted 0x%lx bytes; read 0x%lx bytes.", - hdr->filesize, read); - return 1; - } - } - - if (hdr->filesize < hdr->vmsize) - grub_memset (offset + hdr->vmaddr + hdr->filesize, - 0, hdr->vmsize - hdr->filesize); - return 0; - } - - grub_macho32_cmds_iterate (macho, do_load, 0); - - return err; -} - -grub_uint32_t -grub_macho32_get_entry_point (grub_macho_t macho) -{ - grub_uint32_t entry_point = 0; - auto int NESTED_FUNC_ATTR hook(grub_macho_t _macho, - struct grub_macho_cmd *hdr, - void UNUSED *_arg); - int NESTED_FUNC_ATTR hook(grub_macho_t UNUSED _macho, - struct grub_macho_cmd *hdr, - void UNUSED *_arg) - { - if (hdr->cmd == GRUB_MACHO_CMD_THREAD) - entry_point = ((struct grub_macho_thread32 *) hdr)->entry_point; - return 0; - } - grub_macho32_cmds_iterate (macho, hook, 0); - return entry_point; -} - - grub_err_t grub_macho_close (grub_macho_t macho) { @@ -367,8 +134,7 @@ grub_macho_file (grub_file_t file) } grub_macho_parse32 (macho); - /* FIXME: implement 64-bit.*/ - /* grub_macho_parse64 (macho); */ + grub_macho_parse64 (macho); return macho; diff --git a/loader/xnu.c b/loader/xnu.c index 1f29b69a1..271a746e6 100644 --- a/loader/xnu.c +++ b/loader/xnu.c @@ -35,6 +35,7 @@ struct grub_xnu_devtree_key *grub_xnu_devtree_root = 0; static int driverspackagenum = 0; static int driversnum = 0; +static int is_64bit; /* Allocate heap by 32MB-blocks. */ #define GRUB_XNU_HEAP_ALLOC_BLOCK 0x2000000 @@ -352,7 +353,7 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), { grub_err_t err; grub_macho_t macho; - grub_addr_t startcode, endcode; + grub_uint32_t startcode, endcode; int i; char *ptr, *loadaddr; @@ -368,10 +369,10 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), { grub_macho_close (macho); return grub_error (GRUB_ERR_BAD_OS, - "Kernel doesn't contain suitable architecture"); + "Kernel doesn't contain suitable 32-bit architecture"); } - err = grub_macho32_size (macho, &startcode, &endcode, GRUB_MACHO_NOBSS); + err = grub_macho_size32 (macho, &startcode, &endcode, GRUB_MACHO_NOBSS); if (err) { grub_macho_close (macho); @@ -394,7 +395,7 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), } /* Load kernel. */ - err = grub_macho32_load (macho, loadaddr - startcode, GRUB_MACHO_NOBSS); + err = grub_macho_load32 (macho, loadaddr - startcode, GRUB_MACHO_NOBSS); if (err) { grub_macho_close (macho); @@ -402,7 +403,7 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), return err; } - grub_xnu_entry_point = grub_macho32_get_entry_point (macho); + grub_xnu_entry_point = grub_macho_get_entry_point32 (macho); if (! grub_xnu_entry_point) { grub_macho_close (macho); @@ -443,6 +444,113 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0); grub_xnu_lock (); + is_64bit = 0; + + return 0; +} + +static grub_err_t +grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)), + int argc, char *args[]) +{ + grub_err_t err; + grub_macho_t macho; + grub_uint64_t startcode, endcode; + int i; + char *ptr, *loadaddr; + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + + grub_xnu_unload (); + + macho = grub_macho_open (args[0]); + if (! macho) + return grub_errno; + if (! grub_macho_contains_macho64 (macho)) + { + grub_macho_close (macho); + return grub_error (GRUB_ERR_BAD_OS, + "Kernel doesn't contain suitable 64-bit architecture"); + } + + err = grub_macho_size64 (macho, &startcode, &endcode, GRUB_MACHO_NOBSS); + if (err) + { + grub_macho_close (macho); + grub_xnu_unload (); + return err; + } + + startcode &= 0x0fffffff; + endcode &= 0x0fffffff; + + grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n", + (unsigned long) endcode, (unsigned long) startcode); + + loadaddr = grub_xnu_heap_malloc (endcode - startcode); + grub_xnu_heap_will_be_at = startcode; + + if (! loadaddr) + { + grub_macho_close (macho); + grub_xnu_unload (); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "not enough memory to load kernel"); + } + + /* Load kernel. */ + err = grub_macho_load64 (macho, loadaddr - startcode, GRUB_MACHO_NOBSS); + if (err) + { + grub_macho_close (macho); + grub_xnu_unload (); + return err; + } + + grub_xnu_entry_point = grub_macho_get_entry_point64 (macho) & 0x0fffffff; + if (! grub_xnu_entry_point) + { + grub_macho_close (macho); + grub_xnu_unload (); + return grub_error (GRUB_ERR_BAD_OS, "couldn't find entry point"); + } + + grub_macho_close (macho); + + err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE); + if (err) + { + grub_xnu_unload (); + return err; + } + + /* Copy parameters to kernel command line. */ + ptr = grub_xnu_cmdline; + for (i = 1; i < argc; i++) + { + if (ptr + grub_strlen (args[i]) + 1 + >= grub_xnu_cmdline + sizeof (grub_xnu_cmdline)) + break; + grub_memcpy (ptr, args[i], grub_strlen (args[i])); + ptr += grub_strlen (args[i]); + *ptr = ' '; + ptr++; + } + + /* Replace last space by '\0'. */ + if (ptr != grub_xnu_cmdline) + *(ptr - 1) = 0; + + err = grub_cpu_xnu_fill_devicetree (); + if (err) + return err; + + grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0); + + grub_xnu_lock (); + is_64bit = 1; + return 0; } @@ -560,7 +668,10 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) return grub_error (GRUB_ERR_BAD_OS, "Extension doesn't contain suitable architecture"); } - machosize = grub_macho32_filesize (macho); + if (is_64bit) + machosize = grub_macho_filesize64 (macho); + else + machosize = grub_macho_filesize32 (macho); neededspace += machosize; } else @@ -595,7 +706,11 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) exthead->binaryaddr = (buf - grub_xnu_heap_start) + grub_xnu_heap_will_be_at; exthead->binarysize = machosize; - if ((err = grub_macho32_readfile (macho, buf))) + if (is_64bit) + err = grub_macho_readfile64 (macho, buf); + else + err = grub_macho_readfile32 (macho, buf); + if (err) { grub_macho_close (macho); return err; @@ -695,7 +810,13 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)), } for (i = 0; i < narchs; i++) { - if (GRUB_MACHO_CPUTYPE_IS_HOST32 + if (!is_64bit && GRUB_MACHO_CPUTYPE_IS_HOST32 + (grub_be_to_cpu32 (archs[i].cputype))) + { + readoff = grub_be_to_cpu32 (archs[i].offset); + readlen = grub_be_to_cpu32 (archs[i].size); + } + if (is_64bit && GRUB_MACHO_CPUTYPE_IS_HOST64 (grub_be_to_cpu32 (archs[i].cputype))) { readoff = grub_be_to_cpu32 (archs[i].offset); @@ -1363,13 +1484,16 @@ grub_xnu_unlock () locked = 0; } -static grub_command_t cmd_kernel, cmd_mkext, cmd_kext, cmd_kextdir, - cmd_ramdisk, cmd_devtree, cmd_resume, cmd_splash; +static grub_command_t cmd_kernel64, cmd_kernel, cmd_mkext, cmd_kext; +static grub_command_t cmd_kextdir, cmd_ramdisk, cmd_devtree, cmd_resume; +static grub_command_t cmd_splash; GRUB_MOD_INIT(xnu) { cmd_kernel = grub_register_command ("xnu_kernel", grub_cmd_xnu_kernel, 0, "load a xnu kernel"); + cmd_kernel64 = grub_register_command ("xnu_kernel64", grub_cmd_xnu_kernel64, + 0, "load a 64-bit xnu kernel"); cmd_mkext = grub_register_command ("xnu_mkext", grub_cmd_xnu_mkext, 0, "Load XNU extension package."); cmd_kext = grub_register_command ("xnu_kext", grub_cmd_xnu_kext, 0, @@ -1403,5 +1527,6 @@ GRUB_MOD_FINI(xnu) grub_unregister_command (cmd_devtree); grub_unregister_command (cmd_ramdisk); grub_unregister_command (cmd_kernel); + grub_unregister_command (cmd_kernel64); grub_unregister_command (cmd_splash); } From 8a10b2c63296e5f5e19511549db2b78ca7998907 Mon Sep 17 00:00:00 2001 From: phcoder Date: Wed, 2 Sep 2009 13:34:40 +0200 Subject: [PATCH 09/52] now hangs at maxDec --- efiemu/prepare.c | 55 ++++++++++++++++------- efiemu/runtime/efiemu.c | 7 ++- efiemu/symbols.c | 84 ++++++++++++++++++++++++++++++++++++ include/grub/autoefi.h | 2 + include/grub/efi/efi.h | 4 ++ include/grub/efiemu/efiemu.h | 10 +++++ include/grub/xnu.h | 1 + kern/efi/efi.c | 19 ++++++++ loader/i386/xnu.c | 9 +++- loader/xnu.c | 14 +++--- 10 files changed, 177 insertions(+), 28 deletions(-) diff --git a/efiemu/prepare.c b/efiemu/prepare.c index 9e6d46fa1..620260049 100644 --- a/efiemu/prepare.c +++ b/efiemu/prepare.c @@ -36,7 +36,6 @@ SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks, int cntconftables = 0; struct SUFFIX (grub_efiemu_configuration_table) *conftables = 0; - struct SUFFIX (grub_efiemu_runtime_services) *runtime_services; int i; int handle; grub_off_t off; @@ -54,6 +53,7 @@ SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks, /* Switch from phase 1 (counting) to phase 2 (real job) */ grub_efiemu_alloc_syms (); grub_efiemu_mm_do_alloc (); + grub_efiemu_write_sym_markers (); grub_efiemu_system_table32 = 0; grub_efiemu_system_table64 = 0; @@ -81,16 +81,6 @@ SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks, = (struct SUFFIX (grub_efi_system_table) *) ((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off); - /* compute CRC32 of runtime_services */ - if ((err = grub_efiemu_resolve_symbol ("efiemu_runtime_services", - &handle, &off))) - return err; - runtime_services = (struct SUFFIX (grub_efiemu_runtime_services) *) - ((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off); - runtime_services->hdr.crc32 = 0; - runtime_services->hdr.crc32 = grub_getcrc32 - (0, runtime_services, runtime_services->hdr.header_size); - /* Put pointer to the list of configuration tables in system table */ grub_efiemu_write_value (&(SUFFIX (grub_efiemu_system_table)->configuration_table), 0, @@ -113,16 +103,51 @@ SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks, conftables[i].vendor_table = PTR_TO_UINT64 (cur->data); } + err = SUFFIX (grub_efiemu_crc) (); + if (err) + { + grub_efiemu_unload (); + return err; + } + + grub_dprintf ("efiemu","system_table = %p, conftables = %p (%d entries)\n", + SUFFIX (grub_efiemu_system_table), conftables, cntconftables); + + return GRUB_ERR_NONE; +} + +grub_err_t +SUFFIX (grub_efiemu_crc) (void) +{ + grub_err_t err; + int handle; + grub_off_t off; + struct SUFFIX (grub_efiemu_runtime_services) *runtime_services; + + /* compute CRC32 of runtime_services */ + err = grub_efiemu_resolve_symbol ("efiemu_runtime_services", + &handle, &off); + if (err) + return err; + + runtime_services = (struct SUFFIX (grub_efiemu_runtime_services) *) + ((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off); + runtime_services->hdr.crc32 = 0; + runtime_services->hdr.crc32 = grub_getcrc32 + (0, runtime_services, runtime_services->hdr.header_size); + + err = grub_efiemu_resolve_symbol ("efiemu_system_table", &handle, &off); + if (err) + return err; + /* compute CRC32 of system table */ SUFFIX (grub_efiemu_system_table)->hdr.crc32 = 0; SUFFIX (grub_efiemu_system_table)->hdr.crc32 = grub_getcrc32 (0, SUFFIX (grub_efiemu_system_table), SUFFIX (grub_efiemu_system_table)->hdr.header_size); - grub_dprintf ("efiemu","system_table = %p, runtime_services = %p," - " conftables = %p (%d entries)\n", - SUFFIX (grub_efiemu_system_table), runtime_services, - conftables, cntconftables); + grub_dprintf ("efiemu","system_table = %p, runtime_services = %p\n", + SUFFIX (grub_efiemu_system_table), runtime_services); return GRUB_ERR_NONE; } diff --git a/efiemu/runtime/efiemu.c b/efiemu/runtime/efiemu.c index 085e75d0c..73893414a 100644 --- a/efiemu/runtime/efiemu.c +++ b/efiemu/runtime/efiemu.c @@ -111,9 +111,8 @@ static grub_uint8_t loge[1000] = "EFIEMULOG"; static int logn = 9; #define LOG(x) { if (logn<900) loge[logn++]=x; } -static int ptv_relocated = 0; - /* Interface with grub */ +extern grub_uint8_t efiemu_ptv_relocated; struct grub_efi_runtime_services efiemu_runtime_services; struct grub_efi_system_table efiemu_system_table; extern struct grub_efiemu_ptv_rel efiemu_ptv_relloc[]; @@ -343,9 +342,9 @@ grub_efi_status_t EFI_FUNC LOG ('e'); /* Ensure that we are called only once */ - if (ptv_relocated) + if (efiemu_ptv_relocated) return GRUB_EFI_UNSUPPORTED; - ptv_relocated = 1; + efiemu_ptv_relocated = 1; /* Correct addresses using information supplied by grub */ for (cur_relloc = efiemu_ptv_relloc; cur_relloc->size;cur_relloc++) diff --git a/efiemu/symbols.c b/efiemu/symbols.c index ec508d975..f20761565 100644 --- a/efiemu/symbols.c +++ b/efiemu/symbols.c @@ -26,9 +26,11 @@ static int ptv_written = 0; static int ptv_alloc = 0; static int ptv_handle = 0; +static int relocated_handle = 0; static int ptv_requested = 0; static struct grub_efiemu_sym *efiemu_syms = 0; + struct grub_efiemu_sym { struct grub_efiemu_sym *next; @@ -54,6 +56,8 @@ grub_efiemu_free_syms (void) ptv_requested = 0; grub_efiemu_mm_return_request (ptv_handle); ptv_handle = 0; + grub_efiemu_mm_return_request (relocated_handle); + relocated_handle = 0; } /* Announce that the module will need NUM allocators */ @@ -114,10 +118,26 @@ grub_efiemu_alloc_syms (void) ptv_handle = grub_efiemu_request_memalign (1, (ptv_requested + 1) * sizeof (struct grub_efiemu_ptv_rel), GRUB_EFI_RUNTIME_SERVICES_DATA); + relocated_handle = grub_efiemu_request_memalign + (1, sizeof (grub_uint8_t), GRUB_EFI_RUNTIME_SERVICES_DATA); + + grub_efiemu_register_symbol ("efiemu_ptv_relocated", relocated_handle, 0); grub_efiemu_register_symbol ("efiemu_ptv_relloc", ptv_handle, 0); return grub_errno; } +grub_err_t +grub_efiemu_write_sym_markers (void) +{ + struct grub_efiemu_ptv_rel *ptv_rels + = grub_efiemu_mm_obtain_request (ptv_handle); + grub_uint8_t *relocated = grub_efiemu_mm_obtain_request (relocated_handle); + grub_memset (ptv_rels, 0, (ptv_requested + 1) + * sizeof (struct grub_efiemu_ptv_rel)); + *relocated = 0; + return GRUB_ERR_NONE; +} + /* Write value (pointer to memory PLUS_HANDLE) - (pointer to memory MINUS_HANDLE) + VALUE to ADDR assuming that the size SIZE bytes. If PTV_NEEDED is 1 then announce it to runtime that this @@ -186,3 +206,67 @@ grub_efiemu_write_value (void *addr, grub_uint32_t value, int plus_handle, return GRUB_ERR_NONE; } + +grub_err_t +grub_efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version + __attribute__ ((unused)), + grub_efi_memory_descriptor_t *virtual_map) +{ + grub_uint8_t *ptv_relocated; + struct grub_efiemu_ptv_rel *cur_relloc; + struct grub_efiemu_ptv_rel *ptv_rels; + + ptv_relocated = grub_efiemu_mm_obtain_request (relocated_handle); + ptv_rels = grub_efiemu_mm_obtain_request (ptv_handle); + + /* Ensure that we are called only once */ + if (*ptv_relocated) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "EfiEmu is already relocated."); + *ptv_relocated = 1; + + /* Correct addresses using information supplied by grub */ + for (cur_relloc = ptv_rels; cur_relloc->size; cur_relloc++) + { + grub_int64_t corr = 0; + grub_efi_memory_descriptor_t *descptr; + + /* Compute correction */ + for (descptr = virtual_map; + (grub_size_t) ((grub_uint8_t *) descptr + - (grub_uint8_t *) virtual_map) < memory_map_size; + descptr = (grub_efi_memory_descriptor_t *) + ((grub_uint8_t *) descptr + descriptor_size)) + { + if (descptr->type == cur_relloc->plustype) + corr += descptr->virtual_start - descptr->physical_start; + if (descptr->type == cur_relloc->minustype) + corr -= descptr->virtual_start - descptr->physical_start; + } + + /* Apply correction */ + switch (cur_relloc->size) + { + case 8: + *((grub_uint64_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; + break; + case 4: + *((grub_uint32_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; + break; + case 2: + *((grub_uint16_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; + break; + case 1: + *((grub_uint8_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; + break; + } + } + + /* Recompute crc32 of system table and runtime services */ + + if (grub_efiemu_sizeof_uintn_t () == 4) + return grub_efiemu_crc32 (); + else + return grub_efiemu_crc64 (); +} diff --git a/include/grub/autoefi.h b/include/grub/autoefi.h index 4acd43965..4f5e262f0 100644 --- a/include/grub/autoefi.h +++ b/include/grub/autoefi.h @@ -29,6 +29,7 @@ # define grub_autoefi_finish_boot_services grub_efi_finish_boot_services # define grub_autoefi_system_table grub_efi_system_table # define grub_autoefi_mmap_iterate grub_machine_mmap_iterate +# define grub_autoefi_set_virtual_address_map grub_efi_set_virtual_address_map static inline grub_err_t grub_autoefi_prepare (void) { return GRUB_ERR_NONE; @@ -57,6 +58,7 @@ static inline grub_err_t grub_autoefi_prepare (void) # define grub_autoefi_system_table grub_efiemu_system_table # define grub_autoefi_mmap_iterate grub_efiemu_mmap_iterate # define grub_autoefi_prepare grub_efiemu_prepare +# define grub_autoefi_set_virtual_address_map grub_efiemu_set_virtual_address_map # define GRUB_AUTOEFI_MEMORY_AVAILABLE GRUB_EFIEMU_MEMORY_AVAILABLE # define GRUB_AUTOEFI_MEMORY_RESERVED GRUB_EFIEMU_MEMORY_RESERVED # define GRUB_AUTOEFI_MEMORY_ACPI GRUB_EFIEMU_MEMORY_ACPI diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index 916f9d662..754c4a7cb 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -57,6 +57,10 @@ int EXPORT_FUNC(grub_efi_exit_boot_services) (grub_efi_uintn_t map_key); void EXPORT_FUNC (grub_reboot) (void); void EXPORT_FUNC (grub_halt) (void); int EXPORT_FUNC (grub_efi_finish_boot_services) (void); +grub_err_t EXPORT_FUNC (grub_efiemu_set_virtual_address_map) (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version, + grub_efi_memory_descriptor_t *virtual_map); void grub_efi_mm_init (void); void grub_efi_mm_fini (void); diff --git a/include/grub/efiemu/efiemu.h b/include/grub/efiemu/efiemu.h index 20163dd61..3980d32cd 100644 --- a/include/grub/efiemu/efiemu.h +++ b/include/grub/efiemu/efiemu.h @@ -268,9 +268,19 @@ void grub_efiemu_free_syms (void); grub_err_t grub_efiemu_write_value (void * addr, grub_uint32_t value, int plus_handle, int minus_handle, int ptv_needed, int size); +grub_err_t grub_efiemu_write_sym_markers (void); grub_err_t grub_efiemu_pnvram (void); grub_err_t grub_efiemu_prepare (void); char *grub_efiemu_get_default_core_name (void); void grub_efiemu_pnvram_cmd_unregister (void); grub_err_t grub_efiemu_autocore (void); +grub_err_t grub_efiemu_crc32 (void); +grub_err_t grub_efiemu_crc64 (void); +grub_err_t +grub_efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version + __attribute__ ((unused)), + grub_efi_memory_descriptor_t *virtual_map); + #endif /* ! GRUB_EFI_EMU_HEADER */ diff --git a/include/grub/xnu.h b/include/grub/xnu.h index 67d78d92c..29689479b 100644 --- a/include/grub/xnu.h +++ b/include/grub/xnu.h @@ -106,4 +106,5 @@ extern grub_uint32_t grub_xnu_heap_real_start; extern grub_size_t grub_xnu_heap_size; extern char *grub_xnu_heap_start; extern struct grub_video_bitmap *grub_xnu_bitmap; +extern int grub_xnu_is_64bit; #endif diff --git a/kern/efi/efi.c b/kern/efi/efi.c index 8e09a90c0..630f012b6 100644 --- a/kern/efi/efi.c +++ b/kern/efi/efi.c @@ -188,6 +188,25 @@ grub_efi_exit_boot_services (grub_efi_uintn_t map_key) return status == GRUB_EFI_SUCCESS; } +grub_err_t +grub_efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version, + grub_efi_memory_descriptor_t *virtual_map) +{ + grub_efi_runtime_services_t *r; + grub_efi_status_t status; + + r = grub_efi_system_table->runtime_services; + status = efi_call_4 (r->set_virtual_address_map, memory_map_size, + descriptor_size, descriptor_version, virtual_map); + + if (status == GRUB_EFI_SUCCESS) + return GRUB_ERR_NONE; + + return grub_errno (GRUB_ERR_IO, "set_virtual_address_map failed"); +} + grub_uint32_t grub_get_rtc (void) { diff --git a/loader/i386/xnu.c b/loader/i386/xnu.c index 06e375c69..2bcedebe2 100644 --- a/loader/i386/xnu.c +++ b/loader/i386/xnu.c @@ -474,13 +474,15 @@ grub_xnu_boot (void) grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *) ((char *) memory_map + descriptor_size * i); - /* Some EFI implementations set physical_start to 0 which - causes XNU crash. */ curdesc->virtual_start = curdesc->physical_start; if (curdesc->type == GRUB_EFI_RUNTIME_SERVICES_DATA || curdesc->type == GRUB_EFI_RUNTIME_SERVICES_CODE) { + if (grub_xnu_is_64bit && (SIZEOF_OF_UINTN == 8)) + curdesc->virtual_start |= 0xffffff8000000000ULL; + else + curdesc->virtual_start &= 0x000000007fffffffULL; if (firstruntimeaddr > curdesc->physical_start) firstruntimeaddr = curdesc->physical_start; if (lastruntimeaddr < curdesc->physical_start @@ -572,6 +574,9 @@ grub_xnu_boot (void) if (! grub_autoefi_finish_boot_services ()) return grub_error (GRUB_ERR_IO, "can't exit boot services"); + grub_autoefi_set_virtual_address_map (memory_map_size, descriptor_size, + descriptor_version,memory_map); + grub_xnu_launch (); /* Never reaches here. */ diff --git a/loader/xnu.c b/loader/xnu.c index 271a746e6..2ebca3218 100644 --- a/loader/xnu.c +++ b/loader/xnu.c @@ -35,7 +35,7 @@ struct grub_xnu_devtree_key *grub_xnu_devtree_root = 0; static int driverspackagenum = 0; static int driversnum = 0; -static int is_64bit; +int grub_xnu_is_64bit = 0; /* Allocate heap by 32MB-blocks. */ #define GRUB_XNU_HEAP_ALLOC_BLOCK 0x2000000 @@ -444,7 +444,7 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0); grub_xnu_lock (); - is_64bit = 0; + grub_xnu_is_64bit = 0; return 0; } @@ -549,7 +549,7 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)), grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0); grub_xnu_lock (); - is_64bit = 1; + grub_xnu_is_64bit = 1; return 0; } @@ -668,7 +668,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) return grub_error (GRUB_ERR_BAD_OS, "Extension doesn't contain suitable architecture"); } - if (is_64bit) + if (grub_xnu_is_64bit) machosize = grub_macho_filesize64 (macho); else machosize = grub_macho_filesize32 (macho); @@ -706,7 +706,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) exthead->binaryaddr = (buf - grub_xnu_heap_start) + grub_xnu_heap_will_be_at; exthead->binarysize = machosize; - if (is_64bit) + if (grub_xnu_is_64bit) err = grub_macho_readfile64 (macho, buf); else err = grub_macho_readfile32 (macho, buf); @@ -810,13 +810,13 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)), } for (i = 0; i < narchs; i++) { - if (!is_64bit && GRUB_MACHO_CPUTYPE_IS_HOST32 + if (!grub_xnu_is_64bit && GRUB_MACHO_CPUTYPE_IS_HOST32 (grub_be_to_cpu32 (archs[i].cputype))) { readoff = grub_be_to_cpu32 (archs[i].offset); readlen = grub_be_to_cpu32 (archs[i].size); } - if (is_64bit && GRUB_MACHO_CPUTYPE_IS_HOST64 + if (grub_xnu_is_64bit && GRUB_MACHO_CPUTYPE_IS_HOST64 (grub_be_to_cpu32 (archs[i].cputype))) { readoff = grub_be_to_cpu32 (archs[i].offset); From 0355f074044a3667654d680829243cc01c7ce8e9 Mon Sep 17 00:00:00 2001 From: phcoder Date: Wed, 2 Sep 2009 18:18:11 +0200 Subject: [PATCH 10/52] relocate runtime --- loader/i386/xnu.c | 66 ++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/loader/i386/xnu.c b/loader/i386/xnu.c index 2bcedebe2..0b110bab6 100644 --- a/loader/i386/xnu.c +++ b/loader/i386/xnu.c @@ -435,6 +435,7 @@ grub_xnu_boot (void) grub_efi_uintn_t descriptor_size = 0; grub_efi_uint32_t descriptor_version = 0; grub_uint64_t firstruntimeaddr, lastruntimeaddr; + grub_uint64_t curruntimeaddr; void *devtree; grub_size_t devtreelen; int i; @@ -467,31 +468,6 @@ grub_xnu_boot (void) mmap_relloc_off = (grub_uint8_t *) memory_map - (grub_uint8_t *) grub_xnu_heap_start; - firstruntimeaddr = (grub_uint64_t) (-1); - lastruntimeaddr = 0; - for (i = 0; (unsigned) i < memory_map_size / descriptor_size; i++) - { - grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *) - ((char *) memory_map + descriptor_size * i); - - curdesc->virtual_start = curdesc->physical_start; - - if (curdesc->type == GRUB_EFI_RUNTIME_SERVICES_DATA - || curdesc->type == GRUB_EFI_RUNTIME_SERVICES_CODE) - { - if (grub_xnu_is_64bit && (SIZEOF_OF_UINTN == 8)) - curdesc->virtual_start |= 0xffffff8000000000ULL; - else - curdesc->virtual_start &= 0x000000007fffffffULL; - if (firstruntimeaddr > curdesc->physical_start) - firstruntimeaddr = curdesc->physical_start; - if (lastruntimeaddr < curdesc->physical_start - + curdesc->num_pages * 4096) - lastruntimeaddr = curdesc->physical_start - + curdesc->num_pages * 4096; - } - } - /* Relocate the boot parameters to heap. */ bootparams_relloc = grub_xnu_heap_malloc (sizeof (*bootparams_relloc)); if (! bootparams_relloc) @@ -511,22 +487,52 @@ grub_xnu_boot (void) + grub_xnu_heap_will_be_at; bootparams_relloc->devtreelen = devtreelen; - bootparams_relloc->heap_start = grub_xnu_heap_will_be_at; - bootparams_relloc->heap_size = grub_xnu_heap_size; - + bootparams_relloc->efi_system_table + = PTR_TO_UINT32 (grub_autoefi_system_table); bootparams_relloc->efi_mmap = grub_xnu_heap_will_be_at + mmap_relloc_off; bootparams_relloc->efi_mmap_size = memory_map_size; bootparams_relloc->efi_mem_desc_size = descriptor_size; bootparams_relloc->efi_mem_desc_version = descriptor_version; + memory_map = (grub_efi_memory_descriptor_t *) + ((grub_uint8_t *) grub_xnu_heap_start + mmap_relloc_off); + firstruntimeaddr = ALIGN_UP (((grub_addr_t) grub_xnu_heap_start + + grub_xnu_heap_size + 4096), 4096); + curruntimeaddr = firstruntimeaddr; + for (i = 0; (unsigned) i < memory_map_size / descriptor_size; i++) + { + grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *) + ((char *) memory_map + descriptor_size * i); + + curdesc->virtual_start = curdesc->physical_start; + + if (curdesc->type == GRUB_EFI_RUNTIME_SERVICES_DATA + || curdesc->type == GRUB_EFI_RUNTIME_SERVICES_CODE) + { + curdesc->virtual_start = ALIGN_UP (curruntimeaddr, 4096); + curruntimeaddr += curdesc->num_pages << 12; + if (curdesc->physical_start + <= PTR_TO_UINT64 (grub_autoefi_system_table) + && curdesc->physical_start + (curdesc->num_pages << 12) + > PTR_TO_UINT64 (grub_autoefi_system_table)) + bootparams_relloc->efi_system_table + = PTR_TO_UINT64 (grub_autoefi_system_table) + - curdesc->physical_start + curdesc->virtual_start; + if (SIZEOF_OF_UINTN == 8) + curdesc->virtual_start |= 0xffffff8000000000ULL; + } + } + + lastruntimeaddr = curruntimeaddr; + + bootparams_relloc->heap_start = grub_xnu_heap_will_be_at; + bootparams_relloc->heap_size = grub_xnu_heap_size; bootparams_relloc->efi_runtime_first_page = firstruntimeaddr / GRUB_XNU_PAGESIZE; bootparams_relloc->efi_runtime_npages = ((lastruntimeaddr + GRUB_XNU_PAGESIZE - 1) / GRUB_XNU_PAGESIZE) - (firstruntimeaddr / GRUB_XNU_PAGESIZE); bootparams_relloc->efi_uintnbits = SIZEOF_OF_UINTN * 8; - bootparams_relloc->efi_system_table - = PTR_TO_UINT32 (grub_autoefi_system_table); bootparams_relloc->verminor = GRUB_XNU_BOOTARGS_VERMINOR; bootparams_relloc->vermajor = GRUB_XNU_BOOTARGS_VERMAJOR; From 12d6fc8461b43197a32db6e0efbf56ae4eb95482 Mon Sep 17 00:00:00 2001 From: phcoder Date: Thu, 3 Sep 2009 19:19:59 +0200 Subject: [PATCH 11/52] EFI support --- include/grub/autoefi.h | 2 + include/grub/efi/api.h | 1 + include/grub/efi/efi.h | 8 ++-- kern/efi/efi.c | 10 ++--- loader/i386/xnu.c | 100 ++++++++++++++++++++++------------------- 5 files changed, 65 insertions(+), 56 deletions(-) diff --git a/include/grub/autoefi.h b/include/grub/autoefi.h index 4f5e262f0..245bc0802 100644 --- a/include/grub/autoefi.h +++ b/include/grub/autoefi.h @@ -27,6 +27,7 @@ # include # define grub_autoefi_get_memory_map grub_efi_get_memory_map # define grub_autoefi_finish_boot_services grub_efi_finish_boot_services +# define grub_autoefi_exit_boot_services grub_efi_exit_boot_services # define grub_autoefi_system_table grub_efi_system_table # define grub_autoefi_mmap_iterate grub_machine_mmap_iterate # define grub_autoefi_set_virtual_address_map grub_efi_set_virtual_address_map @@ -55,6 +56,7 @@ static inline grub_err_t grub_autoefi_prepare (void) # include # define grub_autoefi_get_memory_map grub_efiemu_get_memory_map # define grub_autoefi_finish_boot_services grub_efiemu_finish_boot_services +# define grub_autoefi_exit_boot_services grub_efiemu_exit_boot_services # define grub_autoefi_system_table grub_efiemu_system_table # define grub_autoefi_mmap_iterate grub_efiemu_mmap_iterate # define grub_autoefi_prepare grub_efiemu_prepare diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index e870eab41..32904150e 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -21,6 +21,7 @@ #define GRUB_EFI_API_HEADER 1 #include +#include /* For consistency and safety, we name the EFI-defined types differently. All names are transformed into lower case, _t appended, and diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index 754c4a7cb..97051f297 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -57,10 +57,10 @@ int EXPORT_FUNC(grub_efi_exit_boot_services) (grub_efi_uintn_t map_key); void EXPORT_FUNC (grub_reboot) (void); void EXPORT_FUNC (grub_halt) (void); int EXPORT_FUNC (grub_efi_finish_boot_services) (void); -grub_err_t EXPORT_FUNC (grub_efiemu_set_virtual_address_map) (grub_efi_uintn_t memory_map_size, - grub_efi_uintn_t descriptor_size, - grub_efi_uint32_t descriptor_version, - grub_efi_memory_descriptor_t *virtual_map); +grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version, + grub_efi_memory_descriptor_t *virtual_map); void grub_efi_mm_init (void); void grub_efi_mm_fini (void); diff --git a/kern/efi/efi.c b/kern/efi/efi.c index 630f012b6..279d1d61b 100644 --- a/kern/efi/efi.c +++ b/kern/efi/efi.c @@ -189,10 +189,10 @@ grub_efi_exit_boot_services (grub_efi_uintn_t map_key) } grub_err_t -grub_efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size, - grub_efi_uintn_t descriptor_size, - grub_efi_uint32_t descriptor_version, - grub_efi_memory_descriptor_t *virtual_map) +grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version, + grub_efi_memory_descriptor_t *virtual_map) { grub_efi_runtime_services_t *r; grub_efi_status_t status; @@ -204,7 +204,7 @@ grub_efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size, if (status == GRUB_EFI_SUCCESS) return GRUB_ERR_NONE; - return grub_errno (GRUB_ERR_IO, "set_virtual_address_map failed"); + return grub_error (GRUB_ERR_IO, "set_virtual_address_map failed"); } grub_uint32_t diff --git a/loader/i386/xnu.c b/loader/i386/xnu.c index 0b110bab6..59721155a 100644 --- a/loader/i386/xnu.c +++ b/loader/i386/xnu.c @@ -452,21 +452,15 @@ grub_xnu_boot (void) descriptor_size = 0; descriptor_version = 0; - if (grub_autoefi_get_memory_map (&memory_map_size, memory_map, - &map_key, &descriptor_size, - &descriptor_version) < 0) - return grub_errno; + grub_dprintf ("xnu", "eip=%x\n", grub_xnu_entry_point); - memory_map = grub_xnu_heap_malloc (memory_map_size); - if (! memory_map) - return grub_errno; + const char *debug = grub_env_get ("debug"); - if (grub_autoefi_get_memory_map (&memory_map_size, memory_map, - &map_key, &descriptor_size, - &descriptor_version) <= 0) - return grub_errno; - mmap_relloc_off = (grub_uint8_t *) memory_map - - (grub_uint8_t *) grub_xnu_heap_start; + if (debug && (grub_strword (debug, "all") || grub_strword (debug, "xnu"))) + { + grub_printf ("Press any key to launch xnu\n"); + grub_getkey (); + } /* Relocate the boot parameters to heap. */ bootparams_relloc = grub_xnu_heap_malloc (sizeof (*bootparams_relloc)); @@ -474,6 +468,37 @@ grub_xnu_boot (void) return grub_errno; bootparams_relloc_off = (grub_uint8_t *) bootparams_relloc - (grub_uint8_t *) grub_xnu_heap_start; + + /* Set video. */ + err = grub_xnu_set_video (bootparams_relloc); + if (err != GRUB_ERR_NONE) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + grub_printf ("Booting in blind mode\n"); + + bootparams_relloc->lfb_mode = 0; + bootparams_relloc->lfb_width = 0; + bootparams_relloc->lfb_height = 0; + bootparams_relloc->lfb_depth = 0; + bootparams_relloc->lfb_line_len = 0; + bootparams_relloc->lfb_base = 0; + } + + if (grub_autoefi_get_memory_map (&memory_map_size, memory_map, + &map_key, &descriptor_size, + &descriptor_version) < 0) + return grub_errno; + + /* We will do few allocations later. Reserve some space for possible + memory map growth. */ + memory_map_size += 20 * descriptor_size; + memory_map = grub_xnu_heap_malloc (memory_map_size); + if (! memory_map) + return grub_errno; + mmap_relloc_off = (grub_uint8_t *) memory_map + - (grub_uint8_t *) grub_xnu_heap_start; + err = grub_xnu_writetree_toheap (&devtree, &devtreelen); if (err) return err; @@ -487,18 +512,20 @@ grub_xnu_boot (void) + grub_xnu_heap_will_be_at; bootparams_relloc->devtreelen = devtreelen; - bootparams_relloc->efi_system_table - = PTR_TO_UINT32 (grub_autoefi_system_table); - bootparams_relloc->efi_mmap = grub_xnu_heap_will_be_at + mmap_relloc_off; - bootparams_relloc->efi_mmap_size = memory_map_size; - bootparams_relloc->efi_mem_desc_size = descriptor_size; - bootparams_relloc->efi_mem_desc_version = descriptor_version; - memory_map = (grub_efi_memory_descriptor_t *) ((grub_uint8_t *) grub_xnu_heap_start + mmap_relloc_off); firstruntimeaddr = ALIGN_UP (((grub_addr_t) grub_xnu_heap_start + grub_xnu_heap_size + 4096), 4096); curruntimeaddr = firstruntimeaddr; + + if (grub_autoefi_get_memory_map (&memory_map_size, memory_map, + &map_key, &descriptor_size, + &descriptor_version) <= 0) + return grub_errno; + + bootparams_relloc->efi_system_table + = PTR_TO_UINT32 (grub_autoefi_system_table); + for (i = 0; (unsigned) i < memory_map_size / descriptor_size; i++) { grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *) @@ -525,6 +552,11 @@ grub_xnu_boot (void) lastruntimeaddr = curruntimeaddr; + bootparams_relloc->efi_mmap = grub_xnu_heap_will_be_at + mmap_relloc_off; + bootparams_relloc->efi_mmap_size = memory_map_size; + bootparams_relloc->efi_mem_desc_size = descriptor_size; + bootparams_relloc->efi_mem_desc_version = descriptor_version; + bootparams_relloc->heap_start = grub_xnu_heap_will_be_at; bootparams_relloc->heap_size = grub_xnu_heap_size; bootparams_relloc->efi_runtime_first_page = firstruntimeaddr @@ -545,39 +577,13 @@ grub_xnu_boot (void) grub_xnu_launch = (void (*) (void)) (grub_xnu_heap_start + grub_xnu_heap_size); #endif - grub_dprintf ("xnu", "eip=%x\n", grub_xnu_entry_point); - grub_dprintf ("xnu", "launch=%p\n", grub_xnu_launch); - - const char *debug = grub_env_get ("debug"); - - if (debug && (grub_strword (debug, "all") || grub_strword (debug, "xnu"))) - { - grub_printf ("Press any key to launch xnu\n"); - grub_getkey (); - } - - /* Set video. */ - err = grub_xnu_set_video (bootparams_relloc); - if (err != GRUB_ERR_NONE) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - grub_printf ("Booting in blind mode\n"); - - bootparams_relloc->lfb_mode = 0; - bootparams_relloc->lfb_width = 0; - bootparams_relloc->lfb_height = 0; - bootparams_relloc->lfb_depth = 0; - bootparams_relloc->lfb_line_len = 0; - bootparams_relloc->lfb_base = 0; - } grub_memcpy (grub_xnu_heap_start + grub_xnu_heap_size, grub_xnu_launcher_start, grub_xnu_launcher_end - grub_xnu_launcher_start); - if (! grub_autoefi_finish_boot_services ()) + if (! grub_autoefi_exit_boot_services (map_key)) return grub_error (GRUB_ERR_IO, "can't exit boot services"); grub_autoefi_set_virtual_address_map (memory_map_size, descriptor_size, From 55fe0517d402539e0aa0d23a276f2e60d1fe3b02 Mon Sep 17 00:00:00 2001 From: phcoder Date: Fri, 4 Sep 2009 15:31:09 +0200 Subject: [PATCH 12/52] page-based counting. conditional or ffffff8... --- loader/i386/xnu.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/loader/i386/xnu.c b/loader/i386/xnu.c index ca971e675..e7590bf1a 100644 --- a/loader/i386/xnu.c +++ b/loader/i386/xnu.c @@ -431,8 +431,8 @@ grub_xnu_boot (void) grub_efi_uintn_t map_key = 0; grub_efi_uintn_t descriptor_size = 0; grub_efi_uint32_t descriptor_version = 0; - grub_uint64_t firstruntimeaddr, lastruntimeaddr; - grub_uint64_t curruntimeaddr; + grub_uint64_t firstruntimepage, lastruntimepage; + grub_uint64_t curruntimepage; void *devtree; grub_size_t devtreelen; int i; @@ -523,6 +523,11 @@ grub_xnu_boot (void) bootparams_relloc->efi_system_table = PTR_TO_UINT32 (grub_autoefi_system_table); + firstruntimepage = (((grub_addr_t) grub_xnu_heap_will_be_at + + grub_xnu_heap_size + GRUB_XNU_PAGESIZE - 1) + / GRUB_XNU_PAGESIZE) + 20; + curruntimepage = firstruntimepage; + for (i = 0; (unsigned) i < memory_map_size / descriptor_size; i++) { grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *) @@ -533,8 +538,8 @@ grub_xnu_boot (void) if (curdesc->type == GRUB_EFI_RUNTIME_SERVICES_DATA || curdesc->type == GRUB_EFI_RUNTIME_SERVICES_CODE) { - curdesc->virtual_start = ALIGN_UP (curruntimeaddr, 4096); - curruntimeaddr += curdesc->num_pages << 12; + curdesc->virtual_start = curruntimepage << 12; + curruntimepage += curdesc->num_pages; if (curdesc->physical_start <= PTR_TO_UINT64 (grub_autoefi_system_table) && curdesc->physical_start + (curdesc->num_pages << 12) @@ -542,12 +547,12 @@ grub_xnu_boot (void) bootparams_relloc->efi_system_table = PTR_TO_UINT64 (grub_autoefi_system_table) - curdesc->physical_start + curdesc->virtual_start; - if (SIZEOF_OF_UINTN == 8) + if (SIZEOF_OF_UINTN == 8 && grub_xnu_is_64bit) curdesc->virtual_start |= 0xffffff8000000000ULL; } } - lastruntimeaddr = curruntimeaddr; + lastruntimepage = curruntimepage; bootparams_relloc->efi_mmap = grub_xnu_heap_will_be_at + mmap_relloc_off; bootparams_relloc->efi_mmap_size = memory_map_size; From 444eea11fc6ef54aa3cfb53904323d27bd0c2e7d Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 6 Sep 2009 00:25:33 +0200 Subject: [PATCH 13/52] fix --- loader/i386/xnu.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/loader/i386/xnu.c b/loader/i386/xnu.c index e7590bf1a..856e0148c 100644 --- a/loader/i386/xnu.c +++ b/loader/i386/xnu.c @@ -511,9 +511,6 @@ grub_xnu_boot (void) memory_map = (grub_efi_memory_descriptor_t *) ((grub_uint8_t *) grub_xnu_heap_start + mmap_relloc_off); - firstruntimeaddr = ALIGN_UP (((grub_addr_t) grub_xnu_heap_start - + grub_xnu_heap_size + 4096), 4096); - curruntimeaddr = firstruntimeaddr; if (grub_autoefi_get_memory_map (&memory_map_size, memory_map, &map_key, &descriptor_size, @@ -561,11 +558,9 @@ grub_xnu_boot (void) bootparams_relloc->heap_start = grub_xnu_heap_will_be_at; bootparams_relloc->heap_size = grub_xnu_heap_size; - bootparams_relloc->efi_runtime_first_page = firstruntimeaddr - / GRUB_XNU_PAGESIZE; - bootparams_relloc->efi_runtime_npages - = ((lastruntimeaddr + GRUB_XNU_PAGESIZE - 1) / GRUB_XNU_PAGESIZE) - - (firstruntimeaddr / GRUB_XNU_PAGESIZE); + bootparams_relloc->efi_runtime_first_page = firstruntimepage; + + bootparams_relloc->efi_runtime_npages = lastruntimepage - firstruntimepage; bootparams_relloc->efi_uintnbits = SIZEOF_OF_UINTN * 8; bootparams_relloc->verminor = GRUB_XNU_BOOTARGS_VERMINOR; From ab6e34cc81c89614502a52b02c9210a8cfc05f86 Mon Sep 17 00:00:00 2001 From: phcoder Date: Thu, 10 Sep 2009 23:54:12 +0200 Subject: [PATCH 14/52] missing files --- loader/macho32.c | 18 ++++ loader/macho64.c | 18 ++++ loader/machoXX.c | 234 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 270 insertions(+) create mode 100644 loader/macho32.c create mode 100644 loader/macho64.c create mode 100644 loader/machoXX.c diff --git a/loader/macho32.c b/loader/macho32.c new file mode 100644 index 000000000..0d740eda7 --- /dev/null +++ b/loader/macho32.c @@ -0,0 +1,18 @@ +#include +#include + +#define SUFFIX(x) x ## 32 +typedef struct grub_macho_header32 grub_macho_header_t; +typedef struct grub_macho_segment32 grub_macho_segment_t; +typedef grub_uint32_t grub_macho_addr_t; +typedef struct grub_macho_thread32 grub_macho_thread_t; +#define offsetXX offset32 +#define ncmdsXX ncmds32 +#define cmdsizeXX cmdsize32 +#define cmdsXX cmds32 +#define endXX end32 +#define XX "32" +#define GRUB_MACHO_MAGIC GRUB_MACHO_MAGIC32 +#define GRUB_MACHO_CMD_SEGMENT GRUB_MACHO_CMD_SEGMENT32 +#include "machoXX.c" + diff --git a/loader/macho64.c b/loader/macho64.c new file mode 100644 index 000000000..17a8021e0 --- /dev/null +++ b/loader/macho64.c @@ -0,0 +1,18 @@ +#include +#include + +#define SUFFIX(x) x ## 64 +typedef struct grub_macho_header64 grub_macho_header_t; +typedef struct grub_macho_segment64 grub_macho_segment_t; +typedef grub_uint64_t grub_macho_addr_t; +typedef struct grub_macho_thread64 grub_macho_thread_t; +#define offsetXX offset64 +#define ncmdsXX ncmds64 +#define cmdsizeXX cmdsize64 +#define cmdsXX cmds64 +#define endXX end64 +#define XX "64" +#define GRUB_MACHO_MAGIC GRUB_MACHO_MAGIC64 +#define GRUB_MACHO_CMD_SEGMENT GRUB_MACHO_CMD_SEGMENT64 +#include "machoXX.c" + diff --git a/loader/machoXX.c b/loader/machoXX.c new file mode 100644 index 000000000..b07bab937 --- /dev/null +++ b/loader/machoXX.c @@ -0,0 +1,234 @@ + +#include +#include +#include + +#define min(a,b) (((a) < (b)) ? (a) : (b)) + +int +SUFFIX (grub_macho_contains_macho) (grub_macho_t macho) +{ + return macho->offsetXX != -1; +} + +void +SUFFIX (grub_macho_parse) (grub_macho_t macho) +{ + grub_macho_header_t head; + + /* Is there any candidate at all? */ + if (macho->offsetXX == -1) + return; + + /* Read header and check magic*/ + if (grub_file_seek (macho->file, macho->offsetXX) == (grub_off_t) -1 + || grub_file_read (macho->file, &head, sizeof (head)) + != sizeof(head)) + { + grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header."); + macho->offsetXX = -1; + return; + } + if (head.magic != GRUB_MACHO_MAGIC) + { + grub_error (GRUB_ERR_BAD_OS, "Invalid Mach-O 32-bit header."); + macho->offsetXX = -1; + return; + } + + /* Read commands. */ + macho->ncmdsXX = head.ncmds; + macho->cmdsizeXX = head.sizeofcmds; + macho->cmdsXX = grub_malloc(macho->cmdsizeXX); + if (! macho->cmdsXX) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "not enough memory to read commands"); + return; + } + if (grub_file_read (macho->file, macho->cmdsXX, + (grub_size_t) macho->cmdsizeXX) + != (grub_ssize_t) macho->cmdsizeXX) + { + grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header."); + macho->offsetXX = -1; + } +} + +typedef int NESTED_FUNC_ATTR (*grub_macho_iter_hook_t) +(grub_macho_t , struct grub_macho_cmd *, + void *); + +static grub_err_t +grub_macho_cmds_iterate (grub_macho_t macho, + grub_macho_iter_hook_t hook, + void *hook_arg) +{ + grub_uint8_t *hdrs = macho->cmdsXX; + int i; + if (! macho->cmdsXX) + return grub_error (GRUB_ERR_BAD_OS, "Couldn't find " XX "-bit Mach-O"); + for (i = 0; i < macho->ncmdsXX; i++) + { + struct grub_macho_cmd *hdr = (struct grub_macho_cmd *) hdrs; + if (hook (macho, hdr, hook_arg)) + break; + hdrs += hdr->cmdsize; + } + + return grub_errno; +} + +grub_size_t +SUFFIX (grub_macho_filesize) (grub_macho_t macho) +{ + if (SUFFIX (grub_macho_contains_macho) (macho)) + return macho->endXX - macho->offsetXX; + return 0; +} + +grub_err_t +SUFFIX (grub_macho_readfile) (grub_macho_t macho, void *dest) +{ + grub_ssize_t read; + if (! SUFFIX (grub_macho_contains_macho) (macho)) + return grub_error (GRUB_ERR_BAD_OS, + "Couldn't read architecture-specific part"); + + if (grub_file_seek (macho->file, macho->offset32) == (grub_off_t) -1) + { + grub_error_push (); + return grub_error (GRUB_ERR_BAD_OS, + "Invalid offset in program header."); + } + + read = grub_file_read (macho->file, dest, + macho->end32 - macho->offset32); + if (read != (grub_ssize_t) (macho->end32 - macho->offset32)) + { + grub_error_push (); + return grub_error (GRUB_ERR_BAD_OS, + "Couldn't read architecture-specific part"); + } + return GRUB_ERR_NONE; +} + +/* Calculate the amount of memory spanned by the segments. */ +grub_err_t +SUFFIX (grub_macho_size) (grub_macho_t macho, grub_macho_addr_t *segments_start, + grub_macho_addr_t *segments_end, int flags) +{ + int nr_phdrs = 0; + + /* Run through the program headers to calculate the total memory size we + should claim. */ + auto int NESTED_FUNC_ATTR calcsize (grub_macho_t _macho, + struct grub_macho_cmd *phdr, void *_arg); + int NESTED_FUNC_ATTR calcsize (grub_macho_t UNUSED _macho, + struct grub_macho_cmd *hdr0, void UNUSED *_arg) + { + grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0; + if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT) + return 0; + if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS)) + return 0; + + nr_phdrs++; + if (hdr->vmaddr < *segments_start) + *segments_start = hdr->vmaddr; + if (hdr->vmaddr + hdr->vmsize > *segments_end) + *segments_end = hdr->vmaddr + hdr->vmsize; + return 0; + } + + *segments_start = (grub_macho_addr_t) -1; + *segments_end = 0; + + grub_macho_cmds_iterate (macho, calcsize, 0); + + if (nr_phdrs == 0) + return grub_error (GRUB_ERR_BAD_OS, "No program headers present"); + + if (*segments_end < *segments_start) + /* Very bad addresses. */ + return grub_error (GRUB_ERR_BAD_OS, "Bad program header load addresses"); + + return GRUB_ERR_NONE; +} + +/* Load every loadable segment into memory specified by `_load_hook'. */ +grub_err_t +SUFFIX (grub_macho_load) (grub_macho_t macho, char *offset, int flags) +{ + grub_err_t err = 0; + auto int NESTED_FUNC_ATTR do_load(grub_macho_t _macho, + struct grub_macho_cmd *hdr0, + void UNUSED *_arg); + int NESTED_FUNC_ATTR do_load(grub_macho_t _macho, + struct grub_macho_cmd *hdr0, + void UNUSED *_arg) + { + grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0; + + if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT) + return 0; + + if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS)) + return 0; + if (! hdr->vmsize) + return 0; + + if (grub_file_seek (_macho->file, hdr->fileoff + + _macho->offsetXX) == (grub_off_t) -1) + { + grub_error_push (); + grub_error (GRUB_ERR_BAD_OS, + "Invalid offset in program header."); + return 1; + } + + if (hdr->filesize) + { + grub_ssize_t read; + read = grub_file_read (_macho->file, offset + hdr->vmaddr, + min (hdr->filesize, hdr->vmsize)); + if (read != (grub_ssize_t) min (hdr->filesize, hdr->vmsize)) + { + /* XXX How can we free memory from `load_hook'? */ + grub_error_push (); + err=grub_error (GRUB_ERR_BAD_OS, + "Couldn't read segment from file: " + "wanted 0x%lx bytes; read 0x%lx bytes.", + hdr->filesize, read); + return 1; + } + } + + if (hdr->filesize < hdr->vmsize) + grub_memset (offset + hdr->vmaddr + hdr->filesize, + 0, hdr->vmsize - hdr->filesize); + return 0; + } + + grub_macho_cmds_iterate (macho, do_load, 0); + + return err; +} + +grub_macho_addr_t +SUFFIX (grub_macho_get_entry_point) (grub_macho_t macho) +{ + grub_macho_addr_t entry_point = 0; + auto int NESTED_FUNC_ATTR hook(grub_macho_t _macho, + struct grub_macho_cmd *hdr, + void UNUSED *_arg); + int NESTED_FUNC_ATTR hook(grub_macho_t UNUSED _macho, + struct grub_macho_cmd *hdr, + void UNUSED *_arg) + { + if (hdr->cmd == GRUB_MACHO_CMD_THREAD) + entry_point = ((grub_macho_thread_t *) hdr)->entry_point; + return 0; + } + grub_macho_cmds_iterate (macho, hook, 0); + return entry_point; +} From 29434648114f02b6717e8a78efa6b6b3f24a71c3 Mon Sep 17 00:00:00 2001 From: phcoder Date: Thu, 17 Sep 2009 10:03:12 +0200 Subject: [PATCH 15/52] fixed 64-bit loading --- loader/machoXX.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/loader/machoXX.c b/loader/machoXX.c index b07bab937..01e6879ea 100644 --- a/loader/machoXX.c +++ b/loader/machoXX.c @@ -129,6 +129,10 @@ SUFFIX (grub_macho_size) (grub_macho_t macho, grub_macho_addr_t *segments_start, grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0; if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT) return 0; + + if (! hdr->vmsize) + return 0; + if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS)) return 0; From 2cb69d2fee3140dac56f9e0437ea70d30913edad Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 20 Sep 2009 15:14:22 +0200 Subject: [PATCH 16/52] bugfix --- loader/machoXX.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/loader/machoXX.c b/loader/machoXX.c index 01e6879ea..d42dd8b55 100644 --- a/loader/machoXX.c +++ b/loader/machoXX.c @@ -31,7 +31,7 @@ SUFFIX (grub_macho_parse) (grub_macho_t macho) } if (head.magic != GRUB_MACHO_MAGIC) { - grub_error (GRUB_ERR_BAD_OS, "Invalid Mach-O 32-bit header."); + grub_error (GRUB_ERR_BAD_OS, "Invalid Mach-O " XX "-bit header."); macho->offsetXX = -1; return; } @@ -94,7 +94,7 @@ SUFFIX (grub_macho_readfile) (grub_macho_t macho, void *dest) return grub_error (GRUB_ERR_BAD_OS, "Couldn't read architecture-specific part"); - if (grub_file_seek (macho->file, macho->offset32) == (grub_off_t) -1) + if (grub_file_seek (macho->file, macho->offsetXX) == (grub_off_t) -1) { grub_error_push (); return grub_error (GRUB_ERR_BAD_OS, @@ -102,8 +102,8 @@ SUFFIX (grub_macho_readfile) (grub_macho_t macho, void *dest) } read = grub_file_read (macho->file, dest, - macho->end32 - macho->offset32); - if (read != (grub_ssize_t) (macho->end32 - macho->offset32)) + macho->endXX - macho->offsetXX); + if (read != (grub_ssize_t) (macho->endXX - macho->offsetXX)) { grub_error_push (); return grub_error (GRUB_ERR_BAD_OS, From 1d3c6f1de73f05a66dde89608ed3fdac1758e411 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 9 Nov 2009 18:43:53 +0100 Subject: [PATCH 17/52] Manually reimported XNU branch --- ChangeLog | 43 +++ autogen.sh | 0 bus/usb/usb.c | 36 --- commands/usbtest.c | 49 +++- conf/common.rmk | 5 + efiemu/main.c | 15 +- efiemu/pnvram.c | 451 ++++++++++++-------------------- fs/fat.c | 1 + fs/hfsplus.c | 1 + fs/i386/pc/pxe.c | 1 - fs/iso9660.c | 1 + fs/jfs.c | 1 + fs/ntfs.c | 1 + gendistlist.sh | 0 include/grub/charset.h | 112 ++++++++ include/grub/i386/xnu.h | 42 ++- include/grub/misc.h | 3 - include/grub/usb.h | 3 - include/grub/xnu.h | 1 + kern/efi/efi.c | 1 + kern/misc.c | 62 ----- lib/charset.c | 116 +++++++++ loader/efi/chainloader.c | 1 + loader/i386/xnu.c | 460 ++++++++++++++++++++++++++++++++- loader/machoXX.c | 8 +- loader/xnu.c | 301 ++++++++------------- normal/completion.c | 17 +- normal/misc.c | 4 +- util/i386/efi/grub-dumpdevtree | 25 -- 29 files changed, 1128 insertions(+), 633 deletions(-) mode change 100644 => 100755 autogen.sh mode change 100644 => 100755 gendistlist.sh create mode 100644 include/grub/charset.h create mode 100644 lib/charset.c delete mode 100644 util/i386/efi/grub-dumpdevtree diff --git a/ChangeLog b/ChangeLog index ea2145770..3aecde16f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -769,6 +769,20 @@ 2009-08-29 Vladimir Serbinenko + * kern/misc.c (grub_utf16_to_utf8): Move from here ... + * include/grub/charset.h (grub_utf16_to_utf8): ... to here. Inlined. + All users updated. + * include/grub/misc.h (grub_utf16_to_utf8): Removed. + +2009-08-28 Vladimir Serbinenko + + * bus/usb/usb.c (grub_usb_get_string): Move from here ... + * commands/usbtest.c (grub_usb_get_string): ... move here. + (usb_print_str): Fix error handling. + * include/grub/usb.h (grub_usb_get_string): Remove. + +2009-08-28 Vladimir Serbinenko + * include/grub/i386/xnu.h: Add license header. include grub/err.h explicitly. @@ -1030,6 +1044,35 @@ * kern/misc.c (grub_tolower): Moved from here ... * include/grub/misc.h (grub_tolower): ... here. Inlined. +2009-08-24 Vladimir Serbinenko + + Eliminate ad-hoc tree format in XNU and EfiEmu. + + * efiemu/main.c (grub_efiemu_prepare): Update comment. + * efiemu/pnvram.c: Rewritten to use environment variables. + All users updated. + * include/grub/xnu.h (grub_xnu_fill_devicetree): New prototype. + * loader/i386/xnu.c (grub_xnu_boot): Call grub_cpu_xnu_fill_devicetree + and grub_xnu_fill_devicetree. + * loader/xnu.c (grub_cmd_xnu_kernel): Don't call + grub_cpu_xnu_fill_devicetree. + (grub_xnu_parse_devtree): Removed. + (grub_cmd_xnu_devtree): Likewise. + (hextoval): New function. + (unescape): Likewise. + (grub_xnu_fill_devicetree): Likewise. + +2009-08-24 Vladimir Serbinenko + + UTF-8 to UTF-16 transformation. + + * conf/common.rmk (pkglib_MODULES): Add utf.mod + (utf_mod_SOURCES): New variable. + (utf_mod_CFLAGS): Likewise. + (utf_mod_LDFLAGS): Likewise. + * include/grub/utf.h: New file. + * lib/utf.c: New file. (Based on grub_utf8_to_ucs4 from kern/misc.c) + 2009-08-24 Vladimir Serbinenko * script/sh/function.c (grub_script_function_find): Cut error message diff --git a/autogen.sh b/autogen.sh old mode 100644 new mode 100755 diff --git a/bus/usb/usb.c b/bus/usb/usb.c index 310b8cc6a..8289185da 100644 --- a/bus/usb/usb.c +++ b/bus/usb/usb.c @@ -155,42 +155,6 @@ grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr) return NULL; } -grub_usb_err_t -grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid, - char **string) -{ - struct grub_usb_desc_str descstr; - struct grub_usb_desc_str *descstrp; - grub_usb_err_t err; - - /* Only get the length. */ - err = grub_usb_control_msg (dev, 1 << 7, - 0x06, (3 << 8) | index, - langid, 1, (char *) &descstr); - if (err) - return err; - - descstrp = grub_malloc (descstr.length); - if (! descstrp) - return GRUB_USB_ERR_INTERNAL; - err = grub_usb_control_msg (dev, 1 << 7, - 0x06, (3 << 8) | index, - langid, descstr.length, (char *) descstrp); - - *string = grub_malloc (descstr.length / 2); - if (! *string) - { - grub_free (descstrp); - return GRUB_USB_ERR_INTERNAL; - } - - grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, descstrp->length / 2 - 1); - (*string)[descstr.length / 2 - 1] = '\0'; - grub_free (descstrp); - - return GRUB_USB_ERR_NONE; -} - grub_usb_err_t grub_usb_device_initialize (grub_usb_device_t dev) { diff --git a/commands/usbtest.c b/commands/usbtest.c index 018c1a25b..3405c3b4d 100644 --- a/commands/usbtest.c +++ b/commands/usbtest.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -59,18 +60,60 @@ static const char *usb_devspeed[] = "High" }; +static grub_usb_err_t +grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid, + char **string) +{ + struct grub_usb_desc_str descstr; + struct grub_usb_desc_str *descstrp; + grub_usb_err_t err; + + /* Only get the length. */ + err = grub_usb_control_msg (dev, 1 << 7, + 0x06, (3 << 8) | index, + langid, 1, (char *) &descstr); + if (err) + return err; + + descstrp = grub_malloc (descstr.length); + if (! descstrp) + return GRUB_USB_ERR_INTERNAL; + err = grub_usb_control_msg (dev, 1 << 7, + 0x06, (3 << 8) | index, + langid, descstr.length, (char *) descstrp); + + *string = grub_malloc (descstr.length / 2); + if (! *string) + { + grub_free (descstrp); + return GRUB_USB_ERR_INTERNAL; + } + + grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, descstrp->length / 2 - 1); + (*string)[descstr.length / 2 - 1] = '\0'; + grub_free (descstrp); + + return GRUB_USB_ERR_NONE; +} + static void usb_print_str (const char *description, grub_usb_device_t dev, int idx) { char *name; + grub_usb_err_t err; /* XXX: LANGID */ if (! idx) return; - grub_usb_get_string (dev, idx, 0x0409, &name); - grub_printf ("%s: `%s'\n", description, name); - grub_free (name); + err = grub_usb_get_string (dev, idx, 0x0409, &name); + if (err) + grub_printf ("Error %d retrieving %s\n", err, description); + else + { + grub_printf ("%s: `%s'\n", description, name); + grub_free (name); + } } static int diff --git a/conf/common.rmk b/conf/common.rmk index c1f0bbdcf..99af0662a 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -608,3 +608,8 @@ pkglib_MODULES += setjmp.mod setjmp_mod_SOURCES = lib/$(target_cpu)/setjmp.S setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS) setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += charset.mod +charset_mod_SOURCES = lib/charset.c +charset_mod_CFLAGS = $(COMMON_CFLAGS) +charset_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/efiemu/main.c b/efiemu/main.c index b5608e666..05787284d 100644 --- a/efiemu/main.c +++ b/efiemu/main.c @@ -39,6 +39,7 @@ grub_efi_system_table64_t *grub_efiemu_system_table64 = 0; static struct grub_efiemu_prepare_hook *efiemu_prepare_hooks = 0; /* Linked list of configuration tables */ static struct grub_efiemu_configuration_table *efiemu_config_tables = 0; +static int prepared = 0; /* Free all allocated space */ grub_err_t @@ -70,6 +71,8 @@ grub_efiemu_unload (void) } efiemu_prepare_hooks = 0; + prepared = 0; + return GRUB_ERR_NONE; } @@ -277,14 +280,19 @@ grub_efiemu_prepare (void) { grub_err_t err; + if (prepared) + return GRUB_ERR_NONE; + grub_dprintf ("efiemu", "Preparing %d-bit efiemu\n", 8 * grub_efiemu_sizeof_uintn_t ()); err = grub_efiemu_autocore (); - /* Create NVRAM if not yet done. */ + /* Create NVRAM. */ grub_efiemu_pnvram (); + prepared = 1; + if (grub_efiemu_sizeof_uintn_t () == 4) return grub_efiemu_prepare32 (efiemu_prepare_hooks, efiemu_config_tables); else @@ -316,9 +324,6 @@ grub_cmd_efiemu_load (grub_command_t cmd __attribute__ ((unused)), static grub_command_t cmd_loadcore, cmd_prepare, cmd_unload; -void -grub_efiemu_pnvram_cmd_register (void); - GRUB_MOD_INIT(efiemu) { cmd_loadcore = grub_register_command ("efiemu_loadcore", @@ -332,7 +337,6 @@ GRUB_MOD_INIT(efiemu) cmd_unload = grub_register_command ("efiemu_unload", grub_cmd_efiemu_unload, "efiemu_unload", "Unload EFI emulator"); - grub_efiemu_pnvram_cmd_register (); } GRUB_MOD_FINI(efiemu) @@ -340,5 +344,4 @@ GRUB_MOD_FINI(efiemu) grub_unregister_command (cmd_loadcore); grub_unregister_command (cmd_prepare); grub_unregister_command (cmd_unload); - grub_efiemu_pnvram_cmd_unregister (); } diff --git a/efiemu/pnvram.c b/efiemu/pnvram.c index 04ad6e284..ede59ede1 100644 --- a/efiemu/pnvram.c +++ b/efiemu/pnvram.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -34,62 +35,181 @@ static int timezone_handle = 0; static int accuracy_handle = 0; static int daylight_handle = 0; -/* Temporary place */ -static grub_uint8_t *nvram; static grub_size_t nvramsize; -static grub_uint32_t high_monotonic_count; -static grub_int16_t timezone; -static grub_uint8_t daylight; -static grub_uint32_t accuracy; - -static const struct grub_arg_option options[] = { - {"size", 's', 0, "number of bytes to reserve for pseudo NVRAM", 0, - ARG_TYPE_INT}, - {"high-monotonic-count", 'm', 0, - "Initial value of high monotonic count", 0, ARG_TYPE_INT}, - {"timezone", 't', 0, - "Timezone, offset in minutes from GMT", 0, ARG_TYPE_INT}, - {"accuracy", 'a', 0, - "Accuracy of clock, in 1e-12 units", 0, ARG_TYPE_INT}, - {"daylight", 'd', 0, - "Daylight value, as per EFI specifications", 0, ARG_TYPE_INT}, - {0, 0, 0, 0, 0, 0} -}; /* Parse signed value */ static int -grub_strtosl (char *arg, char **end, int base) +grub_strtosl (const char *arg, char **end, int base) { if (arg[0] == '-') return -grub_strtoul (arg + 1, end, base); return grub_strtoul (arg, end, base); } +static inline int +hextoval (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'z') + return c - 'a' + 10; + if (c >= 'A' && c <= 'Z') + return c - 'A' + 10; + return 0; +} + +static inline grub_err_t +unescape (char *in, char *out, char *outmax, int *len) +{ + char *ptr, *dptr; + dptr = out; + for (ptr = in; *ptr && dptr < outmax; ) + if (*ptr == '%' && ptr[1] && ptr[2]) + { + *dptr = (hextoval (ptr[1]) << 4) | (hextoval (ptr[2])); + ptr += 3; + dptr++; + } + else + { + *dptr = *ptr; + ptr++; + dptr++; + } + if (dptr == outmax) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "Too many NVRAM variables for reserved variable space." + " Try increasing EfiEmu.pnvram.size."); + *len = dptr - out; + return 0; +} + /* Export stuff for efiemu */ static grub_err_t nvram_set (void * data __attribute__ ((unused))) { + const char *env; /* Take definitive pointers */ - grub_uint8_t *nvram_def = grub_efiemu_mm_obtain_request (nvram_handle); + char *nvram = grub_efiemu_mm_obtain_request (nvram_handle); grub_uint32_t *nvramsize_def = grub_efiemu_mm_obtain_request (nvramsize_handle); - grub_uint32_t *high_monotonic_count_def + grub_uint32_t *high_monotonic_count = grub_efiemu_mm_obtain_request (high_monotonic_count_handle); - grub_int16_t *timezone_def + grub_int16_t *timezone = grub_efiemu_mm_obtain_request (timezone_handle); - grub_uint8_t *daylight_def + grub_uint8_t *daylight = grub_efiemu_mm_obtain_request (daylight_handle); - grub_uint32_t *accuracy_def + grub_uint32_t *accuracy = grub_efiemu_mm_obtain_request (accuracy_handle); + char *nvramptr; + + auto int iterate_env (struct grub_env_var *var); + int iterate_env (struct grub_env_var *var) + { + char *guid, *attr, *name, *varname; + struct efi_variable *efivar; + int len = 0; + + if (grub_memcmp (var->name, "EfiEmu.pnvram.", + sizeof ("EfiEmu.pnvram.") - 1) != 0) + return 0; + + guid = var->name + sizeof ("EfiEmu.pnvram.") - 1; + + attr = grub_strchr (guid, '.'); + if (!attr) + return 0; + attr++; + + name = grub_strchr (attr, '.'); + if (!name) + return 0; + name++; + + efivar = (struct efi_variable *) nvramptr; + if (nvramptr - nvram + sizeof (struct efi_variable) > nvramsize) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, + "Too many NVRAM variables for reserved variable space." + " Try increasing EfiEmu.pnvram.size."); + return 1; + } + + nvramptr += sizeof (struct efi_variable); + + efivar->guid.data1 = grub_cpu_to_le32 (grub_strtoul (guid, &guid, 16)); + if (*guid != '-') + return 0; + guid++; + + efivar->guid.data2 = grub_cpu_to_le16 (grub_strtoul (guid, &guid, 16)); + if (*guid != '-') + return 0; + guid++; + + efivar->guid.data3 = grub_cpu_to_le16 (grub_strtoul (guid, &guid, 16)); + if (*guid != '-') + return 0; + guid++; + + *(grub_uint64_t *) &(efivar->guid.data4) + = grub_cpu_to_be64 (grub_strtoull (guid, 0, 16)); + + efivar->attributes = grub_strtoull (attr, 0, 16); + + varname = grub_malloc (grub_strlen (name) + 1); + if (! varname) + return 1; + + if (unescape (name, varname, varname + grub_strlen (name) + 1, &len)) + return 1; + + len = grub_utf8_to_utf16 ((grub_uint16_t *) nvramptr, + (nvramsize - (nvramptr - nvram)) / 2, + (grub_uint8_t *) varname, len, NULL); + + if (len < 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "Broken UTF-8 in variable name\n"); + return 1; + } + + nvramptr += 2 * len; + *((grub_uint16_t *) nvramptr) = 0; + nvramptr += 2; + efivar->namelen = 2 * len + 2; + + if (unescape (var->value, nvramptr, nvram + nvramsize, &len)) + { + efivar->namelen = 0; + return 1; + } + + nvramptr += len; + + efivar->size = len; + + return 0; + } /* Copy to definitive loaction */ grub_dprintf ("efiemu", "preparing pnvram\n"); - grub_memcpy (nvram_def, nvram, nvramsize); + + env = grub_env_get ("EfiEmu.pnvram.high_monotonic_count"); + *high_monotonic_count = env ? grub_strtoul (env, 0, 0) : 1; + env = grub_env_get ("EfiEmu.pnvram.timezone"); + *timezone = env ? grub_strtosl (env, 0, 0) : GRUB_EFI_UNSPECIFIED_TIMEZONE; + env = grub_env_get ("EfiEmu.pnvram.accuracy"); + *accuracy = env ? grub_strtoul (env, 0, 0) : 50000000; + env = grub_env_get ("EfiEmu.pnvram.daylight"); + *daylight = env ? grub_strtoul (env, 0, 0) : 0; + + nvramptr = nvram; + grub_memset (nvram, 0, nvramsize); + grub_env_iterate (iterate_env); + if (grub_errno) + return grub_errno; *nvramsize_def = nvramsize; - *high_monotonic_count_def = high_monotonic_count; - *timezone_def = timezone; - *daylight_def = daylight; - *accuracy_def = accuracy; /* Register symbols */ grub_efiemu_register_symbol ("efiemu_variables", nvram_handle, 0); @@ -113,197 +233,27 @@ nvram_unload (void * data __attribute__ ((unused))) grub_efiemu_mm_return_request (timezone_handle); grub_efiemu_mm_return_request (accuracy_handle); grub_efiemu_mm_return_request (daylight_handle); - - grub_free (nvram); - nvram = 0; } -/* Load the variables file It's in format - guid1:attr1:name1:data1; - guid2:attr2:name2:data2; - ... - Where all fields are in hex -*/ -static grub_err_t -read_pnvram (char *filename) -{ - char *buf, *ptr, *ptr2; - grub_file_t file; - grub_size_t size; - grub_uint8_t *nvramptr = nvram; - struct efi_variable *efivar; - grub_size_t guidlen, datalen; - unsigned i, j; - - file = grub_file_open (filename); - if (!file) - return grub_error (GRUB_ERR_BAD_OS, "couldn't read pnvram"); - size = grub_file_size (file); - buf = grub_malloc (size + 1); - if (!buf) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't read pnvram"); - if (grub_file_read (file, buf, size) != (grub_ssize_t) size) - return grub_error (GRUB_ERR_BAD_OS, "couldn't read pnvram"); - buf[size] = 0; - grub_file_close (file); - - for (ptr = buf; *ptr; ) - { - if (grub_isspace (*ptr)) - { - ptr++; - continue; - } - - efivar = (struct efi_variable *) nvramptr; - if (nvramptr - nvram + sizeof (struct efi_variable) > nvramsize) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "file is too large for reserved variable space"); - - nvramptr += sizeof (struct efi_variable); - - /* look ahow long guid field is*/ - guidlen = 0; - for (ptr2 = ptr; (grub_isspace (*ptr2) - || (*ptr2 >= '0' && *ptr2 <= '9') - || (*ptr2 >= 'a' && *ptr2 <= 'f') - || (*ptr2 >= 'A' && *ptr2 <= 'F')); - ptr2++) - if (!grub_isspace (*ptr2)) - guidlen++; - guidlen /= 2; - - /* Read guid */ - if (guidlen != sizeof (efivar->guid)) - { - grub_free (buf); - return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename); - } - for (i = 0; i < 2 * sizeof (efivar->guid); i++) - { - int hex = 0; - while (grub_isspace (*ptr)) - ptr++; - if (*ptr >= '0' && *ptr <= '9') - hex = *ptr - '0'; - if (*ptr >= 'a' && *ptr <= 'f') - hex = *ptr - 'a' + 10; - if (*ptr >= 'A' && *ptr <= 'F') - hex = *ptr - 'A' + 10; - - if (i%2 == 0) - ((grub_uint8_t *)&(efivar->guid))[i/2] = hex << 4; - else - ((grub_uint8_t *)&(efivar->guid))[i/2] |= hex; - ptr++; - } - - while (grub_isspace (*ptr)) - ptr++; - if (*ptr != ':') - { - grub_dprintf ("efiemu", "Not colon\n"); - grub_free (buf); - return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename); - } - ptr++; - while (grub_isspace (*ptr)) - ptr++; - - /* Attributes can be just parsed by existing functions */ - efivar->attributes = grub_strtoul (ptr, &ptr, 16); - - while (grub_isspace (*ptr)) - ptr++; - if (*ptr != ':') - { - grub_dprintf ("efiemu", "Not colon\n"); - grub_free (buf); - return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename); - } - ptr++; - while (grub_isspace (*ptr)) - ptr++; - - /* Read name and value */ - for (j = 0; j < 2; j++) - { - /* Look the length */ - datalen = 0; - for (ptr2 = ptr; *ptr2 && (grub_isspace (*ptr2) - || (*ptr2 >= '0' && *ptr2 <= '9') - || (*ptr2 >= 'a' && *ptr2 <= 'f') - || (*ptr2 >= 'A' && *ptr2 <= 'F')); - ptr2++) - if (!grub_isspace (*ptr2)) - datalen++; - datalen /= 2; - - if (nvramptr - nvram + datalen > nvramsize) - { - grub_free (buf); - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "file is too large for reserved " - " variable space"); - } - - for (i = 0; i < 2 * datalen; i++) - { - int hex = 0; - while (grub_isspace (*ptr)) - ptr++; - if (*ptr >= '0' && *ptr <= '9') - hex = *ptr - '0'; - if (*ptr >= 'a' && *ptr <= 'f') - hex = *ptr - 'a' + 10; - if (*ptr >= 'A' && *ptr <= 'F') - hex = *ptr - 'A' + 10; - - if (i%2 == 0) - nvramptr[i/2] = hex << 4; - else - nvramptr[i/2] |= hex; - ptr++; - } - nvramptr += datalen; - while (grub_isspace (*ptr)) - ptr++; - if (*ptr != (j ? ';' : ':')) - { - grub_free (buf); - grub_dprintf ("efiemu", j?"Not semicolon\n":"Not colon\n"); - return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename); - } - if (j) - efivar->size = datalen; - else - efivar->namelen = datalen; - - ptr++; - } - } - grub_free (buf); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_efiemu_make_nvram (void) +grub_err_t +grub_efiemu_pnvram (void) { + const char *size; grub_err_t err; - err = grub_efiemu_autocore (); - if (err) - { - grub_free (nvram); - return err; - } + nvramsize = 0; + + size = grub_env_get ("EfiEmu.pnvram.size"); + if (size) + nvramsize = grub_strtoul (size, 0, 0); + + if (!nvramsize) + nvramsize = 2048; err = grub_efiemu_register_prepare_hook (nvram_set, nvram_unload, 0); if (err) - { - grub_free (nvram); - return err; - } + return err; + nvram_handle = grub_efiemu_request_memalign (1, nvramsize, GRUB_EFI_RUNTIME_SERVICES_DATA); @@ -323,78 +273,5 @@ grub_efiemu_make_nvram (void) = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t), GRUB_EFI_RUNTIME_SERVICES_DATA); - grub_efiemu_request_symbols (6); return GRUB_ERR_NONE; } - -grub_err_t -grub_efiemu_pnvram (void) -{ - if (nvram) - return GRUB_ERR_NONE; - - nvramsize = 2048; - high_monotonic_count = 1; - timezone = GRUB_EFI_UNSPECIFIED_TIMEZONE; - accuracy = 50000000; - daylight = 0; - - nvram = grub_zalloc (nvramsize); - if (!nvram) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Couldn't allocate space for temporary pnvram storage"); - - return grub_efiemu_make_nvram (); -} - -static grub_err_t -grub_cmd_efiemu_pnvram (struct grub_extcmd *cmd, - int argc, char **args) -{ - struct grub_arg_list *state = cmd->state; - grub_err_t err; - - if (argc > 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "only one argument expected"); - - nvramsize = state[0].set ? grub_strtoul (state[0].arg, 0, 0) : 2048; - high_monotonic_count = state[1].set ? grub_strtoul (state[1].arg, 0, 0) : 1; - timezone = state[2].set ? grub_strtosl (state[2].arg, 0, 0) - : GRUB_EFI_UNSPECIFIED_TIMEZONE; - accuracy = state[3].set ? grub_strtoul (state[3].arg, 0, 0) : 50000000; - daylight = state[4].set ? grub_strtoul (state[4].arg, 0, 0) : 0; - - nvram = grub_zalloc (nvramsize); - if (!nvram) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Couldn't allocate space for temporary pnvram storage"); - - if (argc == 1 && (err = read_pnvram (args[0]))) - { - grub_free (nvram); - return err; - } - return grub_efiemu_make_nvram (); -} - -static grub_extcmd_t cmd; - -void grub_efiemu_pnvram_cmd_register (void); -void grub_efiemu_pnvram_cmd_unregister (void); - -void -grub_efiemu_pnvram_cmd_register (void) -{ - cmd = grub_register_extcmd ("efiemu_pnvram", grub_cmd_efiemu_pnvram, - GRUB_COMMAND_FLAG_BOTH, - "efiemu_pnvram [FILENAME]", - "Initialise pseudo-NVRAM and load variables " - "from FILE", - options); -} - -void -grub_efiemu_pnvram_cmd_unregister (void) -{ - grub_unregister_extcmd (cmd); -} diff --git a/fs/fat.c b/fs/fat.c index e7f01629e..ab84ee49a 100644 --- a/fs/fat.c +++ b/fs/fat.c @@ -25,6 +25,7 @@ #include #include #include +#include #define GRUB_FAT_DIR_ENTRY_SIZE 32 diff --git a/fs/hfsplus.c b/fs/hfsplus.c index b306e8d6a..71910330f 100644 --- a/fs/hfsplus.c +++ b/fs/hfsplus.c @@ -28,6 +28,7 @@ #include #include #include +#include #define GRUB_HFSPLUS_MAGIC 0x482B #define GRUB_HFSPLUSX_MAGIC 0x4858 diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c index 4032e1254..1a99ad466 100644 --- a/fs/i386/pc/pxe.c +++ b/fs/i386/pc/pxe.c @@ -65,7 +65,6 @@ grub_pxe_open (const char *name, grub_disk_t disk) disk->total_sectors = 0; disk->id = (unsigned long) "pxe"; - disk->has_partitions = 0; disk->data = 0; return GRUB_ERR_NONE; diff --git a/fs/iso9660.c b/fs/iso9660.c index 9b7ce765b..976222a45 100644 --- a/fs/iso9660.c +++ b/fs/iso9660.c @@ -26,6 +26,7 @@ #include #include #include +#include #define GRUB_ISO9660_FSTYPE_DIR 0040000 #define GRUB_ISO9660_FSTYPE_REG 0100000 diff --git a/fs/jfs.c b/fs/jfs.c index b73f9bdd4..589b6ae5a 100644 --- a/fs/jfs.c +++ b/fs/jfs.c @@ -24,6 +24,7 @@ #include #include #include +#include #define GRUB_JFS_MAX_SYMLNK_CNT 8 #define GRUB_JFS_FILETYPE_MASK 0170000 diff --git a/fs/ntfs.c b/fs/ntfs.c index 163f3e0a8..495cdd159 100644 --- a/fs/ntfs.c +++ b/fs/ntfs.c @@ -24,6 +24,7 @@ #include #include #include +#include static grub_dl_t my_mod; diff --git a/gendistlist.sh b/gendistlist.sh old mode 100644 new mode 100755 diff --git a/include/grub/charset.h b/include/grub/charset.h new file mode 100644 index 000000000..f85862f8b --- /dev/null +++ b/include/grub/charset.h @@ -0,0 +1,112 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 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 . + */ + +#ifndef GRUB_CHARSET_HEADER +#define GRUB_CHARSET_HEADER 1 + +#include + +#define GRUB_UINT8_1_LEADINGBIT 0x80 +#define GRUB_UINT8_2_LEADINGBITS 0xc0 +#define GRUB_UINT8_3_LEADINGBITS 0xe0 +#define GRUB_UINT8_4_LEADINGBITS 0xf0 +#define GRUB_UINT8_5_LEADINGBITS 0xf8 +#define GRUB_UINT8_6_LEADINGBITS 0xfc +#define GRUB_UINT8_7_LEADINGBITS 0xfe + +#define GRUB_UINT8_1_TRAILINGBIT 0x01 +#define GRUB_UINT8_2_TRAILINGBITS 0x03 +#define GRUB_UINT8_3_TRAILINGBITS 0x07 +#define GRUB_UINT8_4_TRAILINGBITS 0x0f +#define GRUB_UINT8_5_TRAILINGBITS 0x1f +#define GRUB_UINT8_6_TRAILINGBITS 0x3f + +#define GRUB_UCS2_LIMIT 0x10000 +#define GRUB_UTF16_UPPER_SURROGATE(code) \ + (0xD800 + ((((code) - GRUB_UCS2_LIMIT) >> 12) & 0xfff)) +#define GRUB_UTF16_LOWER_SURROGATE(code) \ + (0xDC00 + (((code) - GRUB_UCS2_LIMIT) & 0xfff)) + +grub_ssize_t +grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize, + const grub_uint8_t *src, grub_size_t srcsize, + const grub_uint8_t **srcend); + +/* Convert UTF-16 to UTF-8. */ +static inline grub_uint8_t * +grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src, + grub_size_t size) +{ + grub_uint32_t code_high = 0; + + while (size--) + { + grub_uint32_t code = *src++; + + if (code_high) + { + if (code >= 0xDC00 && code <= 0xDFFF) + { + /* Surrogate pair. */ + code = ((code_high - 0xD800) << 12) + (code - 0xDC00) + 0x10000; + + *dest++ = (code >> 18) | 0xF0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + else + { + /* Error... */ + *dest++ = '?'; + } + + code_high = 0; + } + else + { + if (code <= 0x007F) + *dest++ = code; + else if (code <= 0x07FF) + { + *dest++ = (code >> 6) | 0xC0; + *dest++ = (code & 0x3F) | 0x80; + } + else if (code >= 0xD800 && code <= 0xDBFF) + { + code_high = code; + continue; + } + else if (code >= 0xDC00 && code <= 0xDFFF) + { + /* Error... */ + *dest++ = '?'; + } + else + { + *dest++ = (code >> 12) | 0xE0; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + } + } + + return dest; +} + +#endif diff --git a/include/grub/i386/xnu.h b/include/grub/i386/xnu.h index 57ba0f0b6..a05d67fc3 100644 --- a/include/grub/i386/xnu.h +++ b/include/grub/i386/xnu.h @@ -20,6 +20,7 @@ #define GRUB_CPU_XNU_H 1 #include +#include #define GRUB_XNU_PAGESIZE 4096 typedef grub_uint32_t grub_xnu_ptr_t; @@ -67,13 +68,52 @@ struct grub_xnu_boot_params #define GRUB_XNU_BOOTARGS_VERMINOR 5 #define GRUB_XNU_BOOTARGS_VERMAJOR 1 +struct grub_xnu_devprop_header +{ + grub_uint32_t length; + /* Always set to 1. Version? */ + grub_uint32_t alwaysone; + grub_uint32_t num_devices; +}; + +struct grub_xnu_devprop_device_header +{ + grub_uint32_t length; + grub_uint32_t num_values; +}; + +void grub_cpu_xnu_unload (void); + +struct grub_xnu_devprop_device_descriptor; + +struct grub_xnu_devprop_device_descriptor * +grub_xnu_devprop_add_device (struct grub_efi_device_path *path, int length); +grub_err_t +grub_xnu_devprop_remove_device (struct grub_xnu_devprop_device_descriptor *dev); +grub_err_t +grub_xnu_devprop_remove_property (struct grub_xnu_devprop_device_descriptor *dev, + char *name); +grub_err_t +grub_xnu_devprop_add_property_utf8 (struct grub_xnu_devprop_device_descriptor *dev, + char *name, void *data, int datalen); +grub_err_t +grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor *dev, + grub_uint16_t *name, int namelen, + void *data, int datalen); +grub_err_t +grub_xnu_devprop_remove_property_utf8 (struct grub_xnu_devprop_device_descriptor *dev, + char *name); +void grub_cpu_xnu_init (void); +void grub_cpu_xnu_fini (void); + extern grub_uint32_t grub_xnu_entry_point; extern grub_uint32_t grub_xnu_stack; extern grub_uint32_t grub_xnu_arg1; extern char grub_xnu_cmdline[1024]; grub_err_t grub_xnu_boot (void); -grub_err_t grub_cpu_xnu_fill_devicetree (void); grub_err_t grub_xnu_set_video (struct grub_xnu_boot_params *bootparams_relloc); +grub_err_t +grub_cpu_xnu_fill_devicetree (void); extern grub_uint32_t grub_xnu_heap_will_be_at; extern grub_uint8_t grub_xnu_launcher_start[]; extern grub_uint8_t grub_xnu_launcher_end[]; diff --git a/include/grub/misc.h b/include/grub/misc.h index faa2d5c42..1939becbd 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -180,9 +180,6 @@ int EXPORT_FUNC(grub_sprintf) (char *str, const char *fmt, ...) __attribute__ (( int EXPORT_FUNC(grub_vsprintf) (char *str, const char *fmt, va_list args); void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn)); void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn)); -grub_uint8_t *EXPORT_FUNC(grub_utf16_to_utf8) (grub_uint8_t *dest, - grub_uint16_t *src, - grub_size_t size); grub_ssize_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest, grub_size_t destsize, const grub_uint8_t *src, diff --git a/include/grub/usb.h b/include/grub/usb.h index 8dd3b6e2e..dc90e7879 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -64,9 +64,6 @@ grub_usb_err_t grub_usb_clear_halt (grub_usb_device_t dev, int endpoint); grub_usb_err_t grub_usb_set_configuration (grub_usb_device_t dev, int configuration); -grub_usb_err_t grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, - int langid, char **string); - void grub_usb_controller_dev_register (grub_usb_controller_dev_t usb); void grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb); diff --git a/include/grub/xnu.h b/include/grub/xnu.h index 29689479b..b0146728c 100644 --- a/include/grub/xnu.h +++ b/include/grub/xnu.h @@ -102,6 +102,7 @@ grub_err_t grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired, grub_err_t grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired, int maxrecursion); void *grub_xnu_heap_malloc (int size); +grub_err_t grub_xnu_fill_devicetree (void); extern grub_uint32_t grub_xnu_heap_real_start; extern grub_size_t grub_xnu_heap_size; extern char *grub_xnu_heap_start; diff --git a/kern/efi/efi.c b/kern/efi/efi.c index 279d1d61b..501ab4578 100644 --- a/kern/efi/efi.c +++ b/kern/efi/efi.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include diff --git a/kern/misc.c b/kern/misc.c index cacfbc753..a1a998eeb 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -837,68 +837,6 @@ grub_sprintf (char *str, const char *fmt, ...) return ret; } -/* Convert UTF-16 to UTF-8. */ -grub_uint8_t * -grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src, - grub_size_t size) -{ - grub_uint32_t code_high = 0; - - while (size--) - { - grub_uint32_t code = *src++; - - if (code_high) - { - if (code >= 0xDC00 && code <= 0xDFFF) - { - /* Surrogate pair. */ - code = ((code_high - 0xD800) << 12) + (code - 0xDC00) + 0x10000; - - *dest++ = (code >> 18) | 0xF0; - *dest++ = ((code >> 12) & 0x3F) | 0x80; - *dest++ = ((code >> 6) & 0x3F) | 0x80; - *dest++ = (code & 0x3F) | 0x80; - } - else - { - /* Error... */ - *dest++ = '?'; - } - - code_high = 0; - } - else - { - if (code <= 0x007F) - *dest++ = code; - else if (code <= 0x07FF) - { - *dest++ = (code >> 6) | 0xC0; - *dest++ = (code & 0x3F) | 0x80; - } - else if (code >= 0xD800 && code <= 0xDBFF) - { - code_high = code; - continue; - } - else if (code >= 0xDC00 && code <= 0xDFFF) - { - /* Error... */ - *dest++ = '?'; - } - else - { - *dest++ = (code >> 12) | 0xE0; - *dest++ = ((code >> 6) & 0x3F) | 0x80; - *dest++ = (code & 0x3F) | 0x80; - } - } - } - - return dest; -} - /* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string. Return the number of characters converted. DEST must be able to hold diff --git a/lib/charset.c b/lib/charset.c new file mode 100644 index 000000000..8bc5b9149 --- /dev/null +++ b/lib/charset.c @@ -0,0 +1,116 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 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 . + */ + +/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE + bytes (if SRCSIZE is -1, it is ignored) in length to a UTF-16 string. + Return the number of characters converted. DEST must be able to hold + at least DESTSIZE characters. If an invalid sequence is found, return -1. + If SRCEND is not NULL, then *SRCEND is set to the next byte after the + last byte used in SRC. */ + +#include + +grub_ssize_t +grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize, + const grub_uint8_t *src, grub_size_t srcsize, + const grub_uint8_t **srcend) +{ + grub_uint16_t *p = dest; + int count = 0; + grub_uint32_t code = 0; + + if (srcend) + *srcend = src; + + while (srcsize && destsize) + { + grub_uint32_t c = *src++; + if (srcsize != (grub_size_t)-1) + srcsize--; + if (count) + { + if ((c & GRUB_UINT8_2_LEADINGBITS) != GRUB_UINT8_1_LEADINGBIT) + { + /* invalid */ + return -1; + } + else + { + code <<= 6; + code |= (c & GRUB_UINT8_6_TRAILINGBITS); + count--; + } + } + else + { + if (c == 0) + break; + + if ((c & GRUB_UINT8_1_LEADINGBIT) == 0) + code = c; + else if ((c & GRUB_UINT8_3_LEADINGBITS) == GRUB_UINT8_2_LEADINGBITS) + { + count = 1; + code = c & GRUB_UINT8_5_TRAILINGBITS; + } + else if ((c & GRUB_UINT8_4_LEADINGBITS) == GRUB_UINT8_3_LEADINGBITS) + { + count = 2; + code = c & GRUB_UINT8_4_TRAILINGBITS; + } + else if ((c & GRUB_UINT8_5_LEADINGBITS) == GRUB_UINT8_4_LEADINGBITS) + { + count = 3; + code = c & GRUB_UINT8_3_TRAILINGBITS; + } + else if ((c & GRUB_UINT8_6_LEADINGBITS) == GRUB_UINT8_5_LEADINGBITS) + { + count = 4; + code = c & GRUB_UINT8_2_TRAILINGBITS; + } + else if ((c & GRUB_UINT8_7_LEADINGBITS) == GRUB_UINT8_6_LEADINGBITS) + { + count = 5; + code = c & GRUB_UINT8_1_TRAILINGBIT; + } + else + return -1; + } + + if (count == 0) + { + if (destsize < 2 && code >= GRUB_UCS2_LIMIT) + break; + if (code >= GRUB_UCS2_LIMIT) + { + *p++ = GRUB_UTF16_UPPER_SURROGATE (code); + *p++ = GRUB_UTF16_LOWER_SURROGATE (code); + destsize -= 2; + } + else + { + *p++ = code; + destsize--; + } + } + } + + if (srcend) + *srcend = src; + return p - dest; +} diff --git a/loader/efi/chainloader.c b/loader/efi/chainloader.c index 01acc4135..9c833e9b9 100644 --- a/loader/efi/chainloader.c +++ b/loader/efi/chainloader.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/loader/i386/xnu.c b/loader/i386/xnu.c index 35f2beb23..857d6b63c 100644 --- a/loader/i386/xnu.c +++ b/loader/i386/xnu.c @@ -25,9 +25,13 @@ #include #include #include +#include #include #include +#include #include +#include +#include char grub_xnu_cmdline[1024]; @@ -44,6 +48,14 @@ struct tbl_alias table_aliases[] = {GRUB_EFI_ACPI_TABLE_GUID, "ACPI"}, }; +struct grub_xnu_devprop_device_descriptor +{ + struct grub_xnu_devprop_device_descriptor *next; + struct property_descriptor *properties; + struct grub_efi_device_path *path; + int pathlen; +}; + /* The following function is used to be able to debug xnu loader with grub-emu. */ #ifdef GRUB_UTIL @@ -205,6 +217,417 @@ guessfsb (void) ((msrlow >> 7) & 0x3e) + ((msrlow >> 14) & 1), 0); } +struct property_descriptor +{ + struct property_descriptor *next; + grub_uint8_t *name; + grub_uint16_t *name16; + int name16len; + int length; + void *data; +}; + +struct grub_xnu_devprop_device_descriptor *devices = 0; + +grub_err_t +grub_xnu_devprop_remove_property (struct grub_xnu_devprop_device_descriptor *dev, + char *name) +{ + struct property_descriptor *prop; + prop = grub_named_list_find (GRUB_AS_NAMED_LIST_P (&dev->properties), name); + if (!prop) + return GRUB_ERR_NONE; + + grub_free (prop->name); + grub_free (prop->name16); + grub_free (prop->data); + + grub_list_remove (GRUB_AS_LIST_P (&dev->properties), GRUB_AS_LIST (prop)); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_xnu_devprop_remove_device (struct grub_xnu_devprop_device_descriptor *dev) +{ + void *t; + struct property_descriptor *prop; + + grub_list_remove (GRUB_AS_LIST_P (&devices), GRUB_AS_LIST (dev)); + + for (prop = dev->properties; prop; ) + { + grub_free (prop->name); + grub_free (prop->name16); + grub_free (prop->data); + t = prop; + prop = prop->next; + grub_free (t); + } + + grub_free (dev->path); + grub_free (dev); + + return GRUB_ERR_NONE; +} + +struct grub_xnu_devprop_device_descriptor * +grub_xnu_devprop_add_device (struct grub_efi_device_path *path, int length) +{ + struct grub_xnu_devprop_device_descriptor *ret; + + ret = grub_zalloc (sizeof (*ret)); + if (!ret) + return 0; + + ret->path = grub_malloc (length); + if (!ret->path) + { + grub_free (ret); + return 0; + } + ret->pathlen = length; + grub_memcpy (ret->path, path, length); + + grub_list_push (GRUB_AS_LIST_P (&devices), GRUB_AS_LIST (ret)); + + return ret; +} + +static grub_err_t +grub_xnu_devprop_add_property (struct grub_xnu_devprop_device_descriptor *dev, + grub_uint8_t *utf8, grub_uint16_t *utf16, + int utf16len, void *data, int datalen) +{ + struct property_descriptor *prop; + + prop = grub_malloc (sizeof (*prop)); + if (!prop) + return grub_errno; + + prop->name = utf8; + prop->name16 = utf16; + prop->name16len = utf16len; + + prop->length = datalen; + prop->data = grub_malloc (prop->length); + if (!prop->data) + { + grub_free (prop); + grub_free (prop->name); + grub_free (prop->name16); + return grub_errno; + } + grub_memcpy (prop->data, data, prop->length); + grub_list_push (GRUB_AS_LIST_P (&dev->properties), + GRUB_AS_LIST (prop)); + return GRUB_ERR_NONE; +} + +grub_err_t +grub_xnu_devprop_add_property_utf8 (struct grub_xnu_devprop_device_descriptor *dev, + char *name, void *data, int datalen) +{ + grub_uint8_t *utf8; + grub_uint16_t *utf16; + int len, utf16len; + grub_err_t err; + + utf8 = (grub_uint8_t *) grub_strdup (name); + if (!utf8) + return grub_errno; + + len = grub_strlen (name); + utf16 = grub_malloc (sizeof (grub_uint16_t) * len); + if (!utf16) + { + grub_free (utf8); + return grub_errno; + } + + utf16len = grub_utf8_to_utf16 (utf16, len, utf8, len, NULL); + if (utf16len < 0) + { + grub_free (utf8); + grub_free (utf16); + return grub_errno; + } + + err = grub_xnu_devprop_add_property (dev, utf8, utf16, + utf16len, data, datalen); + if (err) + { + grub_free (utf8); + grub_free (utf16); + return err; + } + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor *dev, + grub_uint16_t *name, int namelen, + void *data, int datalen) +{ + grub_uint8_t *utf8; + grub_uint16_t *utf16; + grub_err_t err; + + utf16 = grub_malloc (sizeof (grub_uint16_t) * namelen); + if (!utf16) + return grub_errno; + grub_memcpy (utf16, name, sizeof (grub_uint16_t) * namelen); + + utf8 = grub_malloc (namelen * 4 + 1); + if (!utf8) + { + grub_free (utf8); + return grub_errno; + } + + *grub_utf16_to_utf8 ((grub_uint8_t *) utf8, name, namelen) = '\0'; + + err = grub_xnu_devprop_add_property (dev, utf8, utf16, + namelen, data, datalen); + if (err) + { + grub_free (utf8); + grub_free (utf16); + return err; + } + + return GRUB_ERR_NONE; +} + +static inline int +hextoval (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'z') + return c - 'a' + 10; + if (c >= 'A' && c <= 'Z') + return c - 'A' + 10; + return 0; +} + +void +grub_cpu_xnu_unload (void) +{ + struct grub_xnu_devprop_device_descriptor *dev1, *dev2; + + for (dev1 = devices; dev1; ) + { + dev2 = dev1->next; + grub_xnu_devprop_remove_device (dev1); + dev1 = dev2; + } +} + +static grub_err_t +grub_cpu_xnu_fill_devprop (void) +{ + struct grub_xnu_devtree_key *efikey; + int total_length = sizeof (struct grub_xnu_devprop_header); + struct grub_xnu_devtree_key *devprop; + struct grub_xnu_devprop_device_descriptor *device; + void *ptr; + struct grub_xnu_devprop_header *head; + void *t; + int numdevs = 0; + + /* The key "efi". */ + efikey = grub_xnu_create_key (&grub_xnu_devtree_root, "efi"); + if (! efikey) + return grub_errno; + + for (device = devices; device; device = device->next) + { + struct property_descriptor *propdesc; + total_length += sizeof (struct grub_xnu_devprop_device_header); + total_length += device->pathlen; + + for (propdesc = device->properties; propdesc; propdesc = propdesc->next) + { + total_length += sizeof (grub_uint32_t); + total_length += sizeof (grub_uint16_t) + * (propdesc->name16len + 1); + total_length += sizeof (grub_uint32_t); + total_length += propdesc->length; + } + numdevs++; + } + + devprop = grub_xnu_create_value (&(efikey->first_child), "device-properties"); + if (devprop) + { + devprop->data = grub_malloc (total_length); + devprop->datasize = total_length; + } + + ptr = devprop->data; + head = ptr; + ptr = head + 1; + head->length = total_length; + head->alwaysone = 1; + head->num_devices = numdevs; + for (device = devices; device; ) + { + struct grub_xnu_devprop_device_header *devhead; + struct property_descriptor *propdesc; + devhead = ptr; + devhead->num_values = 0; + ptr = devhead + 1; + + grub_memcpy (ptr, device->path, device->pathlen); + ptr = (char *) ptr + device->pathlen; + + for (propdesc = device->properties; propdesc; ) + { + grub_uint32_t *len; + grub_uint16_t *name; + void *data; + + len = ptr; + *len = 2 * propdesc->name16len + sizeof (grub_uint16_t) + + sizeof (grub_uint32_t); + ptr = len + 1; + + name = ptr; + grub_memcpy (name, propdesc->name16, 2 * propdesc->name16len); + name += propdesc->name16len; + + /* NUL terminator. */ + *name = 0; + ptr = name + 1; + + len = ptr; + *len = propdesc->length + sizeof (grub_uint32_t); + data = len + 1; + ptr = data; + grub_memcpy (ptr, propdesc->data, propdesc->length); + ptr = (char *) ptr + propdesc->length; + + grub_free (propdesc->name); + grub_free (propdesc->name16); + grub_free (propdesc->data); + t = propdesc; + propdesc = propdesc->next; + grub_free (t); + devhead->num_values++; + } + + devhead->length = (char *) ptr - (char *) devhead; + t = device; + device = device->next; + grub_free (t); + } + + devices = 0; + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_devprop_load (grub_command_t cmd __attribute__ ((unused)), + int argc, char *args[]) +{ + grub_file_t file; + void *buf, *bufstart, *bufend; + struct grub_xnu_devprop_header *head; + grub_size_t size; + unsigned i, j; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "File name required. "); + + file = grub_gzfile_open (args[0], 1); + if (! file) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, + "Couldn't load device-propertie dump. "); + size = grub_file_size (file); + buf = grub_malloc (size); + if (!buf) + { + grub_file_close (file); + return grub_errno; + } + if (grub_file_read (file, buf, size) != (grub_ssize_t) size) + { + grub_file_close (file); + return grub_errno; + } + grub_file_close (file); + + bufstart = buf; + bufend = (char *) buf + size; + head = buf; + buf = head + 1; + for (i = 0; i < grub_le_to_cpu32 (head->num_devices) && buf < bufend; i++) + { + struct grub_efi_device_path *dp, *dpstart; + struct grub_xnu_devprop_device_descriptor *dev; + struct grub_xnu_devprop_device_header *devhead; + + devhead = buf; + buf = devhead + 1; + dpstart = buf; + + do + { + dp = buf; + buf = (char *) buf + GRUB_EFI_DEVICE_PATH_LENGTH (dp); + } + while (!GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp) && buf < bufend); + + dev = grub_xnu_devprop_add_device (dpstart, (char *) buf + - (char *) dpstart); + + for (j = 0; j < grub_le_to_cpu32 (devhead->num_values) && buf < bufend; + j++) + { + grub_uint32_t *namelen; + grub_uint32_t *datalen; + grub_uint16_t *utf16; + void *data; + grub_err_t err; + + namelen = buf; + buf = namelen + 1; + if (buf >= bufend) + break; + + utf16 = buf; + buf = (char *) buf + *namelen - sizeof (grub_uint32_t); + if (buf >= bufend) + break; + + datalen = buf; + buf = datalen + 1; + if (buf >= bufend) + break; + + data = buf; + buf = (char *) buf + *datalen - sizeof (grub_uint32_t); + if (buf >= bufend) + break; + err = grub_xnu_devprop_add_property_utf16 + (dev, utf16, (*namelen - sizeof (grub_uint32_t) + - sizeof (grub_uint16_t)) / sizeof (grub_uint16_t), + data, *datalen - sizeof (grub_uint32_t)); + if (err) + { + grub_free (bufstart); + return err; + } + } + } + + grub_free (bufstart); + return GRUB_ERR_NONE; +} + /* Fill device tree. */ /* FIXME: some entries may be platform-agnostic. Move them to loader/xnu.c. */ grub_err_t @@ -216,11 +639,6 @@ grub_cpu_xnu_fill_devicetree (void) struct grub_xnu_devtree_key *runtimesrvkey; struct grub_xnu_devtree_key *platformkey; unsigned i, j; - grub_err_t err; - - err = grub_autoefi_prepare (); - if (err) - return err; /* The value "model". */ /* FIXME: may this value be sometimes different? */ @@ -436,6 +854,22 @@ grub_xnu_boot (void) grub_size_t devtreelen; int i; + err = grub_autoefi_prepare (); + if (err) + return err; + + err = grub_cpu_xnu_fill_devprop (); + if (err) + return err; + + err = grub_cpu_xnu_fill_devicetree (); + if (err) + return err; + + err = grub_xnu_fill_devicetree (); + if (err) + return err; + /* Page-align to avoid following parts to be inadvertently freed. */ err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE); if (err) @@ -590,3 +1024,19 @@ grub_xnu_boot (void) /* Never reaches here. */ return 0; } + +static grub_command_t cmd_devprop_load; + +void +grub_cpu_xnu_init (void) +{ + cmd_devprop_load = grub_register_command ("xnu_devprop_load", + grub_cmd_devprop_load, + 0, "Load device-properties dump."); +} + +void +grub_cpu_xnu_fini (void) +{ + grub_unregister_command (cmd_devprop_load); +} diff --git a/loader/machoXX.c b/loader/machoXX.c index d42dd8b55..01e6879ea 100644 --- a/loader/machoXX.c +++ b/loader/machoXX.c @@ -31,7 +31,7 @@ SUFFIX (grub_macho_parse) (grub_macho_t macho) } if (head.magic != GRUB_MACHO_MAGIC) { - grub_error (GRUB_ERR_BAD_OS, "Invalid Mach-O " XX "-bit header."); + grub_error (GRUB_ERR_BAD_OS, "Invalid Mach-O 32-bit header."); macho->offsetXX = -1; return; } @@ -94,7 +94,7 @@ SUFFIX (grub_macho_readfile) (grub_macho_t macho, void *dest) return grub_error (GRUB_ERR_BAD_OS, "Couldn't read architecture-specific part"); - if (grub_file_seek (macho->file, macho->offsetXX) == (grub_off_t) -1) + if (grub_file_seek (macho->file, macho->offset32) == (grub_off_t) -1) { grub_error_push (); return grub_error (GRUB_ERR_BAD_OS, @@ -102,8 +102,8 @@ SUFFIX (grub_macho_readfile) (grub_macho_t macho, void *dest) } read = grub_file_read (macho->file, dest, - macho->endXX - macho->offsetXX); - if (read != (grub_ssize_t) (macho->endXX - macho->offsetXX)) + macho->end32 - macho->offset32); + if (read != (grub_ssize_t) (macho->end32 - macho->offset32)) { grub_error_push (); return grub_error (GRUB_ERR_BAD_OS, diff --git a/loader/xnu.c b/loader/xnu.c index 2ebca3218..523443a1c 100644 --- a/loader/xnu.c +++ b/loader/xnu.c @@ -31,6 +31,7 @@ #include #include #include +#include struct grub_xnu_devtree_key *grub_xnu_devtree_root = 0; static int driverspackagenum = 0; @@ -334,6 +335,8 @@ grub_xnu_create_value (struct grub_xnu_devtree_key **parent, char *name) static grub_err_t grub_xnu_unload (void) { + grub_cpu_xnu_unload (); + grub_xnu_free_devtree (grub_xnu_devtree_root); grub_xnu_devtree_root = 0; @@ -437,10 +440,6 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), if (ptr != grub_xnu_cmdline) *(ptr - 1) = 0; - err = grub_cpu_xnu_fill_devicetree (); - if (err) - return err; - grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0); grub_xnu_lock (); @@ -542,10 +541,6 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)), if (ptr != grub_xnu_cmdline) *(ptr - 1) = 0; - err = grub_cpu_xnu_fill_devicetree (); - if (err) - return err; - grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0); grub_xnu_lock (); @@ -907,135 +902,6 @@ grub_cmd_xnu_ramdisk (grub_command_t cmd __attribute__ ((unused)), return grub_xnu_register_memory ("RAMDisk", 0, loadto, size); } -/* Parse a devtree file. It uses the following format: - valuename:valuedata; - keyname{ - contents - } - keyname, valuename and valuedata are in hex. - */ -static char * -grub_xnu_parse_devtree (struct grub_xnu_devtree_key **parent, - char *start, char *end) -{ - char *ptr, *ptr2; - char *name, *data; - int namelen, datalen, i; - for (ptr = start; ptr && ptr < end; ) - { - if (grub_isspace (*ptr)) - { - ptr++; - continue; - } - if (*ptr == '}') - return ptr + 1; - namelen = 0; - - /* Parse the name. */ - for (ptr2 = ptr; ptr2 < end && (grub_isspace (*ptr2) - || (*ptr2 >= '0' && *ptr2 <= '9') - || (*ptr2 >= 'a' && *ptr2 <= 'f') - || (*ptr2 >= 'A' && *ptr2 <= 'F')); - ptr2++) - if (! grub_isspace (*ptr2)) - namelen++; - if (ptr2 == end) - return 0; - namelen /= 2; - name = grub_malloc (namelen + 1); - if (!name) - return 0; - for (i = 0; i < 2 * namelen; i++) - { - int hex = 0; - while (grub_isspace (*ptr)) - ptr++; - if (*ptr >= '0' && *ptr <= '9') - hex = *ptr - '0'; - if (*ptr >= 'a' && *ptr <= 'f') - hex = *ptr - 'a' + 10; - if (*ptr >= 'A' && *ptr <= 'F') - hex = *ptr - 'A' + 10; - - if (i % 2 == 0) - name[i / 2] = hex << 4; - else - name[i / 2] |= hex; - ptr++; - } - name [namelen] = 0; - while (grub_isspace (*ptr)) - ptr++; - - /* If it describes a key recursively invoke the function. */ - if (*ptr == '{') - { - struct grub_xnu_devtree_key *newkey - = grub_xnu_create_key (parent, name); - grub_free (name); - if (! newkey) - return 0; - ptr = grub_xnu_parse_devtree (&(newkey->first_child), ptr + 1, end); - continue; - } - - /* Parse the data. */ - if (*ptr != ':') - return 0; - ptr++; - datalen = 0; - for (ptr2 = ptr; ptr2 < end && (grub_isspace (*ptr2) - || (*ptr2 >= '0' && *ptr2 <= '9') - || (*ptr2 >= 'a' && *ptr2 <= 'f') - || (*ptr2 >= 'A' && *ptr2 <= 'F')); - ptr2++) - if (! grub_isspace (*ptr2)) - datalen++; - if (ptr2 == end) - return 0; - datalen /= 2; - data = grub_malloc (datalen); - if (! data) - return 0; - for (i = 0; i < 2 * datalen; i++) - { - int hex = 0; - while (grub_isspace (*ptr)) - ptr++; - if (*ptr >= '0' && *ptr <= '9') - hex = *ptr - '0'; - if (*ptr >= 'a' && *ptr <= 'f') - hex = *ptr - 'a' + 10; - if (*ptr >= 'A' && *ptr <= 'F') - hex = *ptr - 'A' + 10; - - if (i % 2 == 0) - data[i / 2] = hex << 4; - else - data[i / 2] |= hex; - ptr++; - } - while (ptr < end && grub_isspace (*ptr)) - ptr++; - { - struct grub_xnu_devtree_key *newkey - = grub_xnu_create_value (parent, name); - grub_free (name); - if (! newkey) - return 0; - newkey->datasize = datalen; - newkey->data = data; - } - if (*ptr != ';') - return 0; - ptr++; - } - if (ptr >= end && *parent != grub_xnu_devtree_root) - return 0; - return ptr; -} - /* Returns true if the kext should be loaded according to plist and osbundlereq. Also fill BINNAME. */ static int @@ -1332,53 +1198,6 @@ grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired, return GRUB_ERR_NONE; } -/* Load devtree file. */ -static grub_err_t -grub_cmd_xnu_devtree (grub_command_t cmd __attribute__ ((unused)), - int argc, char *args[]) -{ - grub_file_t file; - char *data, *endret; - grub_size_t datalen; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Filename required"); - - if (! grub_xnu_heap_size) - return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded"); - - /* Load the file. */ - file = grub_gzfile_open (args[0], 1); - if (! file) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load device tree"); - datalen = grub_file_size (file); - data = grub_malloc (datalen + 1); - if (! data) - { - grub_file_close (file); - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Could load device tree into memory"); - } - if (grub_file_read (file, data, datalen) != (grub_ssize_t) datalen) - { - grub_file_close (file); - grub_free (data); - grub_error_push (); - return grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", args[0]); - } - grub_file_close (file); - data[datalen] = 0; - - /* Parse the file. */ - endret = grub_xnu_parse_devtree (&grub_xnu_devtree_root, - data, data + datalen); - grub_free (data); - - if (! endret) - return grub_error (GRUB_ERR_BAD_OS, "Couldn't parse devtree"); - - return GRUB_ERR_NONE; -} static int locked=0; static grub_dl_t my_mod; @@ -1439,6 +1258,107 @@ grub_cmd_xnu_kextdir (grub_command_t cmd __attribute__ ((unused)), } } +static inline int +hextoval (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'z') + return c - 'a' + 10; + if (c >= 'A' && c <= 'Z') + return c - 'A' + 10; + return 0; +} + +static inline void +unescape (char *name, char *curdot, char *nextdot, int *len) +{ + char *ptr, *dptr; + dptr = name; + for (ptr = curdot; ptr < nextdot;) + if (ptr + 2 < nextdot && *ptr == '%') + { + *dptr = (hextoval (ptr[1]) << 4) | (hextoval (ptr[2])); + ptr += 3; + dptr++; + } + else + { + *dptr = *ptr; + ptr++; + dptr++; + } + *len = dptr - name; +} + +grub_err_t +grub_xnu_fill_devicetree (void) +{ + auto int iterate_env (struct grub_env_var *var); + int iterate_env (struct grub_env_var *var) + { + char *nextdot = 0, *curdot; + struct grub_xnu_devtree_key **curkey = &grub_xnu_devtree_root; + struct grub_xnu_devtree_key *curvalue; + char *name = 0, *data; + int len; + + if (grub_memcmp (var->name, "XNU.DeviceTree.", + sizeof ("XNU.DeviceTree.") - 1) != 0) + return 0; + + curdot = var->name + sizeof ("XNU.DeviceTree.") - 1; + nextdot = grub_strchr (curdot, '.'); + if (nextdot) + nextdot++; + while (nextdot) + { + name = grub_realloc (name, nextdot - curdot + 1); + + if (!name) + return 1; + + unescape (name, curdot, nextdot, &len); + name[len - 1] = 0; + + curkey = &(grub_xnu_create_key (curkey, name)->first_child); + + curdot = nextdot; + nextdot = grub_strchr (nextdot, '.'); + if (nextdot) + nextdot++; + } + + nextdot = curdot + grub_strlen (curdot) + 1; + + name = grub_realloc (name, nextdot - curdot + 1); + + if (!name) + return 1; + + unescape (name, curdot, nextdot, &len); + name[len] = 0; + + curvalue = grub_xnu_create_value (curkey, name); + grub_free (name); + + data = grub_malloc (grub_strlen (var->value) + 1); + if (!data) + return 1; + + unescape (data, var->value, var->value + grub_strlen (var->value), + &len); + curvalue->datasize = len; + curvalue->data = data; + + return 0; + } + + grub_env_iterate (iterate_env); + + return grub_errno; +} + struct grub_video_bitmap *grub_xnu_bitmap = 0; static grub_err_t @@ -1485,8 +1405,7 @@ grub_xnu_unlock () } static grub_command_t cmd_kernel64, cmd_kernel, cmd_mkext, cmd_kext; -static grub_command_t cmd_kextdir, cmd_ramdisk, cmd_devtree, cmd_resume; -static grub_command_t cmd_splash; +static grub_command_t cmd_kextdir, cmd_ramdisk, cmd_resume, cmd_splash; GRUB_MOD_INIT(xnu) { @@ -1504,8 +1423,6 @@ GRUB_MOD_INIT(xnu) cmd_ramdisk = grub_register_command ("xnu_ramdisk", grub_cmd_xnu_ramdisk, 0, "Load XNU ramdisk. " "It will be seen as md0"); - cmd_devtree = grub_register_command ("xnu_devtree", grub_cmd_xnu_devtree, 0, - "Load XNU devtree"); cmd_splash = grub_register_command ("xnu_splash", grub_cmd_xnu_splash, 0, "Load a splash image for XNU"); @@ -1513,7 +1430,10 @@ GRUB_MOD_INIT(xnu) cmd_resume = grub_register_command ("xnu_resume", grub_cmd_xnu_resume, 0, "Load XNU hibernate image."); #endif - my_mod=mod; + + grub_cpu_xnu_init (); + + my_mod = mod; } GRUB_MOD_FINI(xnu) @@ -1524,9 +1444,10 @@ GRUB_MOD_FINI(xnu) grub_unregister_command (cmd_mkext); grub_unregister_command (cmd_kext); grub_unregister_command (cmd_kextdir); - grub_unregister_command (cmd_devtree); grub_unregister_command (cmd_ramdisk); grub_unregister_command (cmd_kernel); grub_unregister_command (cmd_kernel64); grub_unregister_command (cmd_splash); + + grub_cpu_xnu_fini (); } diff --git a/normal/completion.c b/normal/completion.c index 4b38e334d..7b3de449c 100644 --- a/normal/completion.c +++ b/normal/completion.c @@ -161,14 +161,23 @@ iterate_dev (const char *devname) if (dev) { - if (dev->disk && dev->disk->has_partitions) + char tmp[grub_strlen (devname) + sizeof (",")]; + + grub_memcpy (tmp, devname, grub_strlen (devname)); + + if (grub_strcmp (devname, current_word) == 0) { - if (add_completion (devname, ",", GRUB_COMPLETION_TYPE_DEVICE)) + if (add_completion (devname, ")", GRUB_COMPLETION_TYPE_PARTITION)) return 1; + + if (dev->disk) + if (grub_partition_iterate (dev->disk, iterate_partition)) + return 1; } else { - if (add_completion (devname, ")", GRUB_COMPLETION_TYPE_DEVICE)) + grub_memcpy (tmp + grub_strlen (devname), "", sizeof ("")); + if (add_completion (tmp, "", GRUB_COMPLETION_TYPE_DEVICE)) return 1; } } @@ -216,7 +225,7 @@ complete_device (void) if (dev) { - if (dev->disk && dev->disk->has_partitions) + if (dev->disk) { if (grub_partition_iterate (dev->disk, iterate_partition)) { diff --git a/normal/misc.c b/normal/misc.c index 0a1a2f052..cddd1d3d3 100644 --- a/normal/misc.c +++ b/normal/misc.c @@ -94,10 +94,8 @@ grub_normal_print_device_info (const char *name) grub_errno = GRUB_ERR_NONE; } } - else if (! dev->disk->has_partitions || dev->disk->partition) - grub_printf ("Unknown filesystem"); else - grub_printf ("Partition table"); + grub_printf ("Unknown filesystem"); grub_device_close (dev); } diff --git a/util/i386/efi/grub-dumpdevtree b/util/i386/efi/grub-dumpdevtree deleted file mode 100644 index bc13e3c35..000000000 --- a/util/i386/efi/grub-dumpdevtree +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2009 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 . - -hexify() -{ - echo -n "$@" | od -A n -t x1 - | sed -e 's/ //g' | tr '\n' '\0' -} - -echo "`hexify efi`{ `hexify device-properties`:" -ioreg -lw0 -p IODeviceTree -n efi -r -x |grep device-properties | sed 's/.*.*//;' -echo ";}" From d89a9b58cd39181547b54da39396814954d86ee0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 9 Nov 2009 21:36:17 +0100 Subject: [PATCH 18/52] Fixed antialiasing warning --- efiemu/pnvram.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/efiemu/pnvram.c b/efiemu/pnvram.c index ede59ede1..7af01c055 100644 --- a/efiemu/pnvram.c +++ b/efiemu/pnvram.c @@ -109,6 +109,8 @@ nvram_set (void * data __attribute__ ((unused))) char *guid, *attr, *name, *varname; struct efi_variable *efivar; int len = 0; + int i; + grub_uint64_t guidcomp; if (grub_memcmp (var->name, "EfiEmu.pnvram.", sizeof ("EfiEmu.pnvram.") - 1) != 0) @@ -152,8 +154,9 @@ nvram_set (void * data __attribute__ ((unused))) return 0; guid++; - *(grub_uint64_t *) &(efivar->guid.data4) - = grub_cpu_to_be64 (grub_strtoull (guid, 0, 16)); + guidcomp = grub_strtoull (guid, 0, 16); + for (i = 0; i < 8; i++) + efivar->guid.data4[i] = (guidcomp >> (56 - 8 * i)) & 0xff; efivar->attributes = grub_strtoull (attr, 0, 16); From 3ecf8ade3cbc58f47967b1d5d9e38c353fc51cff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 9 Nov 2009 22:44:37 +0100 Subject: [PATCH 19/52] Put ChangeLog into right place --- ChangeLog | 43 ------------------------------------------- 1 file changed, 43 deletions(-) diff --git a/ChangeLog b/ChangeLog index d0b149f3a..fa0493190 100644 --- a/ChangeLog +++ b/ChangeLog @@ -913,20 +913,6 @@ 2009-08-29 Vladimir Serbinenko - * kern/misc.c (grub_utf16_to_utf8): Move from here ... - * include/grub/charset.h (grub_utf16_to_utf8): ... to here. Inlined. - All users updated. - * include/grub/misc.h (grub_utf16_to_utf8): Removed. - -2009-08-28 Vladimir Serbinenko - - * bus/usb/usb.c (grub_usb_get_string): Move from here ... - * commands/usbtest.c (grub_usb_get_string): ... move here. - (usb_print_str): Fix error handling. - * include/grub/usb.h (grub_usb_get_string): Remove. - -2009-08-28 Vladimir Serbinenko - * include/grub/i386/xnu.h: Add license header. include grub/err.h explicitly. @@ -1188,35 +1174,6 @@ * kern/misc.c (grub_tolower): Moved from here ... * include/grub/misc.h (grub_tolower): ... here. Inlined. -2009-08-24 Vladimir Serbinenko - - Eliminate ad-hoc tree format in XNU and EfiEmu. - - * efiemu/main.c (grub_efiemu_prepare): Update comment. - * efiemu/pnvram.c: Rewritten to use environment variables. - All users updated. - * include/grub/xnu.h (grub_xnu_fill_devicetree): New prototype. - * loader/i386/xnu.c (grub_xnu_boot): Call grub_cpu_xnu_fill_devicetree - and grub_xnu_fill_devicetree. - * loader/xnu.c (grub_cmd_xnu_kernel): Don't call - grub_cpu_xnu_fill_devicetree. - (grub_xnu_parse_devtree): Removed. - (grub_cmd_xnu_devtree): Likewise. - (hextoval): New function. - (unescape): Likewise. - (grub_xnu_fill_devicetree): Likewise. - -2009-08-24 Vladimir Serbinenko - - UTF-8 to UTF-16 transformation. - - * conf/common.rmk (pkglib_MODULES): Add utf.mod - (utf_mod_SOURCES): New variable. - (utf_mod_CFLAGS): Likewise. - (utf_mod_LDFLAGS): Likewise. - * include/grub/utf.h: New file. - * lib/utf.c: New file. (Based on grub_utf8_to_ucs4 from kern/misc.c) - 2009-08-24 Vladimir Serbinenko * script/sh/function.c (grub_script_function_find): Cut error message From c8f1864ba6c3141605bd605200ce59115409f450 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 9 Nov 2009 22:57:37 +0100 Subject: [PATCH 20/52] Add missing file --- ChangeLog.xnu | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 ChangeLog.xnu diff --git a/ChangeLog.xnu b/ChangeLog.xnu new file mode 100644 index 000000000..442e44c92 --- /dev/null +++ b/ChangeLog.xnu @@ -0,0 +1,43 @@ +2009-08-29 Vladimir Serbinenko + + * kern/misc.c (grub_utf16_to_utf8): Move from here ... + * include/grub/charset.h (grub_utf16_to_utf8): ... to here. Inlined. + All users updated. + * include/grub/misc.h (grub_utf16_to_utf8): Removed. + +2009-08-28 Vladimir Serbinenko + + * bus/usb/usb.c (grub_usb_get_string): Move from here ... + * commands/usbtest.c (grub_usb_get_string): ... move here. + (usb_print_str): Fix error handling. + * include/grub/usb.h (grub_usb_get_string): Remove. + +2009-08-24 Vladimir Serbinenko + + Eliminate ad-hoc tree format in XNU and EfiEmu. + + * efiemu/main.c (grub_efiemu_prepare): Update comment. + * efiemu/pnvram.c: Rewritten to use environment variables. + All users updated. + * include/grub/xnu.h (grub_xnu_fill_devicetree): New prototype. + * loader/i386/xnu.c (grub_xnu_boot): Call grub_cpu_xnu_fill_devicetree + and grub_xnu_fill_devicetree. + * loader/xnu.c (grub_cmd_xnu_kernel): Don't call + grub_cpu_xnu_fill_devicetree. + (grub_xnu_parse_devtree): Removed. + (grub_cmd_xnu_devtree): Likewise. + (hextoval): New function. + (unescape): Likewise. + (grub_xnu_fill_devicetree): Likewise. + +2009-08-24 Vladimir Serbinenko + + UTF-8 to UTF-16 transformation. + + * conf/common.rmk (pkglib_MODULES): Add utf.mod + (utf_mod_SOURCES): New variable. + (utf_mod_CFLAGS): Likewise. + (utf_mod_LDFLAGS): Likewise. + * include/grub/utf.h: New file. + * lib/utf.c: New file. (Based on grub_utf8_to_ucs4 from kern/misc.c) + From e4eff4ed62a3ed5bff1f7ce69cde22e26882821c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 20 Nov 2009 23:37:33 +0100 Subject: [PATCH 21/52] changed leftover 32 to XX --- loader/machoXX.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/loader/machoXX.c b/loader/machoXX.c index 01e6879ea..d42dd8b55 100644 --- a/loader/machoXX.c +++ b/loader/machoXX.c @@ -31,7 +31,7 @@ SUFFIX (grub_macho_parse) (grub_macho_t macho) } if (head.magic != GRUB_MACHO_MAGIC) { - grub_error (GRUB_ERR_BAD_OS, "Invalid Mach-O 32-bit header."); + grub_error (GRUB_ERR_BAD_OS, "Invalid Mach-O " XX "-bit header."); macho->offsetXX = -1; return; } @@ -94,7 +94,7 @@ SUFFIX (grub_macho_readfile) (grub_macho_t macho, void *dest) return grub_error (GRUB_ERR_BAD_OS, "Couldn't read architecture-specific part"); - if (grub_file_seek (macho->file, macho->offset32) == (grub_off_t) -1) + if (grub_file_seek (macho->file, macho->offsetXX) == (grub_off_t) -1) { grub_error_push (); return grub_error (GRUB_ERR_BAD_OS, @@ -102,8 +102,8 @@ SUFFIX (grub_macho_readfile) (grub_macho_t macho, void *dest) } read = grub_file_read (macho->file, dest, - macho->end32 - macho->offset32); - if (read != (grub_ssize_t) (macho->end32 - macho->offset32)) + macho->endXX - macho->offsetXX); + if (read != (grub_ssize_t) (macho->endXX - macho->offsetXX)) { grub_error_push (); return grub_error (GRUB_ERR_BAD_OS, From 636813f768bc3c5d0561551a9198a0ffdac52bd2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 25 Nov 2009 23:39:59 +0100 Subject: [PATCH 22/52] Split relocators from mips branch --- THANKS | 1 + conf/i386.rmk | 6 + include/grub/i386/memory.h | 30 +++ include/grub/i386/multiboot.h | 11 +- include/grub/i386/pc/memory.h | 5 +- include/grub/i386/relocator.h | 41 ++++ kern/i386/realmode.S | 4 +- lib/i386/relocator.c | 102 +++++++++ lib/i386/relocator_asm.S | 250 +++++++++++++++++++++++ lib/i386/relocator_backward.S | 2 + lib/mips/relocator.c | 109 ++++++++++ lib/mips/relocator_asm.S | 71 +++++++ lib/relocator.c | 113 ++++++++++ loader/i386/multiboot.c | 70 ++++--- loader/i386/multiboot_elfxx.c | 14 +- loader/i386/multiboot_helper.S | 75 ------- po/ca.po | 30 +-- po/id.po | 363 ++++++++++++++++++++++++++++----- po/zh_CN.po | 275 ++++++++++++++++++++++--- 19 files changed, 1356 insertions(+), 216 deletions(-) create mode 100644 include/grub/i386/memory.h create mode 100644 include/grub/i386/relocator.h create mode 100644 lib/i386/relocator.c create mode 100644 lib/i386/relocator_asm.S create mode 100644 lib/i386/relocator_backward.S create mode 100644 lib/mips/relocator.c create mode 100644 lib/mips/relocator_asm.S create mode 100644 lib/relocator.c diff --git a/THANKS b/THANKS index 5ce190944..82b4bc838 100644 --- a/THANKS +++ b/THANKS @@ -8,6 +8,7 @@ generally assist in the GRUB 2 maintainership process: Andrey Shuvikov Bibo Mao +David Miller Guillem Jover Harley D. Eades III Hitoshi Ozeki diff --git a/conf/i386.rmk b/conf/i386.rmk index bf102a9b6..c3f036d0f 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -15,6 +15,12 @@ vga_text_mod_SOURCES = term/i386/pc/vga_text.c term/i386/vga_common.c vga_text_mod_CFLAGS = $(COMMON_CFLAGS) vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES += relocator.mod +relocator_mod_SOURCES = lib/i386/relocator.c lib/i386/relocator_asm.S lib/i386/relocator_backward.S +relocator_mod_CFLAGS = $(COMMON_CFLAGS) +relocator_mod_ASFLAGS = $(COMMON_ASFLAGS) +relocator_mod_LDFLAGS = $(COMMON_LDFLAGS) + pkglib_MODULES += ata.mod ata_mod_SOURCES = disk/ata.c ata_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/include/grub/i386/memory.h b/include/grub/i386/memory.h new file mode 100644 index 000000000..a0f3192b8 --- /dev/null +++ b/include/grub/i386/memory.h @@ -0,0 +1,30 @@ +/* memory.h - describe the memory map */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2007,2008 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 . + */ + +#ifndef GRUB_MEMORY_CPU_HEADER +#define GRUB_MEMORY_CPU_HEADER 1 + +/* The flag for protected mode. */ +#define GRUB_MEMORY_CPU_CR0_PE_ON 0x1 +#define GRUB_MEMORY_CPU_CR4_PAE_ON 0x00000040 +#define GRUB_MEMORY_CPU_CR0_PAGING_ON 0x80000000 +#define GRUB_MEMORY_CPU_AMD64_MSR 0xc0000080 +#define GRUB_MEMORY_CPU_AMD64_MSR_ON 0x00000100 + +#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/i386/multiboot.h b/include/grub/i386/multiboot.h index b8cab9d24..2d990bf86 100644 --- a/include/grub/i386/multiboot.h +++ b/include/grub/i386/multiboot.h @@ -27,16 +27,11 @@ void grub_multiboot2_real_boot (grub_addr_t entry, struct multiboot_info *mbi) __attribute__ ((noreturn)); -extern grub_addr_t grub_multiboot_payload_orig; +extern grub_uint32_t grub_multiboot_payload_eip; +extern char *grub_multiboot_payload_orig; extern grub_addr_t grub_multiboot_payload_dest; extern grub_size_t grub_multiboot_payload_size; -extern grub_uint32_t grub_multiboot_payload_entry_offset; -extern grub_uint8_t grub_multiboot_forward_relocator; -extern grub_uint8_t grub_multiboot_forward_relocator_end; -extern grub_uint8_t grub_multiboot_backward_relocator; -extern grub_uint8_t grub_multiboot_backward_relocator_end; - -#define RELOCATOR_SIZEOF(x) (&grub_multiboot_##x##_relocator_end - &grub_multiboot_##x##_relocator) +#define GRUB_MULTIBOOT_STACK_SIZE 4096 #endif /* ! GRUB_MULTIBOOT_CPU_HEADER */ diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h index 4ce3a6283..1b470f8c2 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -27,6 +27,8 @@ #include #endif +#include + /* The scratch buffer used in real mode code. */ #define GRUB_MEMORY_MACHINE_SCRATCH_ADDR 0x68000 #define GRUB_MEMORY_MACHINE_SCRATCH_SEG (GRUB_MEMORY_MACHINE_SCRATCH_ADDR >> 4) @@ -62,9 +64,6 @@ /* The address where another boot loader is loaded. */ #define GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR 0x7c00 -/* The flag for protected mode. */ -#define GRUB_MEMORY_MACHINE_CR0_PE_ON 0x1 - /* The code segment of the protected mode. */ #define GRUB_MEMORY_MACHINE_PROT_MODE_CSEG 0x8 diff --git a/include/grub/i386/relocator.h b/include/grub/i386/relocator.h new file mode 100644 index 000000000..ef7fe23aa --- /dev/null +++ b/include/grub/i386/relocator.h @@ -0,0 +1,41 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 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 . + */ + +#ifndef GRUB_RELOCATOR_CPU_HEADER +#define GRUB_RELOCATOR_CPU_HEADER 1 + +#include +#include + +struct grub_relocator32_state +{ + grub_uint32_t esp; + grub_uint32_t eax; + grub_uint32_t ebx; + grub_uint32_t ecx; + grub_uint32_t edx; + grub_uint32_t eip; +}; + +void *grub_relocator32_alloc (grub_size_t size); +grub_err_t grub_relocator32_boot (void *relocator, grub_uint32_t dest, + struct grub_relocator32_state state); +void *grub_relocator32_realloc (void *relocator, grub_size_t size); +void grub_relocator32_free (void *relocator); + +#endif /* ! GRUB_RELOCATOR_CPU_HEADER */ diff --git a/kern/i386/realmode.S b/kern/i386/realmode.S index 11f4d5347..5f28f9eb3 100644 --- a/kern/i386/realmode.S +++ b/kern/i386/realmode.S @@ -127,7 +127,7 @@ real_to_prot: /* turn on protected mode */ movl %cr0, %eax - orl $GRUB_MEMORY_MACHINE_CR0_PE_ON, %eax + orl $GRUB_MEMORY_CPU_CR0_PE_ON, %eax movl %eax, %cr0 /* jump to relocation, flush prefetch queue, and reload %cs */ @@ -196,7 +196,7 @@ tmpcseg: /* clear the PE bit of CR0 */ movl %cr0, %eax - andl $(~GRUB_MEMORY_MACHINE_CR0_PE_ON), %eax + andl $(~GRUB_MEMORY_CPU_CR0_PE_ON), %eax movl %eax, %cr0 /* flush prefetch queue, reload %cs */ diff --git a/lib/i386/relocator.c b/lib/i386/relocator.c new file mode 100644 index 000000000..ae7caf28b --- /dev/null +++ b/lib/i386/relocator.c @@ -0,0 +1,102 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 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 . + */ + +#include +#include + +#include +#include +#include + +#include + +extern grub_uint8_t grub_relocator32_forward_start; +extern grub_uint8_t grub_relocator32_forward_end; +extern grub_uint8_t grub_relocator32_backward_start; +extern grub_uint8_t grub_relocator32_backward_end; + +extern grub_uint32_t grub_relocator32_backward_dest; +extern grub_uint32_t grub_relocator32_backward_size; +extern grub_addr_t grub_relocator32_backward_src; + +extern grub_uint32_t grub_relocator32_forward_dest; +extern grub_uint32_t grub_relocator32_forward_size; +extern grub_addr_t grub_relocator32_forward_src; + +extern grub_uint32_t grub_relocator32_forward_eax; +extern grub_uint32_t grub_relocator32_forward_ebx; +extern grub_uint32_t grub_relocator32_forward_ecx; +extern grub_uint32_t grub_relocator32_forward_edx; +extern grub_uint32_t grub_relocator32_forward_eip; +extern grub_uint32_t grub_relocator32_forward_esp; + +extern grub_uint32_t grub_relocator32_backward_eax; +extern grub_uint32_t grub_relocator32_backward_ebx; +extern grub_uint32_t grub_relocator32_backward_ecx; +extern grub_uint32_t grub_relocator32_backward_edx; +extern grub_uint32_t grub_relocator32_backward_eip; +extern grub_uint32_t grub_relocator32_backward_esp; + +#define RELOCATOR_SIZEOF(x) (&grub_relocator32_##x##_end - &grub_relocator32_##x##_start) +#define RELOCATOR_ALIGN 16 +#define PREFIX(x) grub_relocator32_ ## x + +static void +write_call_relocator_bw (void *ptr, void *src, grub_uint32_t dest, + grub_size_t size, struct grub_relocator32_state state) +{ + grub_relocator32_backward_dest = dest; + grub_relocator32_backward_src = PTR_TO_UINT64 (src); + grub_relocator32_backward_size = size; + + grub_relocator32_backward_eax = state.eax; + grub_relocator32_backward_ebx = state.ebx; + grub_relocator32_backward_ecx = state.ecx; + grub_relocator32_backward_edx = state.edx; + grub_relocator32_backward_eip = state.eip; + grub_relocator32_backward_esp = state.esp; + + grub_memmove (ptr, + &grub_relocator32_backward_start, + RELOCATOR_SIZEOF (backward)); + ((void (*) (void)) ptr) (); +} + +static void +write_call_relocator_fw (void *ptr, void *src, grub_uint32_t dest, + grub_size_t size, struct grub_relocator32_state state) +{ + + grub_relocator32_forward_dest = dest; + grub_relocator32_forward_src = PTR_TO_UINT64 (src); + grub_relocator32_forward_size = size; + + grub_relocator32_forward_eax = state.eax; + grub_relocator32_forward_ebx = state.ebx; + grub_relocator32_forward_ecx = state.ecx; + grub_relocator32_forward_edx = state.edx; + grub_relocator32_forward_eip = state.eip; + grub_relocator32_forward_esp = state.esp; + + grub_memmove (ptr, + &grub_relocator32_forward_start, + RELOCATOR_SIZEOF (forward)); + ((void (*) (void)) ptr) (); +} + +#include "../relocator.c" diff --git a/lib/i386/relocator_asm.S b/lib/i386/relocator_asm.S new file mode 100644 index 000000000..343991d3d --- /dev/null +++ b/lib/i386/relocator_asm.S @@ -0,0 +1,250 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 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 . + */ + +#include +#include + +#ifdef BACKWARD +#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_backward_ ## x) +#else +#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_forward_ ## x) +#endif +#ifdef __x86_64__ +#define RAX %rax +#define RCX %rcx +#define RDX %rdx +#define RDI %rdi +#define RSI %rdi +#else +#define RAX %eax +#define RCX %ecx +#define RDX %edx +#define RDI %edi +#define RSI %esi +#endif + +/* The code segment of the protected mode. */ +#define CODE_SEGMENT 0x10 + +/* The data segment of the protected mode. */ +#define DATA_SEGMENT 0x18 + + .p2align 4 /* force 16-byte alignment */ + +RELOCATOR_VARIABLE(start) +#ifdef BACKWARD +LOCAL(base): +#endif + cli + +#ifndef __x86_64__ + /* mov imm32, %eax */ + .byte 0xb8 +RELOCATOR_VARIABLE(dest) + .long 0 + movl %eax, %edi + + /* mov imm32, %eax */ + .byte 0xb8 +RELOCATOR_VARIABLE(src) + .long 0 + movl %eax, %esi + + /* mov imm32, %ecx */ + .byte 0xb9 +RELOCATOR_VARIABLE(size) + .long 0 +#else + xorq %rax, %rax + + /* mov imm32, %eax */ + .byte 0xb8 +RELOCATOR_VARIABLE(dest) + .long 0 + movq %rax, %rdi + + /* mov imm64, %rax */ + .byte 0x48 + .byte 0xb8 +RELOCATOR_VARIABLE(src) + .long 0, 0 + movq %rax, %rsi + + xorq %rcx, %rcx + /* mov imm32, %ecx */ + .byte 0xb9 +RELOCATOR_VARIABLE(size) + .long 0 + +#endif + + mov RDI, RAX + +#ifdef BACKWARD + add RCX, RSI + add RDX, RDI +#endif + +#ifndef BACKWARD + add RCX, RAX +#endif + add $0x3, RCX + shr $2, RCX + + +#ifdef BACKWARD + /* Backward movsl is implicitly off-by-four. compensate that. */ + sub $4, RSI + sub $4, RDI + + /* Backward copy. */ + std + + rep + movsl + +#else + /* Forward copy. */ + cld + rep + movsl +#endif + + /* %rax contains now our new 'base'. */ + mov RAX, RSI + add $(LOCAL(cont0) - LOCAL(base)), RAX + jmp *RAX +LOCAL(cont0): + lea (LOCAL(cont1) - LOCAL(base)) (RSI, 1), RAX + movl %eax, (LOCAL(jump_vector) - LOCAL(base)) (RSI, 1) + + lea (LOCAL(gdt) - LOCAL(base)) (RSI, 1), RAX + mov RAX, (LOCAL(gdt_addr) - LOCAL(base)) (RSI, 1) + + /* Switch to compatibility mode. */ + + lgdt (LOCAL(gdtdesc) - LOCAL(base)) (RSI, 1) + + /* Update %cs. Thanks to David Miller for pointing this mistake out. */ + ljmp *(LOCAL(jump_vector) - LOCAL(base)) (RSI, 1) + +LOCAL(cont1): + .code32 + + /* Update other registers. */ + movl $DATA_SEGMENT, %eax + movl %eax, %ds + movl %eax, %es + movl %eax, %fs + movl %eax, %gs + movl %eax, %ss + + /* Disable paging. */ + movl %cr0, %eax + andl $(~GRUB_MEMORY_CPU_CR0_PAGING_ON), %eax + movl %eax, %cr0 + + /* Disable amd64. */ + movl $GRUB_MEMORY_CPU_AMD64_MSR, %ecx + rdmsr + andl $(~GRUB_MEMORY_CPU_AMD64_MSR_ON), %eax + wrmsr + + /* Turn off PAE. */ + movl %cr4, %eax + andl $GRUB_MEMORY_CPU_CR4_PAE_ON, %eax + movl %eax, %cr4 + + jmp LOCAL(cont2) +LOCAL(cont2): + .code32 + + /* mov imm32, %eax */ + .byte 0xb8 +RELOCATOR_VARIABLE (esp) + .long 0 + + movl %eax, %esp + + /* mov imm32, %eax */ + .byte 0xb8 +RELOCATOR_VARIABLE (eax) + .long 0 + + /* mov imm32, %ebx */ + .byte 0xbb +RELOCATOR_VARIABLE (ebx) + .long 0 + + /* mov imm32, %ecx */ + .byte 0xb9 +RELOCATOR_VARIABLE (ecx) + .long 0 + + /* mov imm32, %edx */ + .byte 0xba +RELOCATOR_VARIABLE (edx) + .long 0 + + /* Cleared direction flag is of no problem with any current + payload and makes this implementation easier. */ + cld + + .byte 0xea +RELOCATOR_VARIABLE (eip) + .long 0 + .word 0x08 + + /* GDT. Copied from loader/i386/linux.c. */ + .p2align 4 +LOCAL(gdt): + /* NULL. */ + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + /* Reserved. */ + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + /* Code segment. */ + .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00 + + /* Data segment. */ + .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00 + + .p2align 4 +LOCAL(gdtdesc): + .word 0x27 +LOCAL(gdt_addr): +#ifdef __x86_64__ + /* Filled by the code. */ + .quad 0 +#else + /* Filled by the code. */ + .long 0 +#endif + + .p2align 4 +LOCAL(jump_vector): + /* Jump location. Is filled by the code */ + .long 0 + .long CODE_SEGMENT + +#ifndef BACKWARD +LOCAL(base): +#endif + +RELOCATOR_VARIABLE(end) diff --git a/lib/i386/relocator_backward.S b/lib/i386/relocator_backward.S new file mode 100644 index 000000000..06913470e --- /dev/null +++ b/lib/i386/relocator_backward.S @@ -0,0 +1,2 @@ +#define BACKWARD +#include "relocator_asm.S" diff --git a/lib/mips/relocator.c b/lib/mips/relocator.c new file mode 100644 index 000000000..796473bf7 --- /dev/null +++ b/lib/mips/relocator.c @@ -0,0 +1,109 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 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 . + */ + +#include +#include + +#include +#include +#include +#include + +#include + +/* Remark: doesn't work with source outside of 4G. + Use relocator64 in this case. + */ + +extern grub_uint8_t grub_relocator32_forward_start; +extern grub_uint8_t grub_relocator32_forward_end; +extern grub_uint8_t grub_relocator32_backward_start; +extern grub_uint8_t grub_relocator32_backward_end; + +#define REGW_SIZEOF (2 * sizeof (grub_uint32_t)) +#define JUMP_SIZEOF (sizeof (grub_uint32_t)) + +#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator32_##x##_end \ + - &grub_relocator32_##x##_start) +#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \ + + REGW_SIZEOF * (31 + 3) + JUMP_SIZEOF) +#define RELOCATOR_ALIGN 16 + +#define PREFIX(x) grub_relocator32_ ## x + +static void +write_reg (int regn, grub_uint32_t val, void **target) +{ + /* lui $r, (val+0x8000). */ + *(grub_uint32_t *) *target = ((0x3c00 | regn) << 16) | ((val + 0x8000) >> 16); + *target = ((grub_uint32_t *) *target) + 1; + /* addiu $r, $r, val. */ + *(grub_uint32_t *) *target = (((0x2400 | regn << 5 | regn) << 16) + | (val & 0xffff)); + *target = ((grub_uint32_t *) *target) + 1; +} + +static void +write_jump (int regn, void **target) +{ + /* j $r. */ + *(grub_uint32_t *) *target = (regn<<21) | 0x8; + *target = ((grub_uint32_t *) *target) + 1; +} + +static void +write_call_relocator_bw (void *ptr0, void *src, grub_uint32_t dest, + grub_size_t size, struct grub_relocator32_state state) +{ + void *ptr = ptr0; + int i; + write_reg (8, (grub_uint32_t) src, &ptr); + write_reg (9, dest, &ptr); + write_reg (10, size, &ptr); + grub_memcpy (ptr, &grub_relocator32_backward_start, + RELOCATOR_SRC_SIZEOF (backward)); + ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (backward); + for (i = 1; i < 32; i++) + write_reg (i, state.gpr[i], &ptr); + write_jump (state.jumpreg, &ptr); + grub_arch_sync_caches (ptr0, (grub_uint8_t *) ptr - (grub_uint8_t *) ptr0); + grub_dprintf ("relocator", "Backward relocator: about to jump to %p\n", ptr0); + ((void (*) (void)) ptr0) (); +} + +static void +write_call_relocator_fw (void *ptr0, void *src, grub_uint32_t dest, + grub_size_t size, struct grub_relocator32_state state) +{ + void *ptr = ptr0; + int i; + write_reg (8, (grub_uint32_t) src, &ptr); + write_reg (9, dest, &ptr); + write_reg (10, size, &ptr); + grub_memcpy (ptr, &grub_relocator32_forward_start, + RELOCATOR_SRC_SIZEOF (forward)); + ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (forward); + for (i = 1; i < 32; i++) + write_reg (i, state.gpr[i], &ptr); + write_jump (state.jumpreg, &ptr); + grub_arch_sync_caches (ptr0, (grub_uint8_t *) ptr - (grub_uint8_t *) ptr0); + grub_dprintf ("relocator", "Forward relocator: about to jump to %p\n", ptr0); + ((void (*) (void)) ptr0) (); +} + +#include "../relocator.c" diff --git a/lib/mips/relocator_asm.S b/lib/mips/relocator_asm.S new file mode 100644 index 000000000..f9cdf1470 --- /dev/null +++ b/lib/mips/relocator_asm.S @@ -0,0 +1,71 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 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 . + */ + +#include + + .p2align 4 /* force 16-byte alignment */ + +VARIABLE (grub_relocator32_forward_start) + move $12, $9 + move $13, $10 + +copycont1: + lb $11,0($8) + sb $11,0($9) + addiu $8, $8, 0x1 + addiu $9, $9, 0x1 + addiu $10, $10, 0xffff + subu $11,$10,$0 + bne $11, $0, copycont1 + +cachecont1: + cache 1,0($12) + cache 0,0($12) + addiu $12, $12, 0x1 + addiu $13, $13, 0xffff + subu $11,$13,$0 + bne $11, $0, cachecont1 +VARIABLE (grub_relocator32_forward_end) + +VARIABLE (grub_relocator32_backward_start) + move $12, $9 + move $13, $10 + + addu $9, $9, $10 + addu $8, $8, $10 + /* Backward movsl is implicitly off-by-one. compensate that. */ + addiu $9, $9, 0xffff + addiu $8, $8, 0xffff +copycont2: + lb $11,0($8) + sb $11,0($9) + cache 1, 0($9) + cache 0, 0($9) + addiu $8, $8, 0xffff + addiu $9, $9, 0xffff + addiu $10, 0xffff + subu $11,$10,$0 + bne $11, $0, copycont2 +cachecont2: + cache 1,0($12) + cache 0,0($12) + addiu $12, $12, 0x1 + addiu $13, $13, 0xffff + subu $11,$13,$0 + bne $11, $0, cachecont2 +VARIABLE (grub_relocator32_backward_end) diff --git a/lib/relocator.c b/lib/relocator.c new file mode 100644 index 000000000..bebf7ada9 --- /dev/null +++ b/lib/relocator.c @@ -0,0 +1,113 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 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 . + */ + +void * +PREFIX (alloc) (grub_size_t size) +{ + char *playground; + + playground = grub_malloc ((RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) + + size + + (RELOCATOR_SIZEOF (backward) + + RELOCATOR_ALIGN)); + if (!playground) + return 0; + + *(grub_size_t *) playground = size; + + return playground + RELOCATOR_SIZEOF (forward); +} + +void * +PREFIX (realloc) (void *relocator, grub_size_t size) +{ + char *playground; + + playground = (char *) relocator - RELOCATOR_SIZEOF (forward); + + playground = grub_realloc (playground, + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) + + size + + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN)); + if (!playground) + return 0; + + *(grub_size_t *) playground = size; + + return playground + RELOCATOR_SIZEOF (forward); +} + +void +PREFIX(free) (void *relocator) +{ + if (relocator) + grub_free ((char *) relocator - RELOCATOR_SIZEOF (forward)); +} + +grub_err_t +PREFIX (boot) (void *relocator, grub_uint32_t dest, + struct grub_relocator32_state state) +{ + grub_size_t size; + char *playground; + + playground = (char *) relocator - RELOCATOR_SIZEOF (forward); + size = *(grub_size_t *) playground; + + grub_dprintf ("relocator", + "Relocator: source: %p, destination: 0x%x, size: 0x%x\n", + relocator, dest, size); + + if (UINT_TO_PTR (dest) >= relocator) + { + int overhead; + overhead = + ALIGN_UP (dest - RELOCATOR_SIZEOF (backward) - RELOCATOR_ALIGN, + RELOCATOR_ALIGN); + grub_dprintf ("relocator", + "Backward relocator: code %p, source: %p, " + "destination: 0x%x, size: 0x%x\n", + (char *) relocator - overhead, + (char *) relocator - overhead, + dest - overhead, size + overhead); + + write_call_relocator_bw ((char *) relocator - overhead, + (char *) relocator - overhead, + dest - overhead, size + overhead, state); + } + else + { + int overhead; + + overhead = ALIGN_UP (dest + size, RELOCATOR_ALIGN) + + RELOCATOR_SIZEOF (forward) - (dest + size); + grub_dprintf ("relocator", + "Forward relocator: code %p, source: %p, " + "destination: 0x%x, size: 0x%x\n", + (char *) relocator + size + overhead + - RELOCATOR_SIZEOF (forward), + relocator, dest, size + overhead); + + write_call_relocator_fw ((char *) relocator + size + overhead + - RELOCATOR_SIZEOF (forward), + relocator, dest, size + overhead, state); + } + + /* Not reached. */ + return GRUB_ERR_NONE; +} diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index d1ea307d2..33c7433f2 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -48,18 +48,35 @@ #include #include #endif +#include extern grub_dl_t my_mod; static struct multiboot_info *mbi, *mbi_dest; -static grub_addr_t entry; -static char *playground = 0; static grub_size_t code_size; +char *grub_multiboot_payload_orig; +grub_addr_t grub_multiboot_payload_dest; +grub_size_t grub_multiboot_payload_size; +grub_uint32_t grub_multiboot_payload_eip; +grub_uint32_t grub_multiboot_payload_esp; + static grub_err_t grub_multiboot_boot (void) { - grub_multiboot_real_boot (entry, mbi_dest); + struct grub_relocator32_state state = + { + .eax = MULTIBOOT_MAGIC2, + .ebx = PTR_TO_UINT32 (mbi_dest), + .ecx = 0, + .edx = 0, + .eip = grub_multiboot_payload_eip, + .esp = grub_multiboot_payload_esp + }; + + grub_relocator32_boot (grub_multiboot_payload_orig, + grub_multiboot_payload_dest, + state); /* Not reached. */ return GRUB_ERR_NONE; @@ -68,7 +85,7 @@ grub_multiboot_boot (void) static grub_err_t grub_multiboot_unload (void) { - if (playground) + if (mbi) { unsigned int i; for (i = 0; i < mbi->mods_count; i++) @@ -79,11 +96,11 @@ grub_multiboot_unload (void) ((struct multiboot_mod_list *) mbi->mods_addr)[i].cmdline); } grub_free ((void *) mbi->mods_addr); - grub_free (playground); } + grub_relocator32_free (grub_multiboot_payload_orig); mbi = NULL; - playground = NULL; + grub_multiboot_payload_orig = NULL; grub_dl_unref (my_mod); return GRUB_ERR_NONE; @@ -250,11 +267,8 @@ grub_multiboot (int argc, char *argv[]) goto fail; } - if (playground) - { - grub_free (playground); - playground = NULL; - } + grub_relocator32_free (grub_multiboot_payload_orig); + grub_multiboot_payload_orig = NULL; mmap_length = grub_get_multiboot_mmap_len (); @@ -276,11 +290,13 @@ grub_multiboot (int argc, char *argv[]) ((void *) ((x) + code_size + cmdline_length)) #define mbi_addr(x) ((void *) ((x) + code_size + cmdline_length + boot_loader_name_length)) #define mmap_addr(x) ((void *) ((x) + code_size + cmdline_length + boot_loader_name_length + sizeof (struct multiboot_info))) +#define stack_addr(x) ((void *) ((x) + code_size + cmdline_length + boot_loader_name_length + sizeof (struct multiboot_info) + mmap_length + GRUB_MULTIBOOT_STACK_SIZE)) grub_multiboot_payload_size = cmdline_length /* boot_loader_name_length might need to grow for mbi,etc to be aligned (see below) */ + boot_loader_name_length + 3 - + sizeof (struct multiboot_info) + mmap_length; + + sizeof (struct multiboot_info) + mmap_length + + GRUB_MULTIBOOT_STACK_SIZE; if (header->flags & MULTIBOOT_AOUT_KLUDGE) { @@ -296,11 +312,12 @@ grub_multiboot (int argc, char *argv[]) grub_multiboot_payload_dest = header->load_addr; grub_multiboot_payload_size += code_size; - playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward)); - if (! playground) - goto fail; - grub_multiboot_payload_orig = (long) playground + RELOCATOR_SIZEOF(forward); + grub_multiboot_payload_orig + = grub_relocator32_alloc (grub_multiboot_payload_size); + + if (! grub_multiboot_payload_orig) + goto fail; if ((grub_file_seek (file, offset)) == (grub_off_t) - 1) goto fail; @@ -313,7 +330,7 @@ grub_multiboot (int argc, char *argv[]) grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0, header->bss_end_addr - header->load_addr - load_size); - grub_multiboot_payload_entry_offset = header->entry_addr - header->load_addr; + grub_multiboot_payload_eip = header->entry_addr; } else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE) @@ -334,23 +351,6 @@ grub_multiboot (int argc, char *argv[]) mbi->mmap_addr = (grub_uint32_t) mmap_addr (grub_multiboot_payload_dest); mbi->flags |= MULTIBOOT_INFO_MEM_MAP; - if (grub_multiboot_payload_dest >= grub_multiboot_payload_orig) - { - grub_memmove (playground, &grub_multiboot_forward_relocator, RELOCATOR_SIZEOF(forward)); - entry = (grub_addr_t) playground; - } - else - { - grub_memmove ((char *) (grub_multiboot_payload_orig + grub_multiboot_payload_size), - &grub_multiboot_backward_relocator, RELOCATOR_SIZEOF(backward)); - entry = (grub_addr_t) grub_multiboot_payload_orig + grub_multiboot_payload_size; - } - - grub_dprintf ("multiboot_loader", "dest=%p, size=0x%x, entry_offset=0x%x\n", - (void *) grub_multiboot_payload_dest, - grub_multiboot_payload_size, - grub_multiboot_payload_entry_offset); - /* Convert from bytes to kilobytes. */ mbi->mem_lower = grub_mmap_get_lower () / 1024; mbi->mem_upper = grub_mmap_get_upper () / 1024; @@ -382,6 +382,8 @@ grub_multiboot (int argc, char *argv[]) if (grub_multiboot_get_bootdev (&mbi->boot_device)) mbi->flags |= MULTIBOOT_INFO_BOOTDEV; + grub_multiboot_payload_esp = PTR_TO_UINT32 (stack_addr (grub_multiboot_payload_dest)); + grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 1); fail: diff --git a/loader/i386/multiboot_elfxx.c b/loader/i386/multiboot_elfxx.c index 77c47118c..0b9820dcc 100644 --- a/loader/i386/multiboot_elfxx.c +++ b/loader/i386/multiboot_elfxx.c @@ -32,6 +32,8 @@ #error "I'm confused" #endif +#include + #define CONCAT(a,b) CONCAT_(a, b) #define CONCAT_(a,b) a ## b @@ -99,11 +101,12 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer) grub_multiboot_payload_dest = phdr(lowest_segment)->p_paddr; grub_multiboot_payload_size += code_size; - playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward)); - if (! playground) - return grub_errno; - grub_multiboot_payload_orig = (long) playground + RELOCATOR_SIZEOF(forward); + grub_multiboot_payload_orig + = grub_relocator32_alloc (grub_multiboot_payload_size); + + if (!grub_multiboot_payload_orig) + return grub_errno; /* Load every loadable segment in memory. */ for (i = 0; i < ehdr->e_phnum; i++) @@ -135,8 +138,7 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer) if (phdr(i)->p_vaddr <= ehdr->e_entry && phdr(i)->p_vaddr + phdr(i)->p_memsz > ehdr->e_entry) { - grub_multiboot_payload_entry_offset = (ehdr->e_entry - phdr(i)->p_vaddr) - + (phdr(i)->p_paddr - phdr(lowest_segment)->p_paddr); + grub_multiboot_payload_eip = ehdr->e_entry; break; } diff --git a/loader/i386/multiboot_helper.S b/loader/i386/multiboot_helper.S index d1094588b..2f9af778b 100644 --- a/loader/i386/multiboot_helper.S +++ b/loader/i386/multiboot_helper.S @@ -22,81 +22,6 @@ .p2align 2 /* force 4-byte alignment */ -/* - * This starts the multiboot kernel. - */ - -VARIABLE(grub_multiboot_payload_size) - .long 0 -VARIABLE(grub_multiboot_payload_orig) - .long 0 -VARIABLE(grub_multiboot_payload_dest) - .long 0 -VARIABLE(grub_multiboot_payload_entry_offset) - .long 0 - -/* - * The relocators below understand the following parameters: - * ecx: Size of the block to be copied. - * esi: Where to copy from (always lowest address, even if we're relocating - * backwards). - * edi: Where to copy to (likewise). - * edx: Offset of the entry point (relative to the beginning of the block). - */ - -VARIABLE(grub_multiboot_forward_relocator) - /* Add entry offset. */ - addl %edi, %edx - - /* Forward copy. */ - cld - rep - movsb - - jmp *%edx -VARIABLE(grub_multiboot_forward_relocator_end) - -VARIABLE(grub_multiboot_backward_relocator) - /* Add entry offset (before %edi is mangled). */ - addl %edi, %edx - - /* Backward movsb is implicitly off-by-one. compensate that. */ - decl %esi - decl %edi - - /* Backward copy. */ - std - addl %ecx, %esi - addl %ecx, %edi - rep - movsb - - cld - jmp *%edx -VARIABLE(grub_multiboot_backward_relocator_end) - -FUNCTION(grub_multiboot_real_boot) - /* Push the entry address on the stack. */ - pushl %eax - /* Move the address of the multiboot information structure to ebx. */ - movl %edx,%ebx - - /* Interrupts should be disabled. */ - cli - - /* Where do we copy what from. */ - movl EXT_C(grub_multiboot_payload_size), %ecx - movl EXT_C(grub_multiboot_payload_orig), %esi - movl EXT_C(grub_multiboot_payload_dest), %edi - movl EXT_C(grub_multiboot_payload_entry_offset), %edx - - /* Move the magic value into eax. */ - movl $MULTIBOOT_MAGIC2, %eax - - /* Jump to the relocator. */ - popl %ebp - jmp *%ebp - /* * This starts the multiboot 2 kernel. */ diff --git a/po/ca.po b/po/ca.po index 58783edbd..a72601c84 100644 --- a/po/ca.po +++ b/po/ca.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: GNU GRUB\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-11-22 11:45+0000\n" +"POT-Creation-Date: 2009-11-25 23:35+0100\n" "PO-Revision-Date: 2009-11-17 12:26+0100\n" "Last-Translator: Robert Millan \n" "Language-Team: None \n" @@ -40,7 +40,7 @@ msgstr "" msgid "Core image is too big (%p > %p)\n" msgstr "" -#: util/i386/pc/grub-mkimage.c:321 util/i386/pc/grub-setup.c:587 +#: util/i386/pc/grub-mkimage.c:321 util/i386/pc/grub-setup.c:589 #, c-format msgid "Try ``%s --help'' for more information.\n" msgstr "Proveu «%s --help» per a obtenir més informació.\n" @@ -162,39 +162,39 @@ msgstr "" msgid "If you really want blocklists, use --force." msgstr "" -#: util/i386/pc/grub-setup.c:439 +#: util/i386/pc/grub-setup.c:441 #, c-format msgid "attempting to read the core image `%s' from GRUB" msgstr "" -#: util/i386/pc/grub-setup.c:440 +#: util/i386/pc/grub-setup.c:442 #, c-format msgid "attempting to read the core image `%s' from GRUB again" msgstr "" -#: util/i386/pc/grub-setup.c:498 +#: util/i386/pc/grub-setup.c:500 #, c-format msgid "Cannot read `%s' correctly" msgstr "" -#: util/i386/pc/grub-setup.c:511 +#: util/i386/pc/grub-setup.c:513 msgid "No terminator in the core image" msgstr "" -#: util/i386/pc/grub-setup.c:522 +#: util/i386/pc/grub-setup.c:524 msgid "Failed to read the first sector of the core image" msgstr "" -#: util/i386/pc/grub-setup.c:528 +#: util/i386/pc/grub-setup.c:530 msgid "Failed to read the rest sectors of the core image" msgstr "" -#: util/i386/pc/grub-setup.c:547 +#: util/i386/pc/grub-setup.c:549 #, c-format msgid "Cannot open `%s'" msgstr "" -#: util/i386/pc/grub-setup.c:589 +#: util/i386/pc/grub-setup.c:591 #, c-format msgid "" "Usage: grub-setup [OPTION]... DEVICE\n" @@ -216,27 +216,27 @@ msgid "" "Report bugs to <%s>.\n" msgstr "" -#: util/i386/pc/grub-setup.c:719 +#: util/i386/pc/grub-setup.c:721 #, c-format msgid "No device is specified.\n" msgstr "" -#: util/i386/pc/grub-setup.c:725 +#: util/i386/pc/grub-setup.c:727 #, c-format msgid "Unknown extra argument `%s'.\n" msgstr "" -#: util/i386/pc/grub-setup.c:742 +#: util/i386/pc/grub-setup.c:744 #, c-format msgid "Invalid device `%s'.\n" msgstr "" -#: util/i386/pc/grub-setup.c:755 +#: util/i386/pc/grub-setup.c:757 #, c-format msgid "Invalid root device `%s'" msgstr "" -#: util/i386/pc/grub-setup.c:768 +#: util/i386/pc/grub-setup.c:770 msgid "Cannot guess the root device. Specify the option ``--root-device''." msgstr "" diff --git a/po/id.po b/po/id.po index d97cfb9e7..69692a003 100644 --- a/po/id.po +++ b/po/id.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: grub 1.97+20091122\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-11-22 11:48+0100\n" +"POT-Creation-Date: 2009-11-25 23:35+0100\n" "PO-Revision-Date: 2009-11-22 20:00+0700\n" "Last-Translator: Arif E. Nugroho \n" "Language-Team: Indonesian \n" @@ -41,7 +41,7 @@ msgstr "besar diskboot.img seharusnya %u bytes" msgid "Core image is too big (%p > %p)\n" msgstr "Image core terlalu besar (%p >%p)\n" -#: util/i386/pc/grub-mkimage.c:321 util/i386/pc/grub-setup.c:587 +#: util/i386/pc/grub-mkimage.c:321 util/i386/pc/grub-setup.c:589 #, c-format msgid "Try ``%s --help'' for more information.\n" msgstr "Coba ``%s --help'' untuk informasi lebih lanjut.\n" @@ -72,7 +72,8 @@ msgstr "" " -p, --prefix=DIR set direktori grub_prefix [baku=%s]\n" " -m, --memdisk=BERKAS tempatkan BERKAS sebagai sebuah image memdisk\n" " -c, --config=BERKAS tempatkan BERKAS sebagai konfigurasi boot\n" -" -o, --output=BERKAS keluarkan sebuah image yang dihasilkan ke BERKAS [baku=stdout]\n" +" -o, --output=BERKAS keluarkan sebuah image yang dihasilkan ke BERKAS " +"[baku=stdout]\n" " -h, --help tampilkan pesan ini dan keluar\n" " -V, --version tampilkan informasi versi dan keluar\n" " -v, --verbose tampilkan informasi secara detail\n" @@ -114,86 +115,122 @@ msgstr "Ukuran dari `%s' terlalu besar" #: util/i386/pc/grub-setup.c:261 #, c-format msgid "Unable to identify a filesystem in %s; safety check can't be performed" -msgstr "Tidak dapat mengidentifikasikan sebuah sistem berkas dalam %s; pemeriksaan keamanan tidak dapat dilakukan" +msgstr "" +"Tidak dapat mengidentifikasikan sebuah sistem berkas dalam %s; pemeriksaan " +"keamanan tidak dapat dilakukan" #: util/i386/pc/grub-setup.c:265 #, c-format -msgid "%s appears to contain a %s filesystem which isn't known to reserve space for DOS-style boot. Installing GRUB there could result in FILESYSTEM DESTRUCTION if valuable data is overwritten by grub-setup (--skip-fs-probe disables this check, use at your own risk)" -msgstr "%s sepertinya berisi sebuah sistem berkas %s yang tidak diketahui untuk mereserve ruang untuk boot gaya-DOS. Memasang GRUB disana dapat berakibat KERUSAKAN SISTEM BERKAS jika data berharga dipaksa tulis oleh grub-setup (--skip-fs-probe menonaktifkan pemeriksaan ini, gunakan sesuai resiko anda)" +msgid "" +"%s appears to contain a %s filesystem which isn't known to reserve space for " +"DOS-style boot. Installing GRUB there could result in FILESYSTEM " +"DESTRUCTION if valuable data is overwritten by grub-setup (--skip-fs-probe " +"disables this check, use at your own risk)" +msgstr "" +"%s sepertinya berisi sebuah sistem berkas %s yang tidak diketahui untuk " +"mereserve ruang untuk boot gaya-DOS. Memasang GRUB disana dapat berakibat " +"KERUSAKAN SISTEM BERKAS jika data berharga dipaksa tulis oleh grub-setup (--" +"skip-fs-probe menonaktifkan pemeriksaan ini, gunakan sesuai resiko anda)" #: util/i386/pc/grub-setup.c:314 msgid "No DOS-style partitions found" msgstr "Tidak ditemukan gaya partisi DOS" #: util/i386/pc/grub-setup.c:330 util/i386/pc/grub-setup.c:355 -msgid "Attempting to install GRUB to a partitionless disk. This is a BAD idea." -msgstr "Mencoba memasang GRUB ke sebuah disk yang tidak berpartisi. Ini mungkin bukan ide baik." +msgid "" +"Attempting to install GRUB to a partitionless disk. This is a BAD idea." +msgstr "" +"Mencoba memasang GRUB ke sebuah disk yang tidak berpartisi. Ini mungkin " +"bukan ide baik." #: util/i386/pc/grub-setup.c:336 -msgid "Attempting to install GRUB to a partition instead of the MBR. This is a BAD idea." -msgstr "Mencoba memasang GRUB ke sebuah partisi daripada MBR. Ini mungkin bukan ide baik." +msgid "" +"Attempting to install GRUB to a partition instead of the MBR. This is a BAD " +"idea." +msgstr "" +"Mencoba memasang GRUB ke sebuah partisi daripada MBR. Ini mungkin bukan ide " +"baik." #: util/i386/pc/grub-setup.c:365 -msgid "This msdos-style partition label has no post-MBR gap; embedding won't be possible!" -msgstr "Label partisi gaya msdos ini tidak memiliki post-MBR gap; penempatan tidak memungkinkan!" +msgid "" +"This msdos-style partition label has no post-MBR gap; embedding won't be " +"possible!" +msgstr "" +"Label partisi gaya msdos ini tidak memiliki post-MBR gap; penempatan tidak " +"memungkinkan!" #: util/i386/pc/grub-setup.c:367 -msgid "This GPT partition label has no BIOS Boot Partition; embedding won't be possible!" -msgstr "Label partisi GPT ini tidak memiliki partisi boot BIOS; penempatan tidak memungkinkan!" +msgid "" +"This GPT partition label has no BIOS Boot Partition; embedding won't be " +"possible!" +msgstr "" +"Label partisi GPT ini tidak memiliki partisi boot BIOS; penempatan tidak " +"memungkinkan!" #: util/i386/pc/grub-setup.c:374 msgid "Your core.img is unusually large. It won't fit in the embedding area." -msgstr "Besar core.img anda sangat besar. Ini tidak akan masuk dalam area penempatan." +msgstr "" +"Besar core.img anda sangat besar. Ini tidak akan masuk dalam area penempatan." #: util/i386/pc/grub-setup.c:376 msgid "Your embedding area is unusually small. core.img won't fit in it." msgstr "Penempatan anda sangat kecil. core.img tidak akan masuk disana." #: util/i386/pc/grub-setup.c:418 -msgid "Embedding is not possible, but this is required when the root device is on a RAID array or LVM volume." -msgstr "Penempatan tidak memungkinkan, tetapi ini dibutuhkan ketika perangkat root berada di sebuah array RAID atau volume LVM." +msgid "" +"Embedding is not possible, but this is required when the root device is on a " +"RAID array or LVM volume." +msgstr "" +"Penempatan tidak memungkinkan, tetapi ini dibutuhkan ketika perangkat root " +"berada di sebuah array RAID atau volume LVM." #: util/i386/pc/grub-setup.c:421 -msgid "Embedding is not possible. GRUB can only be installed in this setup by using blocklists. However, blocklists are UNRELIABLE and its use is discouraged." -msgstr "Penempatan tidak memungkinkan. GRUB hanya dapat dipasang di konfigurasi ini dengan menggunakan blocklists. Akan tetapi, blocklists TIDAK DAPAT DIJAGAKAN dan penggunaan ini tidak disarankan." +msgid "" +"Embedding is not possible. GRUB can only be installed in this setup by " +"using blocklists. However, blocklists are UNRELIABLE and its use is " +"discouraged." +msgstr "" +"Penempatan tidak memungkinkan. GRUB hanya dapat dipasang di konfigurasi ini " +"dengan menggunakan blocklists. Akan tetapi, blocklists TIDAK DAPAT DIJAGAKAN " +"dan penggunaan ini tidak disarankan." #: util/i386/pc/grub-setup.c:425 msgid "If you really want blocklists, use --force." msgstr "Jika anda benar benar menginginkan blocklists, gunakan --force." -#: util/i386/pc/grub-setup.c:439 +#: util/i386/pc/grub-setup.c:441 #, c-format msgid "attempting to read the core image `%s' from GRUB" msgstr "mencoba untuk membaca image core `%s' dari GRUB" -#: util/i386/pc/grub-setup.c:440 +#: util/i386/pc/grub-setup.c:442 #, c-format msgid "attempting to read the core image `%s' from GRUB again" msgstr "mencoba untuk membaca image core `%s' dari GRUB lagi" -#: util/i386/pc/grub-setup.c:498 +#: util/i386/pc/grub-setup.c:500 #, c-format msgid "Cannot read `%s' correctly" msgstr "Tidak dapat membaca `%s' secara benar" -#: util/i386/pc/grub-setup.c:511 +#: util/i386/pc/grub-setup.c:513 msgid "No terminator in the core image" msgstr "Tidak ada pengakhir dalam image core" -#: util/i386/pc/grub-setup.c:522 +#: util/i386/pc/grub-setup.c:524 msgid "Failed to read the first sector of the core image" msgstr "Gagal untuk membaca sektor pertama dari core image" -#: util/i386/pc/grub-setup.c:528 +#: util/i386/pc/grub-setup.c:530 msgid "Failed to read the rest sectors of the core image" msgstr "Gagal untuk membaca sektor selanjutnya dari image core" -#: util/i386/pc/grub-setup.c:547 +#: util/i386/pc/grub-setup.c:549 #, c-format msgid "Cannot open `%s'" msgstr "Tidak dapat membuka `%s'" -#: util/i386/pc/grub-setup.c:589 +#: util/i386/pc/grub-setup.c:591 #, c-format msgid "" "Usage: grub-setup [OPTION]... DEVICE\n" @@ -225,36 +262,38 @@ msgstr "" " -m, --device-map=BERKAS gunakan BERKAS sebagai peta perangkat [baku=%s]\n" " -r, --root-device=DEV gunakan DEV sebagai perangkat root [baku=ditebak]\n" " -f, --force pasang walaupun masalah terdeteksi\n" -" -s, --skip-fs-probe jangan periksa untuk sistem berkas dalam PERANGKAT\n" +" -s, --skip-fs-probe jangan periksa untuk sistem berkas dalam " +"PERANGKAT\n" " -h, --help tampilkan pesan bantuan ini dan keluar\n" " -V, --version tampilkan informasi versi dan keluar\n" " -v, --verbose tampilkan informasi secara detail\n" "\n" "Laporkan bugs ke <%s>.\n" -#: util/i386/pc/grub-setup.c:719 +#: util/i386/pc/grub-setup.c:721 #, c-format msgid "No device is specified.\n" msgstr "Perangkat tidak dispesifikasikan.\n" -#: util/i386/pc/grub-setup.c:725 +#: util/i386/pc/grub-setup.c:727 #, c-format msgid "Unknown extra argument `%s'.\n" msgstr "Argumen ekstra `%s' tidak diketahui.\n" -#: util/i386/pc/grub-setup.c:742 +#: util/i386/pc/grub-setup.c:744 #, c-format msgid "Invalid device `%s'.\n" msgstr "Perangkat `%s' tidak valid.\n" -#: util/i386/pc/grub-setup.c:755 +#: util/i386/pc/grub-setup.c:757 #, c-format msgid "Invalid root device `%s'" msgstr "Perangkat root `%s' tidak valid" -#: util/i386/pc/grub-setup.c:768 +#: util/i386/pc/grub-setup.c:770 msgid "Cannot guess the root device. Specify the option ``--root-device''." -msgstr "Tidak dapat menebak perangkat root. Spesifikasikan pilihan ``--root-device''." +msgstr "" +"Tidak dapat menebak perangkat root. Spesifikasikan pilihan ``--root-device''." #: util/mkisofs/eltorito.c:96 #, c-format @@ -269,7 +308,9 @@ msgstr "Mohon periksa berkas berikut: %s.\n" #: util/mkisofs/eltorito.c:98 #, c-format msgid "This file must be removed before a bootable CD can be done.\n" -msgstr "Berkas ini mungkin telah terhapus sebelum sebuah CD bootable dapat dilakukan.\n" +msgstr "" +"Berkas ini mungkin telah terhapus sebelum sebuah CD bootable dapat " +"dilakukan.\n" #: util/mkisofs/eltorito.c:110 #, c-format @@ -360,7 +401,9 @@ msgstr "Error menulis ke boot image (%s)" #: util/mkisofs/joliet.c:359 util/mkisofs/write.c:981 #, c-format msgid "Unable to generate sane path tables - too many directories (%d)\n" -msgstr "Tidak dapat menghasilkan tabel jalur yang masuk akal - terlalu banyak direktori (%d)\n" +msgstr "" +"Tidak dapat menghasilkan tabel jalur yang masuk akal - terlalu banyak " +"direktori (%d)\n" #: util/mkisofs/joliet.c:398 util/mkisofs/write.c:1017 #, c-format @@ -392,6 +435,208 @@ msgstr "Fatal goof - tidak dapat menemukan lokasi direktori\n" msgid "Unexpected joliet directory length %d %d %s\n" msgstr "Panjang direktori joliet tidak terduga %d %d %s\n" +#: util/mkisofs/mkisofs.c:203 +msgid "Process all files (don't skip backup files)" +msgstr "" + +#: util/mkisofs/mkisofs.c:205 +#, fuzzy +msgid "Set Abstract filename" +msgstr "String nama berkas abstrak terlalu panjang\n" + +#: util/mkisofs/mkisofs.c:207 +msgid "Set Application ID" +msgstr "" + +#: util/mkisofs/mkisofs.c:209 +#, fuzzy +msgid "Set Bibliographic filename" +msgstr "String nama berkas bibliographic terlalu panjang\n" + +#: util/mkisofs/mkisofs.c:211 +#, fuzzy +msgid "Set Copyright filename" +msgstr "String nama berkas Hak Cipta terlalu panjang\n" + +#: util/mkisofs/mkisofs.c:213 +msgid "Set El Torito boot image name" +msgstr "" + +#: util/mkisofs/mkisofs.c:215 +#, fuzzy +msgid "Set El Torito boot catalog name" +msgstr "Error menulis ke katalog boot" + +#: util/mkisofs/mkisofs.c:217 +msgid "Patch Boot Info Table in El Torito boot image" +msgstr "" + +#: util/mkisofs/mkisofs.c:219 +msgid "Dummy option for backward compatibility" +msgstr "" + +#: util/mkisofs/mkisofs.c:221 +msgid "Enable floppy drive emulation for El Torito" +msgstr "" + +#: util/mkisofs/mkisofs.c:223 +msgid "Magic parameters from cdrecord" +msgstr "" + +#: util/mkisofs/mkisofs.c:225 +msgid "Omit trailing periods from filenames" +msgstr "" + +#: util/mkisofs/mkisofs.c:227 +#, fuzzy +msgid "Disable deep directory relocation" +msgstr "Fatal goof - tidak dapat menemukan lokasi direktori\n" + +#: util/mkisofs/mkisofs.c:229 +msgid "Follow symbolic links" +msgstr "" + +#: util/mkisofs/mkisofs.c:231 util/mkisofs/mkisofs.c:233 +msgid "Print option help" +msgstr "" + +#: util/mkisofs/mkisofs.c:235 +msgid "Print version information and exit" +msgstr "" + +#: util/mkisofs/mkisofs.c:237 +msgid "Hide ISO9660/RR file" +msgstr "" + +#: util/mkisofs/mkisofs.c:239 +msgid "Hide Joliet file" +msgstr "" + +#: util/mkisofs/mkisofs.c:241 +#, fuzzy +msgid "No longer supported" +msgstr "pilihan -i tidak lagi didukung.\n" + +#: util/mkisofs/mkisofs.c:243 +msgid "Generate Joliet directory information" +msgstr "" + +#: util/mkisofs/mkisofs.c:245 +msgid "Allow full 32 character filenames for iso9660 names" +msgstr "" + +#: util/mkisofs/mkisofs.c:247 +msgid "Allow iso9660 filenames to start with '.'" +msgstr "" + +#: util/mkisofs/mkisofs.c:249 +#, fuzzy +msgid "Re-direct messages to LOG_FILE" +msgstr "menredireksikan seluruh pesan ke %s\n" + +#: util/mkisofs/mkisofs.c:251 +msgid "Exclude file name" +msgstr "" + +#: util/mkisofs/mkisofs.c:253 +#, fuzzy +msgid "Set path to previous session to merge" +msgstr "Tidak dapat membuka sesi image sebelumnya %s\n" + +#: util/mkisofs/mkisofs.c:255 +msgid "Omit version number from iso9660 filename" +msgstr "" + +#: util/mkisofs/mkisofs.c:257 +msgid "Inhibit splitting symlink components" +msgstr "" + +#: util/mkisofs/mkisofs.c:259 +msgid "Inhibit splitting symlink fields" +msgstr "" + +#: util/mkisofs/mkisofs.c:261 +msgid "Set output file name" +msgstr "" + +#: util/mkisofs/mkisofs.c:263 +msgid "Set Volume preparer" +msgstr "" + +#: util/mkisofs/mkisofs.c:265 +msgid "Print estimated filesystem size and exit" +msgstr "" + +#: util/mkisofs/mkisofs.c:267 +msgid "Set Volume publisher" +msgstr "" + +#: util/mkisofs/mkisofs.c:269 +msgid "Run quietly" +msgstr "" + +#: util/mkisofs/mkisofs.c:271 +msgid "Generate rationalized Rock Ridge directory information" +msgstr "" + +#: util/mkisofs/mkisofs.c:273 +msgid "Generate Rock Ridge directory information" +msgstr "" + +#: util/mkisofs/mkisofs.c:275 +msgid "Split output into files of approx. 1GB size" +msgstr "" + +#: util/mkisofs/mkisofs.c:277 +msgid "Set System ID" +msgstr "" + +#: util/mkisofs/mkisofs.c:279 +msgid "" +"Generate translation tables for systems that don't understand long filenames" +msgstr "" + +#: util/mkisofs/mkisofs.c:281 +msgid "Verbose" +msgstr "" + +#: util/mkisofs/mkisofs.c:283 +msgid "Set Volume ID" +msgstr "" + +#: util/mkisofs/mkisofs.c:285 +msgid "Set Volume set ID" +msgstr "" + +#: util/mkisofs/mkisofs.c:287 +msgid "Set Volume set size" +msgstr "" + +#: util/mkisofs/mkisofs.c:289 +#, fuzzy +msgid "Set Volume set sequence number" +msgstr "Set urutan nomor volume terlalu besar\n" + +#: util/mkisofs/mkisofs.c:291 +msgid "Exclude file name (deprecated)" +msgstr "" + +#: util/mkisofs/mkisofs.c:297 +msgid "Override creation date" +msgstr "" + +#: util/mkisofs/mkisofs.c:299 +msgid "Override modification date" +msgstr "" + +#: util/mkisofs/mkisofs.c:301 +msgid "Override expiration date" +msgstr "" + +#: util/mkisofs/mkisofs.c:303 +msgid "Override effective date" +msgstr "" + #: util/mkisofs/mkisofs.c:373 #, c-format msgid "Using \"%s\"\n" @@ -509,12 +754,16 @@ msgstr "Peringatan: setrlimit" #: util/mkisofs/mkisofs.c:978 #, c-format msgid "Multisession usage bug: Must specify -C if -M is used.\n" -msgstr "Bug penggunaan multi sesi: Harus menspesifikasikan -C jika -M digunakan.\n" +msgstr "" +"Bug penggunaan multi sesi: Harus menspesifikasikan -C jika -M digunakan.\n" #: util/mkisofs/mkisofs.c:984 #, c-format -msgid "Warning: -C specified without -M: old session data will not be merged.\n" -msgstr "Peringatan: -C dispesifikasikan tanpa -M: data sesi lama tidak akan digabungkan.\n" +msgid "" +"Warning: -C specified without -M: old session data will not be merged.\n" +msgstr "" +"Peringatan: -C dispesifikasikan tanpa -M: data sesi lama tidak akan " +"digabungkan.\n" #: util/mkisofs/mkisofs.c:1023 #, c-format @@ -574,8 +823,13 @@ msgstr "**Atribut versi RR buruk" #: util/mkisofs/multi.c:546 #, c-format -msgid "Warning: Neither Rock Ridge (-R) nor TRANS.TBL (-T) name translations were found on previous session. ISO (8.3) file names have been used instead.\n" -msgstr "Peringatan: Bukan Rock Ridge (-R) ataupun TRANS.TBL (-T) nama terjemahan ditemukan dalam sesi sebelumnya. ISO (8.3) nama berkas yang telah digunakan.\n" +msgid "" +"Warning: Neither Rock Ridge (-R) nor TRANS.TBL (-T) name translations were " +"found on previous session. ISO (8.3) file names have been used instead.\n" +msgstr "" +"Peringatan: Bukan Rock Ridge (-R) ataupun TRANS.TBL (-T) nama terjemahan " +"ditemukan dalam sesi sebelumnya. ISO (8.3) nama berkas yang telah " +"digunakan.\n" #: util/mkisofs/multi.c:764 #, c-format @@ -593,12 +847,15 @@ msgstr "Parameter cdwrite salah format\n" #: util/mkisofs/rock.c:309 #, c-format msgid "symbolic link ``%s'' to long for one SL System Use Field, splitting" -msgstr "link simbolik ``%s'' terlalu panjang untuk satu SL Sistem Menggunakan Field, dipisahkan" +msgstr "" +"link simbolik ``%s'' terlalu panjang untuk satu SL Sistem Menggunakan " +"Field, dipisahkan" #: util/mkisofs/rock.c:517 #, c-format msgid "Unable to insert transparent compressed file - name conflict\n" -msgstr "Tidak dapat memasukan berkas terkompress secara transparan - konflik nama\n" +msgstr "" +"Tidak dapat memasukan berkas terkompress secara transparan - konflik nama\n" #: util/mkisofs/rock.c:591 msgid "Extension record too long\n" @@ -674,7 +931,8 @@ msgstr "Tidak ada atau tidak dapat diakses: %s\n" #: util/mkisofs/tree.c:997 util/mkisofs/tree.c:1103 #, c-format msgid "Unable to stat file %s - ignoring and continuing.\n" -msgstr "Tidak dapat memperoleh statistik berkas %s - mengabaikan dan melanjutkan.\n" +msgstr "" +"Tidak dapat memperoleh statistik berkas %s - mengabaikan dan melanjutkan.\n" #: util/mkisofs/tree.c:1003 #, c-format @@ -791,8 +1049,11 @@ msgstr "Total ekstensi yang sebenarnya tertulis = %llu\n" #: util/mkisofs/write.c:1154 #, c-format -msgid "Number of extents written different than what was predicted. Please fix.\n" -msgstr "Jumlah dari ekstensi yang ditulis berbeda dari apa yang direncanakan. Mohon betulkan.\n" +msgid "" +"Number of extents written different than what was predicted. Please fix.\n" +msgstr "" +"Jumlah dari ekstensi yang ditulis berbeda dari apa yang direncanakan. Mohon " +"betulkan.\n" #: util/mkisofs/write.c:1155 #, c-format @@ -819,6 +1080,13 @@ msgstr "Total bytes direktori: %d\n" msgid "Path table size(bytes): %d\n" msgstr "Ukuran tabel jalur(bytes): %d\n" +#: normal/menu_text.c:97 +#, c-format +msgid "" +"\n" +" Use the %C and %C keys to select which entry is highlighted.\n" +msgstr "" + #: util/grub.d/10_kfreebsd.in:40 msgid "%s, with kFreeBSD %s" msgstr "%s, dengan kFreeBSD %s" @@ -858,7 +1126,8 @@ msgstr "%s, dengan Linux %s" #~ msgid "the core image will be embedded at sector 0x%llx" #~ msgstr "core image akan di ditempatkan di sektor 0x%llx" -#~ msgid "succeeded in opening the core image but the size is different (%d != %d)" +#~ msgid "" +#~ "succeeded in opening the core image but the size is different (%d != %d)" #~ msgstr "sukses dalam membuka image core tetapi ukurannya berbeda (%d != %d)" #~ msgid "succeeded in opening the core image but cannot read %d bytes" diff --git a/po/zh_CN.po b/po/zh_CN.po index 9816afbad..8858f0a6a 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -8,10 +8,11 @@ msgid "" msgstr "" "Project-Id-Version: grub 1.97+20091122\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-11-22 11:48+0100\n" +"POT-Creation-Date: 2009-11-25 23:35+0100\n" "PO-Revision-Date: 2009-11-23 18:36+0800\n" "Last-Translator: Aron Xu \n" -"Language-Team: Chinese (simplified) \n" +"Language-Team: Chinese (simplified) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -42,7 +43,7 @@ msgstr "diskboot.img 的大小必须为 %u 字节" msgid "Core image is too big (%p > %p)\n" msgstr "核心映像太大(%p > %p)\n" -#: util/i386/pc/grub-mkimage.c:321 util/i386/pc/grub-setup.c:587 +#: util/i386/pc/grub-mkimage.c:321 util/i386/pc/grub-setup.c:589 #, c-format msgid "Try ``%s --help'' for more information.\n" msgstr "请尝试运行 ``%s --help'' 以获得更多信息。\n" @@ -105,7 +106,11 @@ msgstr "" #: util/i386/pc/grub-setup.c:265 #, c-format -msgid "%s appears to contain a %s filesystem which isn't known to reserve space for DOS-style boot. Installing GRUB there could result in FILESYSTEM DESTRUCTION if valuable data is overwritten by grub-setup (--skip-fs-probe disables this check, use at your own risk)" +msgid "" +"%s appears to contain a %s filesystem which isn't known to reserve space for " +"DOS-style boot. Installing GRUB there could result in FILESYSTEM " +"DESTRUCTION if valuable data is overwritten by grub-setup (--skip-fs-probe " +"disables this check, use at your own risk)" msgstr "" #: util/i386/pc/grub-setup.c:314 @@ -113,19 +118,26 @@ msgid "No DOS-style partitions found" msgstr "未找到 DOS 类型分区" #: util/i386/pc/grub-setup.c:330 util/i386/pc/grub-setup.c:355 -msgid "Attempting to install GRUB to a partitionless disk. This is a BAD idea." +msgid "" +"Attempting to install GRUB to a partitionless disk. This is a BAD idea." msgstr "正在试图安装 GRUB 到未分区的磁盘。 这是一个坏主意。" #: util/i386/pc/grub-setup.c:336 -msgid "Attempting to install GRUB to a partition instead of the MBR. This is a BAD idea." +msgid "" +"Attempting to install GRUB to a partition instead of the MBR. This is a BAD " +"idea." msgstr "正在试图安装 GRUB 到分区而非 MBR。 这是一个坏主意。" #: util/i386/pc/grub-setup.c:365 -msgid "This msdos-style partition label has no post-MBR gap; embedding won't be possible!" +msgid "" +"This msdos-style partition label has no post-MBR gap; embedding won't be " +"possible!" msgstr "" #: util/i386/pc/grub-setup.c:367 -msgid "This GPT partition label has no BIOS Boot Partition; embedding won't be possible!" +msgid "" +"This GPT partition label has no BIOS Boot Partition; embedding won't be " +"possible!" msgstr "" #: util/i386/pc/grub-setup.c:374 @@ -137,50 +149,55 @@ msgid "Your embedding area is unusually small. core.img won't fit in it." msgstr "您的嵌入式环境超乎寻常的小。core.img 无法适用于此处。" #: util/i386/pc/grub-setup.c:418 -msgid "Embedding is not possible, but this is required when the root device is on a RAID array or LVM volume." +msgid "" +"Embedding is not possible, but this is required when the root device is on a " +"RAID array or LVM volume." msgstr "" #: util/i386/pc/grub-setup.c:421 -msgid "Embedding is not possible. GRUB can only be installed in this setup by using blocklists. However, blocklists are UNRELIABLE and its use is discouraged." +msgid "" +"Embedding is not possible. GRUB can only be installed in this setup by " +"using blocklists. However, blocklists are UNRELIABLE and its use is " +"discouraged." msgstr "" #: util/i386/pc/grub-setup.c:425 msgid "If you really want blocklists, use --force." msgstr "" -#: util/i386/pc/grub-setup.c:439 +#: util/i386/pc/grub-setup.c:441 #, c-format msgid "attempting to read the core image `%s' from GRUB" msgstr "正在尝试从 GRUB 读取核心映像 `%s'" -#: util/i386/pc/grub-setup.c:440 +#: util/i386/pc/grub-setup.c:442 #, c-format msgid "attempting to read the core image `%s' from GRUB again" msgstr "正在再次尝试从 GRUB 读取核心映像 `%s'" -#: util/i386/pc/grub-setup.c:498 +#: util/i386/pc/grub-setup.c:500 #, c-format msgid "Cannot read `%s' correctly" msgstr "无法正确读取 `%s'" -#: util/i386/pc/grub-setup.c:511 +#: util/i386/pc/grub-setup.c:513 msgid "No terminator in the core image" msgstr "核心映像中没有终止符" -#: util/i386/pc/grub-setup.c:522 +#: util/i386/pc/grub-setup.c:524 msgid "Failed to read the first sector of the core image" msgstr "" -#: util/i386/pc/grub-setup.c:528 +#: util/i386/pc/grub-setup.c:530 msgid "Failed to read the rest sectors of the core image" msgstr "" -#: util/i386/pc/grub-setup.c:547 +#: util/i386/pc/grub-setup.c:549 #, c-format msgid "Cannot open `%s'" msgstr "无法打开 `%s'" -#: util/i386/pc/grub-setup.c:589 +#: util/i386/pc/grub-setup.c:591 #, c-format msgid "" "Usage: grub-setup [OPTION]... DEVICE\n" @@ -202,27 +219,27 @@ msgid "" "Report bugs to <%s>.\n" msgstr "" -#: util/i386/pc/grub-setup.c:719 +#: util/i386/pc/grub-setup.c:721 #, c-format msgid "No device is specified.\n" msgstr "没有指定设备。\n" -#: util/i386/pc/grub-setup.c:725 +#: util/i386/pc/grub-setup.c:727 #, c-format msgid "Unknown extra argument `%s'.\n" msgstr "未知的额外参数 `%s'。\n" -#: util/i386/pc/grub-setup.c:742 +#: util/i386/pc/grub-setup.c:744 #, c-format msgid "Invalid device `%s'.\n" msgstr "无效的设备 `%s'。\n" -#: util/i386/pc/grub-setup.c:755 +#: util/i386/pc/grub-setup.c:757 #, c-format msgid "Invalid root device `%s'" msgstr "无效的根设备 `%s'" -#: util/i386/pc/grub-setup.c:768 +#: util/i386/pc/grub-setup.c:770 msgid "Cannot guess the root device. Specify the option ``--root-device''." msgstr "无法猜测根设备。请使用 ``--root-device'' 选项指定。" @@ -362,6 +379,201 @@ msgstr "" msgid "Unexpected joliet directory length %d %d %s\n" msgstr "" +#: util/mkisofs/mkisofs.c:203 +msgid "Process all files (don't skip backup files)" +msgstr "" + +#: util/mkisofs/mkisofs.c:205 +msgid "Set Abstract filename" +msgstr "" + +#: util/mkisofs/mkisofs.c:207 +msgid "Set Application ID" +msgstr "" + +#: util/mkisofs/mkisofs.c:209 +msgid "Set Bibliographic filename" +msgstr "" + +#: util/mkisofs/mkisofs.c:211 +msgid "Set Copyright filename" +msgstr "" + +#: util/mkisofs/mkisofs.c:213 +msgid "Set El Torito boot image name" +msgstr "" + +#: util/mkisofs/mkisofs.c:215 +msgid "Set El Torito boot catalog name" +msgstr "" + +#: util/mkisofs/mkisofs.c:217 +msgid "Patch Boot Info Table in El Torito boot image" +msgstr "" + +#: util/mkisofs/mkisofs.c:219 +msgid "Dummy option for backward compatibility" +msgstr "" + +#: util/mkisofs/mkisofs.c:221 +msgid "Enable floppy drive emulation for El Torito" +msgstr "" + +#: util/mkisofs/mkisofs.c:223 +msgid "Magic parameters from cdrecord" +msgstr "" + +#: util/mkisofs/mkisofs.c:225 +msgid "Omit trailing periods from filenames" +msgstr "" + +#: util/mkisofs/mkisofs.c:227 +msgid "Disable deep directory relocation" +msgstr "" + +#: util/mkisofs/mkisofs.c:229 +msgid "Follow symbolic links" +msgstr "" + +#: util/mkisofs/mkisofs.c:231 util/mkisofs/mkisofs.c:233 +msgid "Print option help" +msgstr "" + +#: util/mkisofs/mkisofs.c:235 +msgid "Print version information and exit" +msgstr "" + +#: util/mkisofs/mkisofs.c:237 +msgid "Hide ISO9660/RR file" +msgstr "" + +#: util/mkisofs/mkisofs.c:239 +msgid "Hide Joliet file" +msgstr "" + +#: util/mkisofs/mkisofs.c:241 +#, fuzzy +msgid "No longer supported" +msgstr "-i 选项已不再被支持。\n" + +#: util/mkisofs/mkisofs.c:243 +msgid "Generate Joliet directory information" +msgstr "" + +#: util/mkisofs/mkisofs.c:245 +msgid "Allow full 32 character filenames for iso9660 names" +msgstr "" + +#: util/mkisofs/mkisofs.c:247 +msgid "Allow iso9660 filenames to start with '.'" +msgstr "" + +#: util/mkisofs/mkisofs.c:249 +msgid "Re-direct messages to LOG_FILE" +msgstr "" + +#: util/mkisofs/mkisofs.c:251 +msgid "Exclude file name" +msgstr "" + +#: util/mkisofs/mkisofs.c:253 +#, fuzzy +msgid "Set path to previous session to merge" +msgstr "无法打开上一会话使用的映像 %s\n" + +#: util/mkisofs/mkisofs.c:255 +msgid "Omit version number from iso9660 filename" +msgstr "" + +#: util/mkisofs/mkisofs.c:257 +msgid "Inhibit splitting symlink components" +msgstr "" + +#: util/mkisofs/mkisofs.c:259 +msgid "Inhibit splitting symlink fields" +msgstr "" + +#: util/mkisofs/mkisofs.c:261 +msgid "Set output file name" +msgstr "" + +#: util/mkisofs/mkisofs.c:263 +msgid "Set Volume preparer" +msgstr "" + +#: util/mkisofs/mkisofs.c:265 +msgid "Print estimated filesystem size and exit" +msgstr "" + +#: util/mkisofs/mkisofs.c:267 +msgid "Set Volume publisher" +msgstr "" + +#: util/mkisofs/mkisofs.c:269 +msgid "Run quietly" +msgstr "" + +#: util/mkisofs/mkisofs.c:271 +msgid "Generate rationalized Rock Ridge directory information" +msgstr "" + +#: util/mkisofs/mkisofs.c:273 +msgid "Generate Rock Ridge directory information" +msgstr "" + +#: util/mkisofs/mkisofs.c:275 +msgid "Split output into files of approx. 1GB size" +msgstr "" + +#: util/mkisofs/mkisofs.c:277 +msgid "Set System ID" +msgstr "" + +#: util/mkisofs/mkisofs.c:279 +msgid "" +"Generate translation tables for systems that don't understand long filenames" +msgstr "" + +#: util/mkisofs/mkisofs.c:281 +msgid "Verbose" +msgstr "" + +#: util/mkisofs/mkisofs.c:283 +msgid "Set Volume ID" +msgstr "" + +#: util/mkisofs/mkisofs.c:285 +msgid "Set Volume set ID" +msgstr "" + +#: util/mkisofs/mkisofs.c:287 +msgid "Set Volume set size" +msgstr "" + +#: util/mkisofs/mkisofs.c:289 +msgid "Set Volume set sequence number" +msgstr "" + +#: util/mkisofs/mkisofs.c:291 +msgid "Exclude file name (deprecated)" +msgstr "" + +#: util/mkisofs/mkisofs.c:297 +msgid "Override creation date" +msgstr "" + +#: util/mkisofs/mkisofs.c:299 +msgid "Override modification date" +msgstr "" + +#: util/mkisofs/mkisofs.c:301 +msgid "Override expiration date" +msgstr "" + +#: util/mkisofs/mkisofs.c:303 +msgid "Override effective date" +msgstr "" + #: util/mkisofs/mkisofs.c:373 #, c-format msgid "Using \"%s\"\n" @@ -483,7 +695,8 @@ msgstr "" #: util/mkisofs/mkisofs.c:984 #, c-format -msgid "Warning: -C specified without -M: old session data will not be merged.\n" +msgid "" +"Warning: -C specified without -M: old session data will not be merged.\n" msgstr "" #: util/mkisofs/mkisofs.c:1023 @@ -544,7 +757,9 @@ msgstr "" #: util/mkisofs/multi.c:546 #, c-format -msgid "Warning: Neither Rock Ridge (-R) nor TRANS.TBL (-T) name translations were found on previous session. ISO (8.3) file names have been used instead.\n" +msgid "" +"Warning: Neither Rock Ridge (-R) nor TRANS.TBL (-T) name translations were " +"found on previous session. ISO (8.3) file names have been used instead.\n" msgstr "" #: util/mkisofs/multi.c:764 @@ -761,7 +976,8 @@ msgstr "" #: util/mkisofs/write.c:1154 #, c-format -msgid "Number of extents written different than what was predicted. Please fix.\n" +msgid "" +"Number of extents written different than what was predicted. Please fix.\n" msgstr "" #: util/mkisofs/write.c:1155 @@ -789,6 +1005,13 @@ msgstr "" msgid "Path table size(bytes): %d\n" msgstr "" +#: normal/menu_text.c:97 +#, c-format +msgid "" +"\n" +" Use the %C and %C keys to select which entry is highlighted.\n" +msgstr "" + #: util/grub.d/10_kfreebsd.in:40 msgid "%s, with kFreeBSD %s" msgstr "" From 928506da8b405370c54ad41aab44e329af143325 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 26 Nov 2009 16:50:56 +0100 Subject: [PATCH 23/52] Fix wrong segment selector --- lib/i386/relocator_asm.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/i386/relocator_asm.S b/lib/i386/relocator_asm.S index 343991d3d..bd25143e8 100644 --- a/lib/i386/relocator_asm.S +++ b/lib/i386/relocator_asm.S @@ -208,7 +208,7 @@ RELOCATOR_VARIABLE (edx) .byte 0xea RELOCATOR_VARIABLE (eip) .long 0 - .word 0x08 + .word CODE_SEGMENT /* GDT. Copied from loader/i386/linux.c. */ .p2align 4 From bd7fbf102065df36e6eea1d54edd71eb1e0767e3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 26 Nov 2009 16:52:10 +0100 Subject: [PATCH 24/52] Prevent relocator of overwriting itself --- lib/relocator.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/lib/relocator.c b/lib/relocator.c index bebf7ada9..68260b197 100644 --- a/lib/relocator.c +++ b/lib/relocator.c @@ -16,15 +16,17 @@ * along with GRUB. If not, see . */ +#define MAX_OVERHEAD ((RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) \ + + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN) \ + + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) \ + + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN)) + void * PREFIX (alloc) (grub_size_t size) { char *playground; - playground = grub_malloc ((RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) - + size - + (RELOCATOR_SIZEOF (backward) + - RELOCATOR_ALIGN)); + playground = grub_malloc (size + MAX_OVERHEAD); if (!playground) return 0; @@ -40,10 +42,7 @@ PREFIX (realloc) (void *relocator, grub_size_t size) playground = (char *) relocator - RELOCATOR_SIZEOF (forward); - playground = grub_realloc (playground, - (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) - + size - + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN)); + playground = grub_realloc (playground, size + MAX_OVERHEAD); if (!playground) return 0; @@ -73,6 +72,25 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, "Relocator: source: %p, destination: 0x%x, size: 0x%x\n", relocator, dest, size); + /* Very unlikely condition: Relocator may risk overwrite itself. + Just move it a bit up. */ + if ((grub_uint8_t *) UINT_TO_PTR (dest) - (grub_uint8_t *) relocator + < RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN + && (grub_uint8_t *) UINT_TO_PTR (dest) - (grub_uint8_t *) relocator + > -(RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN)) + { + void *relocator_new = ((grub_uint8_t *) relocator) + + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) + + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN); + grub_dprintf ("relocator", "Overwrite condition detected moving " + "relocator from %p to %p\n", relocator, relocator_new); + grub_memmove (relocator_new, relocator, + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) + + size + + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN)); + relocator = relocator_new; + } + if (UINT_TO_PTR (dest) >= relocator) { int overhead; From d4e56ea7877ef15eac42f174d49fddbc4117e462 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 26 Nov 2009 22:19:37 +0100 Subject: [PATCH 25/52] Fix warning on some build systems --- lib/relocator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/relocator.c b/lib/relocator.c index 68260b197..31695ff62 100644 --- a/lib/relocator.c +++ b/lib/relocator.c @@ -75,9 +75,9 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, /* Very unlikely condition: Relocator may risk overwrite itself. Just move it a bit up. */ if ((grub_uint8_t *) UINT_TO_PTR (dest) - (grub_uint8_t *) relocator - < RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN + < (signed) (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN) && (grub_uint8_t *) UINT_TO_PTR (dest) - (grub_uint8_t *) relocator - > -(RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN)) + > - (signed) (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN)) { void *relocator_new = ((grub_uint8_t *) relocator) + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) From f93415cfee91ca1e7a68409092653a95c05b2b48 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 26 Nov 2009 22:20:06 +0100 Subject: [PATCH 26/52] Improved cache handling in mips --- lib/mips/relocator_asm.S | 46 +++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/lib/mips/relocator_asm.S b/lib/mips/relocator_asm.S index f9cdf1470..9daf0d32f 100644 --- a/lib/mips/relocator_asm.S +++ b/lib/mips/relocator_asm.S @@ -30,16 +30,28 @@ copycont1: addiu $8, $8, 0x1 addiu $9, $9, 0x1 addiu $10, $10, 0xffff - subu $11,$10,$0 - bne $11, $0, copycont1 + bne $10, $0, copycont1 -cachecont1: + move $9, $12 + move $10, $13 +cachecont1a: cache 1,0($12) + addiu $12, $12, 0x1 + addiu $13, $13, 0xffff + bne $13, $0, cachecont1a + + sync + + move $12, $9 + move $13, $10 +cachecont1b: cache 0,0($12) addiu $12, $12, 0x1 addiu $13, $13, 0xffff - subu $11,$13,$0 - bne $11, $0, cachecont1 + bne $13, $0, cachecont1b + + sync + VARIABLE (grub_relocator32_forward_end) VARIABLE (grub_relocator32_backward_start) @@ -54,18 +66,28 @@ VARIABLE (grub_relocator32_backward_start) copycont2: lb $11,0($8) sb $11,0($9) - cache 1, 0($9) - cache 0, 0($9) addiu $8, $8, 0xffff addiu $9, $9, 0xffff addiu $10, 0xffff - subu $11,$10,$0 - bne $11, $0, copycont2 -cachecont2: + bne $10, $0, copycont2 + + move $9, $12 + move $10, $13 +cachecont2a: cache 1,0($12) + addiu $12, $12, 0x1 + addiu $13, $13, 0xffff + bne $13, $0, cachecont2a + + sync + + move $12, $9 + move $13, $10 +cachecont2b: cache 0,0($12) addiu $12, $12, 0x1 addiu $13, $13, 0xffff - subu $11,$13,$0 - bne $11, $0, cachecont2 + bne $13, $0, cachecont2b + + sync VARIABLE (grub_relocator32_backward_end) From bbd46b09667317cab3393c07c2fac5b6c86f296b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 26 Nov 2009 22:51:00 +0100 Subject: [PATCH 27/52] Fixes for backwards relocator --- lib/i386/relocator_asm.S | 4 +--- lib/relocator.c | 13 +++++++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/i386/relocator_asm.S b/lib/i386/relocator_asm.S index bd25143e8..c1be85c2b 100644 --- a/lib/i386/relocator_asm.S +++ b/lib/i386/relocator_asm.S @@ -27,13 +27,11 @@ #ifdef __x86_64__ #define RAX %rax #define RCX %rcx -#define RDX %rdx #define RDI %rdi #define RSI %rdi #else #define RAX %eax #define RCX %ecx -#define RDX %edx #define RDI %edi #define RSI %esi #endif @@ -97,7 +95,7 @@ RELOCATOR_VARIABLE(size) #ifdef BACKWARD add RCX, RSI - add RDX, RDI + add RCX, RDI #endif #ifndef BACKWARD diff --git a/lib/relocator.c b/lib/relocator.c index 31695ff62..176379eb7 100644 --- a/lib/relocator.c +++ b/lib/relocator.c @@ -20,6 +20,7 @@ + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN) \ + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) \ + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN)) +#define PRE_REGION_SIZE (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN) void * PREFIX (alloc) (grub_size_t size) @@ -32,7 +33,7 @@ PREFIX (alloc) (grub_size_t size) *(grub_size_t *) playground = size; - return playground + RELOCATOR_SIZEOF (forward); + return playground + PRE_REGION_SIZE; } void * @@ -40,7 +41,7 @@ PREFIX (realloc) (void *relocator, grub_size_t size) { char *playground; - playground = (char *) relocator - RELOCATOR_SIZEOF (forward); + playground = (char *) relocator - PRE_REGION_SIZE; playground = grub_realloc (playground, size + MAX_OVERHEAD); if (!playground) @@ -48,14 +49,14 @@ PREFIX (realloc) (void *relocator, grub_size_t size) *(grub_size_t *) playground = size; - return playground + RELOCATOR_SIZEOF (forward); + return playground + PRE_REGION_SIZE; } void PREFIX(free) (void *relocator) { if (relocator) - grub_free ((char *) relocator - RELOCATOR_SIZEOF (forward)); + grub_free ((char *) relocator - PRE_REGION_SIZE); } grub_err_t @@ -65,7 +66,7 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, grub_size_t size; char *playground; - playground = (char *) relocator - RELOCATOR_SIZEOF (forward); + playground = (char *) relocator - PRE_REGION_SIZE; size = *(grub_size_t *) playground; grub_dprintf ("relocator", @@ -94,7 +95,7 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, if (UINT_TO_PTR (dest) >= relocator) { int overhead; - overhead = + overhead = dest - ALIGN_UP (dest - RELOCATOR_SIZEOF (backward) - RELOCATOR_ALIGN, RELOCATOR_ALIGN); grub_dprintf ("relocator", From c442639fc0411934c77f3f31e053ea626c357b32 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 27 Nov 2009 09:41:24 +0100 Subject: [PATCH 28/52] Add support for realloc (NULL, size) in relocators --- lib/relocator.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/relocator.c b/lib/relocator.c index 176379eb7..d4bfebc8e 100644 --- a/lib/relocator.c +++ b/lib/relocator.c @@ -41,6 +41,9 @@ PREFIX (realloc) (void *relocator, grub_size_t size) { char *playground; + if (!relocator) + return PREFIX (alloc) (size); + playground = (char *) relocator - PRE_REGION_SIZE; playground = grub_realloc (playground, size + MAX_OVERHEAD); From 159194989d76d4df4b41fd3517e9fe717597c9ba Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 27 Nov 2009 09:42:50 +0100 Subject: [PATCH 29/52] Ported xnu to relocator framework --- conf/i386-efi.rmk | 2 +- conf/i386-pc.rmk | 2 +- conf/x86_64-efi.rmk | 2 +- include/grub/i386/xnu.h | 5 +- include/grub/xnu.h | 4 +- loader/i386/xnu.c | 53 +++++----- loader/i386/xnu_helper.S | 211 --------------------------------------- loader/xnu.c | 41 ++++---- loader/xnu_resume.c | 17 +--- 9 files changed, 53 insertions(+), 284 deletions(-) delete mode 100644 loader/i386/xnu_helper.S diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index 80c2978da..f90ee5dc5 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -155,7 +155,7 @@ efi_fb_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += xnu.mod xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c\ - loader/macho.c loader/xnu.c loader/i386/xnu_helper.S + loader/macho.c loader/xnu.c xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 2b0894eae..672204725 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -188,7 +188,7 @@ linux_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += xnu.mod xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/pc/xnu.c\ - loader/macho.c loader/xnu.c loader/i386/xnu_helper.S + loader/macho.c loader/xnu.c xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk index 3b7ac34fa..726bf23fa 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -161,7 +161,7 @@ efi_fb_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += xnu.mod xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c\ - loader/macho.c loader/xnu.c loader/i386/xnu_helper.S + loader/macho.c loader/xnu.c xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/include/grub/i386/xnu.h b/include/grub/i386/xnu.h index 68674e605..306dc7b65 100644 --- a/include/grub/i386/xnu.h +++ b/include/grub/i386/xnu.h @@ -20,6 +20,9 @@ #define GRUB_CPU_XNU_H 1 #include +#include + +#define XNU_RELOCATOR(x) (grub_relocator32_ ## x) #define GRUB_XNU_PAGESIZE 4096 typedef grub_uint32_t grub_xnu_ptr_t; @@ -75,6 +78,4 @@ grub_err_t grub_xnu_boot (void); grub_err_t grub_cpu_xnu_fill_devicetree (void); grub_err_t grub_xnu_set_video (struct grub_xnu_boot_params *bootparams_relloc); extern grub_uint32_t grub_xnu_heap_will_be_at; -extern grub_uint8_t grub_xnu_launcher_start[]; -extern grub_uint8_t grub_xnu_launcher_end[]; #endif diff --git a/include/grub/xnu.h b/include/grub/xnu.h index c3902e670..cf778cf6b 100644 --- a/include/grub/xnu.h +++ b/include/grub/xnu.h @@ -92,6 +92,7 @@ struct grub_xnu_devtree_key *grub_xnu_create_value (struct grub_xnu_devtree_key void grub_xnu_lock (void); void grub_xnu_unlock (void); grub_err_t grub_xnu_resume (char *imagename); +grub_err_t grub_xnu_boot_resume (void); struct grub_xnu_devtree_key *grub_xnu_find_key (struct grub_xnu_devtree_key *parent, char *name); grub_err_t grub_xnu_align_heap (int align); @@ -100,8 +101,7 @@ grub_err_t grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired, grub_err_t grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired, int maxrecursion); void *grub_xnu_heap_malloc (int size); -extern grub_uint32_t grub_xnu_heap_real_start; extern grub_size_t grub_xnu_heap_size; -extern char *grub_xnu_heap_start; +extern void *grub_xnu_heap_start; extern struct grub_video_bitmap *grub_xnu_bitmap; #endif diff --git a/loader/i386/xnu.c b/loader/i386/xnu.c index 275b50dbc..6a3535950 100644 --- a/loader/i386/xnu.c +++ b/loader/i386/xnu.c @@ -30,6 +30,8 @@ #include char grub_xnu_cmdline[1024]; +grub_uint32_t grub_xnu_heap_will_be_at; +grub_uint32_t grub_xnu_entry_point, grub_xnu_arg1, grub_xnu_stack; /* Aliases set for some tables. */ struct tbl_alias @@ -44,21 +46,6 @@ struct tbl_alias table_aliases[] = {GRUB_EFI_ACPI_TABLE_GUID, "ACPI"}, }; -/* The following function is used to be able to debug xnu loader - with grub-emu. */ -#ifdef GRUB_UTIL -static grub_err_t -grub_xnu_launch (void) -{ - grub_printf ("Fake launch %x:%p:%p", grub_xnu_entry_point, grub_xnu_arg1, - grub_xnu_stack); - grub_getkey (); - return 0; -} -#else -static void (*grub_xnu_launch) (void) = 0; -#endif - static int utf16_strlen (grub_uint16_t *in) { @@ -417,6 +404,19 @@ grub_cpu_xnu_fill_devicetree (void) return GRUB_ERR_NONE; } +grub_err_t +grub_xnu_boot_resume (void) +{ + struct grub_relocator32_state state; + + state.esp = grub_xnu_stack; + state.eip = grub_xnu_entry_point; + state.eax = grub_xnu_arg1; + + return grub_relocator32_boot (grub_xnu_heap_start, grub_xnu_heap_will_be_at, + state); +} + /* Boot xnu. */ grub_err_t grub_xnu_boot (void) @@ -434,6 +434,7 @@ grub_xnu_boot (void) void *devtree; grub_size_t devtreelen; int i; + struct grub_relocator32_state state; /* Page-align to avoid following parts to be inadvertently freed. */ err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE); @@ -501,7 +502,8 @@ grub_xnu_boot (void) grub_memcpy (bootparams_relloc->cmdline, grub_xnu_cmdline, sizeof (bootparams_relloc->cmdline)); - bootparams_relloc->devtree = ((char *) devtree - grub_xnu_heap_start) + bootparams_relloc->devtree + = ((grub_uint8_t *) devtree - (grub_uint8_t *) grub_xnu_heap_start) + grub_xnu_heap_will_be_at; bootparams_relloc->devtreelen = devtreelen; @@ -529,12 +531,7 @@ grub_xnu_boot (void) grub_xnu_stack = bootparams_relloc->heap_start + bootparams_relloc->heap_size + GRUB_XNU_PAGESIZE; grub_xnu_arg1 = bootparams_relloc_off + grub_xnu_heap_will_be_at; -#ifndef GRUB_UTIL - grub_xnu_launch = (void (*) (void)) - (grub_xnu_heap_start + grub_xnu_heap_size); -#endif grub_dprintf ("xnu", "eip=%x\n", grub_xnu_entry_point); - grub_dprintf ("xnu", "launch=%p\n", grub_xnu_launch); const char *debug = grub_env_get ("debug"); @@ -560,16 +557,12 @@ grub_xnu_boot (void) bootparams_relloc->lfb_base = 0; } - grub_memcpy (grub_xnu_heap_start + grub_xnu_heap_size, - grub_xnu_launcher_start, - grub_xnu_launcher_end - grub_xnu_launcher_start); - - if (! grub_autoefi_finish_boot_services ()) return grub_error (GRUB_ERR_IO, "can't exit boot services"); - grub_xnu_launch (); - - /* Never reaches here. */ - return 0; + state.eip = grub_xnu_entry_point; + state.eax = grub_xnu_arg1; + state.esp = grub_xnu_stack; + return grub_relocator32_boot (grub_xnu_heap_start, grub_xnu_heap_will_be_at, + state); } diff --git a/loader/i386/xnu_helper.S b/loader/i386/xnu_helper.S deleted file mode 100644 index 4250c58ad..000000000 --- a/loader/i386/xnu_helper.S +++ /dev/null @@ -1,211 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 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 . - */ - -#include - - - .p2align 4 /* force 16-byte alignment */ - -VARIABLE(grub_xnu_launcher_start) -base: - cli - -#ifndef __x86_64__ - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_xnu_heap_will_be_at) - .long 0 - mov %eax, %edi - - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_xnu_heap_start) - .long 0 - mov %eax, %esi - - /* mov imm32, %ecx */ - .byte 0xb9 -VARIABLE(grub_xnu_heap_size) - .long 0 - mov %edi, %eax - add %ecx, %eax - /* %rax now contains our starting position after relocation. */ - /* One more page to copy: ourselves. */ - add $0x403, %ecx - shr $2, %ecx - - /* Forward copy. */ - cld - rep - movsl - - mov %eax, %esi - add $(cont0-base), %eax - jmp *%eax -cont0: -#else - xorq %rax, %rax - - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_xnu_heap_will_be_at) - .long 0 - mov %rax, %rdi - - /* mov imm32, %rax */ - .byte 0x48 - .byte 0xb8 -VARIABLE(grub_xnu_heap_start) - .long 0 - .long 0 - mov %rax, %rsi - - /* mov imm32, %rcx */ - .byte 0x48 - .byte 0xb9 -VARIABLE(grub_xnu_heap_size) - .long 0 - .long 0 - mov %rdi, %rax - add %rcx, %rax - /* %rax now contains our starting position after relocation. */ - /* One more page to copy: ourselves. */ - add $0x403, %rcx - shr $2, %rcx - - /* Forward copy. */ - cld - rep - movsl - - mov %rax, %rsi -#ifdef APPLE_CC - add $(cont0-base), %eax -#else - add $(cont0-base), %rax -#endif - jmp *%rax - -cont0: -#ifdef APPLE_CC - lea (cont1 - base) (%esi, 1), %eax - mov %eax, (jump_vector - base) (%esi, 1) - - lea (gdt - base) (%esi, 1), %eax - mov %eax, (gdt_addr - base) (%esi, 1) - - /* Switch to compatibility mode. */ - - lgdt (gdtdesc - base) (%esi, 1) - - /* Update %cs. Thanks to David Miller for pointing this mistake out. */ - ljmp *(jump_vector - base) (%esi,1) -#else - lea (cont1 - base) (%rsi, 1), %rax - mov %eax, (jump_vector - base) (%rsi, 1) - - lea (gdt - base) (%rsi, 1), %rax - mov %rax, (gdt_addr - base) (%rsi, 1) - - /* Switch to compatibility mode. */ - - lgdt (gdtdesc - base) (%rsi, 1) - - /* Update %cs. Thanks to David Miller for pointing this mistake out. */ - ljmp *(jump_vector - base) (%rsi, 1) -#endif - -cont1: - .code32 - - /* Update other registers. */ - mov $0x18, %eax - mov %eax, %ds - mov %eax, %es - mov %eax, %fs - mov %eax, %gs - mov %eax, %ss - - /* Disable paging. */ - mov %cr0, %eax - and $0x7fffffff, %eax - mov %eax, %cr0 - - /* Disable amd64. */ - mov $0xc0000080, %ecx - rdmsr - and $0xfffffeff, %eax - wrmsr - - /* Turn off PAE. */ - movl %cr4, %eax - and $0xffffffcf, %eax - mov %eax, %cr4 - - jmp cont2 -cont2: -#endif - .code32 - - /* Registers on XNU boot: eip, esp and eax. */ - /* mov imm32, %ecx */ - .byte 0xb9 -VARIABLE (grub_xnu_entry_point) - .long 0 - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE (grub_xnu_arg1) - .long 0 - /* mov imm32, %ebx */ - .byte 0xbb -VARIABLE (grub_xnu_stack) - .long 0 - - movl %ebx, %esp - - jmp *%ecx - -#ifdef __x86_64__ - /* GDT. Copied from loader/i386/linux.c. */ - .p2align 4 -gdt: - /* NULL. */ - .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - - /* Reserved. */ - .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - - /* Code segment. */ - .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00 - - /* Data segment. */ - .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00 - -gdtdesc: - .word 31 -gdt_addr: - /* Filled by the code. */ - .quad 0 - - .p2align 4 -jump_vector: - /* Jump location. Is filled by the code */ - .long 0 - .long 0x10 -#endif -VARIABLE(grub_xnu_launcher_end) diff --git a/loader/xnu.c b/loader/xnu.c index aac4ae372..cc6d55ae2 100644 --- a/loader/xnu.c +++ b/loader/xnu.c @@ -36,6 +36,9 @@ struct grub_xnu_devtree_key *grub_xnu_devtree_root = 0; static int driverspackagenum = 0; static int driversnum = 0; +void *grub_xnu_heap_start = 0; +grub_size_t grub_xnu_heap_size = 0; + /* Allocate heap by 32MB-blocks. */ #define GRUB_XNU_HEAP_ALLOC_BLOCK 0x2000000 @@ -46,12 +49,6 @@ void * grub_xnu_heap_malloc (int size) { void *val; - -#if 0 - /* This way booting is faster but less reliable. - Once we have advanced mm second way will be as fast as this one. */ - val = grub_xnu_heap_start = (char *) 0x100000; -#else int oldblknum, newblknum; /* The page after the heap is used for stack. Ensure it's usable. */ @@ -63,25 +60,21 @@ grub_xnu_heap_malloc (int size) newblknum = (grub_xnu_heap_size + size + GRUB_XNU_PAGESIZE + GRUB_XNU_HEAP_ALLOC_BLOCK - 1) / GRUB_XNU_HEAP_ALLOC_BLOCK; if (oldblknum != newblknum) - /* FIXME: instruct realloc to allocate at 1MB if possible once - advanced mm is ready. */ - val = grub_realloc (grub_xnu_heap_start, - newblknum * GRUB_XNU_HEAP_ALLOC_BLOCK); - else - val = grub_xnu_heap_start; - if (! val) { - grub_error (GRUB_ERR_OUT_OF_MEMORY, - "not enough space on xnu memory heap"); - return 0; + /* FIXME: instruct realloc to allocate at 1MB if possible once + advanced mm is ready. */ + grub_xnu_heap_start + = XNU_RELOCATOR (realloc) (grub_xnu_heap_start, + newblknum + * GRUB_XNU_HEAP_ALLOC_BLOCK); + if (!grub_xnu_heap_start) + return NULL; } - grub_xnu_heap_start = val; -#endif - val = (char *) grub_xnu_heap_start + grub_xnu_heap_size; + val = (grub_uint8_t *) grub_xnu_heap_start + grub_xnu_heap_size; grub_xnu_heap_size += size; grub_dprintf ("xnu", "val=%p\n", val); - return (char *) val; + return val; } /* Make sure next block of the heap will be aligned. @@ -251,7 +244,7 @@ grub_xnu_writetree_toheap (void **start, grub_size_t *size) - *size % GRUB_XNU_PAGESIZE); /* Put real data in the dummy. */ - extdesc->addr = (char *) *start - grub_xnu_heap_start + extdesc->addr = (grub_uint8_t *) *start - (grub_uint8_t *) grub_xnu_heap_start + grub_xnu_heap_will_be_at; extdesc->size = (grub_uint32_t) *size; @@ -503,7 +496,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) grub_file_t infoplist; struct grub_xnu_extheader *exthead; int neededspace = sizeof (*exthead); - char *buf; + grub_uint8_t *buf; grub_size_t infoplistsize = 0, machosize = 0; if (! grub_xnu_heap_size) @@ -552,7 +545,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) /* Load the binary. */ if (macho) { - exthead->binaryaddr = (buf - grub_xnu_heap_start) + exthead->binaryaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start) + grub_xnu_heap_will_be_at; exthead->binarysize = machosize; if ((err = grub_macho32_readfile (macho, buf))) @@ -568,7 +561,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) /* Load the plist. */ if (infoplist) { - exthead->infoplistaddr = (buf - grub_xnu_heap_start) + exthead->infoplistaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start) + grub_xnu_heap_will_be_at; exthead->infoplistsize = infoplistsize + 1; if (grub_file_read (infoplist, buf, infoplistsize) diff --git a/loader/xnu_resume.c b/loader/xnu_resume.c index 77f688726..bfc1eb1e8 100644 --- a/loader/xnu_resume.c +++ b/loader/xnu_resume.c @@ -45,7 +45,7 @@ grub_xnu_resume (char *imagename) grub_file_t file; grub_size_t total_header_size; struct grub_xnu_hibernate_header hibhead; - char *buf, *codetmp; + grub_uint8_t *buf; grub_uint32_t codedest; grub_uint32_t codesize; @@ -94,12 +94,11 @@ grub_xnu_resume (char *imagename) /* Try to allocate necessary space. FIXME: mm isn't good enough yet to handle huge allocations. */ - grub_xnu_hibernate_image = buf = grub_malloc (hibhead.image_size); + grub_xnu_hibernate_image = buf = XNU_RELOCATOR (alloc) (hibhead.image_size); if (! buf) { grub_file_close (file); - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "not enough memory to load image"); + return grub_errno; } /* Read image. */ @@ -112,22 +111,16 @@ grub_xnu_resume (char *imagename) } grub_file_close (file); - codetmp = grub_memalign (GRUB_XNU_PAGESIZE, codesize + GRUB_XNU_PAGESIZE); /* Setup variables needed by asm helper. */ grub_xnu_heap_will_be_at = codedest; - grub_xnu_heap_start = codetmp; + grub_xnu_heap_start = buf; grub_xnu_heap_size = codesize; grub_xnu_stack = (codedest + hibhead.stack); grub_xnu_entry_point = (codedest + hibhead.entry_point); grub_xnu_arg1 = (long) buf; - /* Prepare asm helper. */ - grub_memcpy (codetmp, ((grub_uint8_t *) buf) + total_header_size, codesize); - grub_memcpy (codetmp + codesize, grub_xnu_launcher_start, - grub_xnu_launcher_end - grub_xnu_launcher_start); - /* We're ready now. */ - grub_loader_set ((grub_err_t (*) (void)) (codetmp + codesize), + grub_loader_set (grub_xnu_boot_resume, grub_xnu_resume_unload, 0); /* Prevent module from unloading. */ From 3d1933fb20a033fcbdf2d90ad26a232a5bd46132 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 27 Nov 2009 10:57:52 +0100 Subject: [PATCH 30/52] Fix compilation on x86_64-efi --- conf/x86_64-efi.rmk | 6 ++++++ include/grub/x86_64/relocator.h | 1 + lib/relocator.c | 14 ++++++++------ 3 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 include/grub/x86_64/relocator.h diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk index 726bf23fa..25c379c98 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -166,4 +166,10 @@ xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) +pkglib_MODULES += relocator.mod +relocator_mod_SOURCES = lib/i386/relocator.c lib/i386/relocator_asm.S lib/i386/relocator_backward.S +relocator_mod_CFLAGS = $(COMMON_CFLAGS) +relocator_mod_ASFLAGS = $(COMMON_ASFLAGS) +relocator_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk diff --git a/include/grub/x86_64/relocator.h b/include/grub/x86_64/relocator.h new file mode 100644 index 000000000..247e7a18b --- /dev/null +++ b/include/grub/x86_64/relocator.h @@ -0,0 +1 @@ +#include diff --git a/lib/relocator.c b/lib/relocator.c index d4bfebc8e..557fd4f63 100644 --- a/lib/relocator.c +++ b/lib/relocator.c @@ -73,8 +73,8 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, size = *(grub_size_t *) playground; grub_dprintf ("relocator", - "Relocator: source: %p, destination: 0x%x, size: 0x%x\n", - relocator, dest, size); + "Relocator: source: %p, destination: 0x%x, size: 0x%lx\n", + relocator, (unsigned) dest, (unsigned long) size); /* Very unlikely condition: Relocator may risk overwrite itself. Just move it a bit up. */ @@ -103,10 +103,11 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, RELOCATOR_ALIGN); grub_dprintf ("relocator", "Backward relocator: code %p, source: %p, " - "destination: 0x%x, size: 0x%x\n", + "destination: 0x%x, size: 0x%lx\n", (char *) relocator - overhead, (char *) relocator - overhead, - dest - overhead, size + overhead); + (unsigned) dest - overhead, + (unsigned long) size + overhead); write_call_relocator_bw ((char *) relocator - overhead, (char *) relocator - overhead, @@ -120,10 +121,11 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, + RELOCATOR_SIZEOF (forward) - (dest + size); grub_dprintf ("relocator", "Forward relocator: code %p, source: %p, " - "destination: 0x%x, size: 0x%x\n", + "destination: 0x%x, size: 0x%lx\n", (char *) relocator + size + overhead - RELOCATOR_SIZEOF (forward), - relocator, dest, size + overhead); + relocator, (unsigned) dest, + (unsigned long) size + overhead); write_call_relocator_fw ((char *) relocator + size + overhead - RELOCATOR_SIZEOF (forward), From 579877ce8645efb2b39caf382d4ff6f98a4f6d6b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 28 Nov 2009 14:15:53 +0100 Subject: [PATCH 31/52] ChangeLog --- ChangeLog.relocators | 77 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 ChangeLog.relocators diff --git a/ChangeLog.relocators b/ChangeLog.relocators new file mode 100644 index 000000000..4e43b1b60 --- /dev/null +++ b/ChangeLog.relocators @@ -0,0 +1,77 @@ +2009-11-28 Vladimir Serbinenko + + Relocator framework + + * THANKS: Add David Miller. + * loader/i386/xnu_helper.S: Removed. All users updated. + * conf/i386.rmk (pkglib_MODULES): Add relocator.mod. + (relocator_mod_SOURCES): New variable. + (relocator_mod_CFLAGS): Likewise. + (relocator_mod_LDFLAGS): Likewise. + (relocator_mod_ASFLAGS): Likewise. + * conf/x86_64.rmk: Likewise. + * include/grub/i386/multiboot.h (grub_multiboot_payload_orig): Removed. + (grub_multiboot_payload_entry_offset): Likewise. + (grub_multiboot_forward_relocator): Likewise. + (grub_multiboot_forward_relocator_end): Likewise. + (grub_multiboot_backward_relocator): Likewise. + (grub_multiboot_backward_relocator_end): Likewise. + (grub_multiboot_payload_eip): New variable. + (grub_multiboot_payload_orig): Likewise. + (GRUB_MULTIBOOT_STACK_SIZE): New definition. + * include/grub/i386/pc/memory.h: Include grub/i386/memory.h. + (GRUB_MEMORY_MACHINE_CR0_PE_ON): Move from here ... + * include/grub/i386/memory.h + (GRUB_MEMORY_CPU_CR0_PE_ON): ... to here + (GRUB_MEMORY_CPU_CR4_PAE_ON): New definition. + (GRUB_MEMORY_CPU_CR0_PAGING_ON): Likewise. + (GRUB_MEMORY_CPU_AMD64_MSR): Likewise. + (GRUB_MEMORY_CPU_AMD64_MSR_ON): Likewise. + * include/grub/i386/relocator.h: New file. + * include/grub/x86_64/relocator.h: Likewise. + * include/grub/i386/xnu.h: Include grub/cpu/relocator.h. + (XNU_RELOCATOR): New macro. + (grub_xnu_launcher_start): Remove. + (grub_xnu_launcher_end): Likewise. + * include/grub/xnu.h (grub_xnu_boot_resume): New prototype. + (grub_xnu_heap_real_start): Remove. + (grub_xnu_heap_start): Change to void *. All users updated. + * kern/i386/realmode.S (real_to_prot): Use GRUB_MEMORY_CPU_CR0_PE_ON. + * lib/i386/relocator.c: New file. + * lib/i386/relocator_asm.S: Likewise. + * lib/i386/relocator_backward.S: Likewise. + * lib/mips/relocator.c: Likewise. + * lib/mips/relocator_asm.S: Likewise. + * lib/relocator.c: Likewise. + * loader/i386/multiboot.c: Include grub/i386/relocator.h. + (entry): Removed. + (playground): Likewise. + (grub_multiboot_payload_orig): New variable. + (grub_multiboot_payload_dest): Likewise. + (grub_multiboot_payload_size): Likewise. + (grub_multiboot_payload_eip): Likewise. + (grub_multiboot_payload_esp): Likewise. + (grub_multiboot_boot): Use grub_relocator32_boot. + (grub_multiboot_unload): Free relocators. + (grub_multiboot): Setup stack. Use relocators. + * loader/i386/multiboot_elfxx.c: Include grub/i386/relocator.h. + (grub_multiboot_load_elfXX): Use relocators. + * loader/i386/multiboot_helper.S (grub_multiboot_payload_orig): Removed. + (grub_multiboot_payload_size): Likewise. + (grub_multiboot_payload_dest): Likewise. + (grub_multiboot_payload_entry_offset): Likewise. + (grub_multiboot_forward_relocator): Likewise. + (grub_multiboot_backward_relocator): Likewise. + (grub_multiboot_real_boot): Likewise. + * loader/i386/xnu.c (grub_xnu_heap_will_be_at): New variable. + (grub_xnu_entry_point): Likewise. + (grub_xnu_arg1): Likewise. + (grub_xnu_stack): Likewise. + (grub_xnu_launch): Removed. + (grub_xnu_boot_resume): New function. + (grub_xnu_boot): Use relocators. + * loader/i386/xnu_helper.S: Removed. + * loader/xnu.c (grub_xnu_heap_start): New variable. + (grub_xnu_heap_size): Likewise. + (grub_xnu_heap_malloc): Use relocators. + * loader/xnu_resume.c (grub_xnu_resume): Use relocators. From 02ddd45afcef5391a3fa532113f63f0b9bfa67d0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 3 Dec 2009 22:45:41 +0100 Subject: [PATCH 32/52] Fix compilation issue for ppc --- loader/powerpc/ieee1275/linux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/loader/powerpc/ieee1275/linux.c b/loader/powerpc/ieee1275/linux.c index 79fbf0b02..1056ab9eb 100644 --- a/loader/powerpc/ieee1275/linux.c +++ b/loader/powerpc/ieee1275/linux.c @@ -110,7 +110,7 @@ grub_linux_load32 (grub_elf_t elf) if (entry == 0) entry = 0x01400000; - linux_size = grub_elf32_size (elf); + linux_size = grub_elf32_size (elf, 0); if (linux_size == 0) return grub_errno; /* Pad it; the kernel scribbles over memory beyond its load address. */ @@ -160,7 +160,7 @@ grub_linux_load64 (grub_elf_t elf) if (entry == 0) entry = 0x01400000; - linux_size = grub_elf64_size (elf); + linux_size = grub_elf64_size (elf, 0); if (linux_size == 0) return grub_errno; /* Pad it; the kernel scribbles over memory beyond its load address. */ From e420686f133d2e1d56d9ae3936b6cddddc5727a5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 5 Dec 2009 11:29:47 +0100 Subject: [PATCH 33/52] Ignore some VBE info --- video/i386/pc/vbe.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c index a285b26ba..c5c4e64ca 100644 --- a/video/i386/pc/vbe.c +++ b/video/i386/pc/vbe.c @@ -158,8 +158,10 @@ grub_vbe_set_video_mode (grub_uint32_t vbe_mode, /* Try to set video mode. */ status = grub_vbe_bios_set_mode (vbe_mode, 0); +#if 0 if (status != GRUB_VBE_STATUS_OK) return grub_error (GRUB_ERR_BAD_DEVICE, "cannot set VBE mode %x", vbe_mode); +#endif /* Save information for later usage. */ framebuffer.active_vbe_mode = vbe_mode; @@ -387,6 +389,7 @@ grub_video_vbe_setup (unsigned int width, unsigned int height, break; } +#if 0 if ((vbe_mode_info.mode_attributes & 0x001) == 0) /* If not available, skip it. */ continue; @@ -411,6 +414,7 @@ grub_video_vbe_setup (unsigned int width, unsigned int height, && (vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR)) /* Not compatible memory model. */ continue; +#endif if ((vbe_mode_info.x_resolution != width) || (vbe_mode_info.y_resolution != height)) From cbf73baaae754740a84c66db938acace0bfc6167 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Fri, 11 Dec 2009 23:10:57 +0000 Subject: [PATCH 34/52] Indentation fix & missing copyright year. --- include/grub/i386/memory.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/grub/i386/memory.h b/include/grub/i386/memory.h index a0f3192b8..466947cc6 100644 --- a/include/grub/i386/memory.h +++ b/include/grub/i386/memory.h @@ -1,7 +1,7 @@ /* memory.h - describe the memory map */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2007,2008 Free Software Foundation, Inc. + * Copyright (C) 2002,2007,2008,2009 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 @@ -23,8 +23,8 @@ /* The flag for protected mode. */ #define GRUB_MEMORY_CPU_CR0_PE_ON 0x1 #define GRUB_MEMORY_CPU_CR4_PAE_ON 0x00000040 -#define GRUB_MEMORY_CPU_CR0_PAGING_ON 0x80000000 -#define GRUB_MEMORY_CPU_AMD64_MSR 0xc0000080 -#define GRUB_MEMORY_CPU_AMD64_MSR_ON 0x00000100 +#define GRUB_MEMORY_CPU_CR0_PAGING_ON 0x80000000 +#define GRUB_MEMORY_CPU_AMD64_MSR 0xc0000080 +#define GRUB_MEMORY_CPU_AMD64_MSR_ON 0x00000100 #endif /* ! GRUB_MEMORY_CPU_HEADER */ From 087793c68e09189cef9889b27b94f6b89e143041 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 13 Dec 2009 18:03:46 +0100 Subject: [PATCH 35/52] Cleanup address expressions for readability and using only unsigned arithmetics --- lib/relocator.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/relocator.c b/lib/relocator.c index 557fd4f63..d10af34d4 100644 --- a/lib/relocator.c +++ b/lib/relocator.c @@ -78,10 +78,10 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, /* Very unlikely condition: Relocator may risk overwrite itself. Just move it a bit up. */ - if ((grub_uint8_t *) UINT_TO_PTR (dest) - (grub_uint8_t *) relocator - < (signed) (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN) - && (grub_uint8_t *) UINT_TO_PTR (dest) - (grub_uint8_t *) relocator - > - (signed) (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN)) + if ((grub_addr_t) dest < (grub_addr_t) relocator + + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN) + && (grub_addr_t) dest + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) + > (grub_addr_t) relocator) { void *relocator_new = ((grub_uint8_t *) relocator) + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) @@ -95,7 +95,7 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, relocator = relocator_new; } - if (UINT_TO_PTR (dest) >= relocator) + if ((grub_addr_t) dest >= (grub_addr_t) relocator) { int overhead; overhead = dest - From 5a0e0cc6bd85f605834cc5457f3537b6ca75bb34 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 13 Dec 2009 18:07:01 +0100 Subject: [PATCH 36/52] Fix XNU resume. --- loader/xnu_resume.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/loader/xnu_resume.c b/loader/xnu_resume.c index bfc1eb1e8..83c2c3cd1 100644 --- a/loader/xnu_resume.c +++ b/loader/xnu_resume.c @@ -94,16 +94,28 @@ grub_xnu_resume (char *imagename) /* Try to allocate necessary space. FIXME: mm isn't good enough yet to handle huge allocations. */ - grub_xnu_hibernate_image = buf = XNU_RELOCATOR (alloc) (hibhead.image_size); + grub_xnu_hibernate_image = buf = XNU_RELOCATOR (alloc) (hibhead.image_size + + codesize + + GRUB_XNU_PAGESIZE); if (! buf) { grub_file_close (file); return grub_errno; } + /* Read code part. */ + if (grub_file_seek (file, total_header_size) == (grub_off_t) -1 + || grub_file_read (file, buf, codesize) + != (grub_ssize_t) codesize) + { + grub_file_close (file); + return grub_error (GRUB_ERR_READ_ERROR, "Cannot read resume image."); + } + /* Read image. */ - if (grub_file_seek (file, 0) == (grub_off_t)-1 - || grub_file_read (file, buf, hibhead.image_size) + if (grub_file_seek (file, 0) == (grub_off_t) -1 + || grub_file_read (file, buf + codesize + GRUB_XNU_PAGESIZE, + hibhead.image_size) != (grub_ssize_t) hibhead.image_size) { grub_file_close (file); @@ -114,10 +126,14 @@ grub_xnu_resume (char *imagename) /* Setup variables needed by asm helper. */ grub_xnu_heap_will_be_at = codedest; grub_xnu_heap_start = buf; - grub_xnu_heap_size = codesize; + grub_xnu_heap_size = codesize + GRUB_XNU_PAGESIZE + hibhead.image_size; grub_xnu_stack = (codedest + hibhead.stack); grub_xnu_entry_point = (codedest + hibhead.entry_point); - grub_xnu_arg1 = (long) buf; + grub_xnu_arg1 = codedest + codesize + GRUB_XNU_PAGESIZE; + + grub_dprintf ("xnu", "entry point 0x%x\n", codedest + hibhead.entry_point); + grub_dprintf ("xnu", "image at 0x%x\n", + codedest + codesize + GRUB_XNU_PAGESIZE); /* We're ready now. */ grub_loader_set (grub_xnu_boot_resume, From 3e8c081543ac6692aa2d37a6394e5b1db2af8134 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 13 Dec 2009 18:10:53 +0100 Subject: [PATCH 37/52] legacy-like stack handling --- loader/i386/multiboot.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index 33c7433f2..f5036a2ae 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -59,7 +59,6 @@ char *grub_multiboot_payload_orig; grub_addr_t grub_multiboot_payload_dest; grub_size_t grub_multiboot_payload_size; grub_uint32_t grub_multiboot_payload_eip; -grub_uint32_t grub_multiboot_payload_esp; static grub_err_t grub_multiboot_boot (void) @@ -71,7 +70,9 @@ grub_multiboot_boot (void) .ecx = 0, .edx = 0, .eip = grub_multiboot_payload_eip, - .esp = grub_multiboot_payload_esp + /* Set esp to some random location in low memory to avoid breaking + non-compliant kernels. */ + .esp = 0x7ff00 }; grub_relocator32_boot (grub_multiboot_payload_orig, @@ -290,13 +291,11 @@ grub_multiboot (int argc, char *argv[]) ((void *) ((x) + code_size + cmdline_length)) #define mbi_addr(x) ((void *) ((x) + code_size + cmdline_length + boot_loader_name_length)) #define mmap_addr(x) ((void *) ((x) + code_size + cmdline_length + boot_loader_name_length + sizeof (struct multiboot_info))) -#define stack_addr(x) ((void *) ((x) + code_size + cmdline_length + boot_loader_name_length + sizeof (struct multiboot_info) + mmap_length + GRUB_MULTIBOOT_STACK_SIZE)) grub_multiboot_payload_size = cmdline_length /* boot_loader_name_length might need to grow for mbi,etc to be aligned (see below) */ + boot_loader_name_length + 3 - + sizeof (struct multiboot_info) + mmap_length - + GRUB_MULTIBOOT_STACK_SIZE; + + sizeof (struct multiboot_info) + mmap_length; if (header->flags & MULTIBOOT_AOUT_KLUDGE) { @@ -319,7 +318,7 @@ grub_multiboot (int argc, char *argv[]) if (! grub_multiboot_payload_orig) goto fail; - if ((grub_file_seek (file, offset)) == (grub_off_t) - 1) + if ((grub_file_seek (file, offset)) == (grub_off_t) -1) goto fail; grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size); @@ -382,8 +381,6 @@ grub_multiboot (int argc, char *argv[]) if (grub_multiboot_get_bootdev (&mbi->boot_device)) mbi->flags |= MULTIBOOT_INFO_BOOTDEV; - grub_multiboot_payload_esp = PTR_TO_UINT32 (stack_addr (grub_multiboot_payload_dest)); - grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 1); fail: From 616da3a1546560057c2b790047af2c06af9e9ab4 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 13 Dec 2009 18:29:15 +0000 Subject: [PATCH 38/52] 2009-12-13 Robert Millan * loader/i386/multiboot_elfxx.c (CONCAT(grub_multiboot_load_elf, XX)): Fix `grub_multiboot_payload_eip' initialization. --- ChangeLog.relocators | 6 ++++++ loader/i386/multiboot_elfxx.c | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog.relocators b/ChangeLog.relocators index c402ac2db..d64ef24f8 100644 --- a/ChangeLog.relocators +++ b/ChangeLog.relocators @@ -1,3 +1,9 @@ +2009-12-13 Robert Millan + + * loader/i386/multiboot_elfxx.c + (CONCAT(grub_multiboot_load_elf, XX)): Fix `grub_multiboot_payload_eip' + initialization. + 2009-11-28 Vladimir Serbinenko Relocator framework diff --git a/loader/i386/multiboot_elfxx.c b/loader/i386/multiboot_elfxx.c index 0b9820dcc..80db25144 100644 --- a/loader/i386/multiboot_elfxx.c +++ b/loader/i386/multiboot_elfxx.c @@ -138,7 +138,8 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer) if (phdr(i)->p_vaddr <= ehdr->e_entry && phdr(i)->p_vaddr + phdr(i)->p_memsz > ehdr->e_entry) { - grub_multiboot_payload_eip = ehdr->e_entry; + grub_multiboot_payload_eip = grub_multiboot_payload_dest + + (ehdr->e_entry - phdr(i)->p_vaddr) + (phdr(i)->p_paddr - phdr(lowest_segment)->p_paddr); break; } From 2e8a760287ba66ae1c52b5c6e7b86cd5ceb9cf0b Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 13 Dec 2009 19:46:59 +0000 Subject: [PATCH 39/52] 2009-12-13 Robert Millan * util/grub-probe.c (probe): Improve error message. --- ChangeLog | 4 ++++ util/grub-probe.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 026ff3e76..8b09b47c1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-12-13 Robert Millan + + * util/grub-probe.c (probe): Improve error message. + 2009-12-13 Robert Millan * loader/i386/multiboot_elfxx.c diff --git a/util/grub-probe.c b/util/grub-probe.c index 6d421445c..1958308c3 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -123,7 +123,7 @@ probe (const char *path, char *device_name) device_name = grub_guess_root_device (path); if (! device_name) - grub_util_error ("cannot find a device for %s.\n", path); + grub_util_error ("cannot find a device for %s (is /dev mounted?).\n", path); if (print == PRINT_DEVICE) { From c4a3e41a727f97793b87a4d87cc1273314d6dcd5 Mon Sep 17 00:00:00 2001 From: Carles Pina i Estany Date: Sun, 13 Dec 2009 19:51:08 +0000 Subject: [PATCH 40/52] 2009-12-13 Carles Pina i Estany * include/grub/misc.h (grub_puts): New declaration. (grub_puts_): Likewise. * kern/mis.c (grub_puts): New definition. (grub_puts_): Likewise. --- ChangeLog | 7 +++++++ include/grub/misc.h | 2 ++ kern/misc.c | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/ChangeLog b/ChangeLog index 8b09b47c1..4d13b8f80 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-12-13 Carles Pina i Estany + + * include/grub/misc.h (grub_puts): New declaration. + (grub_puts_): Likewise. + * kern/mis.c (grub_puts): New definition. + (grub_puts_): Likewise. + 2009-12-13 Robert Millan * util/grub-probe.c (probe): Improve error message. diff --git a/include/grub/misc.h b/include/grub/misc.h index 1ab63ac0b..926195d2c 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -172,6 +172,8 @@ void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n); grub_size_t EXPORT_FUNC(grub_strlen) (const char *s); int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); +int EXPORT_FUNC(grub_puts) (const char *s); +int EXPORT_FUNC(grub_puts_) (const char *s); void EXPORT_FUNC(grub_real_dprintf) (const char *file, const int line, const char *condition, diff --git a/kern/misc.c b/kern/misc.c index 4415b8204..d9988961c 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -139,6 +139,25 @@ grub_printf_ (const char *fmt, ...) return ret; } +int +grub_puts (const char *s) +{ + while (*s) + { + grub_putchar (*s); + s++; + } + grub_putchar ('\n'); + + return 1; /* Cannot fail. */ +} + +int +grub_puts_ (const char *s) +{ + return grub_puts (_(s)); +} + #if defined (APPLE_CC) && ! defined (GRUB_UTIL) int grub_err_printf (const char *fmt, ...) From 574cce0cfab2095ce45a2c2c61007639220397a6 Mon Sep 17 00:00:00 2001 From: Felix Zielcke Date: Mon, 14 Dec 2009 11:06:24 +0100 Subject: [PATCH 41/52] 2009-12-14 Felix Zielcke Fix a segfault with parsing unknown long options. * util/grub-mkrelpath.c (options): Zero terminate it. --- ChangeLog | 6 ++++++ util/grub-mkrelpath.c | 1 + 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 4d13b8f80..5dbedeff4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-12-14 Felix Zielcke + + Fix a segfault with parsing unknown long options. + + * util/grub-mkrelpath.c (options): Zero terminate it. + 2009-12-13 Carles Pina i Estany * include/grub/misc.h (grub_puts): New declaration. diff --git a/util/grub-mkrelpath.c b/util/grub-mkrelpath.c index a20109628..956e52ed7 100644 --- a/util/grub-mkrelpath.c +++ b/util/grub-mkrelpath.c @@ -27,6 +27,7 @@ static struct option options[] = { {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, + {0, 0, 0, 0}, }; static void From 7ca3f5c2d9c2262c5ddb86980eb084b794154def Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 14 Dec 2009 18:16:32 +0100 Subject: [PATCH 42/52] one more possible fix --- video/i386/pc/vbe.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c index c5c4e64ca..ad87aa441 100644 --- a/video/i386/pc/vbe.c +++ b/video/i386/pc/vbe.c @@ -258,8 +258,10 @@ grub_vbe_get_video_mode (grub_uint32_t *mode) /* Try to query current mode from VESA BIOS. */ status = grub_vbe_bios_get_mode (mode); +#if 0 if (status != GRUB_VBE_STATUS_OK) return grub_error (GRUB_ERR_BAD_DEVICE, "cannot get current VBE mode"); +#endif return GRUB_ERR_NONE; } From c179ebe4ee701f43ea737b0b8ae28beaffaca126 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 16 Dec 2009 15:40:31 +0100 Subject: [PATCH 43/52] 2009-12-16 Vladimir Serbinenko UUID support for HFS. * fs/hfs.c (grub_hfs_uuid): New function. (grub_hfs_fs): New value .uuid. * include/grub/hfs.h (grub_hfs_sblock): New field 'num_serial'. --- ChangeLog | 8 ++++++++ fs/hfs.c | 26 ++++++++++++++++++++++++++ include/grub/hfs.h | 3 ++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5dbedeff4..9506d26ca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-12-16 Vladimir Serbinenko + + UUID support for HFS. + + * fs/hfs.c (grub_hfs_uuid): New function. + (grub_hfs_fs): New value .uuid. + * include/grub/hfs.h (grub_hfs_sblock): New field 'num_serial'. + 2009-12-14 Felix Zielcke Fix a segfault with parsing unknown long options. diff --git a/fs/hfs.c b/fs/hfs.c index 5062b5f71..493455054 100644 --- a/fs/hfs.c +++ b/fs/hfs.c @@ -1072,6 +1072,31 @@ grub_hfs_label (grub_device_t device, char **label) return grub_errno; } +static grub_err_t +grub_hfs_uuid (grub_device_t device, char **uuid) +{ + struct grub_hfs_data *data; + + grub_dl_ref (my_mod); + + data = grub_hfs_mount (device->disk); + if (data && data->sblock.num_serial != 0) + { + *uuid = grub_malloc (16 + sizeof ('\0')); + grub_sprintf (*uuid, "%016llx", + (unsigned long long) + grub_be_to_cpu64 (data->sblock.num_serial)); + } + else + *uuid = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + static struct grub_fs grub_hfs_fs = @@ -1082,6 +1107,7 @@ static struct grub_fs grub_hfs_fs = .read = grub_hfs_read, .close = grub_hfs_close, .label = grub_hfs_label, + .uuid = grub_hfs_uuid, .next = 0 }; diff --git a/include/grub/hfs.h b/include/grub/hfs.h index 08b947ccb..d93b9a2c9 100644 --- a/include/grub/hfs.h +++ b/include/grub/hfs.h @@ -48,7 +48,8 @@ struct grub_hfs_sblock /* A pascal style string that holds the volumename. */ grub_uint8_t volname[28]; - grub_uint8_t unused5[60]; + grub_uint8_t unused5[52]; + grub_uint64_t num_serial; grub_uint16_t embed_sig; struct grub_hfs_extent embed_extent; grub_uint8_t unused6[4]; From db846aed9abd03abaa4db84cad88e68a2ce0b76e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 16 Dec 2009 16:53:01 +0100 Subject: [PATCH 44/52] minimalising ATI impact --- video/i386/pc/vbe.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c index ad87aa441..714f7397e 100644 --- a/video/i386/pc/vbe.c +++ b/video/i386/pc/vbe.c @@ -158,10 +158,8 @@ grub_vbe_set_video_mode (grub_uint32_t vbe_mode, /* Try to set video mode. */ status = grub_vbe_bios_set_mode (vbe_mode, 0); -#if 0 if (status != GRUB_VBE_STATUS_OK) return grub_error (GRUB_ERR_BAD_DEVICE, "cannot set VBE mode %x", vbe_mode); -#endif /* Save information for later usage. */ framebuffer.active_vbe_mode = vbe_mode; @@ -258,10 +256,10 @@ grub_vbe_get_video_mode (grub_uint32_t *mode) /* Try to query current mode from VESA BIOS. */ status = grub_vbe_bios_get_mode (mode); -#if 0 + /* XXX: ATI don't support get_mode. */ if (status != GRUB_VBE_STATUS_OK) - return grub_error (GRUB_ERR_BAD_DEVICE, "cannot get current VBE mode"); -#endif + *mode = 3; + // return grub_error (GRUB_ERR_BAD_DEVICE, "cannot get current VBE mode"); return GRUB_ERR_NONE; } @@ -391,14 +389,15 @@ grub_video_vbe_setup (unsigned int width, unsigned int height, break; } -#if 0 if ((vbe_mode_info.mode_attributes & 0x001) == 0) /* If not available, skip it. */ continue; +#if 0 if ((vbe_mode_info.mode_attributes & 0x002) == 0) /* Not enough information. */ continue; +#endif if ((vbe_mode_info.mode_attributes & 0x008) == 0) /* Monochrome is unusable. */ @@ -416,7 +415,6 @@ grub_video_vbe_setup (unsigned int width, unsigned int height, && (vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR)) /* Not compatible memory model. */ continue; -#endif if ((vbe_mode_info.x_resolution != width) || (vbe_mode_info.y_resolution != height)) From 0297aafb9f74993073773c8a5044cf4507a672ea Mon Sep 17 00:00:00 2001 From: Felix Zielcke Date: Thu, 17 Dec 2009 11:19:12 +0100 Subject: [PATCH 45/52] 2009-12-17 Felix Zielcke * gendistlist.sh: Use POSIX compliant `!' instead of `-not' in the `find' command. --- ChangeLog | 5 +++++ gendistlist.sh | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9506d26ca..22d085fa4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-12-17 Felix Zielcke + + * gendistlist.sh: Use POSIX compliant `!' instead of `-not' in + the `find' command. + 2009-12-16 Vladimir Serbinenko UUID support for HFS. diff --git a/gendistlist.sh b/gendistlist.sh index 43366bd73..102c0c11c 100644 --- a/gendistlist.sh +++ b/gendistlist.sh @@ -36,7 +36,7 @@ dir=`dirname $0` cd $dir for dir in $DISTDIRS; do - for d in `find $dir -type d -not -name .svn -not -name .bzr | sort`; do + for d in `find $dir -type d ! -name .svn ! -name .bzr | sort`; do find $d -maxdepth 1 -name '*.[chSy]' -o -name '*.mk' -o -name '*.rmk' \ -o -name '*.rb' -o -name '*.in' -o -name '*.tex' -o -name '*.texi' \ -o -name '*.info' -o -name 'grub.cfg' -o -name 'README' \ From 5b4f655bad3618c7734406c46d671e032ed43646 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 18 Dec 2009 02:11:26 +0100 Subject: [PATCH 46/52] cleaned ATI fixes --- video/i386/pc/vbe.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c index 714f7397e..be1b519c5 100644 --- a/video/i386/pc/vbe.c +++ b/video/i386/pc/vbe.c @@ -33,6 +33,9 @@ static int vbe_detected = -1; static struct grub_vbe_info_block controller_info; static struct grub_vbe_mode_info_block active_vbe_mode_info; +/* Track last mode to support cards which fail on get_mode. */ +static grub_uint32_t last_set_mode = 3; + static struct { struct grub_video_mode_info mode_info; @@ -160,6 +163,7 @@ grub_vbe_set_video_mode (grub_uint32_t vbe_mode, status = grub_vbe_bios_set_mode (vbe_mode, 0); if (status != GRUB_VBE_STATUS_OK) return grub_error (GRUB_ERR_BAD_DEVICE, "cannot set VBE mode %x", vbe_mode); + last_set_mode = vbe_mode; /* Save information for later usage. */ framebuffer.active_vbe_mode = vbe_mode; @@ -203,6 +207,7 @@ grub_vbe_set_video_mode (grub_uint32_t vbe_mode, case 8: framebuffer.bytes_per_pixel = 1; break; default: grub_vbe_bios_set_mode (old_vbe_mode, 0); + last_set_mode = old_vbe_mode; return grub_error (GRUB_ERR_BAD_DEVICE, "cannot set VBE mode %x", vbe_mode); @@ -256,10 +261,9 @@ grub_vbe_get_video_mode (grub_uint32_t *mode) /* Try to query current mode from VESA BIOS. */ status = grub_vbe_bios_get_mode (mode); - /* XXX: ATI don't support get_mode. */ + /* XXX: ATI cards don't support get_mode. */ if (status != GRUB_VBE_STATUS_OK) - *mode = 3; - // return grub_error (GRUB_ERR_BAD_DEVICE, "cannot get current VBE mode"); + *mode = last_set_mode; return GRUB_ERR_NONE; } @@ -393,12 +397,6 @@ grub_video_vbe_setup (unsigned int width, unsigned int height, /* If not available, skip it. */ continue; -#if 0 - if ((vbe_mode_info.mode_attributes & 0x002) == 0) - /* Not enough information. */ - continue; -#endif - if ((vbe_mode_info.mode_attributes & 0x008) == 0) /* Monochrome is unusable. */ continue; From 0945f1816d92e2bfdeca24bb67211fe477d11721 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 18 Dec 2009 02:21:37 +0100 Subject: [PATCH 47/52] Changelog --- ChangeLog | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index 22d085fa4..d7d6ed847 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-12-18 Vladimir Serbinenko + + Workaround for broken ATI VBE. + + * video/i386/pc/vbe.c (last_set_mode): New variable. + (grub_vbe_set_video_mode): Set 'last_set_mode'. + (grub_vbe_get_video_mode): Use 'last_set_mode' if get_mode fails. + (grub_video_vbe_setup): Don't check for reserved flag. + 2009-12-17 Felix Zielcke * gendistlist.sh: Use POSIX compliant `!' instead of `-not' in From 2cd7057fc895ae79814df7fcaf717a0ef5599dc0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 18 Dec 2009 03:33:24 +0100 Subject: [PATCH 48/52] 30_os-prober update --- util/grub.d/30_os-prober.in | 99 +++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 47 deletions(-) diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index c5728866c..9577926be 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -37,6 +37,56 @@ if [ -z "${OSPROBED}" ] ; then exit 0 fi +function osx_entry { + cat << EOF +menuentry "${LONGNAME} (${2}-bit) (on ${DEVICE})" { +EOF + prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/" + cat << EOF + insmod vbe + do_resume=0 + if [ /var/vm/sleepimage -nt10 / ]; then + if xnu_resume /var/vm/sleepimage; then + do_resume=1 + fi + fi + if [ \$do_resume == 0 ]; then + xnu_uuid ${OSXUUID} uuid + if [ -f /Extra/DSDT.aml ]; then + acpi -e /Extra/DSDT.aml + fi + $1 /mach_kernel boot-uuid=\${uuid} rd=*uuid + if [ /System/Library/Extensions.mkext -nt /System/Library/Extensions ]; then + xnu_mkext /System/Library/Extensions.mkext + else + xnu_kextdir /System/Library/Extensions + fi + if [ -f /Extra/Extensions.mkext ]; then + xnu_mkext /Extra/Extensions.mkext + fi + if [ -d /Extra/Extensions ]; then + xnu_kextdir /Extra/Extensions + fi + if [ -f /Extra/devprop.bin ]; then + xnu_devprop_load /Extra/devprop.bin + fi + if [ -f /Extra/splash.jpg ]; then + insmod jpeg + xnu_splash /Extra/splash.jpg + fi + if [ -f /Extra/splash.png ]; then + insmod png + xnu_splash /Extra/splash.png + fi + if [ -f /Extra/splash.tga ]; then + insmod tga + xnu_splash /Extra/splash.tga + fi + fi +} +EOF +} + for OS in ${OSPROBED} ; do DEVICE="`echo ${OS} | cut -d ':' -f 1`" LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`" @@ -110,53 +160,8 @@ EOF ;; macosx) OSXUUID="`grub-probe --target=fs_uuid --device ${DEVICE} 2> /dev/null`" - cat << EOF -menuentry "${LONGNAME} (on ${DEVICE})" { -EOF - prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/" - cat << EOF - insmod vbe - do_resume=0 - if [ /var/vm/sleepimage -nt10 / ]; then - if xnu_resume /var/vm/sleepimage; then - do_resume=1 - fi - fi - if [ \$do_resume == 0 ]; then - xnu_uuid ${OSXUUID} uuid - if [ -f /Extra/DSDT.aml ]; then - acpi -e /Extra/DSDT.aml - fi - xnu_kernel /mach_kernel boot-uuid=\${uuid} rd=*uuid - if [ /System/Library/Extensions.mkext -nt /System/Library/Extensions ]; then - xnu_mkext /System/Library/Extensions.mkext - else - xnu_kextdir /System/Library/Extensions - fi - if [ -f /Extra/Extensions.mkext ]; then - xnu_mkext /Extra/Extensions.mkext - fi - if [ -d /Extra/Extensions ]; then - xnu_kextdir /Extra/Extensions - fi - if [ -f /Extra/devtree.txt ]; then - xnu_devtree /Extra/devtree.txt - fi - if [ -f /Extra/splash.jpg ]; then - insmod jpeg - xnu_splash /Extra/splash.jpg - fi - if [ -f /Extra/splash.png ]; then - insmod png - xnu_splash /Extra/splash.png - fi - if [ -f /Extra/splash.tga ]; then - insmod tga - xnu_splash /Extra/splash.tga - fi - fi -} -EOF + osx_entry xnu_kernel 32 + osx_entry xnu_kernel64 64 ;; hurd) cat << EOF From 52d1a0fd1a7e36892a9cf334b3d9b335b94a9389 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 18 Dec 2009 04:56:03 +0100 Subject: [PATCH 49/52] Remove unwantred commits --- fs/i386/pc/pxe.c | 1 + normal/completion.c | 17 ++++------------- normal/misc.c | 4 +++- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c index d2c9c7716..6c41d4298 100644 --- a/fs/i386/pc/pxe.c +++ b/fs/i386/pc/pxe.c @@ -65,6 +65,7 @@ grub_pxe_open (const char *name, grub_disk_t disk) disk->total_sectors = 0; disk->id = (unsigned long) "pxe"; + disk->has_partitions = 0; disk->data = 0; return GRUB_ERR_NONE; diff --git a/normal/completion.c b/normal/completion.c index 7b3de449c..4b38e334d 100644 --- a/normal/completion.c +++ b/normal/completion.c @@ -161,23 +161,14 @@ iterate_dev (const char *devname) if (dev) { - char tmp[grub_strlen (devname) + sizeof (",")]; - - grub_memcpy (tmp, devname, grub_strlen (devname)); - - if (grub_strcmp (devname, current_word) == 0) + if (dev->disk && dev->disk->has_partitions) { - if (add_completion (devname, ")", GRUB_COMPLETION_TYPE_PARTITION)) + if (add_completion (devname, ",", GRUB_COMPLETION_TYPE_DEVICE)) return 1; - - if (dev->disk) - if (grub_partition_iterate (dev->disk, iterate_partition)) - return 1; } else { - grub_memcpy (tmp + grub_strlen (devname), "", sizeof ("")); - if (add_completion (tmp, "", GRUB_COMPLETION_TYPE_DEVICE)) + if (add_completion (devname, ")", GRUB_COMPLETION_TYPE_DEVICE)) return 1; } } @@ -225,7 +216,7 @@ complete_device (void) if (dev) { - if (dev->disk) + if (dev->disk && dev->disk->has_partitions) { if (grub_partition_iterate (dev->disk, iterate_partition)) { diff --git a/normal/misc.c b/normal/misc.c index cddd1d3d3..0a1a2f052 100644 --- a/normal/misc.c +++ b/normal/misc.c @@ -94,8 +94,10 @@ grub_normal_print_device_info (const char *name) grub_errno = GRUB_ERR_NONE; } } - else + else if (! dev->disk->has_partitions || dev->disk->partition) grub_printf ("Unknown filesystem"); + else + grub_printf ("Partition table"); grub_device_close (dev); } From 889a4cbaaa00b168cf29a93933201961e8b5103d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 18 Dec 2009 04:56:55 +0100 Subject: [PATCH 50/52] Eliminate empty line --- efiemu/symbols.c | 1 - 1 file changed, 1 deletion(-) diff --git a/efiemu/symbols.c b/efiemu/symbols.c index f20761565..5b9b2aec7 100644 --- a/efiemu/symbols.c +++ b/efiemu/symbols.c @@ -30,7 +30,6 @@ static int relocated_handle = 0; static int ptv_requested = 0; static struct grub_efiemu_sym *efiemu_syms = 0; - struct grub_efiemu_sym { struct grub_efiemu_sym *next; From 68693c074322d1cf3a2dd734e0ae59d3b98987cd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 18 Dec 2009 04:57:29 +0100 Subject: [PATCH 51/52] Reimpliment grub-dumpdevtree --- util/i386/efi/grub-dumpdevtree | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 util/i386/efi/grub-dumpdevtree diff --git a/util/i386/efi/grub-dumpdevtree b/util/i386/efi/grub-dumpdevtree new file mode 100644 index 000000000..25aa35e23 --- /dev/null +++ b/util/i386/efi/grub-dumpdevtree @@ -0,0 +1,22 @@ +#!/bin/sh +# +# Copyright (C) 2009 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 . + +if [ x$1 == x ]; then + echo "Filename required". +fi + +ioreg -lw0 -p IODeviceTree -n efi -r -x |grep device-properties | sed 's/.*.*//;' | xxd -r -p > $1 From 8463a018b2f621122be9409dd1eb4f9fc07f1534 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 18 Dec 2009 04:58:00 +0100 Subject: [PATCH 52/52] ChangeLog --- ChangeLog.xnu | 159 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 131 insertions(+), 28 deletions(-) diff --git a/ChangeLog.xnu b/ChangeLog.xnu index 442e44c92..a7dfcaf25 100644 --- a/ChangeLog.xnu +++ b/ChangeLog.xnu @@ -1,43 +1,146 @@ -2009-08-29 Vladimir Serbinenko +2009-12-18 Vladimir Serbinenko - * kern/misc.c (grub_utf16_to_utf8): Move from here ... - * include/grub/charset.h (grub_utf16_to_utf8): ... to here. Inlined. - All users updated. - * include/grub/misc.h (grub_utf16_to_utf8): Removed. + Fix potential EfiEmu double prepare. -2009-08-28 Vladimir Serbinenko + * efiemu/main.c (prepared): New variable + (grub_efiemu_unload): Set prepare to '0'. + (grub_efiemu_prepare): Return if already prepared. Set prepared. - * bus/usb/usb.c (grub_usb_get_string): Move from here ... - * commands/usbtest.c (grub_usb_get_string): ... move here. - (usb_print_str): Fix error handling. - * include/grub/usb.h (grub_usb_get_string): Remove. + set_virtual_address_map support. -2009-08-24 Vladimir Serbinenko + * include/grub/efi/efi.h (grub_efi_set_virtual_address_map): New + prototype. + * include/grub/efiemu/efiemu.h (grub_efiemu_write_sym_markers): New + prototype. + (grub_efiemu_crc32): Likewise. + (grub_efiemu_crc64): Likewise. + (grub_efiemu_set_virtual_address_map): Likewise. + * include/grub/autoefi.h (grub_autoefi_exit_boot_services): + New definition. + (grub_autoefi_set_virtual_address_map): Likewise. + * kern/efi/efi.c (grub_efi_set_virtual_address_map): New function. + * loader/i386/xnu.c (grub_xnu_boot): Call set_virtual_address_map. + Restructure flow to accomodate it. + * efiemu/prepare.c (grub_efiemu_prepare): Support set_virtual_address_map. + (grub_efiemu_crc): Recompute CRC32. + * efiemu/runtime/efiemu.c (ptv_relocated): Renamed to ... + (efiemu_ptv_relocated): ... this. Made global. All users updated. + * efiemu/symbols.c (relocated_handle): New variable. + (grub_efiemu_free_syms): Free relocated_handle. + (grub_efiemu_alloc_syms): Allocate relocated_handle. + (grub_efiemu_write_sym_markers): New function. + (grub_efiemu_set_virtual_address_map): Likewise. + + Newer XNU parameters. + + * include/grub/i386/xnu.h (GRUB_XNU_BOOTARGS_VERMINOR): Change to 5. + * include/grub/xnu.h (grub_xnu_extheader): Add nameaddr and namesize. + (grub_xnu_fill_devicetree): New prototype. + (grub_xnu_heap_real_start): New variable. + * loader/xnu.c (get_name_ptr): New function. + (grub_xnu_load_driver): Fill namelen and name. + + 64-bit xnu support. + + * conf/i386-efi.rmk (xnu_mod_SOURCES): Add 'loader/macho32.c' + and 'loader/macho64.c'. + * conf/i386-pc.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * include/grub/i386/macho.h (grub_macho_thread64): New structure. + * include/grub/xnu.h (grub_xnu_is_64bit): New variable. + * include/grub/macho.h (grub_macho_segment64): New structure. + * include/grub/machoload.h (grub_macho32_size): Renamed from ... + (grub_macho_size32): ... to this. + (grub_macho32_get_entry_point): Renamed from ... + (grub_macho_get_entry_point32): ... to this. + (grub_macho_contains_macho64): New prototype. + (grub_macho_size64): Likewise. + (grub_macho_get_entry_point64): Likewise. + (grub_macho32_load): Renamed from ... + (grub_macho_load32): ... to this. + (grub_macho32_filesize): Renamed from ... + (grub_macho_filesize32): ... to this. + (grub_macho32_readfile): Renamed from ... + (grub_macho_readfile32): ... to this. + (grub_macho_filesize64): New prototype. + (grub_macho_readfile64): Likewise. + (grub_macho_parse32): Likewise. + (grub_macho_parse64): Likewise. + * loader/macho.c: Split into ... + * loader/machoXX.c: ... and this. Replace 32 with XX. + * loader/macho32.c: New file. + * loader/macho64.c: Likewise. + * loader/xnu.c (grub_xnu_is_64bit): New variable. + (grub_cmd_xnu_kernel): Make 32-bit only. + (grub_cmd_xnu_kernel64): New function. + (grub_xnu_load_driver): Support Mach-O 64. + (grub_cmd_xnu_mkext): Likewise. + * util/grub.d/30_os-prober.in (osx_entry): New function. + Generate entries for 64-bit boot too. Eliminate ad-hoc tree format in XNU and EfiEmu. * efiemu/main.c (grub_efiemu_prepare): Update comment. * efiemu/pnvram.c: Rewritten to use environment variables. All users updated. - * include/grub/xnu.h (grub_xnu_fill_devicetree): New prototype. - * loader/i386/xnu.c (grub_xnu_boot): Call grub_cpu_xnu_fill_devicetree - and grub_xnu_fill_devicetree. - * loader/xnu.c (grub_cmd_xnu_kernel): Don't call - grub_cpu_xnu_fill_devicetree. - (grub_xnu_parse_devtree): Removed. + + Inline utf16_to_utf8. + + * kern/misc.c (grub_utf16_to_utf8): Move from here ... + * include/grub/charset.h (grub_utf16_to_utf8): ... to here. Inlined. + All users updated. + * include/grub/misc.h (grub_utf16_to_utf8): Removed. + + * bus/usb/usb.c (grub_usb_get_string): Move from here ... + * commands/usbtest.c (grub_usb_get_string): ... move here. + (usb_print_str): Fix error handling. + * include/grub/usb.h (grub_usb_get_string): Remove. + + UTF-8 to UTF-16 transformation. + + * conf/common.rmk (pkglib_MODULES): Add charset.mod + (charset_mod_SOURCES): New variable. + (charset_mod_CFLAGS): Likewise. + (charset_mod_LDFLAGS): Likewise. + * include/grub/utf.h: New file. + * lib/utf.c: New file. (Based on grub_utf8_to_ucs4 from kern/misc.c) + + Support for device properties. + + * include/grub/i386/xnu.h (grub_xnu_devprop_header): New structure. + (grub_xnu_devprop_device_header): Likewise. + (grub_xnu_devprop_device_descriptor): Likewise. + (grub_xnu_devprop_add_device): New prototype. + (grub_xnu_devprop_remove_device): Likewise. + (grub_xnu_devprop_remove_property): Likewise. + (grub_xnu_devprop_add_property_utf8): Likewise. + (grub_xnu_devprop_add_property_utf16): Likewise. + (grub_cpu_xnu_init): Likewise. + (grub_cpu_xnu_fini): Likewise. + (grub_cpu_xnu_unload): Likewise. + * loader/i386/xnu.c (grub_xnu_devprop_device_descriptor): New structure. + (property_descriptor): Likewise. + (devices): New variable. + (grub_xnu_devprop_remove_property): New function. + (grub_xnu_devprop_add_device): Likewise. + (grub_xnu_devprop_remove_device): Likewise. + (grub_xnu_devprop_add_property): Likewise. + (grub_xnu_devprop_add_property_utf8): Likewise. + (grub_xnu_devprop_add_property_utf16): Likewise. + (hextoval): Likewise. + (grub_cpu_xnu_fill_devprop): Likewise. + (grub_cmd_devprop_load): Likewise. + (grub_xnu_boot): Call grub_cpu_xnu_fill_devprop, + grub_xnu_fill_devicetree, grub_xnu_fill_devicetree + (cmd_devprop_load): New variable. + (grub_cpu_xnu_init): New function. + (grub_cpu_xnu_fini): Likewise. + * loader/i386/xnu.c (grub_xnu_unload): Call grub_cpu_xnu_unload. + * loader/xnu.c (grub_xnu_parse_devtree): Remove. (grub_cmd_xnu_devtree): Likewise. (hextoval): New function. (unescape): Likewise. (grub_xnu_fill_devicetree): Likewise. -2009-08-24 Vladimir Serbinenko - - UTF-8 to UTF-16 transformation. - - * conf/common.rmk (pkglib_MODULES): Add utf.mod - (utf_mod_SOURCES): New variable. - (utf_mod_CFLAGS): Likewise. - (utf_mod_LDFLAGS): Likewise. - * include/grub/utf.h: New file. - * lib/utf.c: New file. (Based on grub_utf8_to_ucs4 from kern/misc.c) - + * util/grub.d/30_os-prober.in: Load devprop.bin. Don'r load devtree.txt. + * util/i386/efi/grub-dumpdevtree: Generate devprop.bin.