LPC2138/crt
after reset
The 12kB boot block is mapped into 0x7d000. It's also visible at 0x7fff d000.
Bootloader checks for valid checksum of vectors, then hands off control to flash at 0x0, or start serial port shit.
arm exception vector locations
ok, so these fuckers can be remapped:
* boot loader mode (on start up), boot block vectors are mapped here * user flash mode (from boot code), activated by BL, needs valid program sig and non-forced BL. non re-mapped vectors (== stays in flash, bottom) * user ram mode (from program), user program can remap vectors to bottom of SRAM
The 64-byte block is remapped. So some handlers can fit there.
0x0 | Reset |
0x4 | Undefined Instruction |
0x8 | Software Interrupt |
0xc | Prefetch Abort |
0x10 | Data Abort |
0x14 | 2's complement of checksum of vectors |
0x18 | IRQ |
0x1c | FIQ |
Crt.s looks like this<enscript lang=asm>
.section .vectors .code 32 .align 0
.global _vectors
_vectors: .reset: b start .undefined: bl endless .swi: bl endless .prefetchabort: bl endless .dataabort: bl endless .checksum: .word 0x92ffffec /* hand calculated, grr */ .irq: bl endless .fiq: bl endless
endless:
b endless
start:
/* setup sp */ ldr sp, =_ram_end
bl init bl main
b endless
</enscript>
A mofo was also the linker script:<enscript lang=asm> MEMORY {
FLASH (rx) : ORIGIN = 0, LENGTH = 512K RAM (rw) : ORIGIN = 0x40000000, LENGTH = 32K
}
ENTRY(_vectors)
/* http://sourceware.org/binutils/docs/ld/Output-Section-LMA.html */
_ram_end = ORIGIN(RAM) + LENGTH(RAM) - 4;
SECTIONS {
.text : { *(.vectors) *(.text) *(.rodata) *(.rodata.*) } >FLASH
_fldata = . ; .data : ALIGN(4) { _data = . ; *(.data) _edata = . ; } >RAM AT>FLASH
.bss : ALIGN(4) { _bss = . ; *(.bss) *(COMMON) _ebss = . ; } >RAM
} </enscript>
But ok, it works now, and after crt, we can transfer more init to c code:<enscript lang=c>
- include <types.h>
- include <board.h>
extern u32 _fldata, _data, _edata, _bss, _ebss, _ram_end; void init() {
u32 *src = &_fldata; u32 *dest = &_data;
/* copy .data from flash */ while (dest < &_edata) *dest++ = *src++;
/* zero .bss */ dest = &_bss; while (dest < &_ebss) *dest++ = 0;
/* poison the rest of ram */ while (dest < (u32*)&src-16) *dest++ = 0xcbababe;
board_init();
} </enscript>
Hrm, code dumps are boring, but crt.s and linker script really took a while to make it work.