Bootloader cleanup (UNTESTED!)

- Clean up bootloader asm
- Remove fromflash.c - it's not worth doing in C, do it in ASM
- Clean up linker script
- Force use of symbol inside bootphase2 (otherwise linker
  garbage-collects it)
- Link bootloader with gcc instead of ld
This commit is contained in:
marcansoft 2010-02-26 15:14:47 +00:00
parent cc7580be7a
commit 86d3195518
5 changed files with 87 additions and 114 deletions

View file

@ -7,7 +7,7 @@
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# DO NOT use thumb mode in the phase 1 bootloader since that generates a section with glue code # DO NOT use thumb mode in the phase 1 bootloader since that generates a section with glue code
ARMSRC = fromflash.c ARMSRC =
THUMBSRC = usb.c bootrom.c THUMBSRC = usb.c bootrom.c
ASMSRC = ram-reset.s flash-reset.s ASMSRC = ram-reset.s flash-reset.s
@ -27,7 +27,7 @@ include ../common/Makefile.common
all: $(OBJDIR)/bootrom.s19 all: $(OBJDIR)/bootrom.s19
$(OBJDIR)/bootrom.elf: $(VERSIONOBJ) $(ASMOBJ) $(ARMOBJ) $(THUMBOBJ) $(OBJDIR)/bootrom.elf: $(VERSIONOBJ) $(ASMOBJ) $(ARMOBJ) $(THUMBOBJ)
$(LD) -g -Tldscript-flash --oformat elf32-littlearm -Map=$(patsubst %.elf,%.map,$@) -o $@ $^ $(CC) $(LDFLAGS) -Wl,-T,ldscript-flash,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
clean: clean:
$(DELETE) $(OBJDIR)$(PATHSEP)*.o $(DELETE) $(OBJDIR)$(PATHSEP)*.o

View file

@ -6,46 +6,48 @@
@ Reset vector for running from FLASH @ Reset vector for running from FLASH
@----------------------------------------------------------------------------- @-----------------------------------------------------------------------------
.extern CopyBootToRAM
.section .startup,"ax" .section .startup,"ax"
.code 32
.align 0 .arm
.global flashstart .global flashstart
flashstart: flashstart:
b Reset b reset
b UndefinedInstruction b undefined_instruction
b SoftwareInterrupt b software_interrupt
b PrefetchAbort b prefetch_abort
b DataAbort b data_abort
b Reserved b . @reserved
b Irq b irq
b Fiq b fiq
Reset: reset:
ldr sp, .stack_end @ initialize stack pointer to top of RAM ldr sp, =_stack_end @ initialize stack pointer to top of RAM
bl CopyBootToRAM @ copy bootloader to RAM (in case the
@ user re-flashes the bootloader) @ copy bootloader to RAM (in case the user re-flashes the bootloader)
ldr r3, .bootphase2_start @ start address of RAM bootloader ldr r0, =__bootphase2_src_start__
ldr r1, =__bootphase2_start__
ldr r2, =__bootphase2_end__
1:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r1, r2
blo 1b
ldr r3, =ram_start @ start address of RAM bootloader
bx r3 @ jump to it bx r3 @ jump to it
.stack_end: .ltorg
.word _stack_end
.bootphase2_start:
.word __bootphase2_start__
Fiq: undefined_instruction:
b Fiq b .
UndefinedInstruction: software_interrupt:
b UndefinedInstruction b .
SoftwareInterrupt: prefetch_abort:
b SoftwareInterrupt b .
PrefetchAbort: data_abort:
b PrefetchAbort b .
DataAbort: irq:
b DataAbort b .
Reserved: fiq:
b Reserved b .
Irq:
b Irq

View file

@ -1,21 +0,0 @@
//-----------------------------------------------------------------------------
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Helper function for launching the bootloader from FLASH
//-----------------------------------------------------------------------------
#include <proxmark3.h>
extern char __bootphase2_src_start__, __bootphase2_start__, __bootphase2_end__;
void __attribute__((section(".bootphase1"))) CopyBootToRAM(void)
{
int i;
volatile uint32_t *s = (volatile uint32_t *)&__bootphase2_src_start__;
volatile uint32_t *d = (volatile uint32_t *)&__bootphase2_start__;
unsigned int l = (int)&__bootphase2_end__ - (int)&__bootphase2_start__;
for(i = 0; i < l/sizeof(uint32_t); i++) *d++ = *s++;
}

View file

@ -13,49 +13,42 @@ INCLUDE ../common/ldscript.common
ENTRY(flashstart) ENTRY(flashstart)
SECTIONS SECTIONS
{ {
. = 0;
.bootphase1 : { .bootphase1 : {
*(.startup) *(.startup)
*(.bootphase1)
/* It seems to be impossible to flush align a section at the . = ALIGN(4);
end of a memory segment. Instead, we'll put the version_information _version_information_start = .;
wherever the linker wants it, and then put a pointer to the start
of the version information at the end of the section.
-- Henryk Plötz <henryk@ploetzli.ch> 2009-08-28 */
_version_information_start = ABSOLUTE(.);
*(.version_information); *(.version_information);
/* Why doesn't this work even though _bootphase1_version_pointer = 0x1001fc? . = LENGTH(bootphase1) - 0x4;
. = _bootphase1_version_pointer - ORIGIN(bootphase1); */ LONG(_version_information_start);
/* This works, apparently it fools the linker into accepting an absolute address */
. = _bootphase1_version_pointer - ORIGIN(bootphase1) + ORIGIN(bootphase1);
LONG(_version_information_start)
} >bootphase1 } >bootphase1
__bootphase2_src_start__ = ORIGIN(bootphase2);
.bootphase2 : { .bootphase2 : {
__bootphase2_start__ = .;
*(.startphase2) *(.startphase2)
*(.text) *(.text)
*(.text.*)
*(.eh_frame) *(.eh_frame)
*(.glue_7) *(.glue_7)
*(.glue_7t) *(.glue_7t)
*(.rodata) *(.rodata)
*(.rodata.*)
*(.data) *(.data)
. = ALIGN( 32 / 8 ); *(.data.*)
__bootphase2_end__ = .; . = ALIGN(4);
} >ram AT>bootphase2 } >ram AT>bootphase2
__bootphase2_src_start__ = LOADADDR(.bootphase2);
__bootphase2_start__ = ADDR(.bootphase2);
__bootphase2_end__ = __bootphase2_start__ + SIZEOF(.bootphase2);
.bss : { .bss : {
__bss_start__ = .; __bss_start__ = .;
*(.bss) *(.bss)
} >ram *(.bss.*)
. = ALIGN(4);
. = ALIGN( 32 / 8 );
__bss_end__ = .; __bss_end__ = .;
} >ram
.commonarea (NOLOAD) : { .commonarea (NOLOAD) : {
*(.commonarea) *(.commonarea)

View file

@ -9,13 +9,12 @@
.extern BootROM .extern BootROM
.section .startphase2,"ax" .section .startphase2,"ax"
.code 32
.align 0
.global ramstart .arm
ramstart:
ldr sp, .stack_end .global ram_start
ram_start:
ldr sp, =_stack_end
bl BootROM bl BootROM
.stack_end: .ltorg
.word _stack_end