FUNC_NORETURN void _Cstart(void)
{
#ifdef CONFIG_ARCH_HAS_CUSTOM_SWAP_TO_MAIN
void *dummy_thread = NULL;
#else
/* floating point is NOT used during kernel init */
char __stack dummy_stack[_K_THREAD_NO_FLOAT_SIZEOF];
void *dummy_thread = dummy_stack;
#endif
/*
* Initialize kernel data structures. This step includes
* initializing the interrupt subsystem, which must be performed
* before the hardware initialization phase.
*/
prepare_multithreading(dummy_thread);
/* Deprecated */
_sys_device_do_config_level(_SYS_INIT_LEVEL_PRIMARY);
/* perform basic hardware initialization */
_sys_device_do_config_level(_SYS_INIT_LEVEL_PRE_KERNEL_1);
_sys_device_do_config_level(_SYS_INIT_LEVEL_PRE_KERNEL_2);
/* initialize stack canaries */
#ifdef CONFIG_STACK_CANARIES
__stack_chk_guard = (void *)sys_rand32_get();
#endif
/* display boot banner */
PRINT_BOOT_BANNER();
switch_to_main_thread();
/*
* Compiler can't tell that the above routines won't return and issues
* a warning unless we explicitly tell it that control never gets this
* far.
*/
CODE_UNREACHABLE;
}
static void prepare_multithreading(struct k_thread *dummy_thread)
{
#ifdef CONFIG_ARCH_HAS_CUSTOM_SWAP_TO_MAIN
ARG_UNUSED(dummy_thread);
#else
/*
* Initialize the current execution thread to permit a level of
* debugging output if an exception should happen during kernel
* initialization. However, don't waste effort initializing the
* fields of the dummy thread beyond those needed to identify it as a
* dummy thread.
*/
_current = dummy_thread;
dummy_thread->base.user_options = K_ESSENTIAL;
#endif
/* _kernel.ready_q is all zeroes */
/*
* The interrupt library needs to be initialized early since a series
* of handlers are installed into the interrupt table to catch
* spurious interrupts. This must be performed before other kernel
* subsystems install bonafide handlers, or before hardware device
* drivers are initialized.
*/
_IntLibInit();
/* ready the init/main and idle threads */
for (int ii = 0; ii < K_NUM_PRIORITIES; ii++) {
sys_dlist_init(&_ready_q.q[ii]);
}
/*
* prime the cache with the main thread since:
*
* - the cache can never be NULL
* - the main thread will be the one to run first
* - no other thread is initialized yet and thus their priority fields
* contain garbage, which would prevent the cache loading algorithm
* to work as intended
*/
_ready_q.cache = _main_thread;
_new_thread(_main_stack, MAIN_STACK_SIZE,
_main, NULL, NULL, NULL,
CONFIG_MAIN_THREAD_PRIORITY, K_ESSENTIAL);
_mark_thread_as_started(_main_thread);
_add_thread_to_ready_q(_main_thread);
#ifdef CONFIG_MULTITHREADING
_new_thread(_idle_stack, IDLE_STACK_SIZE,
idle, NULL, NULL, NULL,
K_LOWEST_THREAD_PRIO, K_ESSENTIAL);
_mark_thread_as_started(_idle_thread);
_add_thread_to_ready_q(_idle_thread);
#endif
initialize_timeouts();
/* perform any architecture-specific initialization */
nanoArchInit();
}
/** * * @brief Prepare to and run C code * * This routine prepares for the execution of and runs C code. * * @return N/A */void _PrepC(void){relocate_vector_table();enable_fl