diff --git a/Makefile.in b/Makefile.in index 5e3d744..6840004 100644 --- a/Makefile.in +++ b/Makefile.in @@ -64,16 +64,22 @@ mkinstalldirs = $(srcdir)/mkinstalldirs CC = @CC@ CFLAGS = @CFLAGS@ +ASFLAGS = @ASFLAGS@ LDFLAGS = @LDFLAGS@ CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/include -Wall -W \ -DGRUB_LIBDIR=\"$(pkglibdir)\" TARGET_CC = @TARGET_CC@ TARGET_CFLAGS = @TARGET_CFLAGS@ +TARGET_ASFLAGS = @TARGET_ASFLAGS@ +TARGET_MODULE_FORMAT = @TARGET_MODULE_FORMAT@ +TARGET_APPLE_CC = @TARGET_APPLE_CC@ +OBJCONV = @OBJCONV@ TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/include \ -Wall -W TARGET_LDFLAGS = @TARGET_LDFLAGS@ TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@ TARGET_IMG_LDFLAGS = @TARGET_IMG_LDFLAGS@ +TARGET_IMG_CFLAGS = @TARGET_IMG_CFLAGS@ TARGET_OBJ2ELF = @TARGET_OBJ2ELF@ EXEEXT = @EXEEXT@ OBJCOPY = @OBJCOPY@ diff --git a/aclocal.m4 b/aclocal.m4 index 779df3d..ab17445 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -156,6 +156,36 @@ rm -f conftest*]) AC_MSG_RESULT([$grub_cv_i386_asm_addr32])]) +dnl check if our compiler is apple cc +dnl because it requires numerous workarounds +AC_DEFUN(grub_apple_cc, +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING([whether our compiler is apple cc]) +AC_CACHE_VAL(grub_cv_apple_cc, +[if $CC -v 2>&1 | grep "Apple Inc." > /dev/null; then + grub_cv_apple_cc=yes +else + grub_cv_apple_cc=no +fi +]) + +AC_MSG_RESULT([$grub_cv_apple_cc])]) + +dnl check if our target compiler is apple cc +dnl because it requires numerous workarounds +AC_DEFUN(grub_apple_target_cc, +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING([whether our target compiler is apple cc]) +AC_CACHE_VAL(grub_cv_apple_target_cc, +[if $CC -v 2>&1 | grep "Apple Inc." > /dev/null; then + grub_cv_apple_target_cc=yes +else + grub_cv_apple_target_cc=no +fi +]) + +AC_MSG_RESULT([$grub_cv_apple_target_cc])]) + dnl Later versions of GAS requires that addr32 and data32 prefixes dnl appear in the same lines as the instructions they modify, while diff --git a/boot/i386/pc/boot.S b/boot/i386/pc/boot.S index 8056731..c22dccd 100644 --- a/boot/i386/pc/boot.S +++ b/boot/i386/pc/boot.S @@ -30,7 +30,11 @@ #define ABS(x) (x-_start+0x7c00) /* Print message string */ +#ifdef APPLE_CC +#define MSG(x) x ## _abs = ABS(x); movw $x ## _abs, %si; call message +#else #define MSG(x) movw $ABS(x), %si; call message +#endif .file "boot.S" @@ -40,7 +44,9 @@ in real mode. */ .code16 -.globl _start; _start: +.globl _start, start; +_start: +start: /* * _start is loaded at 0x7c00 and is jumped to with CS:IP 0:0x7c00 */ @@ -123,7 +129,12 @@ boot_drive_check: * ljmp to the next instruction because some bogus BIOSes * jump to 07C0:0000 instead of 0000:7C00. */ +#ifdef APPLE_CC + real_start_abs = ABS(real_start) + ljmp $0, $(real_start_abs) +#else ljmp $0, $ABS(real_start) +#endif real_start: @@ -141,7 +152,12 @@ real_start: * Check if we have a forced disk reference here */ /* assign root_drive at the same time */ - movw ABS(boot_drive), %ax +#ifdef APPLE_CC + boot_drive_abs = ABS (boot_drive) + movw boot_drive_abs, %ax +#else + movw ABS(boot_drive), %ax +#endif movb %ah, %dh cmpb $0xff, %al je 1f @@ -154,7 +170,12 @@ real_start: MSG(notification_string) /* set %si to the disk address packet */ +#ifdef APPLE_CC + disk_address_packet_abs = ABS (disk_address_packet) + movw $disk_address_packet_abs, %si +#else movw $ABS(disk_address_packet), %si +#endif /* do not probe LBA if the drive is a floppy */ testb $GRUB_BOOT_MACHINE_BIOS_HD_FLAG, %dl @@ -195,10 +216,18 @@ lba_mode: movw $0x0010, (%si) /* the absolute address */ +#ifdef APPLE_CC + kernel_sector_abs = ABS (kernel_sector) + movl (kernel_sector_abs), %ebx + movl %ebx, 8(%si) + movl (kernel_sector_abs + 4), %ebx + movl %ebx, 12(%si) +#else movl ABS(kernel_sector), %ebx movl %ebx, 8(%si) movl ABS(kernel_sector + 4), %ebx movl %ebx, 12(%si) +#endif /* the segment of buffer address */ movw $GRUB_BOOT_MACHINE_BUFFER_SEG, 6(%si) @@ -265,12 +294,22 @@ final_init: setup_sectors: /* load logical sector start (top half) */ +#ifdef APPLE_CC + kernel_sector_abs = ABS (kernel_sector) + movl (kernel_sector_abs + 4), %eax +#else movl ABS(kernel_sector + 4), %eax +#endif + orl %eax, %eax jnz geometry_error /* load logical sector start (bottom half) */ +#ifdef APPLE_CC + movl (kernel_sector_abs), %eax +#else movl ABS(kernel_sector), %eax +#endif /* zero %edx */ xorl %edx, %edx @@ -334,7 +373,12 @@ setup_sectors: movw %es, %bx copy_buffer: +#ifdef APPLE_CC + kernel_segment_abs = ABS (kernel_segment) + movw (kernel_segment_abs), %es +#else movw ABS(kernel_segment), %es +#endif /* * We need to save %cx and %si because the startup code in @@ -358,7 +402,12 @@ copy_buffer: popw %dx /* boot kernel */ +#ifdef APPLE_CC + kernel_address_abs = ABS (kernel_address) + jmp *(kernel_address_abs) +#else jmp *(kernel_address) +#endif /* END OF MAIN LOOP */ @@ -390,11 +439,11 @@ general_error: int $0x18 stop: jmp stop -notification_string: .string "GRUB " -geometry_error_string: .string "Geom" -hd_probe_error_string: .string "Hard Disk" -read_error_string: .string "Read" -general_error_string: .string " Error" +notification_string: .asciz "GRUB " +geometry_error_string: .asciz "Geom" +hd_probe_error_string: .asciz "Hard Disk" +read_error_string: .asciz "Read" +general_error_string: .asciz " Error" /* * message: write the string pointed to by %si @@ -444,7 +493,12 @@ floppy_probe: * Perform floppy probe. */ +#ifdef APPLE_CC + probe_values_abs = ABS (probe_values) + movw $(probe_values_abs-1), %si +#else movw $ABS(probe_values-1), %si +#endif probe_loop: /* reset floppy controller INT 13h AH=0 */ @@ -464,7 +518,8 @@ probe_loop: MSG(fd_probe_error_string) jmp general_error -fd_probe_error_string: .string "Floppy" +/* "Floppy" */ +fd_probe_error_string: .asciz "Floppy" 1: /* perform read */ diff --git a/boot/i386/pc/cdboot.S b/boot/i386/pc/cdboot.S index 133f8de..b32f82c 100644 --- a/boot/i386/pc/cdboot.S +++ b/boot/i386/pc/cdboot.S @@ -67,8 +67,15 @@ bi_reserved: movw %ax, %ds movw %ax, %es +#ifdef APPLE_CC + err_noboot_msg_abs = 0x7C00 + err_noboot_msg - start + movw $err_noboot_msg_abs, %si + bi_length_dif = bi_length - next + movl %cs:bi_length_dif(%bx), %ecx +#else movw $(0x7C00 + err_noboot_msg - start), %si movl %cs: bi_length - next(%bx), %ecx +#endif orl %ecx, %ecx jz fail @@ -152,7 +159,12 @@ read_cdrom: ret cdrom_fail: +#ifdef APPLE_CC + err_cdfail_msg_abs = 0x7C00 + err_cdfail_msg - start + movw $(err_cdfail_msg_abs), %si +#else movw $(0x7C00 + err_cdfail_msg - start), %si +#endif fail: movb $0x0e, %ah diff --git a/boot/i386/pc/diskboot.S b/boot/i386/pc/diskboot.S index 95f87a0..f29ddaa 100644 --- a/boot/i386/pc/diskboot.S +++ b/boot/i386/pc/diskboot.S @@ -28,7 +28,11 @@ #define ABS(x) (x-_start+GRUB_BOOT_MACHINE_KERNEL_ADDR) /* Print message string */ +#ifdef APPLE_CC +#define MSG(x) x ## _abs = ABS(x); mov $x ## _abs, %esi; call message +#else #define MSG(x) movw $ABS(x), %si; call message +#endif .file "diskboot.S" @@ -61,7 +65,12 @@ _start: popw %si /* this sets up for the first run through "bootloop" */ +#ifdef APPLE_CC + firstlist_off_abs = ABS (firstlist - GRUB_BOOT_MACHINE_LIST_SIZE) + movl $firstlist_off_abs, %edi +#else movw $ABS(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE), %di +#endif /* save the sector number of the second sector in %ebp */ movl (%di), %ebp @@ -326,14 +335,14 @@ general_error: /* go here when you need to stop the machine hard after an error condition */ stop: jmp stop -notification_string: .string "loading" +notification_string: .asciz "loading" -notification_step: .string "." -notification_done: .string "\r\n" +notification_step: .asciz "." +notification_done: .asciz "\r\n" -geometry_error_string: .string "Geom" -read_error_string: .string "Read" -general_error_string: .string " Error" +geometry_error_string: .asciz "Geom" +read_error_string: .asciz "Read" +general_error_string: .asciz " Error" /* * message: write the string pointed to by %si diff --git a/boot/i386/pc/lnxboot.S b/boot/i386/pc/lnxboot.S index e7f55df..f244fec 100644 --- a/boot/i386/pc/lnxboot.S +++ b/boot/i386/pc/lnxboot.S @@ -24,9 +24,15 @@ #include .file "lnxboot.S" + +#ifdef APPLE_CC +#error Building lnxboot.img with Apple's as results in an unusable image +#endif #define CODE_ADDR 0x6000 +#ifndef APPLE_CC #define CODE_LENG (code_end - start) +#endif #define DATA_ADDR ((GRUB_BOOT_MACHINE_KERNEL_ADDR) + 0x200) #define BLCK_LENG 0x4000 @@ -44,7 +50,12 @@ data_start: . = data_start + 0x1F1 setup_sects: +/* Apple's cc can't fill this value. */ +#ifdef APPLE_CC + .byte 0 +#else .byte (CODE_LENG >> 9) +#endif root_flags: .word 0 syssize: @@ -123,8 +134,15 @@ data_leng: linux_init: +#ifdef APPLE_CC + reg_edx_rel = reg_edx - start + code32_start_rel = code32_start - start + movw %cs:(reg_edx_rel), %dx + movl %cs:(code32_start_rel), %ebp +#else movw %cs:(reg_edx - start), %dx movl %cs:(code32_start - start), %ebp +#endif linux_next: @@ -132,12 +150,22 @@ linux_next: normalize: popw %bx +#ifdef APPLE_CC + normalize_rel = normalize - start + subw $(normalize_rel), %bx +#else subw $(normalize - start), %bx +#endif shrw $4, %bx movw %cs, %ax addw %bx, %ax pushw %ax +#ifdef APPLE_CC + real_code_rel = real_code - start + pushw $(real_code_rel) +#else pushw $(real_code - start) +#endif lret /* Jump to real_code. */ real_code: @@ -164,7 +192,12 @@ real_code: rep movsl +#ifdef APPLE_CC + real_code_2_rel = real_code_2 - start + ljmp $(CODE_ADDR >> 4), $(real_code_2_rel) +#else ljmp $(CODE_ADDR >> 4), $(real_code_2 - start) +#endif real_code_2: @@ -189,8 +222,15 @@ real_code_2: cmpl $MULTIBOOT_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_DATA_END) jz 1f +#ifdef APPLE_CC + ramdisk_image_rel = ramdisk_image - start + ramdisk_size_rel = ramdisk_size - start + movl (ramdisk_image_rel), %esi + movl (ramdisk_size_rel), %ecx +#else movl (ramdisk_image - start), %esi movl (ramdisk_size - start), %ecx +#endif movl $(DATA_ADDR - 0x200), %edi jmp 2f @@ -205,7 +245,12 @@ real_code_2: movsbl %dh, %eax movl %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) +#ifdef APPLE_CC + reg_edx_rel = reg_edx - start + movsbl (reg_edx_rel + 2), %eax +#else movsbl (reg_edx + 2 - start), %eax +#endif movl %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART) movb $0xFF, %dh @@ -234,6 +279,28 @@ move_memory: pushl %ecx movl %esi, %eax +#ifdef APPLE_CC + gdt_src1_rel = gdt_src1 - start + gdt_src2_rel = gdt_src2 - start + gdt_dst1_rel = gdt_dst1 - start + gdt_dst2_rel = gdt_dst2 - start + gdt_rel = gdt - start + + movw %si, (gdt_src1_rel) + shrl $16, %eax + movb %al, (gdt_src1_rel + 2) + movb %ah, (gdt_src2_rel) + + movl %edi, %eax + movw %di, (gdt_dst1_rel) + shrl $16, %eax + movb %al, (gdt_dst1_rel + 2) + movb %ah, (gdt_dst2_rel) + + movw $(gdt_rel), %si + movb $0x87, %ah + shrw $1, %cx +#else movw %si, (gdt_src1 - start) shrl $16, %eax movb %al, (gdt_src1 + 2 - start) @@ -248,6 +315,7 @@ move_memory: movw $(gdt - start), %si movb $0x87, %ah shrw $1, %cx +#endif int $0x15 @@ -257,7 +325,12 @@ move_memory: popl %esi jnc 2f +#ifdef APPLE_CC + err_int15_msg_rel = err_int15_msg - start + movw $(err_int15_msg_rel), %si +#else movw $(err_int15_msg - start), %si +#endif jmp fail 2: @@ -289,7 +362,10 @@ fail: err_int15_msg: .ascii "move memory fails\0" + /* Unsupported feature in Apple's cc. */ +#ifndef APPLE_CC . = (. & (~0x1FF)) + 0x1FF +#endif .byte 0 diff --git a/boot/i386/pc/pxeboot.S b/boot/i386/pc/pxeboot.S index 4fdff76..b62c144 100644 --- a/boot/i386/pc/pxeboot.S +++ b/boot/i386/pc/pxeboot.S @@ -23,7 +23,9 @@ .code16 /* Let's go */ -.globl _start; _start: +.globl start, _start; +_start: +start: /* Root drive will default to boot drive */ movb $0xFF, %dh diff --git a/commands/i386/pc/drivemap_int13h.S b/commands/i386/pc/drivemap_int13h.S index 23b7302..7a3e8e7 100644 --- a/commands/i386/pc/drivemap_int13h.S +++ b/commands/i386/pc/drivemap_int13h.S @@ -30,7 +30,12 @@ FUNCTION(grub_drivemap_handler) /* Map the drive number (always in DL). */ push %ax push %bx +#ifdef APPLE_CC + grub_drivemap_mapstart_ofs = INT13H_OFFSET(EXT_C(grub_drivemap_mapstart)) + movw $grub_drivemap_mapstart_ofs, %bx +#else movw $INT13H_OFFSET(EXT_C(grub_drivemap_mapstart)), %bx +#endif more_remaining: movw %cs:(%bx), %ax diff --git a/conf/common.rmk b/conf/common.rmk index 1b9a6cd..1d0427d 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -125,6 +125,16 @@ endif grub_pe2elf_SOURCES = util/grub-pe2elf.c util/misc.c CLEANFILES += grub-pe2elf +# grub_macho2img assumes a lot about source file. +# So installing it definitively is useless +# But adding to bin_UTILITIES is needed for +# genmk.rb to work +ifeq (0,1) +bin_UTILITIES += grub-macho2img +endif +grub_macho2img_SOURCES = util/grub-macho2img.c +CLEANFILES += grub-macho2img + # For grub-mkconfig grub-mkconfig: util/grub-mkconfig.in config.status ./config.status --file=$@:$< diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index d51fa9b..411c789 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -10,37 +10,39 @@ COMMON_LDFLAGS = -m32 -nostdlib script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h # Images. -pkglib_IMAGES = boot.img diskboot.img kernel.img pxeboot.img lnxboot.img \ - cdboot.img +pkglib_IMAGES = boot.img diskboot.img kernel.img pxeboot.img cdboot.img # For boot.img. boot_img_SOURCES = boot/i386/pc/boot.S boot_img_ASFLAGS = $(COMMON_ASFLAGS) -boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,7C00 +boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)7C00 boot_img_FORMAT = binary # For pxeboot.img pxeboot_img_SOURCES = boot/i386/pc/pxeboot.S pxeboot_img_ASFLAGS = $(COMMON_ASFLAGS) -pxeboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,7C00 +pxeboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)7C00 pxeboot_img_FORMAT = binary # For diskboot.img. diskboot_img_SOURCES = boot/i386/pc/diskboot.S diskboot_img_ASFLAGS = $(COMMON_ASFLAGS) -diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,8000 +diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)8000 diskboot_img_FORMAT = binary # For lnxboot.img. +ifeq ($(TARGET_APPLE_CC), 0) +pkglib_IMAGES += lnxboot.img +endif lnxboot_img_SOURCES = boot/i386/pc/lnxboot.S lnxboot_img_ASFLAGS = $(COMMON_ASFLAGS) -lnxboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,6000 +lnxboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)6000 lnxboot_img_FORMAT = binary # For cdboot.img. cdboot_img_SOURCES = boot/i386/pc/cdboot.S cdboot_img_ASFLAGS = $(COMMON_ASFLAGS) -cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,7C00 +cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)7C00 cdboot_img_FORMAT = binary # For kernel.img. @@ -63,9 +65,9 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \ machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \ machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h -kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,$(GRUB_MEMORY_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_MEMORY_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) kernel_img_FORMAT = binary MOSTLYCLEANFILES += symlist.c kernel_syms.lst @@ -397,16 +399,44 @@ hdparm_mod_LDFLAGS = $(COMMON_LDFLAGS) ifeq ($(enable_efiemu), yes) -efiemu32.o: efiemu/runtime/efiemu.c - $(CC) -c -m32 -DELF32 -o $@ -Wall -Werror $< -nostdlib -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude +efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF) + -rm -f $@ +ifeq ($(TARGET_APPLE_CC), 1) + -rm -f address@hidden + $(TARGET_CC) -c -m32 -DELF32 -DAPPLE_CC -o address@hidden -Wall -Werror $< -nostdlib -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude + $(OBJCONV) -felf32 -nu -nd address@hidden $@ + -rm -f address@hidden +else + $(TARGET_CC) -c -m32 -DELF32 -o $@ -Wall -Werror $< -nostdlib -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi +endif + efiemu64_c.o: efiemu/runtime/efiemu.c - $(CC) -c -m64 -DELF64 -o $@ -Wall -Werror $< -nostdlib -mcmodel=large -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude +ifeq ($(TARGET_APPLE_CC), 1) + $(TARGET_CC) $(EFIEMU_CFLAGS) -c -m64 -DAPPLE_CC=1 -DELF64 -o $@ -Wall -Werror $< -nostdlib -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude +else + $(TARGET_CC) $(EFIEMU_CFLAGS) -c -m64 -DELF64 -o $@ -Wall -Werror $< -nostdlib -mcmodel=large -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude +endif efiemu64_s.o: efiemu/runtime/efiemu.S - $(CC) -c -m64 -DELF64 -o $@ -Wall -Werror $< -nostdlib -mcmodel=large -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude + -rm -f $@ +ifeq ($(TARGET_APPLE_CC), 1) + $(TARGET_CC) $(EFIEMU_CFLAGS) -c -m64 -DAPPLE_CC=1 -DELF64 -o $@ -Wall -Werror $< -nostdlib -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude +else + $(TARGET_CC) -c -m64 -DELF64 -o $@ -Wall -Werror $< -nostdlib -mcmodel=large -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude +endif -efiemu64.o: efiemu64_c.o efiemu64_s.o - ld -melf_x86_64 -o $@ -r $^ -nostdlib +efiemu64.o: efiemu64_c.o efiemu64_s.o $(TARGET_OBJ2ELF) + -rm -f $@ +ifeq ($(TARGET_APPLE_CC), 1) + -rm -f address@hidden + $(TARGET_CC) -m64 -o address@hidden -Wl,-r $^ -nostdlib + $(OBJCONV) -felf64 -nu -nd address@hidden $@ + -rm -f address@hidden +else + $(TARGET_CC) -m64 -o $@ -Wl,-r $^ -nostdlib + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi +endif CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o pkglib_DATA += efiemu32.o efiemu64.o diff --git a/configure.ac b/configure.ac index d84e2b6..9d0a8b9 100644 --- a/configure.ac +++ b/configure.ac @@ -101,6 +101,7 @@ esac case "$host_os" in mingw32) host_os=cygwin ;; + darwin*) host_os=darwin ;; esac # This normalizes the names, and creates a new variable ("host_kernel") @@ -167,6 +168,11 @@ AC_C_BIGENDIAN AC_CHECK_SIZEOF(void *) AC_CHECK_SIZEOF(long) +grub_apple_cc +if test x$grub_cv_apple_cc == xyes ; then + CFLAGS="$CFLAGS -DAPPLE_CC=1 -fnested-functions" + ASFLAGS="$ASFLAGS -DAPPLE_CC=1" +fi if test "x$host_m32" = x1; then # Force 32-bit mode. CFLAGS="$CFLAGS -m32" @@ -206,31 +212,6 @@ AC_CHECK_FUNCS(posix_memalign memalign asprintf) # Check for target programs. # - -# Use linker script if present, otherwise use builtin -N script. -AC_MSG_CHECKING([for option to link raw image]) -if test -f "${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"; then - TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc" - TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}" - TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc" -else - TARGET_IMG_LDSCRIPT= - TARGET_IMG_LDFLAGS='-Wl,-N' - TARGET_IMG_LDFLAGS_AC='-Wl,-N' -fi -AC_SUBST(TARGET_IMG_LDSCRIPT) -AC_SUBST(TARGET_IMG_LDFLAGS) -AC_MSG_RESULT([$TARGET_IMG_LDFLAGS_AC]) - -# For platforms where ELF is not the default link format. -AC_MSG_CHECKING([for command to convert module to ELF format]) -case "${host_os}" in - cygwin) TARGET_OBJ2ELF='grub-pe2elf' ;; - *) ;; -esac -AC_SUBST(TARGET_OBJ2ELF) -AC_MSG_RESULT([$TARGET_OBJ2ELF]) - # Find tools for the target. if test "x$target_alias" != x && test "x$host_alias" != "x$target_alias"; then tmp_ac_tool_prefix="$ac_tool_prefix" @@ -287,7 +268,7 @@ if test "x$TARGET_CFLAGS" = x; then # Force no alignment to save space on i386. if test "x$target_cpu" = xi386; then AC_CACHE_CHECK([whether -falign-loops works], [grub_cv_cc_falign_loop], [ - CFLAGS="-falign-loops=1" + CFLAGS="$CFLAGS -falign-loops=1" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [grub_cv_cc_falign_loop=yes], [grub_cv_cc_falign_loop=no]) @@ -301,33 +282,88 @@ if test "x$TARGET_CFLAGS" = x; then fi fi +grub_apple_target_cc +if test x$grub_cv_apple_target_cc == xyes ; then + TARGET_CFLAGS="$TARGET_CFLAGS -DAPPLE_CC=1 -fnested-functions" + CFLAGS="$CFLAGS -DAPPLE_CC=1 -fnested-functions" + TARGET_ASFLAGS="$TARGET_ASFLAGS -DAPPLE_CC=1" + TARGET_APPLE_CC=1 + AC_CHECK_PROG([OBJCONV], [objconv], [objconv], []) + if test "x$OBJCONV" = x ; then + AC_CHECK_PROG([OBJCONV], [objconv], [./objconv], [], [.]) + fi + if test "x$OBJCONV" = x ; then + AC_MSG_ERROR([objconv not found which is required when building with apple compiler]) + fi + TARGET_IMG_LDSCRIPT= + TARGET_IMG_CFLAGS="-static" + TARGET_IMG_LDFLAGS='-nostdlib -static -Wl,-preload -Wl,-segalign,20 -Wl,-image_base,' + TARGET_IMG_LDFLAGS_AC='-nostdlib -static -Wl,-preload -Wl,-segalign,20 -Wl,-image_base,' +else + TARGET_APPLE_CC=0 +# Use linker script if present, otherwise use builtin -N script. +AC_MSG_CHECKING([for option to link raw image]) +if test -f "${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"; then + TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc" + TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT} -Wl,-Ttext," + TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc" +else + TARGET_IMG_LDSCRIPT= + TARGET_IMG_LDFLAGS='-Wl,-N -Wl,-Ttext,' + TARGET_IMG_LDFLAGS_AC='-Wl,-N -Wl,-Ttext,' +fi +TARGET_IMG_CFLAGS= +fi + +AC_SUBST(TARGET_IMG_LDSCRIPT) +AC_SUBST(TARGET_IMG_LDFLAGS) +AC_SUBST(TARGET_IMG_CFLAGS) +AC_MSG_RESULT([$TARGET_IMG_LDFLAGS_AC]) + +# For platforms where ELF is not the default link format. +AC_MSG_CHECKING([for command to convert module to ELF format]) +case "${host_os}" in + cygwin) TARGET_OBJ2ELF='grub-pe2elf' ;; + *) ;; +esac +AC_SUBST(TARGET_OBJ2ELF) +AC_MSG_RESULT([$TARGET_OBJ2ELF]) + + if test "x$target_m32" = x1; then # Force 32-bit mode. TARGET_CFLAGS="$TARGET_CFLAGS -m32" TARGET_LDFLAGS="$TARGET_LDFLAGS -m32" + TARGET_MODULE_FORMAT="elf32" fi if test "x$target_m64" = x1; then # Force 64-bit mode. TARGET_CFLAGS="$TARGET_CFLAGS -m64" TARGET_LDFLAGS="$TARGET_LDFLAGS -m64" + TARGET_MODULE_FORMAT="elf64" fi if test "$target_cpu"-"$platform" = x86_64-efi; then # Use large model to support 4G memory AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [ - CFLAGS="-m64 -mcmodel=large" + SAVED_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -m64 -mcmodel=large" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [grub_cv_cc_mcmodel=yes], [grub_cv_cc_mcmodel=no]) ]) - if test "x$grub_cv_cc_no_mcmodel" = xno; then - AC_MSG_ERROR([-mcmodel=large not supported, upgrade your gcc]) + if test "x$grub_cv_cc_mcmodel" = xno; then + CFLAGS="$SAVED_CFLAGS -m64 -DMCMODEL_SMALL=1" + TARGET_CFLAGS="$TARGET_CFLAGS -DMCMODEL_SMALL=1" + AC_MSG_WARN([-mcmodel=large not supported. You wan't be able to use the memory over 4GiB. Upgrade your gcc]) + else + TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large" fi # EFI writes to stack below %rsp, we must not use the red zone AC_CACHE_CHECK([whether option -mno-red-zone works], grub_cv_cc_no_red_zone, [ - CFLAGS="-m64 -mno-red-zone" + CFLAGS="$CFLAGS -m64 -mno-red-zone" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [grub_cv_cc_no_red_zone=yes], [grub_cv_cc_no_red_zone=no]) @@ -336,7 +372,7 @@ if test "$target_cpu"-"$platform" = x86_64-efi; then AC_MSG_ERROR([-mno-red-zone not supported, upgrade your gcc]) fi - TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large -mno-red-zone" + TARGET_CFLAGS="$TARGET_CFLAGS -mno-red-zone" fi # @@ -361,6 +397,10 @@ if test x"$sap_possible" = xyes; then fi AC_SUBST(TARGET_CFLAGS) +AC_SUBST(TARGET_MODULE_FORMAT) +AC_SUBST(OBJCONV) +AC_SUBST(TARGET_APPLE_CC) +AC_SUBST(TARGET_ASFLAGS) AC_SUBST(TARGET_CPPFLAGS) AC_SUBST(TARGET_LDFLAGS) @@ -375,7 +415,9 @@ AC_CHECK_FUNCS(__bswapsi2 __bswapdi2) # Defined in aclocal.m4. grub_PROG_TARGET_CC +if test "x$TARGET_APPLE_CC" != x1 ; then grub_PROG_OBJCOPY_ABSOLUTE +fi grub_PROG_LD_BUILD_ID_NONE grub_ASM_USCORE if test "x$target_cpu" = xi386; then @@ -383,7 +425,7 @@ if test "x$target_cpu" = xi386; then # Check symbols provided by linker script. CFLAGS="$TARGET_CFLAGS -nostdlib $TARGET_IMG_LDFLAGS_AC -Wl,-Ttext,8000,--defsym,___main=0x8100" fi - if test "x$platform" = xpc; then + if test "x$platform" = xpc && test "x$TARGET_APPLE_CC" != x1 ; then grub_CHECK_BSS_START_SYMBOL grub_CHECK_END_SYMBOL fi @@ -477,6 +519,7 @@ AC_ARG_ENABLE([efiemu], [AS_HELP_STRING([--enable-efiemu], [build and install the efiemu runtimes])]) AC_SUBST([enable_efiemu]) +AC_SUBST(ASFLAGS) # Output files. grub_CHECK_LINK_DIR diff --git a/efiemu/runtime/efiemu.c b/efiemu/runtime/efiemu.c index 5887c48..189f502 100644 --- a/efiemu/runtime/efiemu.c +++ b/efiemu/runtime/efiemu.c @@ -40,18 +40,23 @@ grub_efi_status_t efiemu_set_wakeup_time (grub_efi_boolean_t enabled, grub_efi_time_t *time); +#ifdef APPLE_CC +#define PHYSICAL_ATTRIBUTE __attribute__ ((section("_text-physical, _text-physical"))); +#else +#define PHYSICAL_ATTRIBUTE __attribute__ ((section(".text-physical"))); +#endif grub_efi_status_t efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size, grub_efi_uintn_t descriptor_size, grub_efi_uint32_t descriptor_version, grub_efi_memory_descriptor_t *virtual_map) - __attribute__ ((section(".text-physical"))); + PHYSICAL_ATTRIBUTE; grub_efi_status_t efiemu_convert_pointer (grub_efi_uintn_t debug_disposition, void **address) - __attribute__ ((section(".text-physical"))); + PHYSICAL_ATTRIBUTE; grub_efi_status_t efiemu_get_variable (grub_efi_char16_t *variable_name, @@ -84,17 +89,17 @@ EFI_FUNC (efiemu_set_virtual_address_map) (grub_efi_uintn_t, grub_efi_uintn_t, grub_efi_uint32_t, grub_efi_memory_descriptor_t *) - __attribute__ ((section(".text-physical"))); + PHYSICAL_ATTRIBUTE; grub_efi_status_t EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition, void **address) - __attribute__ ((section(".text-physical"))); + PHYSICAL_ATTRIBUTE; static grub_uint32_t efiemu_getcrc32 (grub_uint32_t crc, void *buf, int size) - __attribute__ ((section(".text-physical"))); + PHYSICAL_ATTRIBUTE; static void init_crc32_table (void) - __attribute__ ((section(".text-physical"))); + PHYSICAL_ATTRIBUTE; /* The log. It's used when examining memory dump @@ -162,8 +167,8 @@ static inline void write_cmos (grub_uint8_t addr, grub_uint8_t val) { __asm__ __volatile__ ("outb %%al,$0x70\n" - "mov %%bl, %%al\n" - "outb %%al,$0x71": :"a" (addr), "b" (val)); + "mov %%cl, %%al\n" + "outb %%al,$0x71": :"a" (addr), "c" (val)); } static inline grub_uint8_t @@ -271,25 +276,25 @@ EFI_FUNC (efiemu_set_wakeup_time) (grub_efi_boolean_t enabled, static grub_uint32_t crc32_table [256]; -static void -init_crc32_table (void) +static grub_uint32_t +reflect (grub_uint32_t ref, int len) { - auto grub_uint32_t reflect (grub_uint32_t ref, int len); - grub_uint32_t reflect (grub_uint32_t ref, int len) + grub_uint32_t result = 0; + int i; + + for (i = 1; i <= len; i++) { - grub_uint32_t result = 0; - int i; - - for (i = 1; i <= len; i++) - { - if (ref & 1) - result |= 1 << (len - i); - ref >>= 1; - } - - return result; + if (ref & 1) + result |= 1 << (len - i); + ref >>= 1; } + + return result; +} +static void +init_crc32_table (void) +{ grub_uint32_t polynomial = 0x04c11db7; int i, j; diff --git a/gencmdlist.sh b/gencmdlist.sh index 5d3897c..7f25490 100644 --- a/gencmdlist.sh +++ b/gencmdlist.sh @@ -17,4 +17,6 @@ module=$1 grep -v "^#" | sed -n \ -e "/grub_register_command *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $module/;p;}" \ - -e "/\(grub_register_extcmd\|grub_register_command_p1\) *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $module/;p;}" + -e "/grub_register_extcmd *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $module/;p;}" \ + -e "/grub_register_command_p1 *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $module/;p;}" + diff --git a/genmk.rb b/genmk.rb index 3532cd8..c3df506 100644 --- a/genmk.rb +++ b/genmk.rb @@ -56,8 +56,18 @@ class Image "CLEANFILES += address@hidden #{exe} #{objs_str} MOSTLYCLEANFILES += #{deps_str} +ifneq ($(TARGET_APPLE_CC),1) address@hidden: #{exe} $(OBJCOPY) -O $(#{prefix}_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@ +else +ifneq (#{exe},kernel.exec) address@hidden: #{exe} ./grub-macho2img + ./grub-macho2img $< $@ +else address@hidden: #{exe} ./grub-macho2img + ./grub-macho2img --bss $< $@ +endif +endif #{exe}: #{objs_str} $(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS) @@ -112,11 +122,20 @@ endif MOSTLYCLEANFILES += #{deps_str} UNDSYMFILES += #{undsym} +ifneq ($(TARGET_APPLE_CC),1) address@hidden: #{pre_obj} #{mod_obj} $(TARGET_OBJ2ELF) -rm -f $@ $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ #{pre_obj} #{mod_obj} if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ +else address@hidden: #{pre_obj} #{mod_obj} $(TARGET_OBJ2ELF) + -rm -f $@ + -rm -f address@hidden + $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o address@hidden #{pre_obj} #{mod_obj} + $(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd address@hidden $@ + -rm -f address@hidden +endif #{pre_obj}: $(#{prefix}_DEPENDENCIES) #{objs_str} -rm -f $@ @@ -129,8 +148,13 @@ UNDSYMFILES += #{undsym} sh $(srcdir)/genmodsrc.sh '#{mod_name}' $< > $@ || (rm -f $@; exit 1) ifneq ($(#{prefix}_EXPORTS),no) +ifneq ($(TARGET_APPLE_CC),1) #{defsym}: #{pre_obj} $(NM) -g --defined-only -P -p $< | sed 's/^\\([^ ]*\\).*/\\1 #{mod_name}/' > $@ +else +#{defsym}: #{pre_obj} + $(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]' | sed 's/^\\([^ ]*\\).*/\\1 #{mod_name}/' > $@ +endif endif #{undsym}: #{pre_obj} diff --git a/genmoddep.awk b/genmoddep.awk index c079b36..5b9bc62 100644 --- a/genmoddep.awk +++ b/genmoddep.awk @@ -50,7 +50,7 @@ END { for (i in depmods) { depmod = depmods[i]; # Ignore kernel, as always loaded. - if (depmod != "kernel") + if (depmod != "kernel" && depmod != mod) uniqmods[depmod] = 1; } modlist = "" diff --git a/include/grub/dl.h b/include/grub/dl.h index 4ff6240..19d6449 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -40,11 +40,19 @@ grub_##name##_fini (void) { grub_mod_fini (); } \ static void \ grub_mod_fini (void) +#ifdef APPLE_CC +#define GRUB_MOD_NAME(name) \ +static char grub_modname[] __attribute__ ((section ("_modname, _modname"), used)) = #name; + +#define GRUB_MOD_DEP(name) \ +__asm__ (".section _moddeps, _moddeps\n.asciz \"" #name "\"\n") +#else #define GRUB_MOD_NAME(name) \ __asm__ (".section .modname\n.string \"" #name "\"\n") #define GRUB_MOD_DEP(name) \ __asm__ (".section .moddeps\n.string \"" #name "\"\n") +#endif struct grub_dl_segment { diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index b6650bc..4e9fb62 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -74,8 +74,10 @@ extern grub_int32_t EXPORT_VAR(grub_boot_drive); /* The root BIOS drive number. */ extern grub_int32_t grub_root_drive; +#if 0 /* The end address of the kernel. */ extern grub_addr_t grub_end_addr; +#endif #endif /* ! ASM_FILE */ diff --git a/include/grub/i386/tsc.h b/include/grub/i386/tsc.h index 9633701..aa40145 100644 --- a/include/grub/i386/tsc.h +++ b/include/grub/i386/tsc.h @@ -29,8 +29,24 @@ grub_get_tsc (void) /* The CPUID instruction is a 'serializing' instruction, and avoids out-of-order execution of the RDTSC instruction. */ +#ifdef APPLE_CC __asm__ __volatile__ ("xorl %%eax, %%eax\n\t" - "cpuid":::"%rax", "%rbx", "%rcx", "%rdx"); +#ifdef __x86_64__ + "push %%rbx\n" +#else + "push %%ebx\n" +#endif + "cpuid\n" +#ifdef __x86_64__ + "pop %%rbx\n" +#else + "pop %%ebx\n" +#endif + :::"%rax", "%rcx", "%rdx"); +#else + __asm__ __volatile__ ("xorl %%eax, %%eax\n\t" + "cpuid":::"%rax", "%rbx", "%rcx", "%rdx"); +#endif /* Read TSC value. We cannot use "=A", since this would use %rax on x86_64. */ __asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi)); @@ -93,11 +109,29 @@ grub_cpu_is_tsc_supported (void) return 0; grub_uint32_t features; +#ifdef APPLE_CC __asm__ ("movl $1, %%eax\n\t" - "cpuid" +#ifdef __x86_64__ + "push %%rbx\n" +#else + "push %%ebx\n" +#endif + "cpuid\n" +#ifdef __x86_64__ + "pop %%rbx\n" +#else + "pop %%ebx\n" +#endif + : "=d" (features) + : /* No inputs. */ + : /* Clobbered: */ "%rax", "%rcx"); +#else + __asm__ ("movl $1, %%eax\n\t" + "cpuid\n" : "=d" (features) : /* No inputs. */ : /* Clobbered: */ "%rax", "%rbx", "%rcx"); +#endif return (features & (1 << 4)) != 0; } diff --git a/include/grub/list.h b/include/grub/list.h index eba1237..6e03492 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -41,7 +41,18 @@ void EXPORT_FUNC(grub_list_insert) (grub_list_t *head, grub_list_t item, /* This function doesn't exist, so if assertion is false for some reason, the linker would fail. */ +#ifdef APPLE_CC +/* This approach fails with Apple's gcc. Use grub_abort. */ +#include +static inline void * +grub_assert_fail (void) +{ + grub_abort (); + return 0; +} +#else extern void* grub_assert_fail (void); +#endif #define GRUB_FIELD_MATCH(ptr, type, field) \ ((char *) &(ptr)->field == (char *) &((type) (ptr))->field) diff --git a/include/grub/misc.h b/include/grub/misc.h index 5c8baa1..23e0ce6 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -40,8 +40,10 @@ char *EXPORT_FUNC(grub_strcat) (char *dest, const char *src); char *EXPORT_FUNC(grub_strncat) (char *dest, const char *src, int c); /* Prototypes for aliases. */ +#if !defined (GRUB_UTIL) || !defined (APPLE_CC) void *EXPORT_FUNC(memmove) (void *dest, const void *src, grub_size_t n); void *EXPORT_FUNC(memcpy) (void *dest, const void *src, grub_size_t n); +#endif int EXPORT_FUNC(grub_memcmp) (const void *s1, const void *s2, grub_size_t n); int EXPORT_FUNC(grub_strcmp) (const char *s1, const char *s2); diff --git a/include/grub/symbol.h b/include/grub/symbol.h index ef19a73..68d9f00 100644 --- a/include/grub/symbol.h +++ b/include/grub/symbol.h @@ -28,7 +28,10 @@ # define EXT_C(sym) sym #endif -#if ! defined (__CYGWIN__) && ! defined (__MINGW32__) +#if defined (APPLE_CC) +#define FUNCTION(x) .globl EXT_C(x) ; EXT_C(x): +#define VARIABLE(x) .globl EXT_C(x) ; EXT_C(x): +#elif ! defined (__CYGWIN__) && ! defined (__MINGW32__) #define FUNCTION(x) .globl EXT_C(x) ; .type EXT_C(x), "function" ; EXT_C(x): #define VARIABLE(x) .globl EXT_C(x) ; .type EXT_C(x), "object" ; EXT_C(x): #else diff --git a/include/grub/term.h b/include/grub/term.h index d12d0f0..3251e36 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -31,7 +31,7 @@ #define GRUB_TERM_NPAGE 3 #define GRUB_TERM_ESC '\e' #define GRUB_TERM_TAB '\t' -#define GRUB_TERM_BACKSPACE '\b' +#define GRUB_TERM_BACKSPACE 8 #ifndef ASM_FILE diff --git a/kern/efi/mm.c b/kern/efi/mm.c index 4635776..30b5ab4 100644 --- a/kern/efi/mm.c +++ b/kern/efi/mm.c @@ -63,7 +63,9 @@ grub_efi_allocate_pages (grub_efi_physical_address_t address, /* Limit the memory access to less than 4GB for 32-bit platforms. */ if (address > 0xffffffff) return 0; +#endif +#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL) if (address == 0) { type = GRUB_EFI_ALLOCATE_MAX_ADDRESS; @@ -218,7 +220,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) { if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY -#if GRUB_TARGET_SIZEOF_VOID_P < 8 +#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL) && desc->physical_start <= 0xffffffff #endif && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000 @@ -234,7 +236,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, desc->physical_start = 0x100000; } -#if GRUB_TARGET_SIZEOF_VOID_P < 8 +#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL) if (BYTES_TO_PAGES (filtered_desc->physical_start) + filtered_desc->num_pages > BYTES_TO_PAGES (0x100000000LL)) diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index 8e8b661..488459d 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -69,7 +69,12 @@ _start: /* * Guarantee that "main" is loaded at 0x0:0x8200. */ +#ifdef APPLE_CC + codestart_abs = ABS(codestart) - 0x10000 + ljmp $0, $(codestart_abs) +#else ljmp $0, $ABS(codestart) +#endif /* * Compatibility version number @@ -105,6 +110,13 @@ VARIABLE(grub_prefix) . = _start + GRUB_KERNEL_MACHINE_DATA_END +#ifdef APPLE_CC +bss_start: + .long 0 +bss_end: + .long 0 +#endif + /* * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). * This uses the a.out kludge to load raw binary to the area starting at 1MB, @@ -249,12 +261,24 @@ codestart: movsb #endif +#ifdef APPLE_CC + /* clean out the bss */ + bss_start_abs = ABS (bss_start) + bss_end_abs = ABS (bss_end) + + movl bss_start_abs, %edi + + /* compute the bss length */ + movl bss_end_abs, %ecx + subl %edi, %ecx +#else /* clean out the bss */ movl $BSS_START_SYMBOL, %edi /* compute the bss length */ movl $END_SYMBOL, %ecx subl %edi, %ecx +#endif /* clean out */ xorl %eax, %eax @@ -281,6 +305,7 @@ VARIABLE(grub_boot_drive) VARIABLE(grub_root_drive) .long 0 +#if 0 VARIABLE(grub_start_addr) .long _start @@ -296,6 +321,7 @@ VARIABLE(grub_apm_bios_info) .word 0 /* cseg_len */ .word 0 /* cseg_16_len */ .word 0 /* dseg_16_len */ +#endif .p2align 2 /* force 4-byte alignment */ @@ -311,7 +337,13 @@ real_to_prot: cli /* load the GDT register */ +#ifdef APPLE_CC + mov %cs, %ax + mov %ax, %ds + DATA32 ADDR32 lgdt gdtdesc +#else DATA32 ADDR32 lgdt %cs:gdtdesc +#endif /* turn on protected mode */ movl %cr0, %eax @@ -1108,7 +1140,18 @@ FUNCTION(grub_get_mmap_entry) xnosmap: xorl %ecx, %ecx +/* Apple's cc jumps few bytes before the correct label in this context. Hence nops */ +#ifdef APPLE_CC + nop + nop + nop + nop + nop + nop +#endif + xsmap: + DATA32 call real_to_prot .code32 @@ -1241,7 +1284,12 @@ translate_keycode: pushw %bx pushw %si +#ifdef APPLE_CC + translation_table_abs = ABS (translation_table) - 0x10000 + movw $(translation_table_abs), %si +#else movw $ABS(translation_table), %si +#endif 1: lodsw /* check if this is the end */ diff --git a/kern/misc.c b/kern/misc.c index 4c71ca8..4b46c67 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -44,11 +44,23 @@ grub_memmove (void *dest, const void *src, grub_size_t n) return dest; } + +#ifndef APPLE_CC void *memmove (void *dest, const void *src, grub_size_t n) __attribute__ ((alias ("grub_memmove"))); /* GCC emits references to memcpy() for struct copies etc. */ void *memcpy (void *dest, const void *src, grub_size_t n) __attribute__ ((alias ("grub_memmove"))); +#else +void *memcpy (void *dest, const void *src, grub_size_t n) +{ + return grub_memmove (dest, src, n); +} +void *memmove (void *dest, const void *src, grub_size_t n) +{ + return grub_memmove (dest, src, n); +} +#endif char * grub_strcpy (char *dest, const char *src) @@ -134,7 +146,22 @@ grub_printf (const char *fmt, ...) return ret; } -#ifndef GRUB_UTIL +#if defined (APPLE_CC) && ! defined (GRUB_UTIL) +int +grub_err_printf (const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start (ap, fmt); + ret = grub_vprintf (fmt, ap); + va_end (ap); + + return ret; +} +#endif + +#if ! defined (APPLE_CC) && ! defined (GRUB_UTIL) int grub_err_printf (const char *fmt, ...) __attribute__ ((alias("grub_printf"))); #endif @@ -185,8 +212,10 @@ grub_memcmp (const void *s1, const void *s2, grub_size_t n) return 0; } +#ifndef APPLE_CC int memcmp (const void *s1, const void *s2, grub_size_t n) __attribute__ ((alias ("grub_memcmp"))); +#endif int grub_strcmp (const char *s1, const char *s2) @@ -534,8 +563,10 @@ grub_memset (void *s, int c, grub_size_t n) return s; } +#ifndef APPLE_CC void *memset (void *s, int c, grub_size_t n) __attribute__ ((alias ("grub_memset"))); +#endif grub_size_t grub_strlen (const char *s) @@ -1066,8 +1097,11 @@ grub_abort (void) grub_exit (); } + +#ifndef APPLE_CC /* GCC emits references to abort(). */ void abort (void) __attribute__ ((alias ("grub_abort"))); +#endif #ifdef NEED_ENABLE_EXECUTE_STACK /* Some gcc versions generate a call to this function diff --git a/loader/i386/xnu.c b/loader/i386/xnu.c index 0860160..2fb490d 100644 --- a/loader/i386/xnu.c +++ b/loader/i386/xnu.c @@ -125,6 +125,28 @@ guessfsb (void) if (! grub_cpu_is_cpuid_supported ()) return sane_value; + +#ifdef APPLE_CC + asm volatile ("movl $0, %%eax\n" +#ifdef __x86_64__ + "push %%rbx\n" +#else + "push %%ebx\n" +#endif + "cpuid\n" +#ifdef __x86_64__ + "pop %%rbx\n" +#else + "pop %%ebx\n" +#endif + : "=a" (max_cpuid), + "=d" (manufacturer[1]), "=c" (manufacturer[2])); + + /* Only Intel for now is done. */ + if (grub_memcmp (manufacturer+1, "ineIntel", 12) != 0) + return sane_value; + +#else asm volatile ("movl $0, %%eax\n" "cpuid" : "=a" (max_cpuid), "=b" (manufacturer[0]), @@ -133,15 +155,33 @@ guessfsb (void) /* Only Intel for now is done. */ if (grub_memcmp (manufacturer, "GenuineIntel", 12) != 0) return sane_value; +#endif /* Check Speedstep. */ if (max_cpuid < 1) return sane_value; +#ifdef APPLE_CC + asm volatile ("movl $1, %%eax\n" +#ifdef __x86_64__ + "push %%rbx\n" +#else + "push %%ebx\n" +#endif + "cpuid\n" +#ifdef __x86_64__ + "pop %%rbx\n" +#else + "pop %%ebx\n" +#endif + : "=c" (capabilities): + : "%rax", "%rdx"); +#else asm volatile ("movl $1, %%eax\n" "cpuid" : "=c" (capabilities): - : "%eax", "%ebx", "%edx"); + : "%rax", "%rbx", "%rdx"); +#endif if (! (capabilities & (1 << 7))) return sane_value; diff --git a/loader/i386/xnu_helper.S b/loader/i386/xnu_helper.S index 77b0a66..fbc4918 100644 --- a/loader/i386/xnu_helper.S +++ b/loader/i386/xnu_helper.S @@ -94,11 +94,28 @@ VARIABLE(grub_xnu_heap_size) movsl mov %rax, %rsi +#ifdef APPLE_CC + add $(cont0-base), %eax +#else add $(cont0-base), %rax +#endif jmp *%rax cont0: +#ifdef APPLE_CC + lea (cont1-base)(%esi, 1), %eax + mov %eax, (jump_vector-base)(%esi,1) + + lea (gdt-base)(%esi, 1), %eax + mov %eax, (gdt_addr-base)(%esi,1) + + /* Switch to compatibility mode. */ + lgdt (gdtdesc-base)(%esi,1) + + /* Update %cs. Thanks to David Miller for pointing this mistake out. */ + ljmp *(jump_vector-base)(%esi,1) +#else lea (cont1-base)(%rsi, 1), %rax mov %eax, (jump_vector-base)(%rsi,1) @@ -111,6 +128,7 @@ cont0: /* Update %cs. Thanks to David Miller for pointing this mistake out. */ ljmp *(jump_vector-base)(%rsi,1) +#endif cont1: .code32 diff --git a/mmap/i386/pc/mmap_helper.S b/mmap/i386/pc/mmap_helper.S index ab7c0d2..f153f1c 100644 --- a/mmap/i386/pc/mmap_helper.S +++ b/mmap/i386/pc/mmap_helper.S @@ -28,7 +28,12 @@ VARIABLE(grub_machine_mmaphook_int12) push %ds push %cs pop %ds +#ifdef APPLE_CC + grub_machine_mmaphook_kblow_rel = DS (EXT_C (grub_machine_mmaphook_kblow)) + movw (grub_machine_mmaphook_kblow_rel), %ax +#else movw DS (EXT_C (grub_machine_mmaphook_kblow)), %ax +#endif pop %ds iret @@ -53,8 +58,15 @@ e801: push %ds push %cs pop %ds +#ifdef APPLE_CC + grub_machine_mmaphook_kbin16mb_rel = DS (EXT_C (grub_machine_mmaphook_kbin16mb)) + grub_machine_mmaphook_64kbin4gb_rel = DS (EXT_C (grub_machine_mmaphook_64kbin4gb)) + movw (grub_machine_mmaphook_kbin16mb_rel), %ax + movw (grub_machine_mmaphook_64kbin4gb_rel), %bx +#else movw DS (EXT_C (grub_machine_mmaphook_kbin16mb)), %ax movw DS (EXT_C (grub_machine_mmaphook_64kbin4gb)), %bx +#endif movw %ax, %cx movw %bx, %dx pop %ds @@ -66,26 +78,42 @@ h88: push %ds push %cs pop %ds +#ifdef APPLE_CC + movw (grub_machine_mmaphook_kbin16mb_rel), %ax +#else movw DS (EXT_C (grub_machine_mmaphook_kbin16mb)), %ax +#endif pop %ds clc iret e820: +#ifdef APPLE_CC + mmaphook_mmap_rel = DS(mmaphook_mmap) + mmaphook_mmap_num_rel = DS(EXT_C(grub_machine_mmaphook_mmap_num)) +#endif popf push %ds push %cs pop %ds cmpw $20, %cx jb errexit +#ifdef APPLE_CC + cmpw (mmaphook_mmap_num_rel), %bx +#else cmpw DS (EXT_C (grub_machine_mmaphook_mmap_num)), %bx +#endif jae errexit cmp $0x534d4150, %edx jne errexit push %si push %di movw $20, %cx +#ifdef APPLE_CC + movl $(mmaphook_mmap_rel), %esi +#else movw $(DS(mmaphook_mmap)), %si +#endif mov %bx, %ax imul $20, %ax add %ax, %si @@ -94,7 +122,11 @@ e820: pop %si movl $20, %ecx inc %bx +#ifdef APPLE_CC + cmpw (mmaphook_mmap_num_rel), %bx +#else cmpw DS(EXT_C(grub_machine_mmaphook_mmap_num)), %bx +#endif jb noclean xor %bx, %bx noclean: diff --git a/util/grub-macho2img.c b/util/grub-macho2img.c new file mode 100644 index 0000000..63c94c7 --- /dev/null +++ b/util/grub-macho2img.c @@ -0,0 +1,116 @@ +/* macho2img.c - tool to convert Mach-O to raw imagw. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +/* XXX: this file assumes particular Mach-O layout and does no checks. */ +/* However as build system ensures correct usage of this tool this + shouldn't be a problem. */ + +int +main (int argc, char **argv) +{ + FILE *in, *out; + int do_bss = 0; + char *buf; + int bufsize; + struct grub_macho_header32 *head; + struct grub_macho_segment32 *curcmd; + unsigned i; + unsigned bssstart = 0; + unsigned bssend = 0; + + if (argc && strcmp (argv[1], "--bss") == 0) + do_bss = 1; + if (argc < 2 + do_bss) + { + printf ("Usage: %s [--bss] filename.exec filename.img\n" + "Convert Mach-O into raw image\n", argv[0]); + return 0; + } + in = fopen (argv[1 + do_bss], "rb"); + if (! in) + { + printf ("Couldn't open %s\n", argv[1 + do_bss]); + return 1; + } + out = fopen (argv[2 + do_bss], "wb"); + if (! out) + { + fclose (in); + printf ("Couldn't open %s\n", argv[2 + do_bss]); + return 2; + } + fseek (in, 0, SEEK_END); + bufsize = ftell (in); + fseek (in, 0, SEEK_SET); + buf = malloc (bufsize); + if (! buf) + { + fclose (in); + fclose (out); + printf ("Couldn't allocate buffer\n"); + return 3; + } + fread (buf, 1, bufsize, in); + head = (struct grub_macho_header32 *) buf; + if (grub_le_to_cpu32 (head->magic) != GRUB_MACHO_MAGIC32) + { + fclose (in); + fclose (out); + free (buf); + printf ("Invalid Mach-O fle\n"); + return 4; + } + curcmd = (struct grub_macho_segment32 *) (buf + sizeof (*head)); + for (i = 0; i < grub_le_to_cpu32 (head->ncmds); i++, + curcmd = (struct grub_macho_segment32 *) + (((char *) curcmd) + curcmd->cmdsize)) + { + if (curcmd->cmd != GRUB_MACHO_CMD_SEGMENT32) + continue; + fwrite (buf + grub_le_to_cpu32 (curcmd->fileoff), 1, + grub_le_to_cpu32 (curcmd->filesize), out); + if (grub_le_to_cpu32 (curcmd->vmsize) + > grub_le_to_cpu32 (curcmd->filesize)) + { + bssstart = grub_le_to_cpu32 (curcmd->vmaddr) + + grub_le_to_cpu32 (curcmd->filesize) ; + bssend = grub_le_to_cpu32 (curcmd->vmaddr) + + grub_le_to_cpu32 (curcmd->vmsize) ; + } + } + if (do_bss) + { + grub_uint32_t tmp; + fseek (out, 0x5c, SEEK_SET); + tmp = grub_cpu_to_le32 (bssstart); + fwrite (&tmp, 4, 1, out); + tmp = grub_cpu_to_le32 (bssend); + fwrite (&tmp, 4, 1, out); + } + fclose (in); + fclose (out); + printf("macho2img complete\n"); + return 0; +} diff --git a/util/i386/efi/grub-mkimage.c b/util/i386/efi/grub-mkimage.c index db88a0f..0505f5e 100644 --- a/util/i386/efi/grub-mkimage.c +++ b/util/i386/efi/grub-mkimage.c @@ -88,7 +88,7 @@ align_pe32_section (Elf_Addr addr) /* Read the whole kernel image. Return the pointer to a read image, and store the size in bytes in *SIZE. */ static char * -read_kernel_module (const char *dir, char *prefix, size_t *size) +read_kernel_module (const char *dir, size_t *size) { char *kernel_image; char *kernel_path; @@ -98,11 +98,6 @@ read_kernel_module (const char *dir, char *prefix, size_t *size) kernel_image = grub_util_read_image (kernel_path); free (kernel_path); - if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) - grub_util_error ("prefix too long"); - - strcpy (kernel_image + sizeof (Elf_Ehdr) + GRUB_KERNEL_MACHINE_PREFIX, prefix); - return kernel_image; } @@ -689,6 +684,8 @@ make_mods_section (FILE *out, Elf_Addr current_address, struct grub_module_info modinfo; Elf_Addr addr; + memset (&modinfo, 0, sizeof (modinfo)); + path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); total_module_size = sizeof (struct grub_module_info); @@ -713,6 +710,8 @@ make_mods_section (FILE *out, Elf_Addr current_address, size_t mod_size; char *mod_image; + memset (&header, 0, sizeof (header)); + grub_util_info ("adding module %s", p->name); mod_size = grub_util_get_image_size (p->name); @@ -973,9 +972,11 @@ convert_elf (const char *dir, char *prefix, FILE *out, char *mods[]) Elf_Addr start_address; Elf_Addr text_address, data_address, reloc_address, mods_address; Elf_Addr end_address; + Elf_Shdr *s; + int i; /* Get the kernel image and check the format. */ - kernel_image = read_kernel_module (dir, prefix, &kernel_size); + kernel_image = read_kernel_module (dir, &kernel_size); e = (Elf_Ehdr *) kernel_image; if (! check_elf_header (e, kernel_size)) grub_util_error ("invalid ELF header"); @@ -990,6 +991,20 @@ convert_elf (const char *dir, char *prefix, FILE *out, char *mods[]) sections = (Elf_Shdr *) (kernel_image + section_offset); strtab = find_strtab (e, sections, section_entsize); + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (is_text_section (s)) + { + Elf_Off offset = grub_le_to_cpu32 (s->sh_offset); + + if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) + grub_util_error ("prefix too long"); + + strcpy (kernel_image + offset + GRUB_KERNEL_MACHINE_PREFIX, prefix); + break; + } + /* Relocate sections then symbols in the virtual address space. */ section_addresses = locate_sections (sections, section_entsize, num_sections, strtab);