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
ARMSRC = fromflash.c
ARMSRC =
THUMBSRC = usb.c bootrom.c
ASMSRC = ram-reset.s flash-reset.s
@ -27,7 +27,7 @@ include ../common/Makefile.common
all: $(OBJDIR)/bootrom.s19
$(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:
$(DELETE) $(OBJDIR)$(PATHSEP)*.o

View file

@ -6,46 +6,48 @@
@ Reset vector for running from FLASH
@-----------------------------------------------------------------------------
.extern CopyBootToRAM
.section .startup,"ax"
.code 32
.align 0
.arm
.global flashstart
flashstart:
b Reset
b UndefinedInstruction
b SoftwareInterrupt
b PrefetchAbort
b DataAbort
b Reserved
b Irq
b Fiq
b reset
b undefined_instruction
b software_interrupt
b prefetch_abort
b data_abort
b . @reserved
b irq
b fiq
Reset:
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)
ldr r3, .bootphase2_start @ start address of RAM bootloader
bx r3 @ jump to it
reset:
ldr sp, =_stack_end @ initialize stack pointer to top of RAM
.stack_end:
.word _stack_end
.bootphase2_start:
.word __bootphase2_start__
@ copy bootloader to RAM (in case the user re-flashes the 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
Fiq:
b Fiq
UndefinedInstruction:
b UndefinedInstruction
SoftwareInterrupt:
b SoftwareInterrupt
PrefetchAbort:
b PrefetchAbort
DataAbort:
b DataAbort
Reserved:
b Reserved
Irq:
b Irq
ldr r3, =ram_start @ start address of RAM bootloader
bx r3 @ jump to it
.ltorg
undefined_instruction:
b .
software_interrupt:
b .
prefetch_abort:
b .
data_abort:
b .
irq:
b .
fiq:
b .

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,51 +13,44 @@ INCLUDE ../common/ldscript.common
ENTRY(flashstart)
SECTIONS
{
. = 0;
.bootphase1 : {
*(.startup)
*(.bootphase1)
/* It seems to be impossible to flush align a section at the
end of a memory segment. Instead, we'll put the version_information
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);
/* Why doesn't this work even though _bootphase1_version_pointer = 0x1001fc?
. = _bootphase1_version_pointer - ORIGIN(bootphase1); */
/* This works, apparently it fools the linker into accepting an absolute address */
. = _bootphase1_version_pointer - ORIGIN(bootphase1) + ORIGIN(bootphase1);
LONG(_version_information_start)
} >bootphase1
__bootphase2_src_start__ = ORIGIN(bootphase2);
.bootphase2 : {
__bootphase2_start__ = .;
*(.startphase2)
*(.text)
*(.eh_frame)
*(.glue_7)
*(.glue_7t)
*(.rodata)
*(.data)
. = ALIGN( 32 / 8 );
__bootphase2_end__ = .;
} >ram AT>bootphase2
.bss : {
__bss_start__ = .;
*(.bss)
} >ram
. = ALIGN( 32 / 8 );
__bss_end__ = .;
.commonarea (NOLOAD) : {
*(.commonarea)
} >commonarea
.bootphase1 : {
*(.startup)
. = ALIGN(4);
_version_information_start = .;
*(.version_information);
. = LENGTH(bootphase1) - 0x4;
LONG(_version_information_start);
} >bootphase1
.bootphase2 : {
*(.startphase2)
*(.text)
*(.text.*)
*(.eh_frame)
*(.glue_7)
*(.glue_7t)
*(.rodata)
*(.rodata.*)
*(.data)
*(.data.*)
. = ALIGN(4);
} >ram AT>bootphase2
__bootphase2_src_start__ = LOADADDR(.bootphase2);
__bootphase2_start__ = ADDR(.bootphase2);
__bootphase2_end__ = __bootphase2_start__ + SIZEOF(.bootphase2);
.bss : {
__bss_start__ = .;
*(.bss)
*(.bss.*)
. = ALIGN(4);
__bss_end__ = .;
} >ram
.commonarea (NOLOAD) : {
*(.commonarea)
} >commonarea
}

View file

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