From ad717faeff732986f1f3d6f55b540e3546782776 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Sep 2010 01:09:00 +0200 Subject: [PATCH 01/28] * Makefile.util.def (libgrub.a): Add missing sunpc. Reported by: Seth Goldberg. --- ChangeLog | 5 +++++ Makefile.util.def | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index f624a70ad..e63b30284 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-01 Vladimir Serbinenko + + * Makefile.util.def (libgrub.a): Add missing sunpc. + Reported by: Seth Goldberg. + 2010-08-30 Vladimir Serbinenko Interrupt wrapping and code simplifications. diff --git a/Makefile.util.def b/Makefile.util.def index 9565dde65..35bcd81b2 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -88,6 +88,7 @@ library = { common = grub-core/partmap/gpt.c; common = grub-core/partmap/msdos.c; common = grub-core/partmap/sun.c; + common = grub-core/partmap/sunpc.c; common = grub-core/script/function.c; common = grub-core/script/lexer.c; common = grub-core/script/main.c; From da2891f9620a706847bbe8f36c06e5b56b31ed40 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 1 Sep 2010 10:29:30 +0100 Subject: [PATCH 02/28] * docs/grub.texi: Add myself as an author. --- ChangeLog | 4 ++++ docs/grub.texi | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index e63b30284..d8851c641 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-01 Colin Watson + + * docs/grub.texi: Add myself as an author. + 2010-09-01 Vladimir Serbinenko * Makefile.util.def (libgrub.a): Add missing sunpc. diff --git a/docs/grub.texi b/docs/grub.texi index 18dc39389..fb0907a59 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -46,6 +46,7 @@ Invariant Sections. @subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}. @author Gordon Matzigkeit @author Yoshinori K. Okuji +@author Colin Watson @c The following two commands start the copyright page. @page @vskip 0pt plus 1filll From 4066f57f1946f459472fc2a8c8f69eab2fd23cab Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 1 Sep 2010 10:32:34 +0100 Subject: [PATCH 03/28] * util/grub-mkrescue.in (usage): Tidy up usage output (and hence generated manual page) a little. --- ChangeLog | 5 +++++ util/grub-mkrescue.in | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d8851c641..220cc61fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-01 Colin Watson + + * util/grub-mkrescue.in (usage): Tidy up usage output (and hence + generated manual page) a little. + 2010-09-01 Colin Watson * docs/grub.texi: Add myself as an author. diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 0f40e92cc..142ee85cd 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -62,7 +62,8 @@ Make GRUB rescue image. $self generates a bootable rescue image with specified source files, source directories, or mkisofs options listed by: xorriso -as mkisofs -help -Option -- switches to native xorriso command mode. or directories. + +Option -- switches to native xorriso command mode. Report bugs to . Mail xorriso support requests to . From f9cefc4eb38f867ccf0419ae7a172d41ec0cd442 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 1 Sep 2010 18:15:46 +0100 Subject: [PATCH 04/28] * NEWS: Document most of the important changes since 1.98. --- ChangeLog | 4 +++ NEWS | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/ChangeLog b/ChangeLog index 220cc61fe..c78bcef7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-01 Colin Watson + + * NEWS: Document most of the important changes since 1.98. + 2010-09-01 Colin Watson * util/grub-mkrescue.in (usage): Tidy up usage output (and hence diff --git a/NEWS b/NEWS index e16504342..bb6b8df3f 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,98 @@ New in 1.99: +* New relocator. Allows for more kernel support and more + straightforward loader writing. + +* Handle USB pendrives exposed as floppies. + +* New Automake-based build system. + +* Add `sendkey' command (i386-pc only). + * ZFS support in `grub-install' and `grub-mkconfig'. Note: complete functionality requires external ZFS implementation (available from grub-extras). +* Support 1.x versions of mdadm metadata. + +* Fix corruption when reading Reiserfs directory entries. + +* Bidirectional text and diacritics support. + +* Skip LVM snapshots. + +* MIPS Yeeloong firmware port. + +* Change grub-mkdevicemap to emit /dev/disk/by-id/ names where possible + on GNU/Linux. + +* Add `grub-mkconfig' support for Xen with Linux. + +* Add `grub-mkconfig' support for initrd images on Fedora 13. + +* Support >3GiB and <16MiB RAM in i386-qemu. + +* Add support for Cirrus 5446 and Bochs video cards. + +* Load more appropriate video drivers automatically in `grub-mkconfig'. + +* USB improvements, including hotplugging/hotunplugging, hub support, + and USB serial support. + +* AMD Geode CS5536 support. + +* Extensive updates to the Texinfo documentation. + +* Add `grub-probe' support for the btrfs filesystem, permitting / to + reside on btrfs as long as /boot is on a filesystem natively supported + by GRUB. + +* Handle symbolic links under /dev/mapper on GNU/Linux. + +* Handle installation across multiple partition table types. + +* Add `cmostest' command (i386/x86_64 only). + +* Add support for DM-RAID disk devices on GNU/Linux. + +* Remove `grub-mkisofs'. `grub-mkrescue' now uses GNU xorriso to build + CD images. + +* `grub-mkrescue' support for EFI, coreboot, and QEMU platforms. + +* Unify `grub-mkimage' source code across platforms. + +* Fix VGA (as opposed to VBE) video driver, formerly a terminal driver. + +* Add menu hotkey support. + +* Add support for the nilfs2 filesystem. + +* `grub-probe' and `grub-mkconfig' support for NetBSD. + +* Support setting a background image in `grub-mkconfig'. + +* Support multiple terminals in `grub-mkconfig'. + +* Regexp support. + +* MIPS multiboot2 support. + +* Multiboot2 tag support. + +* sunpc partition table support. + +* Add a number of new language features to GRUB script: `for', `while', + `until', `elif', function parameters, `break', `continue', and + `shift'. + +* Support nested partition tables. GRUB now prefers to name partitions + in the form `(hd0,msdos1,bsd1)' rather than `(hd0,1,a)'. + +* Speed up consecutive hostdisk operations on the same device. + +* Compile parts of `grub-emu' as modules. + New in 1.98 - 2010-03-06: * Multiboot on EFI support. From 9a093920572de083c853b85b7372c6ca608b1677 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Sep 2010 15:47:03 +0200 Subject: [PATCH 05/28] Fix grub_pxe_scan. * grub-core/fs/i386/pc/pxe.c (grub_pxe_pxenv): Put correct type bangpxe. (grub_pxe_scan): Fix types and pxe_rm_entry computation. All users updated. * include/grub/i386/pc/pxe.h (grub_pxe_bangpxe): New struct. (grub_pxe_pxenv): Correct type. --- ChangeLog | 10 ++++++++++ grub-core/fs/i386/pc/pxe.c | 36 +++++++++++++++++++++--------------- include/grub/i386/pc/pxe.h | 15 ++++++++++++++- 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index c78bcef7d..ce3141985 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-09-02 Vladimir Serbinenko + + Fix grub_pxe_scan. + + * grub-core/fs/i386/pc/pxe.c (grub_pxe_pxenv): Put correct type bangpxe. + (grub_pxe_scan): Fix types and pxe_rm_entry computation. + All users updated. + * include/grub/i386/pc/pxe.h (grub_pxe_bangpxe): New struct. + (grub_pxe_pxenv): Correct type. + 2010-09-01 Colin Watson * NEWS: Document most of the important changes since 1.98. diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c index 0dd44a30a..ee8c55416 100644 --- a/grub-core/fs/i386/pc/pxe.c +++ b/grub-core/fs/i386/pc/pxe.c @@ -41,7 +41,7 @@ struct grub_pxe_disk_data grub_uint32_t gateway_ip; }; -struct grub_pxenv *grub_pxe_pxenv; +struct grub_pxe_bangpxe *grub_pxe_pxenv; static grub_uint32_t grub_pxe_your_ip; static grub_uint32_t grub_pxe_default_server_ip; static grub_uint32_t grub_pxe_default_gateway_ip; @@ -58,41 +58,47 @@ struct grub_pxe_data static grub_uint32_t pxe_rm_entry = 0; -static struct grub_pxenv * +static struct grub_pxe_bangpxe * grub_pxe_scan (void) { struct grub_bios_int_registers regs; - struct grub_pxenv *ret; - void *pxe; + struct grub_pxenv *pxenv; + struct grub_pxe_bangpxe *bangpxe; regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; regs.ebx = 0; regs.ecx = 0; regs.eax = 0x5650; + regs.es = 0; grub_bios_interrupt (0x1a, ®s); if ((regs.eax & 0xffff) != 0x564e) return NULL; - ret = (struct grub_pxenv *) ((regs.es << 4) + (regs.ebx & 0xffff)); - if (grub_memcmp (ret->signature, GRUB_PXE_SIGNATURE, sizeof (ret->signature)) + + pxenv = (struct grub_pxenv *) ((regs.es << 4) + (regs.ebx & 0xffff)); + if (grub_memcmp (pxenv->signature, GRUB_PXE_SIGNATURE, + sizeof (pxenv->signature)) != 0) return NULL; - if (ret->version < 0x201) + + if (pxenv->version < 0x201) return NULL; - pxe = (void *) ((((ret->pxe_ptr & 0xffff0000) >> 16) << 4) - + (ret->pxe_ptr & 0xffff)); - if (!pxe) + bangpxe = (void *) ((((pxenv->pxe_ptr & 0xffff0000) >> 16) << 4) + + (pxenv->pxe_ptr & 0xffff)); + + if (!bangpxe) return NULL; - /* !PXE */ - if (*(grub_uint32_t *) pxe != 0x45585021) + if (grub_memcmp (bangpxe->signature, GRUB_PXE_BANGPXE_SIGNATURE, + sizeof (bangpxe->signature)) != 0) return NULL; - pxe_rm_entry = ret->rm_entry; - return ret; + pxe_rm_entry = bangpxe->rm_entry; + + return bangpxe; } static int @@ -483,7 +489,7 @@ parse_dhcp_vendor (void *vend, int limit) static void grub_pxe_detect (void) { - struct grub_pxenv *pxenv; + struct grub_pxe_bangpxe *pxenv; struct grub_pxenv_get_cached_info ci; struct grub_pxenv_boot_player *bp; diff --git a/include/grub/i386/pc/pxe.h b/include/grub/i386/pc/pxe.h index 049dd1950..62ece21b0 100644 --- a/include/grub/i386/pc/pxe.h +++ b/include/grub/i386/pc/pxe.h @@ -192,6 +192,19 @@ struct grub_pxenv grub_uint32_t pxe_ptr; /* SEG:OFF to !PXE struct. */ } __attribute__ ((packed)); +struct grub_pxe_bangpxe +{ + grub_uint8_t signature[4]; +#define GRUB_PXE_BANGPXE_SIGNATURE "!PXE" + grub_uint8_t length; + grub_uint8_t chksum; + grub_uint8_t rev; + grub_uint8_t reserved; + grub_uint32_t undiromid; + grub_uint32_t baseromid; + grub_uint32_t rm_entry; +} __attribute__ ((packed)); + struct grub_pxenv_get_cached_info { grub_uint16_t status; @@ -306,7 +319,7 @@ struct grub_pxenv_unload_stack int EXPORT_FUNC(grub_pxe_call) (int func, void * data, grub_uint32_t pxe_rm_entry); -extern struct grub_pxenv *grub_pxe_pxenv; +extern struct grub_pxe_bangpxe *grub_pxe_pxenv; void grub_pxe_unload (void); From 529cc99acf9bbb8ac07d95e30af99fa1fefdac4b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Sep 2010 16:07:52 +0200 Subject: [PATCH 06/28] Add i386-pc-pxe image target. * util/grub-mkimage.c (image_target_desc): New enum value IMAGE_I386_PC_PXE. (image_targets): New target i386-pc-pxe. (generate_image): Handle i386-pc-pxe image. --- ChangeLog | 9 +++++++++ util/grub-mkimage.c | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ce3141985..4b1ccafd3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-09-02 Vladimir Serbinenko + + Add i386-pc-pxe image target. + + * util/grub-mkimage.c (image_target_desc): New enum value + IMAGE_I386_PC_PXE. + (image_targets): New target i386-pc-pxe. + (generate_image): Handle i386-pc-pxe image. + 2010-09-02 Vladimir Serbinenko Fix grub_pxe_scan. diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 0e82afae9..4e151dd62 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -54,7 +54,8 @@ struct image_target_desc enum { IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT, IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275, - IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH + IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH, + IMAGE_I386_PC_PXE } id; enum { @@ -140,6 +141,24 @@ struct image_target_desc image_targets[] = .install_bsd_part = GRUB_KERNEL_I386_PC_INSTALL_BSD_PART, .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR }, + { + .name = "i386-pc-pxe", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_PC_PXE, + .flags = PLATFORM_FLAGS_LZMA, + .prefix = GRUB_KERNEL_I386_PC_PREFIX, + .data_end = GRUB_KERNEL_I386_PC_DATA_END, + .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, + .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, + .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, + .compressed_size = GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, + .install_bsd_part = GRUB_KERNEL_I386_PC_INSTALL_BSD_PART, + .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR + }, { .name = "i386-efi", .voidp_sizeof = 4, @@ -664,6 +683,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], switch (image_target->id) { case IMAGE_I386_PC: + case IMAGE_I386_PC_PXE: { unsigned num; char *boot_path, *boot_img; @@ -678,6 +698,20 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], if (num > 0xffff) grub_util_error (_("the core image is too big")); + if (image_target->id == IMAGE_I386_PC_PXE) + { + char *pxeboot_path, *pxeboot_img; + size_t pxeboot_size; + + pxeboot_path = grub_util_get_path (dir, "pxeboot.img"); + pxeboot_size = grub_util_get_image_size (pxeboot_path); + pxeboot_img = grub_util_read_image (pxeboot_path); + + grub_util_write_image (pxeboot_img, pxeboot_size, out); + free (pxeboot_img); + free (pxeboot_path); + } + boot_path = grub_util_get_path (dir, "diskboot.img"); boot_size = grub_util_get_image_size (boot_path); if (boot_size != GRUB_DISK_SECTOR_SIZE) From 9056cbf38e490413e7fb66702e7b1809eaf7a1ee Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 2 Sep 2010 22:36:09 +0100 Subject: [PATCH 07/28] Zero %ebp and %edi when entering Linux's 32-bit entry point, as required by the boot protocol. * include/grub/i386/relocator.h (struct grub_relocator32_state): Add ebp and edi members. * grub-core/lib/i386/relocator.c (grub_relocator_boot): Handle state.ebp and state.edi. * grub-core/lib/i386/relocator32.S (grub_relocator32_start): Set %ebp and %edi according to grub_relocator32_ebp and grub_relocator32_edi respectively. * grub-core/loader/i386/linux.c (grub_linux_boot): Zero state.ebp and state.edi. --- ChangeLog | 15 +++++++++++++++ grub-core/lib/i386/relocator.c | 4 ++++ grub-core/lib/i386/relocator32.S | 16 +++++++++++++++- grub-core/loader/i386/linux.c | 2 +- include/grub/i386/relocator.h | 2 ++ 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4b1ccafd3..a12035634 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2010-09-02 Colin Watson + + Zero %ebp and %edi when entering Linux's 32-bit entry point, as + required by the boot protocol. + + * include/grub/i386/relocator.h (struct grub_relocator32_state): Add + ebp and edi members. + * grub-core/lib/i386/relocator.c (grub_relocator_boot): Handle + state.ebp and state.edi. + * grub-core/lib/i386/relocator32.S (grub_relocator32_start): Set + %ebp and %edi according to grub_relocator32_ebp and + grub_relocator32_edi respectively. + * grub-core/loader/i386/linux.c (grub_linux_boot): Zero state.ebp + and state.edi. + 2010-09-02 Vladimir Serbinenko Add i386-pc-pxe image target. diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c index f06a6ef86..1bc4240c3 100644 --- a/grub-core/lib/i386/relocator.c +++ b/grub-core/lib/i386/relocator.c @@ -59,7 +59,9 @@ extern grub_uint32_t grub_relocator32_ecx; extern grub_uint32_t grub_relocator32_edx; extern grub_uint32_t grub_relocator32_eip; extern grub_uint32_t grub_relocator32_esp; +extern grub_uint32_t grub_relocator32_ebp; extern grub_uint32_t grub_relocator32_esi; +extern grub_uint32_t grub_relocator32_edi; extern grub_uint8_t grub_relocator64_start; extern grub_uint8_t grub_relocator64_end; @@ -165,7 +167,9 @@ grub_relocator32_boot (struct grub_relocator *rel, grub_relocator32_edx = state.edx; grub_relocator32_eip = state.eip; grub_relocator32_esp = state.esp; + grub_relocator32_ebp = state.ebp; grub_relocator32_esi = state.esi; + grub_relocator32_edi = state.edi; grub_memmove (get_virtual_current_address (ch), &grub_relocator32_start, RELOCATOR_SIZEOF (32)); diff --git a/grub-core/lib/i386/relocator32.S b/grub-core/lib/i386/relocator32.S index b581305a5..09ce56ad0 100644 --- a/grub-core/lib/i386/relocator32.S +++ b/grub-core/lib/i386/relocator32.S @@ -65,13 +65,27 @@ VARIABLE(grub_relocator32_esp) movl %eax, %esp + /* mov imm32, %eax */ + .byte 0xb8 +VARIABLE(grub_relocator32_ebp) + .long 0 + + movl %eax, %ebp + /* mov imm32, %eax */ .byte 0xb8 VARIABLE(grub_relocator32_esi) .long 0 movl %eax, %esi - + + /* mov imm32, %eax */ + .byte 0xb8 +VARIABLE(grub_relocator32_edi) + .long 0 + + movl %eax, %edi + /* mov imm32, %eax */ .byte 0xb8 VARIABLE(grub_relocator32_eax) diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index debcdb71f..9cb26a0c2 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -716,7 +716,7 @@ grub_linux_boot (void) /* FIXME. */ /* asm volatile ("lidt %0" : : "m" (idt_desc)); */ - state.ebx = 0; + state.ebp = state.edi = state.ebx = 0; state.esi = real_mode_target; state.esp = real_mode_target; state.eip = params->code32_start; diff --git a/include/grub/i386/relocator.h b/include/grub/i386/relocator.h index 891235f9b..6ff5c6631 100644 --- a/include/grub/i386/relocator.h +++ b/include/grub/i386/relocator.h @@ -26,12 +26,14 @@ struct grub_relocator32_state { grub_uint32_t esp; + grub_uint32_t ebp; grub_uint32_t eax; grub_uint32_t ebx; grub_uint32_t ecx; grub_uint32_t edx; grub_uint32_t eip; grub_uint32_t esi; + grub_uint32_t edi; }; struct grub_relocator16_state From c2a4eba698d6d928aaf974d06ffa28dbda7a2052 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 2 Sep 2010 22:42:36 +0100 Subject: [PATCH 08/28] * .bzrignore: Add *.pp, **/.dirstamp, grub-core/*.module, and grub-core/*.pp. --- .bzrignore | 4 ++++ ChangeLog | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/.bzrignore b/.bzrignore index 3c7150afb..cfdd069fd 100644 --- a/.bzrignore +++ b/.bzrignore @@ -69,6 +69,7 @@ Makefile mod-*.c missing *.pf2 +*.pp po/*.mo po/grub.pot stamp-h @@ -91,7 +92,10 @@ texinfo.tex grub-core/lib/libgcrypt-grub **/.deps-util **/.deps-core +**/.dirstamp Makefile.util.am grub-core/Makefile.core.am grub-core/Makefile.gcry.am grub-core/Makefile.gcry.def +grub-core/*.module +grub-core/*.pp diff --git a/ChangeLog b/ChangeLog index a12035634..0f04c8c79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-02 Colin Watson + + * .bzrignore: Add *.pp, **/.dirstamp, grub-core/*.module, and + grub-core/*.pp. + 2010-09-02 Colin Watson Zero %ebp and %edi when entering Linux's 32-bit entry point, as From 03e261d84cb3cde4776185f573088165c9a353a6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Sep 2010 23:50:07 +0200 Subject: [PATCH 09/28] * grub-core/kern/i386/multiboot_mmap.c: Remove leftover include. --- ChangeLog | 4 ++++ grub-core/kern/i386/multiboot_mmap.c | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0f04c8c79..b144c9507 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-02 Vladimir Serbinenko + + * grub-core/kern/i386/multiboot_mmap.c: Remove leftover include. + 2010-09-02 Colin Watson * .bzrignore: Add *.pp, **/.dirstamp, grub-core/*.module, and diff --git a/grub-core/kern/i386/multiboot_mmap.c b/grub-core/kern/i386/multiboot_mmap.c index 0f463c23c..73c82049f 100644 --- a/grub-core/kern/i386/multiboot_mmap.c +++ b/grub-core/kern/i386/multiboot_mmap.c @@ -16,7 +16,6 @@ * along with GRUB. If not, see . */ -#include #include #include #include From ef8e0ec8ed9a598f6818ff08a775261a1ff3742d Mon Sep 17 00:00:00 2001 From: Ian Turner Date: Thu, 2 Sep 2010 23:59:27 +0200 Subject: [PATCH 10/28] * grub-core/fs/i386/pc/pxe.c (grub_pxefs_read): Keep the blocksize constant for the same file. --- ChangeLog | 5 +++++ grub-core/fs/i386/pc/pxe.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b144c9507..6587cf6b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-02 Ian Turner + + * grub-core/fs/i386/pc/pxe.c (grub_pxefs_read): Keep the blocksize + constant for the same file. + 2010-09-02 Vladimir Serbinenko * grub-core/kern/i386/multiboot_mmap.c: Remove leftover include. diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c index ee8c55416..90dfd5067 100644 --- a/grub-core/fs/i386/pc/pxe.c +++ b/grub-core/fs/i386/pc/pxe.c @@ -327,7 +327,7 @@ grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len) o.gateway_ip = disk_data->gateway_ip; grub_strcpy ((char *)&o.filename[0], data->filename); o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT); - o.packet_size = grub_pxe_blksize; + o.packet_size = data->block_size; grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o, pxe_rm_entry); if (o.status) { From 61d720e53536d3c6bb57b26e427bc11d2dbf9e4f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 3 Sep 2010 00:53:41 +0200 Subject: [PATCH 11/28] * configure.ac: Check for dm_log_with_errno_init in libdevmapper and echo if libdevmapper will be used. --- ChangeLog | 5 +++++ configure.ac | 24 ++++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6587cf6b6..e0249e4ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-02 Vladimir Serbinenko + + * configure.ac: Check for dm_log_with_errno_init in libdevmapper and + echo if libdevmapper will be used. + 2010-09-02 Ian Turner * grub-core/fs/i386/pc/pxe.c (grub_pxefs_read): Keep the blocksize diff --git a/configure.ac b/configure.ac index 9fa460620..d71d94522 100644 --- a/configure.ac +++ b/configure.ac @@ -822,12 +822,23 @@ fi if test x"$device_mapper_excuse" = x ; then # Check for device-mapper library. - AC_CHECK_LIB([devmapper], [dm_task_create], - [LIBDEVMAPPER="-ldevmapper" - AC_DEFINE([HAVE_DEVICE_MAPPER], [1], - [Define to 1 if you have the devmapper library.])], + AC_CHECK_LIB([devmapper], [dm_task_create], [], [device_mapper_excuse="need devmapper library"]) fi + +if test x"$device_mapper_excuse" = x ; then + # Check for device-mapper library. + AC_CHECK_LIB([devmapper], [dm_log_with_errno_init], + [], + [device_mapper_excuse="need devmapper library"]) +fi + +if test x"$device_mapper_excuse" = x ; then + LIBDEVMAPPER="-ldevmapper"; + AC_DEFINE([HAVE_DEVICE_MAPPER], [1], + [Define to 1 if you have the devmapper library.]) +fi + AC_SUBST([LIBDEVMAPPER]) AC_CHECK_LIB([zfs], [libzfs_init], @@ -942,6 +953,11 @@ else echo PCI support for grub-emu: No "($grub_emu_pci_excuse)" fi fi +if test x"$device_mapper_excuse" = x ; then +echo With devmapper support: Yes +else +echo With devmapper support: No "($device_mapper_excuse)" +fi if [ x"$enable_mm_debug" = xyes ]; then echo With memory debugging: Yes else From efa1bee7a153f4f73aa6a9b33c23b5ccedb6b1d3 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 2 Sep 2010 23:57:21 +0100 Subject: [PATCH 12/28] * INSTALL: Document that libdevmapper needs to be 1.02.34 or later. --- ChangeLog | 4 ++++ INSTALL | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e0249e4ba..2e9be10c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-02 Colin Watson + + * INSTALL: Document that libdevmapper needs to be 1.02.34 or later. + 2010-09-02 Vladimir Serbinenko * configure.ac: Check for dm_log_with_errno_init in libdevmapper and diff --git a/INSTALL b/INSTALL index bbfa01f0a..e325fa2b2 100644 --- a/INSTALL +++ b/INSTALL @@ -21,7 +21,7 @@ configuring the GRUB. On GNU/Linux, you also need: -* libdevmapper (recommended) +* libdevmapper 1.02.34 or later (recommended) To build grub-emu, you need: From 9f915872efad66036efff88ecbc705daa0350299 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 3 Sep 2010 03:26:22 +0200 Subject: [PATCH 13/28] * configure.ac: Clean LIBS variable after tests. --- ChangeLog | 4 ++++ configure.ac | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 2e9be10c5..69d46b55c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-02 Vladimir Serbinenko + + * configure.ac: Clean LIBS variable after tests. + 2010-09-02 Colin Watson * INSTALL: Document that libdevmapper needs to be 1.02.34 or later. diff --git a/configure.ac b/configure.ac index d71d94522..d362f68a5 100644 --- a/configure.ac +++ b/configure.ac @@ -853,6 +853,8 @@ AC_CHECK_LIB([nvpair], [nvlist_print], [Define to 1 if you have the NVPAIR library.])],) AC_SUBST([LIBNVPAIR]) +LIBS="" + pkglibrootdir='$(libdir)'/`echo $PACKAGE | sed "$program_transform_name"` AC_SUBST(pkglibrootdir) From a7c00cdb94b9792a74f1ed75c8172c6ee851d094 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 3 Sep 2010 14:05:19 +0200 Subject: [PATCH 14/28] * grub-core/loader/i386/bsd.c (grub_freebsd_boot): Set %ebp to sane value. (grub_openbsd_boot): Likewise. (grub_netbsd_boot): Likewise. * grub-core/loader/i386/xnu.c (grub_xnu_boot_resume): Likewise. (grub_xnu_boot): Likewise. --- ChangeLog | 9 +++++++++ grub-core/loader/i386/bsd.c | 5 ++++- grub-core/loader/i386/xnu.c | 2 ++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 69d46b55c..6c9e3bf6d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-09-03 Vladimir Serbinenko + + * grub-core/loader/i386/bsd.c (grub_freebsd_boot): Set %ebp to sane + value. + (grub_openbsd_boot): Likewise. + (grub_netbsd_boot): Likewise. + * grub-core/loader/i386/xnu.c (grub_xnu_boot_resume): Likewise. + (grub_xnu_boot): Likewise. + 2010-09-02 Vladimir Serbinenko * configure.ac: Clean LIBS variable after tests. diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index cfea3b6a1..d72c8195a 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -746,6 +746,7 @@ grub_freebsd_boot (void) grub_memcpy (&stack[9], &bi, sizeof (bi)); state.eip = entry; state.esp = stack_target; + state.ebp = stack_target; stack[0] = entry; /* "Return" address. */ stack[1] = bootflags | FREEBSD_RB_BOOTINFO; stack[2] = bootdev; @@ -830,7 +831,8 @@ grub_openbsd_boot (void) #endif state.eip = entry; - state.esp = ((grub_uint8_t *) stack - (grub_uint8_t *) buf0) + buf_target; + state.ebp = state.esp + = ((grub_uint8_t *) stack - (grub_uint8_t *) buf0) + buf_target; stack[0] = entry; stack[1] = bootflags; stack[2] = openbsd_root; @@ -1045,6 +1047,7 @@ grub_netbsd_boot (void) state.eip = entry; state.esp = stack_target; + state.ebp = stack_target; stack[0] = entry; stack[1] = bootflags; stack[2] = 0; diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c index 556f1dbf1..d35e9e0aa 100644 --- a/grub-core/loader/i386/xnu.c +++ b/grub-core/loader/i386/xnu.c @@ -836,6 +836,7 @@ grub_xnu_boot_resume (void) struct grub_relocator32_state state; state.esp = grub_xnu_stack; + state.ebp = grub_xnu_stack; state.eip = grub_xnu_entry_point; state.eax = grub_xnu_arg1; @@ -1114,6 +1115,7 @@ grub_xnu_boot (void) state.eip = grub_xnu_entry_point; state.eax = grub_xnu_arg1; state.esp = grub_xnu_stack; + state.ebp = grub_xnu_stack; return grub_relocator32_boot (grub_xnu_relocator, state); } From c8e7bf5ff7bb4fb1b2b9b98ddab057f2dc03a7cf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 3 Sep 2010 14:54:04 +0200 Subject: [PATCH 15/28] Compress grub_prefix. * grub-core/boot/i386/pc/lnxboot.S: Use GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE. * grub-core/kern/i386/pc/startup.S: Move grub_prefix to compressed part. * include/grub/offsets.h: Rename GRUB_MACHINE_DATA_END to GRUB_MACHINE_PREFIX_END. All users updated. (GRUB_KERNEL_I386_PC_PREFIX): Set to GRUB_KERNEL_I386_PC_RAW_SIZE. (GRUB_KERNEL_I386_PC_PREFIX_END): Set to GRUB_KERNEL_I386_PC_PREFIX + 0x40. (GRUB_KERNEL_I386_PC_RAW_SIZE): Decrease. * util/grub-mkimage.c (image_target_desc): Change data_end to prefix_end. All users updated. --- ChangeLog | 16 +++++++++++ grub-core/boot/i386/pc/lnxboot.S | 2 +- grub-core/kern/i386/coreboot/startup.S | 2 +- grub-core/kern/i386/ieee1275/startup.S | 2 +- grub-core/kern/i386/pc/startup.S | 18 ++++++------ grub-core/kern/i386/qemu/startup.S | 2 +- grub-core/kern/mips/startup.S | 2 +- grub-core/kern/powerpc/ieee1275/startup.S | 2 +- grub-core/kern/sparc64/ieee1275/crt0.S | 2 +- include/grub/offsets.h | 35 ++++++++++++----------- util/grub-mkimage.c | 30 +++++++++---------- 11 files changed, 67 insertions(+), 46 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6c9e3bf6d..cbd0337ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2010-09-03 Vladimir Serbinenko + + Compress grub_prefix. + + * grub-core/boot/i386/pc/lnxboot.S: Use + GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE. + * grub-core/kern/i386/pc/startup.S: Move grub_prefix to compressed part. + * include/grub/offsets.h: Rename GRUB_MACHINE_DATA_END to + GRUB_MACHINE_PREFIX_END. All users updated. + (GRUB_KERNEL_I386_PC_PREFIX): Set to GRUB_KERNEL_I386_PC_RAW_SIZE. + (GRUB_KERNEL_I386_PC_PREFIX_END): Set to GRUB_KERNEL_I386_PC_PREFIX + + 0x40. + (GRUB_KERNEL_I386_PC_RAW_SIZE): Decrease. + * util/grub-mkimage.c (image_target_desc): Change data_end to + prefix_end. All users updated. + 2010-09-03 Vladimir Serbinenko * grub-core/loader/i386/bsd.c (grub_freebsd_boot): Set %ebp to sane diff --git a/grub-core/boot/i386/pc/lnxboot.S b/grub-core/boot/i386/pc/lnxboot.S index b4f0030b8..9348553c3 100644 --- a/grub-core/boot/i386/pc/lnxboot.S +++ b/grub-core/boot/i386/pc/lnxboot.S @@ -185,7 +185,7 @@ real_code_2: call LOCAL(move_memory) /* Check for multiboot signature. */ - cmpl $MULTIBOOT_HEADER_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_DATA_END) + cmpl $MULTIBOOT_HEADER_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE) jz 1f movl (ramdisk_image - start), %esi diff --git a/grub-core/kern/i386/coreboot/startup.S b/grub-core/kern/i386/coreboot/startup.S index ec3a0e64b..592073776 100644 --- a/grub-core/kern/i386/coreboot/startup.S +++ b/grub-core/kern/i386/coreboot/startup.S @@ -51,7 +51,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_MACHINE_DATA_END + . = _start + GRUB_KERNEL_MACHINE_PREFIX_END /* * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). diff --git a/grub-core/kern/i386/ieee1275/startup.S b/grub-core/kern/i386/ieee1275/startup.S index 2a04753df..3ecf09598 100644 --- a/grub-core/kern/i386/ieee1275/startup.S +++ b/grub-core/kern/i386/ieee1275/startup.S @@ -51,7 +51,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_MACHINE_DATA_END + . = _start + GRUB_KERNEL_MACHINE_PREFIX_END codestart: movl %eax, EXT_C(grub_ieee1275_entry_fn) diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index b5e9a9b85..9b53deeb2 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -100,14 +100,6 @@ VARIABLE(grub_install_dos_part) .long 0xFFFFFFFF VARIABLE(grub_install_bsd_part) .long 0xFFFFFFFF -VARIABLE(grub_prefix) - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - - . = _start + GRUB_KERNEL_MACHINE_DATA_END #ifdef APPLE_CC bss_start: @@ -450,6 +442,16 @@ gate_a20_check_state: */ . = _start + GRUB_KERNEL_MACHINE_RAW_SIZE + . = _start + GRUB_KERNEL_MACHINE_PREFIX +VARIABLE(grub_prefix) + /* to be filled by grub-mkimage */ + + /* + * Leave some breathing room for the prefix. + */ + . = _start + GRUB_KERNEL_MACHINE_PREFIX_END + + /* * grub_exit() diff --git a/grub-core/kern/i386/qemu/startup.S b/grub-core/kern/i386/qemu/startup.S index e705953b5..680de9dc4 100644 --- a/grub-core/kern/i386/qemu/startup.S +++ b/grub-core/kern/i386/qemu/startup.S @@ -39,7 +39,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_MACHINE_DATA_END + . = _start + GRUB_KERNEL_MACHINE_PREFIX_END codestart: /* Relocate to low memory. First we figure out our location. diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index 134853a9d..6811353ea 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -154,7 +154,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_MACHINE_DATA_END + . = _start + GRUB_KERNEL_MACHINE_PREFIX_END #ifdef GRUB_MACHINE_MIPS_YEELOONG VARIABLE (grub_arch_busclock) .long 0 diff --git a/grub-core/kern/powerpc/ieee1275/startup.S b/grub-core/kern/powerpc/ieee1275/startup.S index 526df1d91..0b1c23346 100644 --- a/grub-core/kern/powerpc/ieee1275/startup.S +++ b/grub-core/kern/powerpc/ieee1275/startup.S @@ -39,7 +39,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_MACHINE_DATA_END + . = _start + GRUB_KERNEL_MACHINE_PREFIX_END codestart: li 2, 0 diff --git a/grub-core/kern/sparc64/ieee1275/crt0.S b/grub-core/kern/sparc64/ieee1275/crt0.S index f0f47416d..f178f5d3c 100644 --- a/grub-core/kern/sparc64/ieee1275/crt0.S +++ b/grub-core/kern/sparc64/ieee1275/crt0.S @@ -42,7 +42,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = EXT_C(_start) + GRUB_KERNEL_MACHINE_DATA_END + . = EXT_C(_start) + GRUB_KERNEL_MACHINE_PREFIX_END codestart: /* Copy the modules past the end of the kernel image. diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 7763e488c..47eb6c9bd 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -34,14 +34,17 @@ /* The offset of GRUB_INSTALL_BSD_PART. */ #define GRUB_KERNEL_I386_PC_INSTALL_BSD_PART 0x18 -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_I386_PC_PREFIX 0x1c - -/* End of the data section. */ -#define GRUB_KERNEL_I386_PC_DATA_END 0x5c +/* The offset of multiboot signature. */ +#define GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE 0x1c /* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_I386_PC_RAW_SIZE (GRUB_KERNEL_I386_PC_DATA_END + 0x5F0) +#define GRUB_KERNEL_I386_PC_RAW_SIZE 0x5D8 + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_I386_PC_PREFIX GRUB_KERNEL_I386_PC_RAW_SIZE + +/* End of the data section. */ +#define GRUB_KERNEL_I386_PC_PREFIX_END (GRUB_KERNEL_I386_PC_PREFIX + 0x40) /* The segment where the kernel is loaded. */ #define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 @@ -65,7 +68,7 @@ #define GRUB_KERNEL_I386_QEMU_PREFIX 0x10 /* End of the data section. */ -#define GRUB_KERNEL_I386_QEMU_DATA_END 0x50 +#define GRUB_KERNEL_I386_QEMU_PREFIX_END 0x50 #define GRUB_KERNEL_I386_QEMU_LINK_ADDR 0x8200 @@ -82,7 +85,7 @@ #define GRUB_KERNEL_SPARC64_IEEE1275_PREFIX 0x14 /* End of the data section. */ -#define GRUB_KERNEL_SPARC64_IEEE1275_DATA_END 0x114 +#define GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END 0x114 #define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12 @@ -91,7 +94,7 @@ #define GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR 0x4400 #define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX 0x4 -#define GRUB_KERNEL_POWERPC_IEEE1275_DATA_END 0x44 +#define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX_END 0x44 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR 0x200000 @@ -105,29 +108,29 @@ #define GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE 0x10 #define GRUB_KERNEL_MIPS_YEELOONG_PREFIX GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE -#define GRUB_KERNEL_MIPS_YEELOONG_DATA_END GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE + 0x48 +#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE + 0x48 /* The offset of GRUB_PREFIX. */ #define GRUB_KERNEL_I386_EFI_PREFIX 0x8 /* End of the data section. */ -#define GRUB_KERNEL_I386_EFI_DATA_END 0x50 +#define GRUB_KERNEL_I386_EFI_PREFIX_END 0x50 /* The offset of GRUB_PREFIX. */ #define GRUB_KERNEL_X86_64_EFI_PREFIX 0x8 /* End of the data section. */ -#define GRUB_KERNEL_X86_64_EFI_DATA_END 0x50 +#define GRUB_KERNEL_X86_64_EFI_PREFIX_END 0x50 #define GRUB_KERNEL_I386_COREBOOT_PREFIX 0x2 -#define GRUB_KERNEL_I386_COREBOOT_DATA_END 0x42 +#define GRUB_KERNEL_I386_COREBOOT_PREFIX_END 0x42 #define GRUB_KERNEL_I386_COREBOOT_LINK_ADDR 0x8200 #define GRUB_KERNEL_I386_MULTIBOOT_PREFIX GRUB_KERNEL_I386_COREBOOT_PREFIX -#define GRUB_KERNEL_I386_MULTIBOOT_DATA_END GRUB_KERNEL_I386_COREBOOT_DATA_END +#define GRUB_KERNEL_I386_MULTIBOOT_PREFIX_END GRUB_KERNEL_I386_COREBOOT_PREFIX_END #define GRUB_KERNEL_I386_IEEE1275_PREFIX 0x2 -#define GRUB_KERNEL_I386_IEEE1275_DATA_END 0x42 +#define GRUB_KERNEL_I386_IEEE1275_PREFIX_END 0x42 #define GRUB_KERNEL_I386_IEEE1275_LINK_ADDR 0x10000 #define GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN 0x1000 @@ -157,7 +160,7 @@ #define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _COMPRESSED_SIZE) #define GRUB_KERNEL_MACHINE_PREFIX GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _PREFIX) -#define GRUB_KERNEL_MACHINE_DATA_END GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _DATA_END) +#define GRUB_KERNEL_MACHINE_PREFIX_END GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _PREFIX_END) #define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, MACHINE, _KERNEL_SEG) #define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, MACHINE, _UPPER) #define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _RAW_SIZE) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 4e151dd62..d798ad052 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -63,7 +63,7 @@ struct image_target_desc PLATFORM_FLAGS_LZMA = 1 } flags; unsigned prefix; - unsigned data_end; + unsigned prefix_end; unsigned raw_size; unsigned total_module_size; unsigned kernel_image_size; @@ -86,7 +86,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_COREBOOT, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_I386_COREBOOT_PREFIX, - .data_end = GRUB_KERNEL_I386_COREBOOT_DATA_END, + .prefix_end = GRUB_KERNEL_I386_COREBOOT_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -108,7 +108,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_COREBOOT, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_I386_MULTIBOOT_PREFIX, - .data_end = GRUB_KERNEL_I386_MULTIBOOT_DATA_END, + .prefix_end = GRUB_KERNEL_I386_MULTIBOOT_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -130,7 +130,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_I386_PC, .flags = PLATFORM_FLAGS_LZMA, .prefix = GRUB_KERNEL_I386_PC_PREFIX, - .data_end = GRUB_KERNEL_I386_PC_DATA_END, + .prefix_end = GRUB_KERNEL_I386_PC_PREFIX_END, .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, @@ -148,7 +148,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_I386_PC_PXE, .flags = PLATFORM_FLAGS_LZMA, .prefix = GRUB_KERNEL_I386_PC_PREFIX, - .data_end = GRUB_KERNEL_I386_PC_DATA_END, + .prefix_end = GRUB_KERNEL_I386_PC_PREFIX_END, .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, @@ -166,7 +166,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_I386_EFI_PREFIX, - .data_end = GRUB_KERNEL_I386_EFI_DATA_END, + .prefix_end = GRUB_KERNEL_I386_EFI_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -188,7 +188,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_I386_IEEE1275, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_I386_IEEE1275_PREFIX, - .data_end = GRUB_KERNEL_I386_IEEE1275_DATA_END, + .prefix_end = GRUB_KERNEL_I386_IEEE1275_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -210,7 +210,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_QEMU, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_I386_QEMU_PREFIX, - .data_end = GRUB_KERNEL_I386_QEMU_DATA_END, + .prefix_end = GRUB_KERNEL_I386_QEMU_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, @@ -228,7 +228,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_X86_64_EFI_PREFIX, - .data_end = GRUB_KERNEL_X86_64_EFI_DATA_END, + .prefix_end = GRUB_KERNEL_X86_64_EFI_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -250,7 +250,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_YEELOONG_FLASH, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, - .data_end = GRUB_KERNEL_MIPS_YEELOONG_DATA_END, + .prefix_end = GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END, .raw_size = GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE, .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE, .compressed_size = GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE, @@ -270,7 +270,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_YEELOONG_ELF, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, - .data_end = GRUB_KERNEL_MIPS_YEELOONG_DATA_END, + .prefix_end = GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END, .raw_size = GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE, .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE, .compressed_size = GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE, @@ -290,7 +290,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_PPC, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_POWERPC_IEEE1275_PREFIX, - .data_end = GRUB_KERNEL_POWERPC_IEEE1275_DATA_END, + .prefix_end = GRUB_KERNEL_POWERPC_IEEE1275_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -312,7 +312,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_SPARC64_RAW, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX, - .data_end = GRUB_KERNEL_SPARC64_IEEE1275_DATA_END, + .prefix_end = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END, .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, @@ -330,7 +330,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_SPARC64_AOUT, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX, - .data_end = GRUB_KERNEL_SPARC64_IEEE1275_DATA_END, + .prefix_end = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END, .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, @@ -578,7 +578,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], total_module_size, &start_address, &rel_section, &reloc_size, &align, image_target); - if (image_target->prefix + strlen (prefix) + 1 > image_target->data_end) + if (image_target->prefix + strlen (prefix) + 1 > image_target->prefix_end) grub_util_error (_("prefix is too long")); strcpy (kernel_img + image_target->prefix, prefix); From 6556eba9c62854f7afcece7db1944bc91f511e7e Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 3 Sep 2010 21:23:00 +0530 Subject: [PATCH 16/28] Add missing files into "make dist" tarball for other platforms. * gentpl.py (script): Use dist_noinst_DATA instead of EXTRA_DIST. * conf/Makefile.common (dist_noinst_DATA): New variable. * conf/Makefile.extra-dist: Added missing make dist files. * grub-core/Makefile.core.def: Likewise. --- ChangeLog | 9 +++++++++ conf/Makefile.common | 1 + conf/Makefile.extra-dist | 9 +++++++-- gentpl.py | 2 +- grub-core/Makefile.core.def | 4 ++++ 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index cbd0337ab..5c64e0207 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-09-03 BVK Chaitanya + + Add missing files into "make dist" tarball for other platforms. + + * gentpl.py (script): Use dist_noinst_DATA instead of EXTRA_DIST. + * conf/Makefile.common (dist_noinst_DATA): New variable. + * conf/Makefile.extra-dist: Added missing make dist files. + * grub-core/Makefile.core.def: Likewise. + 2010-09-03 Vladimir Serbinenko Compress grub_prefix. diff --git a/conf/Makefile.common b/conf/Makefile.common index fe14c0e18..fca0f67ae 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -115,6 +115,7 @@ pkglib_SCRIPTS = noinst_PROGRAMS = grubconf_SCRIPTS = noinst_LIBRARIES = +dist_noinst_DATA = TESTS = EXTRA_DIST = diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist index 3acef7af7..afedc7d28 100644 --- a/conf/Makefile.extra-dist +++ b/conf/Makefile.extra-dist @@ -5,6 +5,11 @@ EXTRA_DIST += gentpl.py EXTRA_DIST += Makefile.tpl EXTRA_DIST += Makefile.util.def +EXTRA_DIST += unicode + +EXTRA_DIST += util/import_gcry.py +EXTRA_DIST += util/import_unicode.py + EXTRA_DIST += docs/man EXTRA_DIST += docs/grub.cfg @@ -26,8 +31,8 @@ EXTRA_DIST += grub-core/genterminallist.sh EXTRA_DIST += grub-core/genparttoollist.sh EXTRA_DIST += grub-core/genemuinitheader.sh +EXTRA_DIST += grub-core/lib/libgcrypt/cipher EXTRA_DIST += $(shell find $(top_srcdir)/include -name '*.h') EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/gnulib -name '*.h') EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/efiemu -name '*.h') -EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib/posix_wrap -name '*.h') -EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib/libgcrypt_wrap -name '*.h') +EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib -name '*.h') diff --git a/gentpl.py b/gentpl.py index abfb20444..cd34fccff 100644 --- a/gentpl.py +++ b/gentpl.py @@ -478,7 +478,7 @@ chmod a+x [+ name +] """) r += gvar_add("CLEANFILES", "[+ name +]") - r += gvar_add("EXTRA_DIST", platform_sources(platform)) + r += gvar_add("dist_noinst_DATA", platform_sources(platform)) return r def module_rules(): diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 353b9d123..b953adfb9 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -137,6 +137,7 @@ kernel = { mips_yeeloong = term/at_keyboard.c; mips_yeeloong = term/serial.c; mips_yeeloong = video/sm712.c; + extra_dist = video/sm712_init.c; powerpc_ieee1275 = kern/ieee1275/init.c; powerpc_ieee1275 = kern/powerpc/cache.S; @@ -1009,6 +1010,9 @@ module = { powerpc = lib/powerpc/relocator_asm.S; powerpc = lib/powerpc/relocator.c; + extra_dist = lib/i386/relocator_common.S; + extra_dist = kern/powerpc/cache_flush.S; + enable = mips; enable = powerpc; enable = x86; From dda060dd0fb1e0db8735e449908fbaaee91f4a75 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 4 Sep 2010 02:18:48 +0200 Subject: [PATCH 17/28] * grub-core/kern/misc.c: Don't add abort alias in utils. Reported by: echoline. --- ChangeLog | 5 +++++ grub-core/kern/misc.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5c64e0207..dcd16e8e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-04 Vladimir Serbinenko + + * grub-core/kern/misc.c: Don't add abort alias in utils. + Reported by: echoline. + 2010-09-03 BVK Chaitanya Add missing files into "make dist" tarball for other platforms. diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index 69fdc3d42..0bfa08992 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -990,7 +990,7 @@ grub_abort (void) grub_exit (); } -#ifndef APPLE_CC +#if ! defined (APPLE_CC) && !defined (GRUB_UTIL) /* GCC emits references to abort(). */ void abort (void) __attribute__ ((alias ("grub_abort"))); #endif From 30b4166fdea35a49e1712efe6997de210cd17ca3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 4 Sep 2010 17:23:51 +0200 Subject: [PATCH 18/28] Reimport setjmp from Tristan's branch. --- ChangeLog.ia64-emu | 6 ++ grub-core/lib/ia64/longjmp.S | 162 +++++++++++++++++++++++++++++++++ grub-core/lib/ia64/setjmp.S | 171 +++++++++++++++++++++++++++++++++++ grub-core/lib/setjmp.S | 2 + 4 files changed, 341 insertions(+) create mode 100644 ChangeLog.ia64-emu create mode 100644 grub-core/lib/ia64/longjmp.S create mode 100644 grub-core/lib/ia64/setjmp.S diff --git a/ChangeLog.ia64-emu b/ChangeLog.ia64-emu new file mode 100644 index 000000000..61a3ca6de --- /dev/null +++ b/ChangeLog.ia64-emu @@ -0,0 +1,6 @@ +2008-01-28 Tristan Gingold +2010-01-18 Robert Millan + + * grub-core/lib/ia64/setjmp.S: New file (from glibc). + * grub-core/lib/ia64/longjmp.S: New file (from glibc). + * grub-core/lib/setjmp.S [__ia64__]: include ia64/setjmp.S. diff --git a/grub-core/lib/ia64/longjmp.S b/grub-core/lib/ia64/longjmp.S new file mode 100644 index 000000000..729bdc76e --- /dev/null +++ b/grub-core/lib/ia64/longjmp.S @@ -0,0 +1,162 @@ +/* Copyright (C) 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc. + Contributed by David Mosberger-Tang . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + Note that __sigsetjmp() did NOT flush the register stack. Instead, + we do it here since __longjmp() is usually much less frequently + invoked than __sigsetjmp(). The only difficulty is that __sigsetjmp() + didn't (and wouldn't be able to) save ar.rnat either. This is a problem + because if we're not careful, we could end up loading random NaT bits. + There are two cases: + + (i) ar.bsp < ia64_rse_rnat_addr(jmpbuf.ar_bsp) + ar.rnat contains the desired bits---preserve ar.rnat + across loadrs and write to ar.bspstore + + (ii) ar.bsp >= ia64_rse_rnat_addr(jmpbuf.ar_bsp) + The desired ar.rnat is stored in + ia64_rse_rnat_addr(jmpbuf.ar_bsp). Load those + bits into ar.rnat after setting ar.bspstore. */ + + + +# define pPos p6 /* is rotate count positive? */ +# define pNeg p7 /* is rotate count negative? */ + + + /* __longjmp(__jmp_buf buf, int val) */ + + .text + .global longjmp + .proc longjmp +longjmp: + alloc r8=ar.pfs,2,1,0,0 + mov r27=ar.rsc + add r2=0x98,in0 // r2 <- &jmpbuf.orig_jmp_buf_addr + ;; + ld8 r8=[r2],-16 // r8 <- orig_jmp_buf_addr + mov r10=ar.bsp + and r11=~0x3,r27 // clear ar.rsc.mode + ;; + flushrs // flush dirty regs to backing store (must be first in insn grp) + ld8 r23=[r2],8 // r23 <- jmpbuf.ar_bsp + sub r8=r8,in0 // r8 <- &orig_jmpbuf - &jmpbuf + ;; + ld8 r25=[r2] // r25 <- jmpbuf.ar_unat + extr.u r8=r8,3,6 // r8 <- (&orig_jmpbuf - &jmpbuf)/8 & 0x3f + ;; + cmp.lt pNeg,pPos=r8,r0 + mov r2=in0 + ;; +(pPos) mov r16=r8 +(pNeg) add r16=64,r8 +(pPos) sub r17=64,r8 +(pNeg) sub r17=r0,r8 + ;; + mov ar.rsc=r11 // put RSE in enforced lazy mode + shr.u r8=r25,r16 + add r3=8,in0 // r3 <- &jmpbuf.r1 + shl r9=r25,r17 + ;; + or r25=r8,r9 + ;; + mov r26=ar.rnat + mov ar.unat=r25 // setup ar.unat (NaT bits for r1, r4-r7, and r12) + ;; + ld8.fill.nta sp=[r2],16 // r12 (sp) + ld8.fill.nta gp=[r3],16 // r1 (gp) + dep r11=-1,r23,3,6 // r11 <- ia64_rse_rnat_addr(jmpbuf.ar_bsp) + ;; + ld8.nta r16=[r2],16 // caller's unat + ld8.nta r17=[r3],16 // fpsr + ;; + ld8.fill.nta r4=[r2],16 // r4 + ld8.fill.nta r5=[r3],16 // r5 (gp) + cmp.geu p8,p0=r10,r11 // p8 <- (ar.bsp >= jmpbuf.ar_bsp) + ;; + ld8.fill.nta r6=[r2],16 // r6 + ld8.fill.nta r7=[r3],16 // r7 + ;; + mov ar.unat=r16 // restore caller's unat + mov ar.fpsr=r17 // restore fpsr + ;; + ld8.nta r16=[r2],16 // b0 + ld8.nta r17=[r3],16 // b1 + ;; +(p8) ld8 r26=[r11] // r26 <- *ia64_rse_rnat_addr(jmpbuf.ar_bsp) + mov ar.bspstore=r23 // restore ar.bspstore + ;; + ld8.nta r18=[r2],16 // b2 + ld8.nta r19=[r3],16 // b3 + ;; + ld8.nta r20=[r2],16 // b4 + ld8.nta r21=[r3],16 // b5 + ;; + ld8.nta r11=[r2],16 // ar.pfs + ld8.nta r22=[r3],56 // ar.lc + ;; + ld8.nta r24=[r2],32 // pr + mov b0=r16 + ;; + ldf.fill.nta f2=[r2],32 + ldf.fill.nta f3=[r3],32 + mov b1=r17 + ;; + ldf.fill.nta f4=[r2],32 + ldf.fill.nta f5=[r3],32 + mov b2=r18 + ;; + ldf.fill.nta f16=[r2],32 + ldf.fill.nta f17=[r3],32 + mov b3=r19 + ;; + ldf.fill.nta f18=[r2],32 + ldf.fill.nta f19=[r3],32 + mov b4=r20 + ;; + ldf.fill.nta f20=[r2],32 + ldf.fill.nta f21=[r3],32 + mov b5=r21 + ;; + ldf.fill.nta f22=[r2],32 + ldf.fill.nta f23=[r3],32 + mov ar.lc=r22 + ;; + ldf.fill.nta f24=[r2],32 + ldf.fill.nta f25=[r3],32 + cmp.eq p8,p9=0,in1 + ;; + ldf.fill.nta f26=[r2],32 + ldf.fill.nta f27=[r3],32 + mov ar.pfs=r11 + ;; + ldf.fill.nta f28=[r2],32 + ldf.fill.nta f29=[r3],32 + ;; + ldf.fill.nta f30=[r2] + ldf.fill.nta f31=[r3] +(p8) mov r8=1 + + mov ar.rnat=r26 // restore ar.rnat + ;; + mov ar.rsc=r27 // restore ar.rsc +(p9) mov r8=in1 + + invala // virt. -> phys. regnum mapping may change + mov pr=r24,-1 + br.ret.dptk.few rp + .endp longjmp diff --git a/grub-core/lib/ia64/setjmp.S b/grub-core/lib/ia64/setjmp.S new file mode 100644 index 000000000..0851885c5 --- /dev/null +++ b/grub-core/lib/ia64/setjmp.S @@ -0,0 +1,171 @@ +/* Copyright (C) 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc. + Contributed by David Mosberger-Tang . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + The layout of the jmp_buf is as follows. This is subject to change + and user-code should never depend on the particular layout of + jmp_buf! + + + offset: description: + ------- ------------ + 0x000 stack pointer (r12) ; unchangeable (see _JMPBUF_UNWINDS) + 0x008 r1 (gp) + 0x010 caller's unat + 0x018 fpsr + 0x020 r4 + 0x028 r5 + 0x030 r6 + 0x038 r7 + 0x040 rp (b0) + 0x048 b1 + 0x050 b2 + 0x058 b3 + 0x060 b4 + 0x068 b5 + 0x070 ar.pfs + 0x078 ar.lc + 0x080 pr + 0x088 ar.bsp ; unchangeable (see __longjmp.S) + 0x090 ar.unat + 0x098 &__jmp_buf ; address of the jmpbuf (needed to locate NaT bits in unat) + 0x0a0 f2 + 0x0b0 f3 + 0x0c0 f4 + 0x0d0 f5 + 0x0e0 f16 + 0x0f0 f17 + 0x100 f18 + 0x110 f19 + 0x120 f20 + 0x130 f21 + 0x130 f22 + 0x140 f23 + 0x150 f24 + 0x160 f25 + 0x170 f26 + 0x180 f27 + 0x190 f28 + 0x1a0 f29 + 0x1b0 f30 + 0x1c0 f31 */ + + + /* The following two entry points are the traditional entry points: */ + + .text + .global setjmp + .proc setjmp +setjmp: + alloc r8=ar.pfs,2,0,0,0 + mov in1=1 + br.cond.sptk.many __sigsetjmp + .endp setjmp + + /* __sigsetjmp(__jmp_buf buf, int savemask) */ + + .proc __sigsetjmp +__sigsetjmp: + //.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2) + alloc loc1=ar.pfs,2,2,2,0 + mov r16=ar.unat + ;; + mov r17=ar.fpsr + mov r2=in0 + add r3=8,in0 + ;; + st8.spill.nta [r2]=sp,16 // r12 (sp) + st8.spill.nta [r3]=gp,16 // r1 (gp) + ;; + st8.nta [r2]=r16,16 // save caller's unat + st8.nta [r3]=r17,16 // save fpsr + add r8=0xa0,in0 + ;; + st8.spill.nta [r2]=r4,16 // r4 + st8.spill.nta [r3]=r5,16 // r5 + add r9=0xb0,in0 + ;; + stf.spill.nta [r8]=f2,32 + stf.spill.nta [r9]=f3,32 + mov loc0=rp + .body + ;; + stf.spill.nta [r8]=f4,32 + stf.spill.nta [r9]=f5,32 + mov r17=b1 + ;; + stf.spill.nta [r8]=f16,32 + stf.spill.nta [r9]=f17,32 + mov r18=b2 + ;; + stf.spill.nta [r8]=f18,32 + stf.spill.nta [r9]=f19,32 + mov r19=b3 + ;; + stf.spill.nta [r8]=f20,32 + stf.spill.nta [r9]=f21,32 + mov r20=b4 + ;; + stf.spill.nta [r8]=f22,32 + stf.spill.nta [r9]=f23,32 + mov r21=b5 + ;; + stf.spill.nta [r8]=f24,32 + stf.spill.nta [r9]=f25,32 + mov r22=ar.lc + ;; + stf.spill.nta [r8]=f26,32 + stf.spill.nta [r9]=f27,32 + mov r24=pr + ;; + stf.spill.nta [r8]=f28,32 + stf.spill.nta [r9]=f29,32 + ;; + stf.spill.nta [r8]=f30 + stf.spill.nta [r9]=f31 + + st8.spill.nta [r2]=r6,16 // r6 + st8.spill.nta [r3]=r7,16 // r7 + ;; + mov r23=ar.bsp + mov r25=ar.unat + mov out0=in0 + + st8.nta [r2]=loc0,16 // b0 + st8.nta [r3]=r17,16 // b1 + mov out1=in1 + ;; + st8.nta [r2]=r18,16 // b2 + st8.nta [r3]=r19,16 // b3 + ;; + st8.nta [r2]=r20,16 // b4 + st8.nta [r3]=r21,16 // b5 + ;; + st8.nta [r2]=loc1,16 // ar.pfs + st8.nta [r3]=r22,16 // ar.lc + ;; + st8.nta [r2]=r24,16 // pr + st8.nta [r3]=r23,16 // ar.bsp + ;; + st8.nta [r2]=r25 // ar.unat + st8.nta [r3]=in0 // &__jmp_buf + mov r8=0 + mov rp=loc0 + mov ar.pfs=loc1 + br.ret.sptk.many rp + + .endp __sigsetjmp diff --git a/grub-core/lib/setjmp.S b/grub-core/lib/setjmp.S index c39c91b9c..7e669d4ff 100644 --- a/grub-core/lib/setjmp.S +++ b/grub-core/lib/setjmp.S @@ -8,6 +8,8 @@ #include "./mips/setjmp.S" #elif defined(__powerpc__) #include "./powerpc/setjmp.S" +#elif defined(__ia64__) +#include "./ia64/setjmp.S" #else #error "Unknwon target cpu type" #endif From 3b2bdd6f73c0e7bf082f8553503b27c3806eb224 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Wed, 8 Sep 2010 01:50:12 +0200 Subject: [PATCH 19/28] Add missing headers for ia64 --- include/grub/ia64/setjmp.h | 28 ++++++++++++++++++++++++++++ include/grub/ia64/time.h | 28 ++++++++++++++++++++++++++++ include/grub/ia64/types.h | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 include/grub/ia64/setjmp.h create mode 100644 include/grub/ia64/time.h create mode 100644 include/grub/ia64/types.h diff --git a/include/grub/ia64/setjmp.h b/include/grub/ia64/setjmp.h new file mode 100644 index 000000000..a71c9c56d --- /dev/null +++ b/include/grub/ia64/setjmp.h @@ -0,0 +1,28 @@ +/* Define the machine-dependent type `jmp_buf'. Linux/IA-64 version. + Copyright (C) 1999, 2000, 2008 Free Software Foundation, Inc. + Contributed by David Mosberger-Tang . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* User code must not depend on the internal representation of jmp_buf. */ + +#define _JBLEN 70 + +/* the __jmp_buf element type should be __float80 per ABI... */ +typedef long grub_jmp_buf[_JBLEN] __attribute__ ((aligned (16))); /* guarantees 128-bit alignment! */ + +int grub_setjmp (grub_jmp_buf env); +void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); diff --git a/include/grub/ia64/time.h b/include/grub/ia64/time.h new file mode 100644 index 000000000..03ee79fa4 --- /dev/null +++ b/include/grub/ia64/time.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 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 KERNEL_CPU_TIME_HEADER +#define KERNEL_CPU_TIME_HEADER 1 + +static __inline void +grub_cpu_idle (void) +{ + /* FIXME: not implemented */ +} + +#endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/ia64/types.h b/include/grub/ia64/types.h new file mode 100644 index 000000000..91a546dd2 --- /dev/null +++ b/include/grub/ia64/types.h @@ -0,0 +1,32 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 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_TYPES_CPU_HEADER +#define GRUB_TYPES_CPU_HEADER 1 + +/* The size of void *. */ +#define GRUB_TARGET_SIZEOF_VOID_P 8 + +/* The size of long. */ +#define GRUB_TARGET_SIZEOF_LONG 8 + +/* ia64 is little-endian (usually). */ +#undef GRUB_TARGET_WORDS_BIGENDIAN + + +#endif /* ! GRUB_TYPES_CPU_HEADER */ From 22a85f6b0abc04e881b8e376cc0793992dc23e16 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 8 Sep 2010 01:51:31 +0200 Subject: [PATCH 20/28] Add ia64-specific libgcc symbols --- configure.ac | 2 +- include/grub/libgcc.h | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d362f68a5..ca886b5dc 100644 --- a/configure.ac +++ b/configure.ac @@ -542,7 +542,7 @@ CFLAGS="$CFLAGS -Wl,--defsym,abort=main" fi # Check for libgcc symbols -AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x) +AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x __ia64_trampoline __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3) if test "x$TARGET_APPLE_CC" = x1 ; then CFLAGS="$TARGET_CFLAGS -nostdlib" diff --git a/include/grub/libgcc.h b/include/grub/libgcc.h index d0adae8c1..703182577 100644 --- a/include/grub/libgcc.h +++ b/include/grub/libgcc.h @@ -38,8 +38,30 @@ void EXPORT_FUNC (__bswapsi2) (void); # ifdef HAVE___BSWAPDI2 void EXPORT_FUNC (__bswapdi2) (void); # endif +# ifdef HAVE___UDIVSI3 +void EXPORT_FUNC (__udivsi3) (void); +# endif +# ifdef HAVE___UMODSI3 +void EXPORT_FUNC (__umodsi3) (void); +# endif +# ifdef HAVE___UMODDI3 +void EXPORT_FUNC (__umoddi3) (void); +# endif +# ifdef HAVE___UDIVDI3 +void EXPORT_FUNC (__udivdi3) (void); +# endif +# ifdef HAVE___DIVSI3 +void EXPORT_FUNC (__divsi3) (void); +# endif +# ifdef HAVE___UMODSI3 +void EXPORT_FUNC (__modsi3) (void); +# endif #endif +# ifdef HAVE___IA64_TRAMPOLINE +void EXPORT_FUNC (__ia64_trampoline) (void); +# endif + #ifdef HAVE___TRAMPOLINE_SETUP void EXPORT_FUNC (__trampoline_setup) (void); #endif From 3a04c65d008246c29d8a0b86fb66770ac6d6634f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 1 Jan 2011 15:13:03 +0100 Subject: [PATCH 21/28] Always add libgcc.h --- grub-core/Makefile.am | 4 +--- include/grub/libgcc.h | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 5d13d0313..7fa00b744 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -74,6 +74,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h if COND_i386_pc KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h @@ -132,7 +133,6 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bitmap_scale.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cs5536.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pci.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/serial.h @@ -140,11 +140,9 @@ endif if COND_powerpc_ieee1275 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h endif if COND_sparc64_ieee1275 -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h endif diff --git a/include/grub/libgcc.h b/include/grub/libgcc.h index 703182577..100c8667b 100644 --- a/include/grub/libgcc.h +++ b/include/grub/libgcc.h @@ -53,7 +53,7 @@ void EXPORT_FUNC (__udivdi3) (void); # ifdef HAVE___DIVSI3 void EXPORT_FUNC (__divsi3) (void); # endif -# ifdef HAVE___UMODSI3 +# ifdef HAVE___MODSI3 void EXPORT_FUNC (__modsi3) (void); # endif #endif From 52f65ea0bc9c3d36a0691a330eb2131df7cacc6d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 1 Jan 2011 15:28:39 +0100 Subject: [PATCH 22/28] add moddi3 and divdi3 --- configure.ac | 2 +- include/grub/libgcc.h | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ca886b5dc..4c710748c 100644 --- a/configure.ac +++ b/configure.ac @@ -542,7 +542,7 @@ CFLAGS="$CFLAGS -Wl,--defsym,abort=main" fi # Check for libgcc symbols -AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x __ia64_trampoline __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3) +AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x __ia64_trampoline __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3 __moddi3 __divdi3) if test "x$TARGET_APPLE_CC" = x1 ; then CFLAGS="$TARGET_CFLAGS -nostdlib" diff --git a/include/grub/libgcc.h b/include/grub/libgcc.h index 100c8667b..be600220e 100644 --- a/include/grub/libgcc.h +++ b/include/grub/libgcc.h @@ -50,6 +50,12 @@ void EXPORT_FUNC (__umoddi3) (void); # ifdef HAVE___UDIVDI3 void EXPORT_FUNC (__udivdi3) (void); # endif +# ifdef HAVE___MODDI3 +void EXPORT_FUNC (__moddi3) (void); +# endif +# ifdef HAVE___DIVDI3 +void EXPORT_FUNC (__divdi3) (void); +# endif # ifdef HAVE___DIVSI3 void EXPORT_FUNC (__divsi3) (void); # endif From 6f49d0aacb1a26d756faa849ea5b18d1322091d5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 1 Jan 2011 15:53:31 +0100 Subject: [PATCH 23/28] Add missing cache.c --- grub-core/Makefile.core.def | 1 + grub-core/kern/emu/cache.c | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 grub-core/kern/emu/cache.c diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index b953adfb9..801ad6d7c 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -158,6 +158,7 @@ kernel = { emu = kern/emu/misc.c; emu = kern/emu/mm.c; emu = kern/emu/time.c; + emu = kern/emu/cache.c; videoinkernel = lib/arg.c; videoinkernel = term/gfxterm.c; diff --git a/grub-core/kern/emu/cache.c b/grub-core/kern/emu/cache.c new file mode 100644 index 000000000..bdff146ef --- /dev/null +++ b/grub-core/kern/emu/cache.c @@ -0,0 +1,10 @@ + +#include + +void __clear_cache (char *beg, char *end); + +void +grub_arch_sync_caches (void *address, grub_size_t len) +{ + __clear_cache (address, (char *) address + len); +} From f9c30af6d08a6d2b0c3e831d116c37dc1d1d7c78 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 2 Jan 2011 14:09:58 +0100 Subject: [PATCH 24/28] Succesfully loaded return-only module on ia64-emu --- grub-core/kern/dl.c | 49 ++++++- grub-core/kern/emu/cache.S | 1 + grub-core/kern/emu/cache.c | 3 + grub-core/kern/emu/full.c | 9 ++ grub-core/kern/emu/lite.c | 2 + grub-core/kern/ia64/dl.c | 288 +++++++++++++++++++++++++++++++++++++ include/grub/dl.h | 20 ++- include/grub/types.h | 3 + 8 files changed, 368 insertions(+), 7 deletions(-) create mode 100644 grub-core/kern/ia64/dl.c diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 02d785b9b..2f2493fca 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -37,6 +37,10 @@ #define GRUB_MODULES_MACHINE_READONLY #endif +#ifdef GRUB_MACHINE_EMU +#include +#endif + grub_dl_t grub_dl_head = 0; @@ -233,11 +237,24 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) if (s->sh_flags & SHF_ALLOC) { grub_dl_segment_t seg; + grub_size_t tramp_size = 0; seg = (grub_dl_segment_t) grub_malloc (sizeof (*seg)); if (! seg) return grub_errno; + tramp_size = grub_arch_dl_get_tramp_size (e, i); + if (tramp_size && s->sh_addralign < GRUB_ARCH_DL_TRAMP_ALIGN) + { + s->sh_addralign = GRUB_ARCH_DL_TRAMP_ALIGN; + s->sh_size = ALIGN_UP (s->sh_size, GRUB_ARCH_DL_TRAMP_ALIGN) + tramp_size; + } +#ifdef GRUB_MACHINE_EMU + if (s->sh_addralign < 8192) + s->sh_addralign = 8192; + s->sh_size = ALIGN_UP (s->sh_size, 8192); +#endif + if (s->sh_size) { void *addr; @@ -260,6 +277,10 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) } seg->addr = addr; +#ifdef GRUB_MACHINE_EMU + if (s->sh_flags & SHF_EXECINSTR) + mprotect (addr, s->sh_size, PROT_READ | PROT_WRITE | PROT_EXEC); +#endif } else seg->addr = 0; @@ -343,9 +364,9 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) return grub_errno; if (grub_strcmp (name, "grub_mod_init") == 0) - mod->init = (void (*) (grub_dl_t)) sym->st_value; + mod->init = sym->st_value; else if (grub_strcmp (name, "grub_mod_fini") == 0) - mod->fini = (void (*) (void)) sym->st_value; + mod->fini = sym->st_value; break; case STT_SECTION: @@ -370,7 +391,16 @@ static void grub_dl_call_init (grub_dl_t mod) { if (mod->init) - (mod->init) (mod); + { +#ifndef __ia64__ + ((void (*) (grub_dl_t)) mod->init) (mod); +#else + char *jmp[2]; + jmp[0] = (char *) mod->init; + jmp[1] = mod->gp; + ((void (*) (grub_dl_t)) jmp) (mod); +#endif + } } static grub_err_t @@ -533,7 +563,7 @@ grub_dl_load_core (void *addr, grub_size_t size) grub_dl_flush_cache (mod); grub_dprintf ("modules", "module name: %s\n", mod->name); - grub_dprintf ("modules", "init function: %p\n", mod->init); + grub_dprintf ("modules", "init function: %" PRIxGRUB_ADDR "\n", mod->init); grub_dl_call_init (mod); if (grub_dl_add (mod)) @@ -633,7 +663,16 @@ grub_dl_unload (grub_dl_t mod) return 0; if (mod->fini) - (mod->fini) (); + { +#ifndef __ia64__ + ((void (*) (void)) mod->fini) (); +#else + char *jmp[2]; + jmp[0] = (char *) mod->fini; + jmp[1] = mod->gp; + ((void (*) (void)) jmp) (); +#endif + } grub_dl_remove (mod); grub_dl_unregister_symbols (mod); diff --git a/grub-core/kern/emu/cache.S b/grub-core/kern/emu/cache.S index 90a5b5396..99637762a 100644 --- a/grub-core/kern/emu/cache.S +++ b/grub-core/kern/emu/cache.S @@ -10,6 +10,7 @@ #include "../mips/cache.S" #elif defined(__powerpc__) #include "../powerpc/cache.S" +#elif defined(__ia64__) #else #error "No target cpu type is defined" #endif diff --git a/grub-core/kern/emu/cache.c b/grub-core/kern/emu/cache.c index bdff146ef..543e457e5 100644 --- a/grub-core/kern/emu/cache.c +++ b/grub-core/kern/emu/cache.c @@ -1,4 +1,5 @@ +#if defined(__ia64__) #include void __clear_cache (char *beg, char *end); @@ -8,3 +9,5 @@ grub_arch_sync_caches (void *address, grub_size_t len) { __clear_cache (address, (char *) address + len); } +#endif + diff --git a/grub-core/kern/emu/full.c b/grub-core/kern/emu/full.c index 0bd33337f..0396d0ab4 100644 --- a/grub-core/kern/emu/full.c +++ b/grub-core/kern/emu/full.c @@ -48,3 +48,12 @@ grub_emu_init (void) { grub_no_autoload = 1; } + +#ifdef __ia64__ +grub_size_t +grub_arch_dl_get_tramp_size (const void *ehdr __attribute__ ((unused)), + unsigned sec __attribute__ ((unused))) +{ + return ~(grub_size_t)0; +} +#endif diff --git a/grub-core/kern/emu/lite.c b/grub-core/kern/emu/lite.c index 9b3728717..5d3588bd0 100644 --- a/grub-core/kern/emu/lite.c +++ b/grub-core/kern/emu/lite.c @@ -15,6 +15,8 @@ #include "../mips/dl.c" #elif defined(__powerpc__) #include "../powerpc/dl.c" +#elif defined(__ia64__) +#include "../ia64/dl.c" #else #error "No target cpu type is defined" #endif diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c new file mode 100644 index 000000000..2b87577a4 --- /dev/null +++ b/grub-core/kern/ia64/dl.c @@ -0,0 +1,288 @@ +/* dl.c - arch-dependent part of loadable module support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2005,2007,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 + +/* Check if EHDR is a valid ELF header. */ +grub_err_t +grub_arch_dl_check_header (void *ehdr) +{ + Elf_Ehdr *e = ehdr; + + /* Check the magic numbers. */ + if (e->e_ident[EI_CLASS] != ELFCLASS64 + || e->e_ident[EI_DATA] != ELFDATA2LSB + || e->e_machine != EM_IA_64) + return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic"); + + return GRUB_ERR_NONE; +} + +#define MASK20 ((1 << 20) - 1) +#define MASK19 ((1 << 19) - 1) + +static void +add_value_to_slot13_20 (Elf_Word *addr, grub_uint32_t value, int slot) +{ + grub_uint32_t *p __attribute__ ((aligned (1))); + switch (slot) + { + case 0: + p = (grub_uint32_t *) (addr + 2); + *p = (((((*p >> 2) & MASK20) + value) & MASK20) << 2) | (*p & ~(MASK20 << 2)); + break; + case 1: + p = (grub_uint32_t *) ((grub_uint8_t *) addr + 7); + *p = (((((*p >> 3) & MASK20) + value) & MASK20) << 3) | (*p & ~(MASK20 << 3)); + break; + case 2: + p = (grub_uint32_t *) ((grub_uint8_t *) addr + 12); + *p = (((((*p >> 4) & MASK20) + value) & MASK20) << 4) | (*p & ~(MASK20 << 4)); + break; + } +} + +static grub_uint8_t nopm[5] = + { + /* [MLX] nop.m 0x0 */ + 0x05, 0x00, 0x00, 0x00, 0x01 + }; + +static grub_uint8_t jump[0x20] = + { + /* ld8 r16=[r15],8 */ + 0x02, 0x80, 0x20, 0x1e, 0x18, 0x14, + /* mov r14=r1;; */ + 0xe0, 0x00, 0x04, 0x00, 0x42, 0x00, + /* nop.i 0x0 */ + 0x00, 0x00, 0x04, 0x00, + /* ld8 r1=[r15] */ + 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, + /* mov b6=r16 */ + 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, + /* br.few b6;; */ + 0x60, 0x00, 0x80, 0x00 + }; + +struct ia64_trampoline +{ + /* nop.m */ + grub_uint8_t nop[5]; + /* movl r15 = addr*/ + grub_uint8_t addr_hi[6]; + grub_uint8_t e0; + grub_uint8_t addr_lo[4]; + grub_uint8_t jump[0x20]; +}; + +static void +make_trampoline (struct ia64_trampoline *tr, grub_uint64_t addr) +{ + grub_memcpy (tr->nop, nopm, sizeof (tr->nop)); + tr->addr_hi[0] = ((addr & 0xc00000) >> 18); + tr->addr_hi[1] = (addr >> 24) & 0xff; + tr->addr_hi[2] = (addr >> 32) & 0xff; + tr->addr_hi[3] = (addr >> 40) & 0xff; + tr->addr_hi[4] = (addr >> 48) & 0xff; + tr->addr_hi[5] = (addr >> 56) & 0xff; + tr->e0 = 0xe0; + tr->addr_lo[0] = ((addr & 0x000f) << 4) | 0x01; + tr->addr_lo[1] = ((addr & 0x0070) >> 4) | ((addr & 0x070000) >> 11) | ((addr & 0x200000) >> 17); + tr->addr_lo[2] = ((addr & 0x1f80) >> 5) | ((addr & 0x180000) >> 19); + tr->addr_lo[3] = ((addr & 0xe000) >> 13) | 0x60; + grub_memcpy (tr->jump, jump, sizeof (tr->jump)); +} + +grub_size_t +grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec) +{ + const Elf_Ehdr *e = ehdr; + int cnt = 0; + const Elf_Shdr *s; + Elf_Word entsize; + unsigned i; + + /* Find a symbol table. */ + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_SYMTAB) + break; + + if (i == e->e_shnum) + return 0; + + entsize = s->sh_entsize; + + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_RELA) + { + Elf_Rela *rel, *max; + + if (s->sh_info != sec) + continue; + + for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; rel++) + if (ELF_R_TYPE (rel->r_info) == R_IA64_PCREL21B) + cnt++; + } + + return cnt * sizeof (struct ia64_trampoline); +} + +/* Relocate symbols. */ +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +{ + Elf_Ehdr *e = ehdr; + Elf_Shdr *s; + Elf_Word entsize; + unsigned i; + grub_uint64_t *gp, *gpptr; + grub_size_t gp_size = 0; + + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_REL) + { + grub_dl_segment_t seg; + + /* Find the target segment. */ + for (seg = mod->segment; seg; seg = seg->next) + if (seg->section == s->sh_info) + break; + + if (seg) + { + Elf_Rel *rel, *max; + + for (rel = (Elf_Rel *) ((char *) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; + rel++) + switch (ELF_R_TYPE (rel->r_info)) + { + default: break; + } + } + } + + if (gp_size > MASK19) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "gp too big"); + + gpptr = gp = grub_malloc (gp_size); + if (!gp) + return grub_errno; + mod->gp = (char *) gp; + + /* Find a symbol table. */ + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_SYMTAB) + break; + + if (i == e->e_shnum) + return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found"); + + entsize = s->sh_entsize; + + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_RELA) + { + grub_dl_segment_t seg; + + /* Find the target segment. */ + for (seg = mod->segment; seg; seg = seg->next) + if (seg->section == s->sh_info) + break; + + if (seg) + { + Elf_Rela *rel, *max; + struct ia64_trampoline *tr; + + for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; + rel++) + { + Elf_Word *addr; + Elf_Sym *sym; + grub_uint64_t value; + int slot = 0; + + if (seg->size < (rel->r_offset & ~3)) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); + + tr = (void *) ((char *) seg->addr + ALIGN_UP (seg->size, GRUB_ARCH_DL_TRAMP_ALIGN)); + + if (ELF_R_TYPE (rel->r_info) == R_IA64_PCREL21B) + { + addr = (Elf_Word *) ((char *) seg->addr + (rel->r_offset & ~3)); + slot = rel->r_offset & 3; + } + else + addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset); + sym = (Elf_Sym *) ((char *) mod->symtab + + entsize * ELF_R_SYM (rel->r_info)); + + /* On the PPC the value does not have an explicit + addend, add it. */ + value = sym->st_value + rel->r_addend; + switch (ELF_R_TYPE (rel->r_info)) + { + case R_IA64_PCREL21B: + { + grub_uint64_t noff; + make_trampoline (tr, value); + noff = ((char *) tr - (char *) addr) >> 4; + tr++; + if (noff & ~MASK19) + return grub_error (GRUB_ERR_BAD_OS, + "trampoline offset too big"); + add_value_to_slot13_20 (addr, noff, slot); + } + break; + case R_IA64_SEGREL64LSB: + *(grub_uint64_t *) addr += value - rel->r_offset; + break; + default: + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "this relocation (0x%x) is not implemented yet", + ELF_R_TYPE (rel->r_info)); + } + } + } + } + + return GRUB_ERR_NONE; +} diff --git a/include/grub/dl.h b/include/grub/dl.h index afc4af41a..e04285280 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -90,8 +90,11 @@ struct grub_dl grub_dl_dep_t dep; grub_dl_segment_t segment; Elf_Sym *symtab; - void (*init) (struct grub_dl *mod); - void (*fini) (void); + grub_addr_t init; + grub_addr_t fini; +#ifdef __ia64__ + char *gp; +#endif struct grub_dl *next; }; typedef struct grub_dl *grub_dl_t; @@ -119,4 +122,17 @@ grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr); void grub_arch_dl_init_linker (void); #endif +#ifdef __ia64__ +grub_size_t grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec); +#define GRUB_ARCH_DL_TRAMP_ALIGN 16 +#else +static inline grub_size_t +grub_arch_dl_get_tramp_size (const void *ehdr __attribute__ ((unused)), int sec __attribute__ ((unused))) +{ + return 0; +} +#define GRUB_ARCH_DL_TRAMP_ALIGN 1 +#endif + + #endif /* ! GRUB_DL_H */ diff --git a/include/grub/types.h b/include/grub/types.h index 4499e4538..b3aa69c1c 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -95,8 +95,10 @@ typedef grub_int64_t grub_ssize_t; # if GRUB_CPU_SIZEOF_LONG == 8 # define PRIxGRUB_SIZE "lx" +# define PRIxGRUB_ADDR "lx" # else # define PRIxGRUB_SIZE "llx" +# define PRIxGRUB_ADDR "llx" # endif #else typedef grub_uint32_t grub_addr_t; @@ -104,6 +106,7 @@ typedef grub_uint32_t grub_size_t; typedef grub_int32_t grub_ssize_t; # define PRIxGRUB_SIZE "x" +# define PRIxGRUB_ADDR "x" #endif #if GRUB_CPU_SIZEOF_LONG == 8 From daca6c5f45406137290e008ae0ef363624bc1887 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 2 Jan 2011 14:39:23 +0100 Subject: [PATCH 25/28] ltoff relocation support --- grub-core/kern/ia64/dl.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c index 2b87577a4..24fa01b90 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -187,6 +187,10 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) rel++) switch (ELF_R_TYPE (rel->r_info)) { + case R_IA64_LTOFF22X: + case R_IA64_LTOFF22: + gp_size += 8; + break; default: break; } } @@ -275,6 +279,16 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) case R_IA64_SEGREL64LSB: *(grub_uint64_t *) addr += value - rel->r_offset; break; + case R_IA64_LTOFF22X: + case R_IA64_LTOFF22: + *gpptr = value; + add_value_to_slot13_20 (addr, (gpptr - gp) * sizeof (grub_uint64_t), slot); + gpptr++; + break; + + /* We treat LTOFF22X as LTOFF22, so we can ignore LDXMOV. */ + case R_IA64_LDXMOV: + break; default: return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "this relocation (0x%x) is not implemented yet", From 73911575dd67eaa09837fe0f691655553c3dea69 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 2 Jan 2011 14:58:57 +0100 Subject: [PATCH 26/28] support for registering functions from modules (not tested yet) --- grub-core/kern/dl.c | 20 +++++++++++++++++--- grub-core/kern/emu/full.c | 8 ++++++++ grub-core/kern/ia64/dl.c | 30 ++++++++++++++++++++---------- include/grub/dl.h | 9 +++++++++ 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 2f2493fca..9dfff5287 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -360,9 +360,22 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod, sym->st_shndx); if (bind != STB_LOCAL) - if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) - return grub_errno; - + { +#ifdef __ia64__ + /* FIXME: free descriptor once it's not used anymore. */ + char **desc; + desc = grub_malloc (2 * sizeof (char *)); + if (!desc) + return grub_errno; + desc[0] = (void *) sym->st_value; + desc[1] = mod->gp; + if (grub_dl_register_symbol (name, (void *) desc, mod)) + return grub_errno; +#else + if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) + return grub_errno; +#endif + } if (grub_strcmp (name, "grub_mod_init") == 0) mod->init = sym->st_value; else if (grub_strcmp (name, "grub_mod_fini") == 0) @@ -552,6 +565,7 @@ grub_dl_load_core (void *addr, grub_size_t size) if (grub_dl_resolve_name (mod, e) || grub_dl_resolve_dependencies (mod, e) || grub_dl_load_segments (mod, e) + || grub_arch_dl_allocate_gp (mod, e) || grub_dl_resolve_symbols (mod, e) || grub_arch_dl_relocate_symbols (mod, e)) { diff --git a/grub-core/kern/emu/full.c b/grub-core/kern/emu/full.c index 0396d0ab4..67a125301 100644 --- a/grub-core/kern/emu/full.c +++ b/grub-core/kern/emu/full.c @@ -56,4 +56,12 @@ grub_arch_dl_get_tramp_size (const void *ehdr __attribute__ ((unused)), { return ~(grub_size_t)0; } + +grub_err_t +grub_arch_dl_allocate_gp (grub_dl_t mod __attribute__ ((unused)), + const void *ehdr __attribute__ ((unused))) +{ + return GRUB_ERR_BAD_MODULE; +} + #endif diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c index 24fa01b90..1fbe185b4 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -154,16 +154,13 @@ grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec) return cnt * sizeof (struct ia64_trampoline); } -/* Relocate symbols. */ grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +grub_arch_dl_allocate_gp (grub_dl_t mod, const void *ehdr) { - Elf_Ehdr *e = ehdr; - Elf_Shdr *s; - Elf_Word entsize; - unsigned i; - grub_uint64_t *gp, *gpptr; grub_size_t gp_size = 0; + const Elf_Ehdr *e = ehdr; + const Elf_Shdr *s; + unsigned i; for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); i < e->e_shnum; @@ -199,10 +196,23 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) if (gp_size > MASK19) return grub_error (GRUB_ERR_OUT_OF_RANGE, "gp too big"); - gpptr = gp = grub_malloc (gp_size); - if (!gp) + mod->gp = grub_malloc (gp_size); + if (!mod->gp) return grub_errno; - mod->gp = (char *) gp; + return GRUB_ERR_NONE; +} + +/* Relocate symbols. */ +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +{ + Elf_Ehdr *e = ehdr; + Elf_Shdr *s; + Elf_Word entsize; + unsigned i; + grub_uint64_t *gp, *gpptr; + + gp = gpptr = (grub_uint64_t *) mod->gp; /* Find a symbol table. */ for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); diff --git a/include/grub/dl.h b/include/grub/dl.h index e04285280..c43c30ca7 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -124,6 +124,8 @@ void grub_arch_dl_init_linker (void); #ifdef __ia64__ grub_size_t grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec); +grub_err_t grub_arch_dl_allocate_gp (grub_dl_t mod, const void *ehdr); + #define GRUB_ARCH_DL_TRAMP_ALIGN 16 #else static inline grub_size_t @@ -131,6 +133,13 @@ grub_arch_dl_get_tramp_size (const void *ehdr __attribute__ ((unused)), int sec { return 0; } +static inline grub_err_t +grub_arch_dl_allocate_gp (grub_dl_t mod __attribute__ ((unused)), + const void *ehdr __attribute__ ((unused))) +{ + return GRUB_ERR_NONE; +} + #define GRUB_ARCH_DL_TRAMP_ALIGN 1 #endif From bbbf84350e06a97de1254fa0866d317ab40c95a7 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 2 Jan 2011 19:20:28 +0100 Subject: [PATCH 27/28] Working hello.mod with extcmd.mod --- grub-core/kern/dl.c | 46 ++++++++----------- grub-core/kern/ia64/dl.c | 99 ++++++++++++++++++++++++++++------------ 2 files changed, 88 insertions(+), 57 deletions(-) diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 9dfff5287..0ccdbe03b 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -238,28 +238,32 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) { grub_dl_segment_t seg; grub_size_t tramp_size = 0; + grub_size_t alsize, align; seg = (grub_dl_segment_t) grub_malloc (sizeof (*seg)); if (! seg) return grub_errno; + alsize = s->sh_size; + align = s->sh_addralign; tramp_size = grub_arch_dl_get_tramp_size (e, i); - if (tramp_size && s->sh_addralign < GRUB_ARCH_DL_TRAMP_ALIGN) + if (tramp_size && align < GRUB_ARCH_DL_TRAMP_ALIGN) { - s->sh_addralign = GRUB_ARCH_DL_TRAMP_ALIGN; - s->sh_size = ALIGN_UP (s->sh_size, GRUB_ARCH_DL_TRAMP_ALIGN) + tramp_size; + align = GRUB_ARCH_DL_TRAMP_ALIGN; + alsize = ALIGN_UP (alsize, GRUB_ARCH_DL_TRAMP_ALIGN); } + alsize += tramp_size; #ifdef GRUB_MACHINE_EMU - if (s->sh_addralign < 8192) - s->sh_addralign = 8192; - s->sh_size = ALIGN_UP (s->sh_size, 8192); + if (align < 8192 * 16) + align = 8192 * 16; + alsize = ALIGN_UP (alsize, 8192 * 16); #endif - if (s->sh_size) + if (alsize) { void *addr; - addr = grub_memalign (s->sh_addralign, s->sh_size); + addr = grub_memalign (align, alsize); if (! addr) { grub_free (seg); @@ -279,7 +283,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) seg->addr = addr; #ifdef GRUB_MACHINE_EMU if (s->sh_flags & SHF_EXECINSTR) - mprotect (addr, s->sh_size, PROT_READ | PROT_WRITE | PROT_EXEC); + mprotect (addr, alsize, PROT_READ | PROT_WRITE | PROT_EXEC); #endif } else @@ -359,9 +363,8 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) case STT_FUNC: sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod, sym->st_shndx); - if (bind != STB_LOCAL) - { #ifdef __ia64__ + { /* FIXME: free descriptor once it's not used anymore. */ char **desc; desc = grub_malloc (2 * sizeof (char *)); @@ -371,10 +374,13 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) desc[1] = mod->gp; if (grub_dl_register_symbol (name, (void *) desc, mod)) return grub_errno; -#else + sym->st_value = (grub_addr_t) desc; + } +#endif + if (bind != STB_LOCAL) + { if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) return grub_errno; -#endif } if (grub_strcmp (name, "grub_mod_init") == 0) mod->init = sym->st_value; @@ -405,14 +411,7 @@ grub_dl_call_init (grub_dl_t mod) { if (mod->init) { -#ifndef __ia64__ ((void (*) (grub_dl_t)) mod->init) (mod); -#else - char *jmp[2]; - jmp[0] = (char *) mod->init; - jmp[1] = mod->gp; - ((void (*) (grub_dl_t)) jmp) (mod); -#endif } } @@ -678,14 +677,7 @@ grub_dl_unload (grub_dl_t mod) if (mod->fini) { -#ifndef __ia64__ ((void (*) (void)) mod->fini) (); -#else - char *jmp[2]; - jmp[0] = (char *) mod->fini; - jmp[1] = mod->gp; - ((void (*) (void)) jmp) (); -#endif } grub_dl_remove (mod); diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c index 1fbe185b4..55b50ff69 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -41,23 +41,62 @@ grub_arch_dl_check_header (void *ehdr) #define MASK20 ((1 << 20) - 1) #define MASK19 ((1 << 19) - 1) -static void -add_value_to_slot13_20 (Elf_Word *addr, grub_uint32_t value, int slot) +struct unaligned_uint32 { - grub_uint32_t *p __attribute__ ((aligned (1))); - switch (slot) + grub_uint32_t val; +} __attribute__ ((packed)); + +static void +add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value) +{ + struct unaligned_uint32 *p; + switch (addr & 3) { case 0: - p = (grub_uint32_t *) (addr + 2); - *p = (((((*p >> 2) & MASK20) + value) & MASK20) << 2) | (*p & ~(MASK20 << 2)); + p = (struct unaligned_uint32 *) ((addr & ~3ULL) + 2); + p->val = (((((p->val >> 2) & MASK20) + value) & MASK20) << 2) | (p->val & ~(MASK20 << 2)); break; case 1: - p = (grub_uint32_t *) ((grub_uint8_t *) addr + 7); - *p = (((((*p >> 3) & MASK20) + value) & MASK20) << 3) | (*p & ~(MASK20 << 3)); + p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 7); + p->val = (((((p->val >> 3) & MASK20) + value) & MASK20) << 3) | (p->val & ~(MASK20 << 3)); break; case 2: - p = (grub_uint32_t *) ((grub_uint8_t *) addr + 12); - *p = (((((*p >> 4) & MASK20) + value) & MASK20) << 4) | (*p & ~(MASK20 << 4)); + p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 12); + p->val = (((((p->val >> 4) & MASK20) + value) & MASK20) << 4) | (p->val & ~(MASK20 << 4)); + break; + } +} + +#define MASKF21 ( ((1 << 23) - 1) & ~((1 << 7) | (1 << 8)) ) + +static grub_uint32_t +add_value_to_slot_21_real (grub_uint32_t a, grub_uint32_t value) +{ + grub_uint32_t high, mid, low, c; + low = (a & 0x00007f); + mid = (a & 0x7fc000) >> 7; + high = (a & 0x003e00) << 5; + c = (low | mid | high) + value; + return (c & 0x7f) | ((c << 7) & 0x7fc000) | ((c >> 5) & 0x003e00); +} + +static void +add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value) +{ + struct unaligned_uint32 *p; + switch (addr & 3) + { + case 0: + p = (struct unaligned_uint32 *) ((addr & ~3ULL) + 2); + p->val = ((add_value_to_slot_21_real (((p->val >> 2) & MASKF21), value) & MASKF21) << 2) | (p->val & ~(MASKF21 << 2)); + break; + case 1: + p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 7); + p->val = ((add_value_to_slot_21_real (((p->val >> 3) & MASKF21), value) & MASKF21) << 3) | (p->val & ~(MASKF21 << 3)); + break; + case 2: + p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 12); + p->val = ((add_value_to_slot_21_real (((p->val >> 4) & MASKF21), value) & MASKF21) << 4) | (p->val & ~(MASKF21 << 4)); break; } } @@ -147,8 +186,8 @@ grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec) for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), max = rel + s->sh_size / s->sh_entsize; rel < max; rel++) - if (ELF_R_TYPE (rel->r_info) == R_IA64_PCREL21B) - cnt++; + if (ELF_R_TYPE (rel->r_info) == R_IA64_PCREL21B) + cnt++; } return cnt * sizeof (struct ia64_trampoline); @@ -165,7 +204,7 @@ grub_arch_dl_allocate_gp (grub_dl_t mod, const void *ehdr) for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); i < e->e_shnum; i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_REL) + if (s->sh_type == SHT_RELA) { grub_dl_segment_t seg; @@ -176,16 +215,18 @@ grub_arch_dl_allocate_gp (grub_dl_t mod, const void *ehdr) if (seg) { - Elf_Rel *rel, *max; + Elf_Rela *rel, *max; - for (rel = (Elf_Rel *) ((char *) e + s->sh_offset), + for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), max = rel + s->sh_size / s->sh_entsize; rel < max; rel++) switch (ELF_R_TYPE (rel->r_info)) { + case R_IA64_LTOFF_FPTR22: case R_IA64_LTOFF22X: case R_IA64_LTOFF22: + case R_IA64_GPREL22: gp_size += 8; break; default: break; @@ -243,29 +284,22 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) Elf_Rela *rel, *max; struct ia64_trampoline *tr; + tr = (void *) ((char *) seg->addr + ALIGN_UP (seg->size, GRUB_ARCH_DL_TRAMP_ALIGN)); + for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), max = rel + s->sh_size / s->sh_entsize; rel < max; rel++) { - Elf_Word *addr; + grub_addr_t addr; Elf_Sym *sym; grub_uint64_t value; - int slot = 0; if (seg->size < (rel->r_offset & ~3)) return grub_error (GRUB_ERR_BAD_MODULE, "reloc offset is out of the segment"); - tr = (void *) ((char *) seg->addr + ALIGN_UP (seg->size, GRUB_ARCH_DL_TRAMP_ALIGN)); - - if (ELF_R_TYPE (rel->r_info) == R_IA64_PCREL21B) - { - addr = (Elf_Word *) ((char *) seg->addr + (rel->r_offset & ~3)); - slot = rel->r_offset & 3; - } - else - addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset); + addr = (grub_addr_t) seg->addr + rel->r_offset; sym = (Elf_Sym *) ((char *) mod->symtab + entsize * ELF_R_SYM (rel->r_info)); @@ -278,21 +312,26 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) { grub_uint64_t noff; make_trampoline (tr, value); - noff = ((char *) tr - (char *) addr) >> 4; + noff = ((char *) tr - (char *) (addr & ~3)) >> 4; tr++; if (noff & ~MASK19) return grub_error (GRUB_ERR_BAD_OS, - "trampoline offset too big"); - add_value_to_slot13_20 (addr, noff, slot); + "trampoline offset too big (%lx)", noff); + add_value_to_slot_20b (addr, noff); } break; case R_IA64_SEGREL64LSB: *(grub_uint64_t *) addr += value - rel->r_offset; break; + case R_IA64_DIR64LSB: + *(grub_uint64_t *) addr += value; + break; + case R_IA64_LTOFF_FPTR22: case R_IA64_LTOFF22X: case R_IA64_LTOFF22: + case R_IA64_GPREL22: *gpptr = value; - add_value_to_slot13_20 (addr, (gpptr - gp) * sizeof (grub_uint64_t), slot); + add_value_to_slot_21 (addr, (gpptr - gp) * sizeof (grub_uint64_t)); gpptr++; break; From f49157dfe52bc95640645080f228cccd69ff72a5 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 2 Jan 2011 23:30:25 +0100 Subject: [PATCH 28/28] Restructure module loading and many fixes. Now normal.mod loads successfully --- grub-core/kern/dl.c | 83 +++++++++++++++++++----------- grub-core/kern/emu/full.c | 15 ++---- grub-core/kern/ia64/dl.c | 105 +++++++++++++------------------------- include/grub/dl.h | 22 +++----- 4 files changed, 99 insertions(+), 126 deletions(-) diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 0ccdbe03b..787fcfad0 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -229,6 +229,46 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) { unsigned i; Elf_Shdr *s; + grub_size_t tsize = 0, talign = 1; +#ifdef __ia64__ + grub_size_t tramp; + grub_size_t got; +#endif + char *ptr; + + for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize)) + { + tsize += ALIGN_UP (s->sh_size, s->sh_addralign); + if (talign < s->sh_addralign) + talign = s->sh_addralign; + } + +#ifdef __ia64__ + grub_arch_dl_get_tramp_got_size (e, &tramp, &got); + tsize += ALIGN_UP (tramp, GRUB_ARCH_DL_TRAMP_ALIGN); + if (talign < GRUB_ARCH_DL_TRAMP_ALIGN) + talign = GRUB_ARCH_DL_TRAMP_ALIGN; + tsize += ALIGN_UP (got, GRUB_ARCH_DL_GOT_ALIGN); + if (talign < GRUB_ARCH_DL_GOT_ALIGN) + talign = GRUB_ARCH_DL_GOT_ALIGN; +#endif + +#ifdef GRUB_MACHINE_EMU + if (talign < 8192 * 16) + talign = 8192 * 16; + tsize = ALIGN_UP (tsize, 8192 * 16); +#endif + + mod->base = grub_memalign (talign, tsize); + if (!mod->base) + return grub_errno; + ptr = mod->base; + +#ifdef GRUB_MACHINE_EMU + mprotect (mod->base, tsize, PROT_READ | PROT_WRITE | PROT_EXEC); +#endif for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff); i < e->e_shnum; @@ -237,38 +277,18 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) if (s->sh_flags & SHF_ALLOC) { grub_dl_segment_t seg; - grub_size_t tramp_size = 0; - grub_size_t alsize, align; seg = (grub_dl_segment_t) grub_malloc (sizeof (*seg)); if (! seg) return grub_errno; - alsize = s->sh_size; - align = s->sh_addralign; - tramp_size = grub_arch_dl_get_tramp_size (e, i); - if (tramp_size && align < GRUB_ARCH_DL_TRAMP_ALIGN) - { - align = GRUB_ARCH_DL_TRAMP_ALIGN; - alsize = ALIGN_UP (alsize, GRUB_ARCH_DL_TRAMP_ALIGN); - } - alsize += tramp_size; -#ifdef GRUB_MACHINE_EMU - if (align < 8192 * 16) - align = 8192 * 16; - alsize = ALIGN_UP (alsize, 8192 * 16); -#endif - - if (alsize) + if (s->sh_size) { void *addr; - addr = grub_memalign (align, alsize); - if (! addr) - { - grub_free (seg); - return grub_errno; - } + ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, s->sh_addralign); + addr = ptr; + ptr += s->sh_size; switch (s->sh_type) { @@ -281,10 +301,6 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) } seg->addr = addr; -#ifdef GRUB_MACHINE_EMU - if (s->sh_flags & SHF_EXECINSTR) - mprotect (addr, alsize, PROT_READ | PROT_WRITE | PROT_EXEC); -#endif } else seg->addr = 0; @@ -295,6 +311,14 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) mod->segment = seg; } } +#ifdef __ia64__ + ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN); + mod->tramp = ptr; + ptr += tramp; + ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_GOT_ALIGN); + mod->got = ptr; + ptr += got; +#endif return GRUB_ERR_NONE; } @@ -371,7 +395,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) if (!desc) return grub_errno; desc[0] = (void *) sym->st_value; - desc[1] = mod->gp; + desc[1] = mod->base; if (grub_dl_register_symbol (name, (void *) desc, mod)) return grub_errno; sym->st_value = (grub_addr_t) desc; @@ -564,7 +588,6 @@ grub_dl_load_core (void *addr, grub_size_t size) if (grub_dl_resolve_name (mod, e) || grub_dl_resolve_dependencies (mod, e) || grub_dl_load_segments (mod, e) - || grub_arch_dl_allocate_gp (mod, e) || grub_dl_resolve_symbols (mod, e) || grub_arch_dl_relocate_symbols (mod, e)) { diff --git a/grub-core/kern/emu/full.c b/grub-core/kern/emu/full.c index 67a125301..80edb991e 100644 --- a/grub-core/kern/emu/full.c +++ b/grub-core/kern/emu/full.c @@ -50,18 +50,11 @@ grub_emu_init (void) } #ifdef __ia64__ -grub_size_t -grub_arch_dl_get_tramp_size (const void *ehdr __attribute__ ((unused)), - unsigned sec __attribute__ ((unused))) +void grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)), + grub_size_t *tramp, grub_size_t *got) { - return ~(grub_size_t)0; -} - -grub_err_t -grub_arch_dl_allocate_gp (grub_dl_t mod __attribute__ ((unused)), - const void *ehdr __attribute__ ((unused))) -{ - return GRUB_ERR_BAD_MODULE; + *tramp = 0; + *got = 0; } #endif diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c index 55b50ff69..9bbebcd2f 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -75,9 +75,9 @@ add_value_to_slot_21_real (grub_uint32_t a, grub_uint32_t value) grub_uint32_t high, mid, low, c; low = (a & 0x00007f); mid = (a & 0x7fc000) >> 7; - high = (a & 0x003e00) << 5; + high = (a & 0x003e00) << 7; c = (low | mid | high) + value; - return (c & 0x7f) | ((c << 7) & 0x7fc000) | ((c >> 5) & 0x003e00); + return (c & 0x7f) | ((c << 7) & 0x7fc000) | ((c >> 7) & 0x0003e00); //0x003e00 } static void @@ -138,7 +138,7 @@ static void make_trampoline (struct ia64_trampoline *tr, grub_uint64_t addr) { grub_memcpy (tr->nop, nopm, sizeof (tr->nop)); - tr->addr_hi[0] = ((addr & 0xc00000) >> 18); + tr->addr_hi[0] = ((addr & 0xc00000) >> 16); tr->addr_hi[1] = (addr >> 24) & 0xff; tr->addr_hi[2] = (addr >> 32) & 0xff; tr->addr_hi[3] = (addr >> 40) & 0xff; @@ -152,11 +152,11 @@ make_trampoline (struct ia64_trampoline *tr, grub_uint64_t addr) grub_memcpy (tr->jump, jump, sizeof (tr->jump)); } -grub_size_t -grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec) +void +grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got) { const Elf_Ehdr *e = ehdr; - int cnt = 0; + grub_size_t cntt = 0, cntg = 0;; const Elf_Shdr *s; Elf_Word entsize; unsigned i; @@ -169,7 +169,7 @@ grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec) break; if (i == e->e_shnum) - return 0; + return; entsize = s->sh_entsize; @@ -180,68 +180,25 @@ grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec) { Elf_Rela *rel, *max; - if (s->sh_info != sec) - continue; - for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), max = rel + s->sh_size / s->sh_entsize; rel < max; rel++) - if (ELF_R_TYPE (rel->r_info) == R_IA64_PCREL21B) - cnt++; + switch (ELF_R_TYPE (rel->r_info)) + { + case R_IA64_PCREL21B: + cntt++; + break; + case R_IA64_LTOFF_FPTR22: + case R_IA64_LTOFF22X: + case R_IA64_LTOFF22: + cntg++; + break; + } } - - return cnt * sizeof (struct ia64_trampoline); + *tramp = cntt * sizeof (struct ia64_trampoline); + *got = cntg * sizeof (grub_uint64_t); } -grub_err_t -grub_arch_dl_allocate_gp (grub_dl_t mod, const void *ehdr) -{ - grub_size_t gp_size = 0; - const Elf_Ehdr *e = ehdr; - const Elf_Shdr *s; - unsigned i; - - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_RELA) - { - grub_dl_segment_t seg; - - /* Find the target segment. */ - for (seg = mod->segment; seg; seg = seg->next) - if (seg->section == s->sh_info) - break; - - if (seg) - { - Elf_Rela *rel, *max; - - for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), - max = rel + s->sh_size / s->sh_entsize; - rel < max; - rel++) - switch (ELF_R_TYPE (rel->r_info)) - { - case R_IA64_LTOFF_FPTR22: - case R_IA64_LTOFF22X: - case R_IA64_LTOFF22: - case R_IA64_GPREL22: - gp_size += 8; - break; - default: break; - } - } - } - - if (gp_size > MASK19) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "gp too big"); - - mod->gp = grub_malloc (gp_size); - if (!mod->gp) - return grub_errno; - return GRUB_ERR_NONE; -} /* Relocate symbols. */ grub_err_t @@ -252,8 +209,11 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) Elf_Word entsize; unsigned i; grub_uint64_t *gp, *gpptr; + struct ia64_trampoline *tr; - gp = gpptr = (grub_uint64_t *) mod->gp; + gp = (grub_uint64_t *) mod->base; + gpptr = (grub_uint64_t *) mod->got; + tr = mod->tramp; /* Find a symbol table. */ for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); @@ -282,9 +242,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) if (seg) { Elf_Rela *rel, *max; - struct ia64_trampoline *tr; - - tr = (void *) ((char *) seg->addr + ALIGN_UP (seg->size, GRUB_ARCH_DL_TRAMP_ALIGN)); for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), max = rel + s->sh_size / s->sh_entsize; @@ -306,6 +263,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) /* On the PPC the value does not have an explicit addend, add it. */ value = sym->st_value + rel->r_addend; + switch (ELF_R_TYPE (rel->r_info)) { case R_IA64_PCREL21B: @@ -323,15 +281,24 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) case R_IA64_SEGREL64LSB: *(grub_uint64_t *) addr += value - rel->r_offset; break; + case R_IA64_FPTR64LSB: case R_IA64_DIR64LSB: *(grub_uint64_t *) addr += value; break; + case R_IA64_PCREL64LSB: + *(grub_uint64_t *) addr += value - addr; + break; + case R_IA64_GPREL22: + add_value_to_slot_21 (addr, value - (grub_addr_t) gp); + break; + case R_IA64_LTOFF_FPTR22: case R_IA64_LTOFF22X: case R_IA64_LTOFF22: - case R_IA64_GPREL22: *gpptr = value; - add_value_to_slot_21 (addr, (gpptr - gp) * sizeof (grub_uint64_t)); + if ((addr & 0xffff) == 0x4301) + grub_dprintf ("modules", "off = %lx\n", (grub_addr_t) gpptr - (grub_addr_t) gp); + add_value_to_slot_21 (addr, (grub_addr_t) gpptr - (grub_addr_t) gp); gpptr++; break; diff --git a/include/grub/dl.h b/include/grub/dl.h index c43c30ca7..b57c3ae87 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -93,8 +93,10 @@ struct grub_dl grub_addr_t init; grub_addr_t fini; #ifdef __ia64__ - char *gp; + void *got; + void *tramp; #endif + void *base; struct grub_dl *next; }; typedef struct grub_dl *grub_dl_t; @@ -123,24 +125,12 @@ void grub_arch_dl_init_linker (void); #endif #ifdef __ia64__ -grub_size_t grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec); -grub_err_t grub_arch_dl_allocate_gp (grub_dl_t mod, const void *ehdr); +void grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got); #define GRUB_ARCH_DL_TRAMP_ALIGN 16 -#else -static inline grub_size_t -grub_arch_dl_get_tramp_size (const void *ehdr __attribute__ ((unused)), int sec __attribute__ ((unused))) -{ - return 0; -} -static inline grub_err_t -grub_arch_dl_allocate_gp (grub_dl_t mod __attribute__ ((unused)), - const void *ehdr __attribute__ ((unused))) -{ - return GRUB_ERR_NONE; -} +#define GRUB_ARCH_DL_GOT_ALIGN 16 -#define GRUB_ARCH_DL_TRAMP_ALIGN 1 +#else #endif