diff options
author | Thorsten Glaser <tg@mirbsd.org> | 2011-01-06 00:22:58 +0000 |
---|---|---|
committer | Waldemar Brodkorb <wbx@openadk.org> | 2011-01-06 01:29:55 +0100 |
commit | 80d8381811821445bc47cd6e46f1eea423d9fce5 (patch) | |
tree | 6860c48f3f049c155e4c5a826dead5abab8772b0 | |
parent | f9ecf651725c10debca0a466de2012bc362d887c (diff) |
Add experimental code to self-relocate vmlinuz on e.g. brcm
This is needed for the following reason: our memory layout
looks like this:
| |vmlinux | |CFE| * |
| | |vmlinuz | |
^
Since CFE can only load to the spot marked with ‘^’ anyway,
we load vmlinub.elf there which is basically a big rodata
blob containing vmlinuz and minimal code moving it to the
location pointed with vmlinuz above. Another solution would
be to use CFE’s “boot -raw” to place it on the location marked
with ‘*’ above (but the CFE location and size are dynamic, and
since it insists on loading to 0x80001000 anyway, this point
is virtually moot).
Signed-off-by: Thorsten Glaser <tg@mirbsd.org>
-rw-r--r-- | target/linux/patches/2.6.36/zboot-brcm-reloc.patch | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/target/linux/patches/2.6.36/zboot-brcm-reloc.patch b/target/linux/patches/2.6.36/zboot-brcm-reloc.patch new file mode 100644 index 000000000..705bd1dde --- /dev/null +++ b/target/linux/patches/2.6.36/zboot-brcm-reloc.patch @@ -0,0 +1,196 @@ +--- /dev/null Thu Jan 6 00:14:18 2011 ++++ arch/mips/boot/compressed/selfreloc.lds.S Wed Jan 5 23:52:43 2011 +@@ -0,0 +1,39 @@ ++/*- ++ * written 2010 by Thorsten Glaser <tg@debian.org> based on ++ * arch/mips/kernel/vmlinux.lds and arch/mips/boot/compressed/ld.script ++ */ ++ ++#include <asm/asm-offsets.h> ++#include <asm/page.h> ++#include <asm-generic/vmlinux.lds.h> ++ ++#undef mips ++#define mips mips ++OUTPUT_ARCH(mips) ++ENTRY(selfreloc_start) ++PHDRS { ++ text PT_LOAD FLAGS(7); /* RWX */ ++} ++SECTIONS ++{ ++ . = VMLINUX_LOAD_ADDRESS; ++ .text : { ++ *(.text) ++ *(.text.*) ++ *(.rodata) ++ *(.rodata.*) ++ *(.data) ++ *(.data.*) ++ *(.bss) ++ *(.bss.*) ++ } :text ++ /DISCARD/ : { ++ *(.MIPS.options) ++ *(.options) ++ *(.pdr) ++ *(.reginfo) ++ *(.comment) ++ *(.note) ++ *(.gnu.attributes) ++ } ++} +--- /dev/null Thu Jan 6 00:14:22 2011 ++++ arch/mips/boot/compressed/selfreloc1.S Wed Jan 5 23:22:30 2011 +@@ -0,0 +1,48 @@ ++/*- ++ * written 2011 by Thorsten Glaser <tg@debian.org> based on ++ * arch/mips/boot/compressed/head.S ++ */ ++ ++#include <asm/asm.h> ++#include <asm/regdef.h> ++ ++ .set noreorder ++ .cprestore ++ ++ .globl selfreloc_move ++ ++ .text ++ LEAF(selfreloc_start) ++selfreloc_start: ++ /* Save boot rom start args */ ++ move s0, a0 ++ move s1, a1 ++ move s2, a2 ++ move s3, a3 ++ ++ PTR_LI a0, VMLINUZ_LOAD_ADDRESS ++ PTR_LA sp, (.stack + 2048) /* stack address */ ++ ++ PTR_LA ra, 2f ++ PTR_LA k0, selfreloc_move ++ jr k0 ++ nop ++2: ++ move a0, s0 ++ move a1, s1 ++ move a2, s2 ++ move a3, s3 ++ PTR_LI k0, VMLINUZ_LOAD_ADDRESS ++ jr k0 ++ nop ++3: ++ b 3b ++ nop ++ END(selfreloc_start) ++ ++ .globl imgbeg ++imgbeg: .incbin "vmlinuz.bin" ++ .globl imgend ++imgend: ++ ++ .comm .stack,2048,4 +--- /dev/null Thu Jan 6 00:14:26 2011 ++++ arch/mips/boot/compressed/selfreloc2.c Wed Jan 5 23:34:00 2011 +@@ -0,0 +1,39 @@ ++/* written 2011 by Thorsten Glaser <tg@mirbsd.org> */ ++ ++extern unsigned char imgbeg, imgend; ++ ++/* debug interfaces */ ++extern void puts(const char *); ++extern void puthex(unsigned long long); ++ ++void selfreloc_move(unsigned char *); ++ ++/* ++ * Note: we assume we are loaded to VMLINUX_LOAD_ADDRESS, ++ * the range between it and our end-of-file doesn't over- ++ * lap VMLINUZ_LOAD_ADDRESS, we need to relocate the code ++ * there and jump to its first byte. ++ */ ++ ++void ++selfreloc_move(unsigned char *dst /* VMLINUZ_LOAD_ADDRESS */) ++{ ++ unsigned char *src; ++ unsigned long len; ++ ++ puts("in selfreloc_move from "); ++ puthex((unsigned long)&imgbeg); ++ puts(":"); ++ puthex((unsigned long)&imgend); ++ puts(" to "); ++ puthex((unsigned long)dst); ++ puts(" ..."); ++ ++ src = &imgbeg; ++ len = (unsigned long)(&imgend) - (unsigned long)(&imgbeg); ++ ++ while (len--) ++ *dst++ = *src++; ++ ++ puts("done\n"); ++} +--- /home/tg/arch/mips/boot/compressed/Makefile Wed Jan 5 21:26:40 2011 ++++ arch/mips/boot/compressed/Makefile Wed Jan 5 23:35:58 2011 +@@ -28,12 +28,14 @@ KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUIL + targets := head.o decompress.o dbg.o uart-16550.o uart-alchemy.o + + # decompressor objects (linked with vmlinuz) +-vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o ++vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o ++vmlinuz-dbg-objs-y := $(obj)/dbg.o + + ifdef CONFIG_DEBUG_ZBOOT +-vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o +-vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY) += $(obj)/uart-alchemy.o ++vmlinuz-dbg-objs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o ++vmlinuz-dbg-objs-$(CONFIG_MIPS_ALCHEMY) += $(obj)/uart-alchemy.o + endif ++vmlinuzobjs-y += $(vmlinuz-dbg-objs-y) + + targets += vmlinux.bin + OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S +@@ -106,4 +107,12 @@ OBJCOPYFLAGS_vmlinuz.srec := $(OBJCOPYFL + vmlinuz.srec: vmlinuz + $(call cmd,objcopy) + +-clean-files := $(objtree)/vmlinuz $(objtree)/vmlinuz.{32,ecoff,bin,srec} ++AFLAGS_selfreloc1.o := -DVMLINUZ_LOAD_ADDRESS=$(VMLINUZ_LOAD_ADDRESS) ++arch/mips/boot/compressed/selfreloc1.o: arch/mips/boot/compressed/selfreloc1.S vmlinuz.bin ++ ++CPPFLAGS_selfreloc.lds := $(KBUILD_CFLAGS) ++ ++vmlinub.elf: arch/mips/boot/compressed/selfreloc1.o arch/mips/boot/compressed/selfreloc2.o arch/mips/boot/compressed/selfreloc.lds $(vmlinuz-dbg-objs-y) ++ $(LD) $(LDFLAGS) -T arch/mips/boot/compressed/selfreloc.lds arch/mips/boot/compressed/selfreloc1.o arch/mips/boot/compressed/selfreloc2.o $(vmlinuz-dbg-objs-y) -o $@ ++ ++clean-files := $(objtree)/vmlinuz $(objtree)/vmlinuz.{32,ecoff,bin,srec} $(objtree)/vmlinub.elf $(objtree)/arch/mips/boot/compressed/selfreloc{{1,2}.o,.lds} +--- /home/tg/arch/mips/Makefile Wed Jan 5 20:26:12 2011 ++++ arch/mips/Makefile Wed Jan 5 22:41:38 2011 +@@ -79,6 +79,7 @@ endif + all-$(CONFIG_BOOT_ELF32) := $(vmlinux-32) + all-$(CONFIG_BOOT_ELF64) := $(vmlinux-64) + all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlinuz ++all-$(CONFIG_BCM47XX) += vmlinub.elf + + # + # GCC uses -G 0 -mabicalls -fpic as default. We don't want PIC in the kernel +@@ -285,7 +286,7 @@ vmlinux.bin vmlinux.ecoff vmlinux.srec: + $(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) arch/mips/boot/$@ + + # boot/compressed +-vmlinuz vmlinuz.bin vmlinuz.ecoff vmlinuz.srec: $(vmlinux-32) FORCE ++vmlinuz vmlinuz.bin vmlinuz.ecoff vmlinuz.srec vmlinub.elf: $(vmlinux-32) FORCE + $(Q)$(MAKE) $(build)=arch/mips/boot/compressed \ + VMLINUX_LOAD_ADDRESS=$(load-y) 32bit-bfd=$(32bit-bfd) $@ + +@@ -322,6 +323,7 @@ define archhelp + echo ' vmlinuz.ecoff - ECOFF zboot image' + echo ' vmlinuz.bin - Raw binary zboot image' + echo ' vmlinuz.srec - SREC zboot image' ++ echo ' vmlinub.elf - ELF self-relocating zboot image' + echo + echo ' These will be default as apropriate for a configured platform.' + endef |