Skip to contentSkip to conversation

U-Boot self-relocatable images

PATCH In review Vladimir 'φ-coder/phcoder' Serbinenko 2 participants 3 messages Feb 23, 2016 Kbuild

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 U-Boot self-relocatable images

Currently to compile arm-uboot port for a different platform you need to relink it at new address with modifying source code. This set of patches changes to U-boot in-place loading and images that relocate themselves. I'd be interested in opinion of ARM guys

From 80f8cfe29ace49167c1ad6439ddd15519b0a5455 Mon Sep 17 00:00:00 2001
From: Vladimir Serbinenko <[email protected]>
Date: Thu, 18 Feb 2016 20:26:44 +0100
Subject: [PATCH 1/6] mkimage.c: Split into separate files.

util/grub-mkimagexx.c is included in a special way into mkimage.c. Interoperation between defines makes this very tricky. Instead just have a clean interface and compile util/grub-mkimage*.c separately from mkimage.c

---
 Makefile.util.def           |  10 ++
 include/grub/util/mkimage.h | 170 +++++++++++++++++++++++++++
 util/grub-mkimage32.c       |  22 ++++
 util/grub-mkimage64.c       |  22 ++++
 util/grub-mkimagexx.c       | 246 +++++++++++++++++++++++++++------------
 util/mkimage.c              | 273 ++------------------------------------------
 6 files changed, 405 insertions(+), 338 deletions(-)
 create mode 100644 include/grub/util/mkimage.h
 create mode 100644 util/grub-mkimage32.c
 create mode 100644 util/grub-mkimage64.c
Makefile.util.def +10 -0
index db7e8ec..ed9b4c6 100644
@@ -172,6 +172,8 @@ program = {
 
   common = util/grub-mkimage.c;
   common = util/mkimage.c;
+  common = util/grub-mkimage32.c;
+  common = util/grub-mkimage64.c;
   common = util/resolve.c;
   common = grub-core/kern/emu/argp_common.c;
   common = grub-core/osdep/init.c;
@@ -510,6 +512,8 @@ program = {
   common = util/render-label.c;
   common = util/glue-efi.c;
   common = util/mkimage.c;
+  common = util/grub-mkimage32.c;
+  common = util/grub-mkimage64.c;
   common = util/grub-install-common.c;
   common = util/setup_bios.c;
   common = util/setup_sparc.c;
@@ -552,6 +556,8 @@ program = {
   common = util/render-label.c;
   common = util/glue-efi.c;
   common = util/mkimage.c;
+  common = util/grub-mkimage32.c;
+  common = util/grub-mkimage64.c;
   common = util/grub-install-common.c;
   common = util/setup_bios.c;
   common = util/setup_sparc.c;
@@ -595,6 +601,8 @@ program = {
   common = util/grub-install.c;
   common = util/probe.c;
   common = util/mkimage.c;
+  common = util/grub-mkimage32.c;
+  common = util/grub-mkimage64.c;
   common = util/grub-install-common.c;
   common = util/setup_bios.c;
   common = util/setup_sparc.c;
@@ -632,6 +640,8 @@ program = {
   common = util/grub-mknetdir.c;
 
   common = util/mkimage.c;
+  common = util/grub-mkimage32.c;
+  common = util/grub-mkimage64.c;
   common = util/grub-install-common.c;
   common = util/setup_bios.c;
   common = util/setup_sparc.c;
include/grub/util/mkimage.h new file +170 -0

170 lines not on this page · raw message

util/grub-mkimage32.c new file +22 -0
new file mode 100644
index 0000000..9b31397
@@ -0,0 +1,22 @@
+#define MKIMAGE_ELF32 1
+
+# define SUFFIX(x)	x ## 32
+# define ELFCLASSXX	ELFCLASS32
+# define Elf_Ehdr	Elf32_Ehdr
+# define Elf_Phdr	Elf32_Phdr
+# define Elf_Nhdr	Elf32_Nhdr
+# define Elf_Addr	Elf32_Addr
+# define Elf_Sym	Elf32_Sym
+# define Elf_Off	Elf32_Off
+# define Elf_Shdr	Elf32_Shdr
+# define Elf_Rela       Elf32_Rela
+# define Elf_Rel        Elf32_Rel
+# define Elf_Word       Elf32_Word
+# define Elf_Half       Elf32_Half
+# define Elf_Section    Elf32_Section
+# define ELF_R_SYM(val)		ELF32_R_SYM(val)
+# define ELF_R_TYPE(val)		ELF32_R_TYPE(val)
+# define ELF_ST_TYPE(val)		ELF32_ST_TYPE(val)
+#define XEN_NOTE_SIZE 132
+
+#include "grub-mkimagexx.c"
util/grub-mkimage64.c new file +22 -0
new file mode 100644
index 0000000..d833459
@@ -0,0 +1,22 @@
+#define MKIMAGE_ELF64 1
+
+# define SUFFIX(x)	x ## 64
+# define ELFCLASSXX	ELFCLASS64
+# define Elf_Ehdr	Elf64_Ehdr
+# define Elf_Phdr	Elf64_Phdr
+# define Elf_Nhdr	Elf64_Nhdr
+# define Elf_Addr	Elf64_Addr
+# define Elf_Sym	Elf64_Sym
+# define Elf_Off	Elf64_Off
+# define Elf_Shdr	Elf64_Shdr
+# define Elf_Rela       Elf64_Rela
+# define Elf_Rel        Elf64_Rel
+# define Elf_Word       Elf64_Word
+# define Elf_Half       Elf64_Half
+# define Elf_Section    Elf64_Section
+# define ELF_R_SYM(val)		ELF64_R_SYM(val)
+# define ELF_R_TYPE(val)		ELF64_R_TYPE(val)
+# define ELF_ST_TYPE(val)		ELF64_ST_TYPE(val)
+#define XEN_NOTE_SIZE 120
+
+#include "grub-mkimagexx.c"
util/grub-mkimagexx.c +170 -76

264 lines not on this page · raw message

util/mkimage.c +11 -262

311 lines not on this page · raw message

Signature · 1 line
2.7.0

From 88091fb936a45f8dece352c5bec26e011f9573c3 Mon Sep 17 00:00:00 2001
From: Vladimir Serbinenko <[email protected]>
Date: Thu, 18 Feb 2016 20:54:37 +0100
Subject: [PATCH 2/6] mkimagexx: Split PE and generic part for relocations.

As a preparation for U-Boot relocations, split emitting PE-relocations from parsing source ELF-relocations.

---
 util/grub-mkimagexx.c | 415 ++++++++++++++++++++++++++------------------------
 1 file changed, 219 insertions(+), 196 deletions(-)
util/grub-mkimagexx.c +219 -196

449 lines not on this page · raw message

Signature · 1 line
2.7.0

From 7cfa8d4568b714b463e0ad4ac900017a538a5840 Mon Sep 17 00:00:00 2001
From: Vladimir Serbinenko <[email protected]>
Date: Fri, 19 Feb 2016 01:49:53 +0100
Subject: [PATCH 3/6] Encapsulate image layout into a separate structure.

Currently we pass around a lot of pointer. Instead put all relevant data into one structure.

---
 include/grub/util/mkimage.h |  32 ++++++++----
 util/grub-mkimagexx.c       | 116 ++++++++++++++++++++++----------------------
 util/mkimage.c              | 112 +++++++++++++++++++++---------------------
 3 files changed, 133 insertions(+), 127 deletions(-)
include/grub/util/mkimage.h +22 -10
index 564adbc..8169939 100644
@@ -19,20 +19,32 @@
 #ifndef GRUB_UTIL_MKIMAGE_HEADER
 #define GRUB_UTIL_MKIMAGE_HEADER	1
 
+struct grub_mkimage_layout
+{
+  size_t exec_size;
+  size_t kernel_size;
+  size_t bss_size;
+  grub_uint64_t start_address;
+  void *reloc_section;
+  size_t reloc_size;
+  size_t align;
+  grub_size_t ia64jmp_off;
+  grub_size_t tramp_off;
+  grub_size_t ia64_got_off;
+  grub_size_t got_size;
+  unsigned ia64jmpnum;
+};
+
 /* Private header. Use only in mkimage-related sources.  */
 char *
-grub_mkimage_load_image32 (const char *kernel_path, size_t *exec_size, 
-			   size_t *kernel_sz, size_t *bss_size,
-			   size_t total_module_size, grub_uint64_t *start,
-			   void **reloc_section, size_t *reloc_size,
-			   size_t *align,
+grub_mkimage_load_image32 (const char *kernel_path,
+			   size_t total_module_size,
+			   struct grub_mkimage_layout *layout,
 			   const struct grub_install_image_target_desc *image_target);
 char *
-grub_mkimage_load_image64 (const char *kernel_path, size_t *exec_size, 
-			   size_t *kernel_sz, size_t *bss_size,
-			   size_t total_module_size, grub_uint64_t *start,
-			   void **reloc_section, size_t *reloc_size,
-			   size_t *align,
+grub_mkimage_load_image64 (const char *kernel_path,
+			   size_t total_module_size,
+			   struct grub_mkimage_layout *layout,
 			   const struct grub_install_image_target_desc *image_target);
 void
 grub_mkimage_generate_elf32 (const struct grub_install_image_target_desc *image_target,
util/grub-mkimagexx.c +57 -59

265 lines not on this page · raw message

util/mkimage.c +54 -58

279 lines not on this page · raw message

Signature · 1 line
2.7.0

From dc76d5c6eb07ddab8b20e71b1161fe3a72ca045f Mon Sep 17 00:00:00 2001
From: Vladimir Serbinenko <[email protected]>
Date: Thu, 18 Feb 2016 20:57:21 +0100
Subject: [PATCH 4/6] Provide __bss_start and _end symbols in grub-mkimage.

For this ensure that all bss sections are merged.

We need this to correctly prelink non-PE relocatable images.

---
 include/grub/util/mkimage.h |   2 +
 util/grub-mkimagexx.c       | 133 ++++++++++++++++++++++++++++----------------
 2 files changed, 87 insertions(+), 48 deletions(-)
include/grub/util/mkimage.h +2 -0
index 8169939..25a49d5 100644
@@ -33,6 +33,8 @@ struct grub_mkimage_layout
   grub_size_t ia64_got_off;
   grub_size_t got_size;
   unsigned ia64jmpnum;
+  Elf_Addr bss_start;
+  Elf_Addr end;
 };
 
 /* Private header. Use only in mkimage-related sources.  */
util/grub-mkimagexx.c +85 -48

196 lines not on this page · raw message

Signature · 1 line
2.7.0

From d116b78258afc7664b0fbcae49bb5facbad08129 Mon Sep 17 00:00:00 2001
From: Vladimir Serbinenko <[email protected]>
Date: Thu, 18 Feb 2016 20:58:38 +0100
Subject: [PATCH 5/6] Allow _start == 0 with relocatable images

---
 util/grub-mkimagexx.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
util/grub-mkimagexx.c +3 -3
index 433322d..fff8112 100644
@@ -495,7 +495,7 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections,
 {
   Elf_Word symtab_size, sym_size, num_syms;
   Elf_Off symtab_offset;
-  Elf_Addr start_address = 0;
+  Elf_Addr start_address = (Elf_Addr) -1;
   Elf_Sym *sym;
   Elf_Word i;
   Elf_Shdr *strtab_section;
@@ -560,7 +560,7 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections,
 		      (unsigned long long) sym->st_value,
 		      (unsigned long long) section_addresses[cur_index]);
 
-      if (! start_address)
+      if (start_address == (Elf_Addr)-1)
 	if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0)
 	  start_address = sym->st_value;
     }
@@ -1797,7 +1797,7 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path,
 					  layout->ia64jmp_off 
 					  + image_target->vaddr_offset,
 					  image_target);
-      if (layout->start_address == 0)
+      if (layout->start_address == (Elf_Addr) -1)
 	grub_util_error ("start symbol is not defined");
 
       SUFFIX (entry_point) = (Elf_Addr) layout->start_address;
Signature · 1 line
2.7.0

From a20df5d8ffa95a8af7bbc175c4beff8454cc9875 Mon Sep 17 00:00:00 2001
From: Vladimir Serbinenko <[email protected]>
Date: Fri, 19 Feb 2016 00:43:36 +0100
Subject: [PATCH 6/6] arm-uboot: Make self-relocatable to allow loading at any
address

---
 grub-core/Makefile.core.def        |   2 +-
 grub-core/kern/arm/uboot/startup.S |  58 +++++--
 include/grub/arm/uboot/kernel.h    |   2 +-
 include/grub/offsets.h             |   1 -
 include/grub/util/mkimage.h        |   5 +-
 util/grub-mkimagexx.c              | 313 +++++++++++++++++++++++++++++--------
 util/mkimage.c                     |   8 +-
 7 files changed, 303 insertions(+), 86 deletions(-)
grub-core/Makefile.core.def +1 -1
index 8874501..58b4208 100644
@@ -90,7 +90,7 @@ kernel = {
   i386_qemu_cppflags     = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
   emu_cflags = '$(CFLAGS_GNULIB)';
   emu_cppflags = '$(CPPFLAGS_GNULIB)';
-  arm_uboot_ldflags       = '-Wl,-Ttext=0x08000000';
+  arm_uboot_ldflags       = '-Wl,-r,-d';
   arm_uboot_stripflags    = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
 
   i386_pc_startup = kern/i386/pc/startup.S;
grub-core/kern/arm/uboot/startup.S +48 -10

93 lines not on this page · raw message

include/grub/arm/uboot/kernel.h +1 -1
index 06e5433..ce0b149 100644
@@ -26,7 +26,7 @@
 
 #endif /* ! ASM_FILE */
 
-#define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000
+#define GRUB_KERNEL_MACHINE_STACK_SIZE GRUB_KERNEL_ARM_STACK_SIZE
 #define GRUB_KERNEL_MACHINE_HEAP_SIZE  (grub_size_t) (16 * 1024 * 1024)
 
 #endif /* ! GRUB_KERNEL_MACHINE_HEADER */
include/grub/offsets.h +0 -1
index 85e7401..3502a43 100644
@@ -120,7 +120,6 @@
 
 #define GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN 	0x8
 #define GRUB_KERNEL_ARM_UBOOT_TOTAL_MODULE_SIZE	0x4
-#define GRUB_KERNEL_ARM_UBOOT_LINK_ADDR		0x08000000
 
 /* Minimal gap between _end and the start of the modules.  It's a hack
    for PowerMac to prevent "CLAIM failed" error.  The real fix is to
include/grub/util/mkimage.h +3 -2
index 25a49d5..2a48942 100644
@@ -33,8 +33,8 @@ struct grub_mkimage_layout
   grub_size_t ia64_got_off;
   grub_size_t got_size;
   unsigned ia64jmpnum;
-  Elf_Addr bss_start;
-  Elf_Addr end;
+  grub_uint32_t bss_start;
+  grub_uint32_t end;
 };
 
 /* Private header. Use only in mkimage-related sources.  */
@@ -83,6 +83,7 @@ struct grub_install_image_target_desc
   unsigned decompressor_compressed_size;
   unsigned decompressor_uncompressed_size;
   unsigned decompressor_uncompressed_addr;
+  unsigned reloc_table_offset;
   unsigned link_align;
   grub_uint16_t elf_target;
   unsigned section_align;
util/grub-mkimagexx.c +246 -67

525 lines not on this page · raw message

util/mkimage.c +4 -4
index 84b4823..06d28e7 100644
@@ -86,6 +86,7 @@ static const struct grub_install_image_target_desc image_targets[] =
       .decompressor_compressed_size = TARGET_NO_FIELD,
       .decompressor_uncompressed_size = TARGET_NO_FIELD,
       .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+      .reloc_table_offset = TARGET_NO_FIELD,
       .section_align = 1,
       .vaddr_offset = 0,
       .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR,
@@ -525,7 +526,6 @@ static const struct grub_install_image_target_desc image_targets[] =
       .decompressor_uncompressed_addr = TARGET_NO_FIELD,
       .section_align = GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN,
       .vaddr_offset = 0,
-      .link_addr = GRUB_KERNEL_ARM_UBOOT_LINK_ADDR,
       .elf_target = EM_ARM,
       .mod_gap = GRUB_KERNEL_ARM_UBOOT_MOD_GAP,
       .mod_align = GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN,
@@ -1520,9 +1520,9 @@ grub_install_generate_image (const char *dir, const char *prefix,
       hdr->ih_magic = grub_cpu_to_be32_compile_time (GRUB_UBOOT_IH_MAGIC);
       hdr->ih_time = grub_cpu_to_be32 (STABLE_EMBEDDING_TIMESTAMP);
       hdr->ih_size = grub_cpu_to_be32 (core_size);
-      hdr->ih_load = grub_cpu_to_be32 (image_target->link_addr);
-      hdr->ih_ep = grub_cpu_to_be32 (image_target->link_addr);
-      hdr->ih_type = GRUB_UBOOT_IH_TYPE_KERNEL;
+      hdr->ih_load = 0;
+      hdr->ih_ep = 0;
+      hdr->ih_type = GRUB_UBOOT_IH_TYPE_KERNEL_NOLOAD;
       hdr->ih_os = GRUB_UBOOT_IH_OS_LINUX;
       hdr->ih_arch = GRUB_UBOOT_IH_ARCH_ARM;
       hdr->ih_comp = GRUB_UBOOT_IH_COMP_NONE;
Signature · 1 line
2.7.0
#1 lore raw

23.02.2016 13:35, Vladimir 'φ-coder/phcoder' Serbinenko пишет:

Quoted 6 lines

Currently to compile arm-uboot port for a different platform you need to relink it at new address with modifying source code. This set of patches changes to U-boot in-place loading and images that relocate themselves. I'd be interested in opinion of ARM guys

Does http://git.savannah.gnu.org/cgit/grub.git/log/?h=phcoder/arm
contain the same set of patches?

#2 lore raw
Quoted 9 lines · Andrei Borzenkov

23.02.2016 13:35, Vladimir 'φ-coder/phcoder' Serbinenko пишет:

Quoted 6 lines

Currently to compile arm-uboot port for a different platform you need to relink it at new address with modifying source code. This set of patches changes to U-boot in-place loading and images that relocate themselves. I'd be interested in opinion of ARM guys

Quoted 3 lines

Does http://git.savannah.gnu.org/cgit/grub.git/log/?h=phcoder/arm
contain the same set of patches?

Not exactly. The branch goes further and adds arm-coreboot port. In local copy of that branch it supports veyron Chromebooks but I pushed only qemu-vexpress part.

Quoted 7 lines

_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel