public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Graeme Russ <graeme.russ@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 7/7] Add primitive relocation to i386 port
Date: Tue, 24 Feb 2009 21:14:56 +1100	[thread overview]
Message-ID: <49A3C8A0.2010604@gmail.com> (raw)

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;
 
 	/*

             reply	other threads:[~2009-02-24 10:14 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-02-24 10:14 Graeme Russ [this message]
2009-02-24 22:37 ` [U-Boot] [PATCH 7/7] Add primitive relocation to i386 port Wolfgang Denk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=49A3C8A0.2010604@gmail.com \
    --to=graeme.russ@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox