Difference between revisions of "LPC2138/crt"
(→after reset: describe shit) |
m (Just a syntax highlighting update.) |
||
(One intermediate revision by one other user not shown) | |||
Line 28: | Line 28: | ||
And that's it. C environment is ready! | And that's it. C environment is ready! | ||
− | == | + | == ARM exception vector locations == |
ok, so these fuckers can be remapped: | ok, so these fuckers can be remapped: | ||
* boot loader mode (on start up), boot block vectors are mapped here | * boot loader mode (on start up), boot block vectors are mapped here | ||
Line 64: | Line 64: | ||
|} | |} | ||
− | Crt.s looks like this< | + | |
+ | Crt.s looks like this<syntaxhighlight lang="asm"> | ||
.section .vectors | .section .vectors | ||
.code 32 | .code 32 | ||
Line 86: | Line 87: | ||
start: | start: | ||
− | /* setup sp */ | + | /* missing: setup of sp for other modes */ |
+ | |||
+ | /* setup sp for Supervisor mode */ | ||
ldr sp, =_ram_end | ldr sp, =_ram_end | ||
Line 93: | Line 96: | ||
b endless | b endless | ||
− | </ | + | </syntaxhighlight> |
+ | |||
+ | |||
− | A mofo was also the linker script:< | + | A mofo was also the linker script:<syntaxhighlight lang="asm"> |
MEMORY | MEMORY | ||
{ | { | ||
Line 106: | Line 111: | ||
/* http://sourceware.org/binutils/docs/ld/Output-Section-LMA.html */ | /* http://sourceware.org/binutils/docs/ld/Output-Section-LMA.html */ | ||
− | _ram_end = ORIGIN(RAM) + LENGTH(RAM) - 4; | + | _ram_end = ORIGIN(RAM) + LENGTH(RAM) - 4; /* quite sure -4 isn't necessary, but i'd need to check */ |
SECTIONS | SECTIONS | ||
Line 134: | Line 139: | ||
} >RAM | } >RAM | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
+ | |||
+ | |||
− | But ok, it works now, and after crt, we can transfer more init to c code:< | + | But ok, it works now, and after crt, we can transfer more init to c code:<syntaxhighlight lang="c"> |
#include <types.h> | #include <types.h> | ||
#include <board.h> | #include <board.h> | ||
Line 161: | Line 168: | ||
board_init(); | board_init(); | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
+ | |||
+ | |||
Hrm, code dumps are boring, but crt.s and linker script really took a while to make it work. | Hrm, code dumps are boring, but crt.s and linker script really took a while to make it work. |
Latest revision as of 10:33, 28 February 2011
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.
Some explanation of startup (relevant to other MCUs too): On startup CPU jumps to location 0, and just starts executing code. Since there's only one instruction space, the first instruction is a branch to reset handler.
Reset handler needs to set up stacks. In this example it only sets up the current (Supervisor) mode stack, but it's easy to set them for other modes... something along these lines: MODE_FIQ ldr sp, =_ram_end-0x100
IF you use User mode... don't forget to switch to that mode last, because you can't switch back.
A word on sections
There's basically three differently handled sections:
- .text/.rodata for code and readonly data
- .data for initialized data
- .bss for uninitialized data
.text and .rodata are obviously just saved into FLASH, and that's fine for them. .data is a bit more tricky, since addresses are from RAM, but data needs to be saved somewhere (well... FLASH, where else). So you need to have code that copies .data section from flash. And following that is the code to zero the .bss.
And that's it. C environment is ready!
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<syntaxhighlight 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:
/* missing: setup of sp for other modes */
/* setup sp for Supervisor mode */ ldr sp, =_ram_end
bl init bl main
b endless
</syntaxhighlight>
A mofo was also the linker script:<syntaxhighlight 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; /* quite sure -4 isn't necessary, but i'd need to check */
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
} </syntaxhighlight>
But ok, it works now, and after crt, we can transfer more init to c code:<syntaxhighlight 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();
} </syntaxhighlight>
Hrm, code dumps are boring, but crt.s and linker script really took a while to make it work.