RISC-V: A Baremetal Introduction using C++. Startup.

Can we write our own startup code in pure C++?

Booting a RISC-V Core

From here https://commons.wikimedia.org/wiki/File:Linux_boot_screen_compact.png
Booting an OS is much more complex, but the entry point relies on the same principles.
extern "C" void _enter(void)  
__attribute__((naked,
section(".text.metal.init.enter")));
extern "C" void _start(void)
__attribute__ ((noreturn));
void _enter(void) {
// Setup SP and GP
// The locations are defined in the linker script
__asm__ volatile (
".option push;"
".option norelax;"
"la gp, __global_pointer$;"
".option pop;"
"la sp, _sp;"
"jal zero, _start;"
: /* output: none %0 */
: /* input: none */
: /* clobbers: none */);
// This point will not be executed,
// _start() will be called with no return.
}

Initializing the C++ World

extern "C" std::uintptr_t metal_segment_bss_target_start, 
metal_segment_bss_target_end,
metal_segment_data_source_start ..
metal_segment_itim_target_end;
extern "C" function_t *__init_array_start, *__init_array_end;
// At this point we have a stack and global pointer,
// but no access to global variables.
void _start(void) {
// Init memory regions
// Clear the .bss section
// (global variables with no initial values)
std::fill(&metal_segment_bss_target_start,
&metal_segment_bss_target_end,
0U);
// Initialize the .data section
//(global variables with initial values)
std::copy(&metal_segment_data_source_start,
&metal_segment_data_source_start +
(&metal_segment_data_target_end -
&metal_segment_data_target_start),
&metal_segment_data_target_start);
// Initialize the .itim section
//(code moved from flash to SRAM to improve performance)
std::copy(&metal_segment_itim_source_start,
&metal_segment_itim_source_start +
(&metal_segment_itim_target_end -
&metal_segment_itim_target_start),
&metal_segment_itim_target_start);
// Call constructors
std::for_each( __init_array_start,
__init_array_end,
[](const function_t pf) {pf();});
// Jump to main
auto rc = main();
// Don't expect to return, if so busy loop in the exit function.
_Exit(rc);
}

Conclusion

--

--

--

Software Engineer, Software Architect, Embedded Systems, Distributed Systems, Digital Design, ソフトウェアエンジニア http://www.linkedin.com/in/phil-mulholland-884a8

Love podcasts or audiobooks? Learn on the go with our new app.

Looking Under The Hood With GCC

The new network, supported by new technologies and new skills

AWS API Gateway Proxy Missing Authentication Token

Masternode Hosting at Social Send Platform

How We are Making a Video Game in Python #4

Modernization — A Cohesive approach

What is a Microservice, Really

How to manage your budget in agile it projects? Part 2

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Phil Mulholland

Phil Mulholland

Software Engineer, Software Architect, Embedded Systems, Distributed Systems, Digital Design, ソフトウェアエンジニア http://www.linkedin.com/in/phil-mulholland-884a8

More from Medium

C++20 Concurrency — Part 2: jthreads

Modern C++ in Advent of Code: Day24

C++ Templates: What is std::enable_if and how to use it?

Difference between static and dynamic library