From e37ffc5cf6dd4989e8c490edd01125566082ac85 Mon Sep 17 00:00:00 2001 From: phcoder Date: Thu, 4 Jun 2009 21:01:11 +0000 Subject: [PATCH] 2009-06-04 Vladimir Serbinenko Use grub-macho2img when compiling with Apple's CC for PCBIOS machine * conf/common.rmk (bin_UTILITIES): add (on false on condition) grub-macho2img (CLEANFILES): add grub-macho2img (grub_macho2img_SOURCES): new variable * kern/i386/pc/startup.S (bss_start): new variable (bss_end): likewise * genmk.rb: use grub-macho2img for *.img when compiled with Apple's CC * util/grub-macho2img.c: new file --- ChangeLog | 13 +++++ conf/common.rmk | 10 ++++ genmk.rb | 10 ++++ kern/i386/pc/startup.S | 7 +++ util/grub-macho2img.c | 116 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 156 insertions(+) create mode 100644 util/grub-macho2img.c diff --git a/ChangeLog b/ChangeLog index f26936e8b..f2abef9dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2009-06-04 Vladimir Serbinenko + + Use grub-macho2img when compiling with Apple's CC for PCBIOS machine + + * conf/common.rmk (bin_UTILITIES): add (on false on condition) + grub-macho2img + (CLEANFILES): add grub-macho2img + (grub_macho2img_SOURCES): new variable + * kern/i386/pc/startup.S (bss_start): new variable + (bss_end): likewise + * genmk.rb: use grub-macho2img for *.img when compiled with Apple's CC + * util/grub-macho2img.c: new file + 2009-06-04 Vladimir Serbinenko Use objconv when compiling with Apple's CC diff --git a/conf/common.rmk b/conf/common.rmk index ca18c534a..3e59c3aac 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/genmk.rb b/genmk.rb index 249dcb5f7..05ecc9662 100644 --- a/genmk.rb +++ b/genmk.rb @@ -56,8 +56,18 @@ class Image "CLEANFILES += #{@name} #{exe} #{objs_str} MOSTLYCLEANFILES += #{deps_str} +ifneq ($(TARGET_APPLE_CC),1) #{@name}: #{exe} $(OBJCOPY) -O $(#{prefix}_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@ +else +ifneq (#{exe},kernel.exec) +#{@name}: #{exe} ./grub-macho2img + ./grub-macho2img $< $@ +else +#{@name}: #{exe} ./grub-macho2img + ./grub-macho2img --bss $< $@ +endif +endif #{exe}: #{objs_str} $(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS) diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index 23f84ede6..6cdc79a1d 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -110,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, diff --git a/util/grub-macho2img.c b/util/grub-macho2img.c new file mode 100644 index 000000000..63c94c742 --- /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; +}