根据之前的了解,我们知道了rtems启动需要经过多个步骤,现在我们根据代码分析,记录一下初始化流程
总流程在函数rtems_initialize_executive中,其实现如下:
void rtems_initialize_executive(void) { const rtems_sysinit_item *item; /* Invoke the registered system initialization handlers */ RTEMS_LINKER_SET_FOREACH( _Sysinit, item ) { ( *item->handler )(); } _Syst_Malloc_Initializeem_state_Set( SYSTEM_STATE_UP ); _SMP_Request_start_multitasking(); _Thread_Start_multitasking(); /******************************************************************* ******************************************************************* ******************************************************************* ****** APPLICATION RUNS HERE ****** ****** THE FUNCTION NEVER RETURNS ****** ******************************************************************* ******************************************************************* *******************************************************************/ }
故分析可知,其主要调用如下:
_Workspace_Handler_initialization _Malloc_Initialize bsp_start zynq_uart_kernel_init _User_extensions_Handler_initialization rtems_initialize_data_structures _Scheduler_Ensure_exactly_one_processor _RTEMS_tasks_Manager_initialization _Thread_Create_idle bsp_r1_heap_extend rtems_libio_init rtems_filesystem_initialize _Console_simple_Initialize _RTEMS_tasks_Initialize_user_task rtems_libio_post_driver _SMP_Request_start_multitasking _Thread_Start_multitasking
初始化堆工作区
_Workspace_Handler_initialization _Workspace_Initialize_for_one_area _Heap_Initialize _Heap_Get_first_and_last_block
初始化malloc
_Malloc_Initialize _Malloc_Initialize_for_one_area _Heap_Initialize _Heap_Get_first_and_last_block
bsp主要初始化中断向量表和增加一致性cache区域,并初始化ecc
bsp_start bsp_interrupt_initialize bsp_interrupt_facility_initialize AArch64_set_exception_handler AArch64_get_vector_base_address VBAR_EL1 *vector_address = handler; /* Execution template: Save volatile regs on interrupt stack Execute irq handler Restore volatile regs from interrupt stack Return to embedded exception vector code */ _AArch64_Exception_interrupt_nest AArch64_Interrupt_Handler bsp_interrupt_dispatch bsp_interrupt_handler_dispatch_unchecked bsp_interrupt_dispatch_entries ( *entry->handler )( entry->arg ); /* Execution template: Save volatile registers on thread stack(some x, all q, ELR, etc.) Switch to interrupt stack Execute interrupt handler Switch to thread stack Call thread dispatch Restore volatile registers from thread stack Return to embedded exception vector code */ _AArch64_Exception_interrupt_no_nest AArch64_Interrupt_Handler _AArch64_Exception_thread_dispatch rtems_cache_coherent_add_area add_area _Heap_Initialize _Heap_Get_first_and_last_block zynqmp_ecc_init
串口初始化,这里后面的字符输出通过zynq_uart_kernel_output_char回调到每个字符的输出
zynq_uart_kernel_init zynq_uart_initialize zynq_uart_kernel_output_char
用户扩展的初始化handler,因为默认没有,故不分析
_User_extensions_Handler_initialization _Chain_Append_unprotected
这里完成cpu,thread,isr,scheduler,smp的初始化
rtems_initialize_data_structures _CPU_Initialize _Thread_Dispatch_initialization _ISR_Handler_initialization _Thread_Handler_initialization _Scheduler_Handler_initialization _Scheduler_priority_Initialize _Scheduler_priority_Ready_queue_initialize _SMP_Handler_initialize _CPU_SMP_Finalize_initialization rtems_interrupt_entry_install # IPI 为bsp_inter_processor_interrupt bsp_interrupt_entry_install bsp_interrupt_entry_install_first
这里只是断言了cpu为1个
_RTEMS_tasks_Manager_initialization _Thread_Initialize_information _User_extensions_Add_API_set _User_extensions_Add_set
创建idle线程
_Thread_Create_idle _Thread_Create_idle_for_CPU _Thread_Initialize _Thread_Try_initialize _User_extensions_Thread_create # 创建线程 cpu->executing = idle; _System_state_Set( SYSTEM_STATE_BEFORE_MULTITASKING );
扩展的heap
libio初始化
imfs的初始化,设置root
rtems_filesystem_initialize mount register_root_file_system mkdir mknod rtems_filesystem_mknod IMFS_mknod
添加/dev/console
_Console_simple_Initialize IMFS_add_node
设置Init函数
_RTEMS_tasks_Initialize_user_task # _RTEMS_tasks_User_task_table/Init rtems_task_create _RTEMS_tasks_Create _RTEMS_tasks_Allocate _Thread_Initialize
rtems_libio_post_driver open # /dev/console
等待状态PER_CPU_STATE_READY_TO_START_MULTITASKING
SYSTEM_STATE_UP _SMP_Request_start_multitasking _SMP_Wait_for_ready_to_start_multitasking _SMP_Try_to_process_message _SMP_Process_message SMP_MESSAGE_SHUTDOWN/SMP_MESSAGE_PERFORM_JOBS/SMP_MESSAGE_FORCE_PROCESSING
启动线程任务
_Thread_Start_multitasking _CPU_Start_multitasking _AArch64_Start_multitasking .L_check_is_executing .L_restore ldp fp, lr, [x1, #0x50] # _CPU_Context_switch_no_return _Thread_Handler _Thread_Entry_adaptor_numeric Init
至此,我们完成了rtems的全部的启动流程,可以看到,最后_Thread_Start_multitasking
会主动回调在rtems_task_start传入的adaptor函数指针,而这个指针指向Init函数。操作系统启动完成。