I found no way to generate a raw image with apple's toolchain so wrote
a converter from Mach-O to raw
Thanks to Islam M. Ahmed Zaid for pointing me the options to simplify
generated Mach-O.

-- 
Regards
Vladimir 'phcoder' Serbinenko
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/genmk.rb b/genmk.rb
index 249dcb5..05ecc96 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 23f84ed..6cdc79a 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 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/macho.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* 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;
+}
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to