From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1IQgsh-0003YV-MV for mharc-grub-devel@gnu.org; Thu, 30 Aug 2007 06:04:07 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1IQgsd-0003XN-LY for grub-devel@gnu.org; Thu, 30 Aug 2007 06:04:04 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1IQgsZ-0003W2-QZ for grub-devel@gnu.org; Thu, 30 Aug 2007 06:04:01 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1IQgsY-0003VR-Oa for grub-devel@gnu.org; Thu, 30 Aug 2007 06:03:58 -0400 Received: from main.gmane.org ([80.91.229.2] helo=ciao.gmane.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1IQgsX-0008Sz-TB for grub-devel@gnu.org; Thu, 30 Aug 2007 06:03:58 -0400 Received: from list by ciao.gmane.org with local (Exim 4.43) id 1IQgsR-0001Lj-AP for grub-devel@gnu.org; Thu, 30 Aug 2007 12:03:51 +0200 Received: from cable-81-173-167-157.netcologne.de ([81.173.167.157]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Thu, 30 Aug 2007 12:03:51 +0200 Received: from patrick by cable-81-173-167-157.netcologne.de with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Thu, 30 Aug 2007 12:03:51 +0200 X-Injected-Via-Gmane: http://gmane.org/ To: grub-devel@gnu.org From: Patrick Georgi Date: Thu, 30 Aug 2007 12:03:47 +0200 Message-ID: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------070900050200040601070307" X-Complaints-To: usenet@sea.gmane.org X-Gmane-NNTP-Posting-Host: cable-81-173-167-157.netcologne.de User-Agent: Thunderbird 2.0b2 (X11/20070411) Sender: news X-Detected-Kernel: Linux 2.6, seldom 2.4 (older, 4) Subject: [PATCH] generic ELF version of grub-mkimage X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Aug 2007 10:04:05 -0000 This is a multi-part message in MIME format. --------------070900050200040601070307 Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit 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 --------------070900050200040601070307 Content-Type: text/plain; name="patch-20070830-1-portable-elf-grub-mkimage" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="patch-20070830-1-portable-elf-grub-mkimage" # # # 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); --------------070900050200040601070307--