U-Boot self-relocatable images
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -33,6 +33,8 @@ struct grub_mkimage_layoutgrub_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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -33,8 +33,8 @@ struct grub_mkimage_layoutgrub_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_descunsigned 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
@@ -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
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?
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