From: Patrick Georgi <patrick@georgi-clan.de>
To: grub-devel@gnu.org
Subject: [PATCH] generic ELF version of grub-mkimage
Date: Thu, 30 Aug 2007 12:03:47 +0200 [thread overview]
Message-ID: <fb64lu$h0k$1@sea.gmane.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 1047 bytes --]
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
[-- Attachment #2: patch-20070830-1-portable-elf-grub-mkimage --]
[-- Type: text/plain, Size: 11229 bytes --]
#
#
# 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);
next reply other threads:[~2007-08-30 10:04 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-08-30 10:03 Patrick Georgi [this message]
2007-10-01 14:53 ` [PATCH] generic ELF version of grub-mkimage Robert Millan
2007-10-11 22:58 ` Robert Millan
2007-10-12 10:52 ` Marco Gerards
2007-10-12 15:55 ` Robert Millan
2007-10-12 16:07 ` Robert Millan
2007-11-10 17:29 ` Marco Gerards
2007-11-10 20:12 ` Robert Millan
2007-11-18 11:39 ` Marco Gerards
2007-11-18 11:54 ` Robert Millan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='fb64lu$h0k$1@sea.gmane.org' \
--to=patrick@georgi-clan.de \
--cc=grub-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.