ruspiro-boot 0.1.1

The crate provides baremetal boot code for the Raspberry Pi 3 to conviniently start your custom kernel within the Rust environment without the need to dangle with all the initial setup like stack pointers, getting MMU setup or getting all cores kicked off for processing.
/***********************************************************************************************************************
 * linker script to define memory addresse / sections and symbols of the binary to be build
 * known constraints:
 * Entry point address need to be 0x8000, the binarry is not allowed to start prior to this address
 * Stack pointer need to be at least 8Bit and heap pointer 16Bit aligned
 *
 * Copyright (c) 2019 by the authors
 *
 * Author: André Borrmann
 * License: Apache License 2.0
 **********************************************************************************************************************/

ENTRY(__boot)

SECTIONS
{
	/* start memory address for RPi modules in RAM */
	. = 0x8000;
	    
    .text : { KEEP(*(.text.boot)) *(.text*) }
    .rodata : { *(.rodata*) }
    .data : { *(.data*) }
    
	. = ALIGN(8);
    .init_array : {
		__init_start = .;
		*(.init_array)
		*(.init_array.*)
		__init_end = .;
	}
    
    /* bss section, contains all static variables of the c code */
    .bss : { 
    	__bss_start__ = .;
    	*(.bss*)
    	*(COMMON)
    	__bss_end__ = .;
    }

	/* fill the binary to always have an aligned binary size - needed for the bootloader on RPi to work properly */
	.fill : {
		FILL(0xDEADBEEF)
		. += 1;
		. = ALIGN(64) - 1;
		BYTE(0xAA) 
	}

	/* after the code the stack pointers will start */
	/* they cannot start from the end of usable memory as the memory */
	/* is split betwean arm cpu and gpu and the gpu memory size is not known during compile time */
	. = ALIGN(16);
	__stack_end__ = .;
	. += 0x8000;
	__stack_top_core3__ = .;
	. += 0x8000;
	__stack_top_core2__ = .;
	. += 0x8000;
	__stack_top_core1__ = .;
	. += 0x1000; /* stack space HYP mode 4kB - stack goes backwards from memory end towards begin*/
	__stack_top_HYP__ = .;
	. += 0x1000;
	__stack_top_UND__ = .;
	. += 0x1000;
	__stack_top_SYS__ = .;
	. += 0x1000;
	__stack_top_ABT__ = .;
	. += 0x1000;
	__stack_top_IRQ__ = .;
	. += 0x1000;
	__stack_top_FIQ__ = .;
	. += 0x2000;
	__stack_top_SVC__ = .;
	__stack_top_core0__ = .;
	__stack_top__ = .;
	/* the heap memory address space starts where the executable and the static variables ends (aligned to 16Bit)*/
    . = ALIGN(16);
	__heap_start = .;
    /* heap end is defined by the usage split of arm/gpu - set this to a fixed value for the time beeing */
	__heap_end = 0x3E000000;
}

/* provide linker sysmbols for interrupt functions that may be implemented elsewhere.
 * Those symbols map to a default implementation as long as no real implementation is found in the compile
 * stage
 */
PROVIDE(__undefined_instruction_h = __exception_handler_Default);
PROVIDE(__software_interrupt_h = __interrupt_handler_Default);
PROVIDE(__prefetch_abort_h = __exception_handler_Default);
PROVIDE(__data_abort_h = __exception_handler_Default);
PROVIDE(__interrupt_h = __interrupt_handler_Default);
PROVIDE(__fast_interrupt_h = __interrupt_handler_Default);