diff options
Diffstat (limited to 'arch/i386/lib')
-rw-r--r-- | arch/i386/lib/bios_setup.c | 14 | ||||
-rw-r--r-- | arch/i386/lib/board.c | 119 | ||||
-rw-r--r-- | arch/i386/lib/realmode.c | 14 | ||||
-rw-r--r-- | arch/i386/lib/zimage.c | 18 |
4 files changed, 82 insertions, 83 deletions
diff --git a/arch/i386/lib/bios_setup.c b/arch/i386/lib/bios_setup.c index a92b77ea23..75407c173c 100644 --- a/arch/i386/lib/bios_setup.c +++ b/arch/i386/lib/bios_setup.c @@ -45,8 +45,8 @@ DECLARE_GLOBAL_DATA_PTR; #define BIOS_BASE ((char*)0xf0000) #define BIOS_CS 0xf000 -extern ulong _i386boot_bios; -extern ulong _i386boot_bios_size; +extern ulong __bios_start; +extern ulong __bios_size; /* these are defined in a 16bit segment and needs * to be accessed with the RELOC_16_xxxx() macros below @@ -141,8 +141,8 @@ static void setvector(int vector, u16 segment, void *handler) int bios_setup(void) { - ulong i386boot_bios = (ulong)&_i386boot_bios + gd->reloc_off; - ulong i386boot_bios_size = (ulong)&_i386boot_bios_size; + ulong bios_start = (ulong)&__bios_start + gd->reloc_off; + ulong bios_size = (ulong)&__bios_size; static int done=0; int vector; @@ -154,13 +154,13 @@ int bios_setup(void) } done = 1; - if (i386boot_bios_size > 65536) { + if (bios_size > 65536) { printf("BIOS too large (%ld bytes, max is 65536)\n", - i386boot_bios_size); + bios_size); return -1; } - memcpy(BIOS_BASE, (void*)i386boot_bios, i386boot_bios_size); + memcpy(BIOS_BASE, (void*)bios_start, bios_size); /* clear bda */ memset(BIOS_DATA, 0, BIOS_DATA_SIZE); diff --git a/arch/i386/lib/board.c b/arch/i386/lib/board.c index 5002203ec8..1129918fe2 100644 --- a/arch/i386/lib/board.c +++ b/arch/i386/lib/board.c @@ -48,13 +48,12 @@ DECLARE_GLOBAL_DATA_PTR; /* Exports from the Linker Script */ -extern ulong _i386boot_text_start; -extern ulong _i386boot_rel_dyn_start; -extern ulong _i386boot_rel_dyn_end; -extern ulong _i386boot_bss_start; -extern ulong _i386boot_bss_size; - -void ram_bootstrap (void *, ulong); +extern ulong __text_start; +extern ulong __data_end; +extern ulong __rel_dyn_start; +extern ulong __rel_dyn_end; +extern ulong __bss_start; +extern ulong __bss_end; const char version_string[] = U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")"; @@ -164,85 +163,77 @@ init_fnc_t *init_sequence[] = { NULL, }; -static gd_t gd_data; gd_t *gd; /* * Load U-Boot into RAM, initialize BSS, perform relocation adjustments */ -void board_init_f (ulong stack_limit) +void board_init_f (ulong gdp) { - void *text_start = &_i386boot_text_start; - void *u_boot_cmd_end = &__u_boot_cmd_end; - Elf32_Rel *rel_dyn_start = (Elf32_Rel *)&_i386boot_rel_dyn_start; - Elf32_Rel *rel_dyn_end = (Elf32_Rel *)&_i386boot_rel_dyn_end; - void *bss_start = &_i386boot_bss_start; - ulong bss_size = (ulong)&_i386boot_bss_size; - - ulong uboot_size; + void *text_start = &__text_start; + void *data_end = &__data_end; + void *rel_dyn_start = &__rel_dyn_start; + void *rel_dyn_end = &__rel_dyn_end; + void *bss_start = &__bss_start; + void *bss_end = &__bss_end; + + ulong *dst_addr; + ulong *src_addr; + ulong *end_addr; + void *dest_addr; ulong rel_offset; - Elf32_Rel *re; + Elf32_Rel *re_src; + Elf32_Rel *re_end; - void (*start_func)(void *, ulong); - - uboot_size = (ulong)u_boot_cmd_end - (ulong)text_start; - dest_addr = (void *)stack_limit - (uboot_size + (ulong)bss_size); + /* Calculate destination RAM Address and relocation offset */ + dest_addr = (void *)gdp - (bss_end - text_start); rel_offset = text_start - dest_addr; - start_func = ram_bootstrap - rel_offset; - /* First stage CPU initialization */ - if (cpu_init_f() != 0) - hang(); + /* Perform low-level initialization only when cold booted */ + if (((gd_t *)gdp)->flags & GD_FLG_COLD_BOOT) { + /* First stage CPU initialization */ + if (cpu_init_f() != 0) + hang(); - /* First stage Board initialization */ - if (board_early_init_f() != 0) - hang(); + /* First stage Board initialization */ + if (board_early_init_f() != 0) + hang(); + } /* Copy U-Boot into RAM */ - memcpy(dest_addr, text_start, uboot_size); + dst_addr = (ulong *)dest_addr; + src_addr = (ulong *)(text_start + ((gd_t *)gdp)->load_off); + end_addr = (ulong *)(data_end + ((gd_t *)gdp)->load_off); + + while (src_addr < end_addr) + *dst_addr++ = *src_addr++; /* Clear BSS */ - memset(bss_start - rel_offset, 0, bss_size); + dst_addr = (ulong *)(bss_start - rel_offset); + end_addr = (ulong *)(bss_end - rel_offset); + + while (dst_addr < end_addr) + *dst_addr++ = 0x00000000; /* Perform relocation adjustments */ - for (re = rel_dyn_start; re < rel_dyn_end; re++) - { - if (re->r_offset >= TEXT_BASE) - if (*(ulong *)re->r_offset >= TEXT_BASE) - *(ulong *)(re->r_offset - rel_offset) -= (Elf32_Addr)rel_offset; - } + re_src = (Elf32_Rel *)(rel_dyn_start + ((gd_t *)gdp)->load_off); + re_end = (Elf32_Rel *)(rel_dyn_end + ((gd_t *)gdp)->load_off); - /* Enter the relocated U-Boot! */ - start_func(dest_addr, rel_offset); - /* NOTREACHED - board_init_f() does not return */ - while(1); -} + do { + if (re_src->r_offset >= TEXT_BASE) + if (*(Elf32_Addr *)(re_src->r_offset - rel_offset) >= TEXT_BASE) + *(Elf32_Addr *)(re_src->r_offset - rel_offset) -= rel_offset; + } while (re_src++ < re_end); -/* - * We cannot initialize gd_data in board_init_f() because we would be - * attempting to write to flash (I have even tried using manual relocation - * adjustments on pointers but it just won't work) and board_init_r() does - * not have enough arguments to allow us to pass the relocation offset - * straight up. This bootstrap function (which runs in RAM) is used to - * setup gd_data in order to pass the relocation offset to the rest of - * U-Boot. - * - * TODO: The compiler optimization barrier is intended to stop GCC from - * optimizing this function into board_init_f(). It seems to work without - * it, but I've left it in to be sure. I think also that the barrier in - * board_init_r() is no longer needed, but left it in 'just in case' - */ -void ram_bootstrap (void *dest_addr, ulong rel_offset) -{ - /* compiler optimization barrier needed for GCC >= 3.4 */ - __asm__ __volatile__("": : :"memory"); + ((gd_t *)gdp)->reloc_off = rel_offset; + ((gd_t *)gdp)->flags |= GD_FLG_RELOC; - /* tell others: relocation done */ - gd_data.reloc_off = rel_offset; - gd_data.flags |= GD_FLG_RELOC; + /* Enter the relocated U-Boot! */ + (board_init_r - rel_offset)((gd_t *)gdp, (ulong)dest_addr); - board_init_r(&gd_data, (ulong)dest_addr); + /* NOTREACHED - board_init_f() does not return */ + while(1); } void board_init_r(gd_t *id, ulong dest_addr) diff --git a/arch/i386/lib/realmode.c b/arch/i386/lib/realmode.c index b3f51230a5..60fe1816a1 100644 --- a/arch/i386/lib/realmode.c +++ b/arch/i386/lib/realmode.c @@ -31,23 +31,23 @@ #define REALMODE_MAILBOX ((char*)0xe00) -extern ulong _i386boot_realmode; -extern ulong _i386boot_realmode_size; +extern ulong __realmode_start; +extern ulong __realmode_size; extern char realmode_enter; int realmode_setup(void) { - ulong i386boot_realmode = (ulong)&_i386boot_realmode + gd->reloc_off; - ulong i386boot_realmode_size = (ulong)&_i386boot_realmode_size; + ulong realmode_start = (ulong)&__realmode_start + gd->reloc_off; + ulong realmode_size = (ulong)&__realmode_size; /* copy the realmode switch code */ - if (i386boot_realmode_size > (REALMODE_MAILBOX-REALMODE_BASE)) { + if (realmode_size > (REALMODE_MAILBOX-REALMODE_BASE)) { printf("realmode switch too large (%ld bytes, max is %d)\n", - i386boot_realmode_size, (REALMODE_MAILBOX-REALMODE_BASE)); + realmode_size, (REALMODE_MAILBOX-REALMODE_BASE)); return -1; } - memcpy(REALMODE_BASE, (void*)i386boot_realmode, i386boot_realmode_size); + memcpy(REALMODE_BASE, (void*)realmode_start, realmode_size); asm("wbinvd\n"); return 0; diff --git a/arch/i386/lib/zimage.c b/arch/i386/lib/zimage.c index 89fe015e6e..0c42072691 100644 --- a/arch/i386/lib/zimage.c +++ b/arch/i386/lib/zimage.c @@ -248,7 +248,8 @@ void boot_zimage(void *setup_base) int do_zboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { void *base_ptr; - void *bzImage_addr; + void *bzImage_addr = NULL; + char *s; ulong bzImage_size = 0; disable_interrupts(); @@ -256,10 +257,17 @@ int do_zboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /* Setup board for maximum PC/AT Compatibility */ setup_pcat_compatibility(); - /* argv[1] holds the address of the bzImage */ - bzImage_addr = (void *)simple_strtoul(argv[1], NULL, 16); + if (argc >= 2) + /* argv[1] holds the address of the bzImage */ + s = argv[1]; + else + s = getenv("fileaddr"); + + if (s) + bzImage_addr = (void *)simple_strtoul(s, NULL, 16); - if (argc == 3) + if (argc >= 3) + /* argv[2] holds the size of the bzImage */ bzImage_size = simple_strtoul(argv[2], NULL, 16); /* Lets look for*/ @@ -282,7 +290,7 @@ int do_zboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } U_BOOT_CMD( - zboot, 3, 0, do_zboot, + zboot, 2, 0, do_zboot, "Boot bzImage", "" ); |