diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 43ed42191..65f4ef1f7 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -425,8 +425,14 @@ image = { i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),$(GRUB_BOOT_MACHINE_LINK_ADDR)'; i386_qemu_ccasflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)'; - sparc64_ieee1275_objcopyflags = '-O a.out-sunos-big'; - sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x4000'; + sparc64_ieee1275_objcopyflags = '-O binary'; + /* The entry point for a.out binaries on sparc64 starts + at 0x4000. Since we are writing the 32 bytes long a.out + header in the assembly code ourselves, we need to tell + the linker to adjust the start of the text segment to + 0x4000 - 0x20 = 0x3fe0. + */ + sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x3fe0'; objcopyflags = '-O binary'; enable = i386_pc; @@ -455,8 +461,15 @@ image = { i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00'; sparc64_ieee1275 = boot/sparc64/ieee1275/boot.S; - sparc64_ieee1275_objcopyflags = '-O a.out-sunos-big'; - sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x4000'; + + sparc64_ieee1275_objcopyflags = '-O binary'; + /* The entry point for a.out binaries on sparc64 starts + at 0x4000. Since we are writing the 32 bytes long a.out + header in the assembly code ourselves, we need to tell + the linker to adjust the start of the text segment to + 0x4000 - 0x20 = 0x3fe0. + */ + sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x3fe0'; sparc64_ieee1275_cppflags = '-DCDBOOT=1'; objcopyflags = '-O binary'; diff --git a/grub-core/boot/sparc64/ieee1275/boot.S b/grub-core/boot/sparc64/ieee1275/boot.S index 9ea9b4e06..ed3aec464 100644 --- a/grub-core/boot/sparc64/ieee1275/boot.S +++ b/grub-core/boot/sparc64/ieee1275/boot.S @@ -21,6 +21,23 @@ .text .align 4 + /* We're writing the a.out header ourselves as newer + * upstream versions of binutils no longer support + * the a.out format on sparc64. + * + * The boot loader fits into 512 bytes with 32 bytes + * used for the a.out header, hence the text segment + * size is 512 - 32. There is no data segment and no + * code relocation, thus those fields remain zero. + */ + .word 0x1030107 /* magic number */ + .word 512 - GRUB_BOOT_AOUT_HEADER_SIZE /* size of text segment */ + .word 0 /* size of initialized data */ + .word 0 /* size of uninitialized data */ + .word 0 /* size of symbol table || checksum */ + .word _start /* entry point */ + .word 0 /* size of text relocation */ + .word 0 /* size of data relocation */ .globl _start _start: /* OF CIF entry point arrives in %o4 */ @@ -40,10 +57,14 @@ pic_base: * * After loading in that block we will execute it by jumping to the * load address plus the size of the prepended A.OUT header (32 bytes). + * + * Since this assembly code includes the 32 bytes long a.out header, + * we need to move the actual code entry point forward by the size + * of the a.out header, i.e. += GRUB_BOOT_AOUT_HEADER_SIZE. */ - .org GRUB_BOOT_MACHINE_BOOT_DEVPATH + .org GRUB_BOOT_MACHINE_BOOT_DEVPATH + GRUB_BOOT_AOUT_HEADER_SIZE boot_path: - .org GRUB_BOOT_MACHINE_KERNEL_BYTE + .org GRUB_BOOT_MACHINE_KERNEL_BYTE + GRUB_BOOT_AOUT_HEADER_SIZE boot_path_end: kernel_byte: .xword (2 << 9) kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR @@ -52,7 +73,7 @@ kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR #define boot_path_end (_start + 1024) #include - .org 8 + .org 8 + GRUB_BOOT_AOUT_HEADER_SIZE kernel_byte: .xword (2 << 9) kernel_size: .word 512 kernel_address: .word GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h index 02d53f28e..cc5a941e3 100644 --- a/include/grub/sparc64/ieee1275/boot.h +++ b/include/grub/sparc64/ieee1275/boot.h @@ -46,8 +46,7 @@ #define GRUB_BOOT_MACHINE_KERNEL_BYTE 0x80 -#define GRUB_BOOT_MACHINE_CODE_END \ - (0x1fc - GRUB_BOOT_AOUT_HEADER_SIZE) +#define GRUB_BOOT_MACHINE_CODE_END 0x1fc #define GRUB_BOOT_MACHINE_KERNEL_ADDR 0x4200