Nicer boot

This commit is contained in:
Romain Goyet
2015-05-03 20:07:10 +02:00
parent c314a1e296
commit f504528463
10 changed files with 8480 additions and 27 deletions

View File

@@ -1,8 +1,12 @@
typedef long uint32_t; //FIXME: Extrude this in another file, and assert it
#include <stdint.h>
#include <string.h>
// FIXME: Use a libc, and memset, bzerto!
extern const void * _data_segment_start_flash;
extern const void * _data_segment_start_ram;
extern const void * _data_segment_end_ram;
extern const void * _data_section_start_flash;
extern const void * _data_section_start_ram;
extern const void * _data_section_end_ram;
extern const void * _bss_section_start_ram;
extern const void * _bss_section_end_ram;
void _start(void);
@@ -20,7 +24,7 @@ typedef void(*ISR)(void);
ISR InitialisationVector[INITIALISATION_VECTOR_SIZE]
__attribute__((section(".isr_vector_table")))
= {
0x20010000, //FIXME: This is the stack pointer!
0x2001FFF0, //FIXME: This is the stack pointer!
_start,
0,
0,
@@ -33,17 +37,18 @@ void _start(void) {
// This is where execution starts after reset.
// Many things are not initialized yet so the code here has to pay attention.
/* Copy data segment to RAM
* The data segment is R/W but its initialization value matters. It's stored
/* Copy data section to RAM
* The data section is R/W but its initialization value matters. It's stored
* in Flash, but linked as if it were in RAM. Now's our opportunity to copy
* it. Note that until then the data segment (e.g. global variables) contains
* it. Note that until then the data section (e.g. global variables) contains
* garbage values and should not be used. */
// int dataSegmentSize = &_data_segment_end_ram - &_data_segment_start_ram;
uint32_t * ramPointer = (uint32_t *)&_data_segment_start_ram;
uint32_t * flashPointer = (uint32_t *)&_data_segment_start_flash;
while (ramPointer < (uint32_t *)&_data_segment_end_ram) {
*ramPointer++ = *flashPointer++;
}
size_t dataSectionLength = (char *)&_data_section_end_ram - (char *)&_data_section_start_ram;
memcpy(&_data_section_start_ram, &_data_section_start_flash, dataSectionLength);
/* Zero-out the bss section in RAM
* Until we do, any uninitialized global variable will be unusable. */
size_t bssSectionLength = (char *)&_bss_section_end_ram - (char *)&_bss_section_start_ram;
memset(&_bss_section_start_ram, 0, bssSectionLength);
main(0, 0x0);
}

View File

@@ -50,17 +50,30 @@ SECTIONS {
* This is required because its initial value matters (so it has to be in
* persistant memory in the first place), but it is a R/W area of memory
* so it will have to live in RAM upon execution (in linker lingo, that
* translate to the data segment having a LMA in Flash and a VMA in RAM).
* translate to the data section having a LMA in Flash and a VMA in RAM).
*
* This means we'll have to copy it from Flash to RAM on initialization.
* To do this, we'll need to know the source location of the data segment
* (in Flash), the target location (in RAM), and the size of the segment.
* To do this, we'll need to know the source location of the data section
* (in Flash), the target location (in RAM), and the size of the section.
* That's why we're defining three symbols that we'll use in the initial-
* -ization routine. */
. = ALIGN(4);
_data_segment_start_flash = LOADADDR(.data);
_data_segment_start_ram = .;
_data_section_start_flash = LOADADDR(.data);
_data_section_start_ram = .;
*(.data)
_data_segment_end_ram = .;
_data_section_end_ram = .;
} >RAM AT> FLASH
.bss : {
/* The bss section contains data for all uninitialized variables
* So like the .data section, it will go in RAM, but unline the data section
* we don't care at all about an initial value.
*
* Before execution, crt0 will erase that section of memory though, so we'll
* need pointers to the beginning and end of this section. */
. = ALIGN(4);
_bss_section_start_ram = .;
*(.bss)
_bss_section_end_ram = .;
} >RAM
}