* [U-Boot] [PATCH 7/7] Add primitive relocation to i386 port
@ 2009-02-24 10:14 Graeme Russ
2009-02-24 22:37 ` Wolfgang Denk
0 siblings, 1 reply; 2+ messages in thread
From: Graeme Russ @ 2009-02-24 10:14 UTC (permalink / raw)
To: u-boot
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;
/*
^ permalink raw reply related [flat|nested] 2+ messages in thread* [U-Boot] [PATCH 7/7] Add primitive relocation to i386 port
2009-02-24 10:14 [U-Boot] [PATCH 7/7] Add primitive relocation to i386 port Graeme Russ
@ 2009-02-24 22:37 ` Wolfgang Denk
0 siblings, 0 replies; 2+ messages in thread
From: Wolfgang Denk @ 2009-02-24 22:37 UTC (permalink / raw)
To: u-boot
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
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Der Dativ ist dem Genitiv sein Tod.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-02-24 22:37 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-24 10:14 [U-Boot] [PATCH 7/7] Add primitive relocation to i386 port Graeme Russ
2009-02-24 22:37 ` Wolfgang Denk
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox