[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] generic ELF version of grub-mkimage
From: |
Patrick Georgi |
Subject: |
[PATCH] generic ELF version of grub-mkimage |
Date: |
Thu, 30 Aug 2007 12:03:47 +0200 |
User-agent: |
Thunderbird 2.0b2 (X11/20070411) |
Hi,
the attached patch makes powerpc-ieee1275's grub-mkimage work with
little endian ELF images, too.
I did this, as I need basically the same functionality for
i386-linuxbios, just with little endian ELFs. I first copied and changed
the file for my needs, but it might be more generally useful (other
architectures), and having to maintain two very similar files seems like
a waste of time to me - hence the merged version.
I also moved the file to util/elf, to denote that it's a generic ELF
mangler now and adapted the powerpc makefile.
Description of changes:
1.
Detect endianess of the kernel (and check it's actually an ELF file)
2.
Configure a set of function pointers appropriately. This also required
me to wrap the grub_cpu_to_be* (and reverse) functions as those are macros.
3.
Replace all grub_cpu_to_be* and grub_be_to_cpu* calls with calls to the
function pointers.
4.
Undefine the old macros in this file as a debugging aid (there should be
any need for them)
Comments are very appreciated.
Regards,
Patrick Georgi
#
#
# rename "util/powerpc/ieee1275/grub-mkimage.c"
# to "util/elf/grub-mkimage.c"
#
# add_dir "util/elf"
#
# patch "conf/powerpc-ieee1275.rmk"
# from [dd6aa1b34a30806ec5739e36ac0c8dd9c3f90cd4]
# to [e41cc58b76b3d62bef76cee905e953629024f753]
#
# patch "util/elf/grub-mkimage.c"
# from [0d5043da1774f2f00e4eb10823f82623735d8976]
# to [f36bb74ba54243e417c618d4294d23f8761afd57]
#
============================================================
--- conf/powerpc-ieee1275.rmk dd6aa1b34a30806ec5739e36ac0c8dd9c3f90cd4
+++ conf/powerpc-ieee1275.rmk e41cc58b76b3d62bef76cee905e953629024f753
@@ -32,7 +32,7 @@ endif
endif
# For grub-mkimage.
-grub_mkimage_SOURCES = util/powerpc/ieee1275/grub-mkimage.c util/misc.c \
+grub_mkimage_SOURCES = util/elf/grub-mkimage.c util/misc.c \
util/resolve.c
# For grub-mkdevicemap.
============================================================
--- util/powerpc/ieee1275/grub-mkimage.c
0d5043da1774f2f00e4eb10823f82623735d8976
+++ util/elf/grub-mkimage.c f36bb74ba54243e417c618d4294d23f8761afd57
@@ -62,6 +62,35 @@ struct grub_ieee1275_note
struct grub_ieee1275_note_desc descriptor;
};
+#define wrapmacro(name, len) \
+ static grub_uint ## len ## _t \
+ name ## len (grub_uint ## len ## _t x) \
+ { return grub_ ## name ## len (x); }
+
+wrapmacro(le_to_cpu, 32)
+wrapmacro(cpu_to_le, 32)
+wrapmacro(le_to_cpu, 16)
+wrapmacro(cpu_to_le, 16)
+wrapmacro(be_to_cpu, 32)
+wrapmacro(cpu_to_be, 32)
+wrapmacro(be_to_cpu, 16)
+wrapmacro(cpu_to_be, 16)
+
+/* those macros should not be used after this. use cpu_to_file32 etc instead */
+#undef grub_cpu_to_le16
+#undef grub_cpu_to_le32
+#undef grub_cpu_to_be16
+#undef grub_cpu_to_be32
+#undef grub_le_to_cpu16
+#undef grub_le_to_cpu32
+#undef grub_be_to_cpu16
+#undef grub_be_to_cpu32
+
+grub_uint32_t (*file_to_cpu32)(grub_uint32_t) = 0;
+grub_uint16_t (*file_to_cpu16)(grub_uint16_t) = 0;
+grub_uint32_t (*cpu_to_file32)(grub_uint32_t) = 0;
+grub_uint16_t (*cpu_to_file16)(grub_uint16_t) = 0;
+
void
load_note (Elf32_Phdr *phdr, FILE *out)
{
@@ -70,28 +99,28 @@ load_note (Elf32_Phdr *phdr, FILE *out)
grub_util_info ("adding CHRP NOTE segment");
- note.header.namesz = grub_cpu_to_be32 (sizeof (GRUB_IEEE1275_NOTE_NAME));
- note.header.descsz = grub_cpu_to_be32 (note_size);
- note.header.type = grub_cpu_to_be32 (GRUB_IEEE1275_NOTE_TYPE);
+ note.header.namesz = cpu_to_file32 (sizeof (GRUB_IEEE1275_NOTE_NAME));
+ note.header.descsz = cpu_to_file32 (note_size);
+ note.header.type = cpu_to_file32 (GRUB_IEEE1275_NOTE_TYPE);
strcpy (note.header.name, GRUB_IEEE1275_NOTE_NAME);
- note.descriptor.real_mode = grub_cpu_to_be32 (0xffffffff);
- note.descriptor.real_base = grub_cpu_to_be32 (0x00c00000);
- note.descriptor.real_size = grub_cpu_to_be32 (0xffffffff);
- note.descriptor.virt_base = grub_cpu_to_be32 (0xffffffff);
- note.descriptor.virt_size = grub_cpu_to_be32 (0xffffffff);
- note.descriptor.load_base = grub_cpu_to_be32 (0x00004000);
+ note.descriptor.real_mode = cpu_to_file32 (0xffffffff);
+ note.descriptor.real_base = cpu_to_file32 (0x00c00000);
+ note.descriptor.real_size = cpu_to_file32 (0xffffffff);
+ note.descriptor.virt_base = cpu_to_file32 (0xffffffff);
+ note.descriptor.virt_size = cpu_to_file32 (0xffffffff);
+ note.descriptor.load_base = cpu_to_file32 (0x00004000);
/* Write the note data to the new segment. */
grub_util_write_image_at (¬e, note_size,
- grub_be_to_cpu32 (phdr->p_offset), out);
+ file_to_cpu32 (phdr->p_offset), out);
/* Fill in the rest of the segment header. */
- phdr->p_type = grub_cpu_to_be32 (PT_NOTE);
- phdr->p_flags = grub_cpu_to_be32 (PF_R);
- phdr->p_align = grub_cpu_to_be32 (sizeof (long));
+ phdr->p_type = cpu_to_file32 (PT_NOTE);
+ phdr->p_flags = cpu_to_file32 (PF_R);
+ phdr->p_align = cpu_to_file32 (sizeof (long));
phdr->p_vaddr = 0;
phdr->p_paddr = 0;
- phdr->p_filesz = grub_cpu_to_be32 (note_size);
+ phdr->p_filesz = cpu_to_file32 (note_size);
phdr->p_memsz = 0;
}
@@ -120,9 +149,9 @@ load_modules (grub_addr_t modbase, Elf32
module_img = xmalloc (total_module_size);
modinfo = (struct grub_module_info *) module_img;
- modinfo->magic = grub_cpu_to_be32 (GRUB_MODULE_MAGIC);
- modinfo->offset = grub_cpu_to_be32 (sizeof (struct grub_module_info));
- modinfo->size = grub_cpu_to_be32 (total_module_size);
+ modinfo->magic = cpu_to_file32 (GRUB_MODULE_MAGIC);
+ modinfo->offset = cpu_to_file32 (sizeof (struct grub_module_info));
+ modinfo->size = cpu_to_file32 (total_module_size);
/* Load all the modules, with headers, into module_img. */
for (p = path_list; p; p = p->next)
@@ -135,8 +164,8 @@ load_modules (grub_addr_t modbase, Elf32
mod_size = grub_util_get_image_size (p->name);
header = (struct grub_module_header *) (module_img + offset);
- header->offset = grub_cpu_to_be32 (sizeof (*header));
- header->size = grub_cpu_to_be32 (mod_size + sizeof (*header));
+ header->offset = cpu_to_file32 (sizeof (*header));
+ header->size = cpu_to_file32 (mod_size + sizeof (*header));
grub_util_load_image (p->name, module_img + offset + sizeof (*header));
@@ -145,16 +174,16 @@ load_modules (grub_addr_t modbase, Elf32
/* Write the module data to the new segment. */
grub_util_write_image_at (module_img, total_module_size,
- grub_cpu_to_be32 (phdr->p_offset), out);
+ cpu_to_file32 (phdr->p_offset), out);
/* Fill in the rest of the segment header. */
- phdr->p_type = grub_cpu_to_be32 (PT_LOAD);
- phdr->p_flags = grub_cpu_to_be32 (PF_R | PF_W | PF_X);
- phdr->p_align = grub_cpu_to_be32 (sizeof (long));
- phdr->p_vaddr = grub_cpu_to_be32 (modbase);
- phdr->p_paddr = grub_cpu_to_be32 (modbase);
- phdr->p_filesz = grub_cpu_to_be32 (total_module_size);
- phdr->p_memsz = grub_cpu_to_be32 (total_module_size);
+ phdr->p_type = cpu_to_file32 (PT_LOAD);
+ phdr->p_flags = cpu_to_file32 (PF_R | PF_W | PF_X);
+ phdr->p_align = cpu_to_file32 (0x1000);
+ phdr->p_vaddr = cpu_to_file32 (modbase);
+ phdr->p_paddr = cpu_to_file32 (modbase);
+ phdr->p_filesz = cpu_to_file32 (total_module_size);
+ phdr->p_memsz = cpu_to_file32 (total_module_size);
}
void
@@ -176,11 +205,31 @@ add_segments (char *dir, FILE *out, int
grub_util_error ("cannot open %s", kernel_path);
grub_util_read_at (&ehdr, sizeof (ehdr), 0, in);
-
- phdrs = xmalloc (grub_be_to_cpu16 (ehdr.e_phentsize)
- * (grub_be_to_cpu16 (ehdr.e_phnum) + 2));
+ if ((ehdr.e_ident[EI_MAG0]!=ELFMAG0) ||
+ (ehdr.e_ident[EI_MAG1]!=ELFMAG1) ||
+ (ehdr.e_ident[EI_MAG2]!=ELFMAG2) ||
+ (ehdr.e_ident[EI_MAG3]!=ELFMAG3)) {
+ grub_util_error("%s is not an ELF image", kernel_path);
+ }
+
+ if (ehdr.e_ident[EI_DATA]==ELFDATA2LSB) {
+ file_to_cpu16 = le_to_cpu16;
+ file_to_cpu32 = le_to_cpu32;
+ cpu_to_file16 = cpu_to_le16;
+ cpu_to_file32 = cpu_to_le32;
+ } else if (ehdr.e_ident[EI_DATA]==ELFDATA2MSB) {
+ file_to_cpu16 = be_to_cpu16;
+ file_to_cpu32 = be_to_cpu32;
+ cpu_to_file16 = cpu_to_be16;
+ cpu_to_file32 = cpu_to_be32;
+ } else {
+ grub_util_error("Unknown file encoding");
+ }
+
+ phdrs = xmalloc (file_to_cpu16 (ehdr.e_phentsize)
+ * (file_to_cpu16 (ehdr.e_phnum) + 2));
/* Copy all existing segments. */
- for (i = 0; i < grub_be_to_cpu16 (ehdr.e_phnum); i++)
+ for (i = 0; i < file_to_cpu16 (ehdr.e_phnum); i++)
{
char *segment_img;
grub_size_t segment_end;
@@ -189,26 +238,26 @@ add_segments (char *dir, FILE *out, int
/* Read segment header. */
grub_util_read_at (phdr, sizeof (Elf32_Phdr),
- (grub_be_to_cpu32 (ehdr.e_phoff)
- + (i * grub_be_to_cpu16 (ehdr.e_phentsize))),
+ (file_to_cpu32 (ehdr.e_phoff)
+ + (i * file_to_cpu16 (ehdr.e_phentsize))),
in);
grub_util_info ("copying segment %d, type %d", i,
- grub_be_to_cpu32 (phdr->p_type));
+ file_to_cpu32 (phdr->p_type));
/* Locate _end. */
- segment_end = grub_be_to_cpu32 (phdr->p_paddr)
- + grub_be_to_cpu32 (phdr->p_memsz);
+ segment_end = file_to_cpu32 (phdr->p_paddr)
+ + file_to_cpu32 (phdr->p_memsz);
grub_util_info ("segment %u end 0x%lx", i, segment_end);
if (segment_end > grub_end)
grub_end = segment_end;
/* Read segment data and write it to new file. */
- segment_img = xmalloc (grub_be_to_cpu32 (phdr->p_filesz));
+ segment_img = xmalloc (file_to_cpu32 (phdr->p_filesz));
- grub_util_read_at (segment_img, grub_be_to_cpu32 (phdr->p_filesz),
- grub_be_to_cpu32 (phdr->p_offset), in);
- grub_util_write_image_at (segment_img, grub_be_to_cpu32 (phdr->p_filesz),
- grub_be_to_cpu32 (phdr->p_offset), out);
+ grub_util_read_at (segment_img, file_to_cpu32 (phdr->p_filesz),
+ file_to_cpu32 (phdr->p_offset), in);
+ grub_util_write_image_at (segment_img, file_to_cpu32 (phdr->p_filesz),
+ file_to_cpu32 (phdr->p_offset), out);
free (segment_img);
}
@@ -218,14 +267,14 @@ add_segments (char *dir, FILE *out, int
grub_addr_t modbase;
/* Place modules just after grub segment. */
- modbase = ALIGN_UP(grub_end, GRUB_IEEE1275_MOD_ALIGN);
+ modbase = ALIGN_UP(grub_end, GRUB_MOD_ALIGN);
/* Construct new segment header for modules. */
- phdr = phdrs + grub_be_to_cpu16 (ehdr.e_phnum);
- ehdr.e_phnum = grub_cpu_to_be16 (grub_be_to_cpu16 (ehdr.e_phnum) + 1);
+ phdr = phdrs + file_to_cpu16 (ehdr.e_phnum);
+ ehdr.e_phnum = cpu_to_file16 (file_to_cpu16 (ehdr.e_phnum) + 1);
/* Fill in p_offset so the callees know where to write. */
- phdr->p_offset = grub_cpu_to_be32 (ALIGN_UP (grub_util_get_fp_size (out),
+ phdr->p_offset = cpu_to_file32 (ALIGN_UP (grub_util_get_fp_size (out),
sizeof (long)));
load_modules (modbase, phdr, dir, mods, out);
@@ -234,11 +283,11 @@ add_segments (char *dir, FILE *out, int
if (chrp)
{
/* Construct new segment header for the CHRP note. */
- phdr = phdrs + grub_be_to_cpu16 (ehdr.e_phnum);
- ehdr.e_phnum = grub_cpu_to_be16 (grub_be_to_cpu16 (ehdr.e_phnum) + 1);
+ phdr = phdrs + file_to_cpu16 (ehdr.e_phnum);
+ ehdr.e_phnum = cpu_to_file16 (file_to_cpu16 (ehdr.e_phnum) + 1);
/* Fill in p_offset so the callees know where to write. */
- phdr->p_offset = grub_cpu_to_be32 (ALIGN_UP (grub_util_get_fp_size (out),
+ phdr->p_offset = cpu_to_file32 (ALIGN_UP (grub_util_get_fp_size (out),
sizeof (long)));
load_note (phdr, out);
@@ -251,12 +300,12 @@ add_segments (char *dir, FILE *out, int
/* Append entire segment table to the file. */
phdroff = ALIGN_UP (grub_util_get_fp_size (out), sizeof (long));
- grub_util_write_image_at (phdrs, grub_be_to_cpu16 (ehdr.e_phentsize)
- * grub_be_to_cpu16 (ehdr.e_phnum), phdroff,
+ grub_util_write_image_at (phdrs, file_to_cpu16 (ehdr.e_phentsize)
+ * file_to_cpu16 (ehdr.e_phnum), phdroff,
out);
/* Write ELF header. */
- ehdr.e_phoff = grub_cpu_to_be32 (phdroff);
+ ehdr.e_phoff = cpu_to_file32 (phdroff);
grub_util_write_image_at (&ehdr, sizeof (ehdr), 0, out);
free (phdrs);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] generic ELF version of grub-mkimage,
Patrick Georgi <=