/** * * @brief Initializes nanokernel data structures * * This routine initializes various nanokernel data structures, including * the background (or idle) task and any architecture-specific initialization. * * Note that all fields of "_nanokernel" are set to zero on entry, which may * be all the initialization many of them require. * * @return N/A */ static void nano_init(struct tcs *dummyOutContext) { /* * Initialize the current execution thread to permit a level of debugging * output if an exception should happen during nanokernel initialization. * However, don't waste effort initializing the fields of the dummy thread * beyond those needed to identify it as a dummy thread. */ _nanokernel.current = dummyOutContext; /* * Do not insert dummy execution context in the list of fibers, so that it * does not get scheduled back in once context-switched out. */ dummyOutContext->link = (struct tcs *)NULL; dummyOutContext->flags = FIBER | ESSENTIAL; dummyOutContext->prio = 0; /* * 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 nanokernel subsystems * install bonafide handlers, or before hardware device drivers are * initialized. */ _IntLibInit(); /* * Initialize the thread control block (TCS) for the main task (either * background or idle task). The entry point for this thread is '_main'. */ _nanokernel.task = (struct tcs *) main_task_stack; _new_thread(main_task_stack, /* pStackMem */ CONFIG_MAIN_STACK_SIZE, /* stackSize */ (_thread_entry_t)_main, /* pEntry */ (_thread_arg_t)0, /* parameter1 */ (_thread_arg_t)0, /* parameter2 */ (_thread_arg_t)0, /* parameter3 */ -1, /* priority */ 0 /* options */ ); /* indicate that failure of this task may be fatal to the entire system */ _nanokernel.task->flags |= ESSENTIAL; initialize_nano_timeouts(); /* perform any architecture-specific initialization */ nanoArchInit(); }
void _PrepC(void) { #ifdef CONFIG_INIT_STACKS init_stacks(); #endif /* * Set PSP and use it to boot without using MSP, so that it * gets set to _interrupt_stack during initialization. */ set_and_switch_to_psp(); relocate_vector_table(); enable_floating_point(); _bss_zero(); _data_copy(); #ifdef CONFIG_BOOT_TIME_MEASUREMENT __start_time_stamp = 0U; #endif _IntLibInit(); _Cstart(); CODE_UNREACHABLE; }
/** * * @brief Initializes kernel data structures * * This routine initializes various kernel data structures, including * the init and idle threads and any architecture-specific initialization. * * Note that all fields of "_kernel" are set to zero on entry, which may * be all the initialization many of them require. * * @return N/A */ 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; dummy_thread->base.thread_state = _THREAD_DUMMY; #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_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_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 */ kernel_arch_init(); }