[U-Boot] [PATCH 7/7] Add primitive relocation to i386 port

Add basic relocation to i386 port
Signed-off-by: Graeme Russ graeme.russ@gmail.com --- This patch provides relocation of the text (code) segment of the i386 binary (in addition to already relocated sections). However, as discussed previously on the mailing list, the relocation does not fix up references to read-only data which is still referenced into Flash. Full relocation is likely going to require some in-depth knowledge of ELF and the very mysterious 'Global Offset Table'
cpu/i386/interrupts.c | 4 ++-- cpu/i386/start.S | 41 +++++++++++++++++++++++++++++++++++++++++ include/configs/sc520_cdp.h | 2 ++ include/configs/sc520_spunk.h | 2 ++ lib_i386/board.c | 27 +++++++++++++++++++++++++++ lib_i386/interrupts.c | 4 ++-- lib_i386/timer.c | 2 +- 7 files changed, 77 insertions(+), 5 deletions(-)
diff --git a/cpu/i386/interrupts.c b/cpu/i386/interrupts.c index 026a21b..063ea42 100644 --- a/cpu/i386/interrupts.c +++ b/cpu/i386/interrupts.c @@ -53,8 +53,8 @@ asm ("idt_ptr:\n"
void set_vector(u8 intnum, void *routine) { - idt[intnum].base_high = (u16)((u32)(routine)>>16); - idt[intnum].base_low = (u16)((u32)(routine)&0xffff); + idt[intnum].base_high = (u16)((u32)(routine + gd->reloc_off) >> 16); + idt[intnum].base_low = (u16)((u32)(routine + gd->reloc_off) & 0xffff); }
diff --git a/cpu/i386/start.S b/cpu/i386/start.S index b6175b1..59089ef 100644 --- a/cpu/i386/start.S +++ b/cpu/i386/start.S @@ -173,7 +173,41 @@ bss_fail: jmp die
bss_ok: +#ifndef CONFIG_SKIP_RELOCATE_UBOOT + /* indicate progress */ + movw $0x06, %ax + movl $.progress6, %ebp + jmp show_boot_progress_asm +.progress6: + + /* copy text section to ram, size must be 4-byte aligned */ + movl $CONFIG_SYS_BL_START_RAM, %edi /* destination address */ + movl $TEXT_BASE, %esi /* source address */ + movl $_i386boot_text_size, %ecx /* number of bytes to copy */ + movl %ecx, %eax + andl $3, %eax + jz text_copy /* Already 4-byte aligned */ + subl $4, %eax /* Add extra bytes to size */ + addl %eax, %ecx +text_copy: + shrl $2, %ecx /* copy 4 byte each time */ + cld + cmpl $0, %ecx + je text_ok +text_segment: + movsl + loop text_segment + jmp text_ok +text_fail: + /* indicate (lack of) progress */ + movw $0x86, %ax + movl $.progress5a, %ebp + jmp show_boot_progress_asm +.progress5a: + jmp die
+text_ok: +#endif wbinvd
@@ -183,7 +217,14 @@ bss_ok: jmp show_boot_progress_asm .progress4:
+#ifndef CONFIG_SKIP_RELOCATE_UBOOT + /* Jump to the RAM copy of start_i386boot */ + movl $start_i386boot, %ebp + addl $(CONFIG_SYS_BL_START_RAM - TEXT_BASE), %ebp + call *%ebp /* Enter, U-boot! */ +#else call start_i386boot /* Enter, U-boot! */ +#endif
/* indicate (lack of) progress */ movw $0x85, %ax diff --git a/include/configs/sc520_cdp.h b/include/configs/sc520_cdp.h index 19e5889..82faca8 100644 --- a/include/configs/sc520_cdp.h +++ b/include/configs/sc520_cdp.h @@ -28,6 +28,8 @@ #ifndef __CONFIG_H #define __CONFIG_H
+#define CONFIG_SKIP_RELOCATE_UBOOT + #define GRUSS_TESTING /* * High Level Configuration Options diff --git a/include/configs/sc520_spunk.h b/include/configs/sc520_spunk.h index 20481bd..3644169 100644 --- a/include/configs/sc520_spunk.h +++ b/include/configs/sc520_spunk.h @@ -28,6 +28,8 @@ #ifndef __CONFIG_H #define __CONFIG_H
+#define CONFIG_SKIP_RELOCATE_UBOOT + /* * High Level Configuration Options * (easy to change) diff --git a/lib_i386/board.c b/lib_i386/board.c index 1734f86..e3d3f06 100644 --- a/lib_i386/board.c +++ b/lib_i386/board.c @@ -225,6 +225,9 @@ void start_i386boot (void) static bd_t bd_data; init_fnc_t **init_fnc_ptr;
+#ifndef CONFIG_SKIP_RELOCATE_UBOOT + cmd_tbl_t *p; +#endif show_boot_progress(0x21);
gd = &gd_data; @@ -238,6 +241,10 @@ void start_i386boot (void)
gd->baudrate = CONFIG_BAUDRATE;
+#ifndef CONFIG_SKIP_RELOCATE_UBOOT + /* Need to set relocation offset here for interrupt initialization */ + gd->reloc_off = CONFIG_SYS_BL_START_RAM - TEXT_BASE; +#endif for (init_fnc_ptr = init_sequence, i=0; *init_fnc_ptr; ++init_fnc_ptr, i++) { show_boot_progress(0xa130|i);
@@ -247,6 +254,26 @@ void start_i386boot (void) } show_boot_progress(0x23);
+#ifndef CONFIG_SKIP_RELOCATE_UBOOT + for (p = &__u_boot_cmd_start; p != &__u_boot_cmd_end; p++) { + ulong addr; + addr = (ulong) (p->cmd) + gd->reloc_off; + p->cmd = (int (*)(struct cmd_tbl_s *, int, int, char *[]))addr; + addr = (ulong)(p->name) + gd->reloc_off; + p->name = (char *)addr; + + if (p->usage != NULL) { + addr = (ulong)(p->usage) + gd->reloc_off; + p->usage = (char *)addr; + } + #ifdef CONFIG_SYS_LONGHELP + if (p->help != NULL) { + addr = (ulong)(p->help) + gd->reloc_off; + p->help = (char *)addr; + } + #endif + } +#endif /* configure available FLASH banks */ size = flash_init(); display_flash_config(size); diff --git a/lib_i386/interrupts.c b/lib_i386/interrupts.c index b0f84de..3f3613a 100644 --- a/lib_i386/interrupts.c +++ b/lib_i386/interrupts.c @@ -70,12 +70,12 @@ void irq_install_handler(int irq, interrupt_handler_t *handler, void *arg)
if (irq_handlers[irq].handler != NULL) printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n", - (ulong) handler, + (ulong) handler + gd->reloc_off, (ulong) irq_handlers[irq].handler);
status = disable_interrupts ();
- irq_handlers[irq].handler = handler; + irq_handlers[irq].handler = handler + gd->reloc_off; irq_handlers[irq].arg = arg; irq_handlers[irq].count = 0;
diff --git a/lib_i386/timer.c b/lib_i386/timer.c index 5cb1f54..58a0212 100644 --- a/lib_i386/timer.c +++ b/lib_i386/timer.c @@ -51,7 +51,7 @@ int register_timer_isr (timer_fnc_t *isr_func) if (new_func == NULL) return 1;
- new_func->isr_func = isr_func; + new_func->isr_func = isr_func + gd->reloc_off; new_func->next = NULL;
/*

Dear Graeme Russ,
In message 49A3C8A0.2010604@gmail.com you wrote:
Add basic relocation to i386 port
Signed-off-by: Graeme Russ graeme.russ@gmail.com
This patch provides relocation of the text (code) segment of the i386 binary (in addition to already relocated sections). However, as discussed previously on the mailing list, the relocation does not fix up references to read-only data which is still referenced into Flash. Full relocation is likely going to require some in-depth knowledge of ELF and the very mysterious 'Global Offset Table'
cpu/i386/interrupts.c | 4 ++-- cpu/i386/start.S | 41 +++++++++++++++++++++++++++++++++++++++++ include/configs/sc520_cdp.h | 2 ++ include/configs/sc520_spunk.h | 2 ++ lib_i386/board.c | 27 +++++++++++++++++++++++++++ lib_i386/interrupts.c | 4 ++-- lib_i386/timer.c | 2 +- 7 files changed, 77 insertions(+), 5 deletions(-)
Applied to "next" branch. Thanks.
Best regards,
Wolfgang Denk
participants (2)
-
Graeme Russ
-
Wolfgang Denk