日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

rtems网络移植-rtems系统初始化过程分析

發布時間:2024/1/18 windows 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 rtems网络移植-rtems系统初始化过程分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

rtems的網絡驅動移植,首先要知道如何將設備初始化函數放入初始化過程中,如何將這個網卡設備注冊到系統中。這涉及到rtems的系統初始化,接下來就具體分析初始化過程:

系統初始化第一階段:

這部分代碼主要是用匯編寫的,屬于bsp的一部分,然后rtems進入基于c代碼的初始化第二階段,但在進入第二階段之前,必須要有一個可靠的運行環境,這就是第一階段的匯編代碼的工作,總結如下:

  • 屏蔽中斷
  • 初始化cpu工作模式
  • 建立內核堆棧
  • 對bss段清零
  • 建立基本的內存布局

最開始的代碼位于/rtems/c/src/lib/libbsp/pc386(這里選擇對應的處理器)/start/start.s
函數調用如下圖所示:

大致的執行流程如下:

  • 屏蔽中斷
  • 讀取grub傳遞的multiboot_info,存放到boot_multiboot_info結構中
  • 跳轉到_load_segment處,加載與pc硬件相關的全局描述符和中斷描述符
  • 跳轉到_establish,建立rtems內核棧空間
  • 清除BSS
  • 調用initvideo函數進行顯示初始化
  • 調用checkcputypesetcr0查找cpu類型
  • 設定調用參數,調用第一個c函數boot_card

系統初始化第二階段:

這一階段主要是初始化內核組件和驅動程序做準備,與bsp聯系緊密,主要工作如下:

  • 初始化rtems_cpu_table結構體的cpu_table全局變量
  • 初始化rtems_configuration_table結構體的configuration全局變量
  • 設置rtems workspace區域
  • 初始化中斷和異常管理 初始化pci bios interface

執行流程:

boot_card函數首先更新cpu配置表和rtems配置表,然后調用bsp_start函數,該函數主要完成以下工作:

  • 計算1ms時間指令的loop值
  • 進一步更新rtems的cpu配置表
  • 制定rtems的workspace的起始地址并分配空間
  • 初始化pci bios interface

執行完bsp_start函數后,進入第三階段,開始執行rtems_initialize_executive_early函數。

系統初始化第三階段:

這一階段的工作量相對于前兩個階段要大很多,其最終目的是完成多任務切換,并切換到用戶提供的任務,這部分主要工作是:

  • 初始化rtems核心層和系統服務層的功能組件
  • 初始化驅動程序
  • 進行多任務初始化

初始化管理器組件介紹:
當板級支持包bsp完成硬件級的基本初始化工作后,把控制權交給初始化管理器,初始化管理器的工作主要是負責啟動和關閉rtems,啟動rtems包括創建并且啟動所有的配置好的初始化任務,并且初始化rtems系統使用到的設備驅動程序。

初始化rtems:
初始化管理器的主要操作體現在rtems_initialize_executive函數的實現機制,如果不使用該機制,也可以采用rtems_initialize_executive_early函數和rtems_initialize_executive_late函數的實現機制初始化。在rtems只能使用一種方法初始化系統化,不能重復初始化。

初始化所有的驅動程序:
這分成四個步驟,在具體執行初始化驅動程序之前,需要執行鉤子函數(predriver_hook),然后執行IO_initialize_all_drivers()來完成具體的驅動程序初始化過程。
具體代碼如下:
bootcard.c

/*** @file** @ingroup bsp_bootcard** @brief Standard system startup.** This is the C entry point for ALL RTEMS BSPs. It is invoked* from the assembly language initialization file usually called* start.S. It provides the framework for the BSP initialization* sequence. For the basic flow of initialization see RTEMS C User's Guide,* Initialization Manager.** This style of initialization ensures that the C++ global* constructors are executed after RTEMS is initialized.* Thanks to Chris Johns <cjohns@plessey.com.au> for the idea* to move C++ global constructors into the first task.*//** COPYRIGHT (c) 1989-2014.* On-Line Applications Research Corporation (OAR).** The license and distribution terms for this file may be* found in the file LICENSE in this distribution or at* http://www.rtems.org/license/LICENSE.*/#include <bsp/bootcard.h>#include <rtems.h> #include <rtems/sysinit.h>/** At most a single pointer to the cmdline for those target* short on memory and not supporting a command line.*/ const char *bsp_boot_cmdline;RTEMS_SYSINIT_ITEM(bsp_work_area_initialize,RTEMS_SYSINIT_BSP_WORK_AREAS,RTEMS_SYSINIT_ORDER_MIDDLE );RTEMS_SYSINIT_ITEM(bsp_start,RTEMS_SYSINIT_BSP_START,RTEMS_SYSINIT_ORDER_MIDDLE );RTEMS_SYSINIT_ITEM(bsp_predriver_hook,RTEMS_SYSINIT_BSP_PRE_DRIVERS,RTEMS_SYSINIT_ORDER_MIDDLE );/** This is the initialization framework routine that weaves together* calls to RTEMS and the BSP in the proper sequence to initialize* the system while maximizing shared code and keeping BSP code in C* as much as possible.*/ void boot_card(const char *cmdline ) {rtems_interrupt_level bsp_isr_level;/** Make sure interrupts are disabled.*/(void) bsp_isr_level;rtems_interrupt_local_disable( bsp_isr_level );bsp_boot_cmdline = cmdline;rtems_initialize_executive();/******************************************************************************************************************************* APPLICATION RUNS NOW!!! We will not return to here!!! *******************************************************************************************************************************/ }

其中包含了三個初始化函數的調用:

RTEMS_SYSINIT_ITEM(bsp_work_area_initialize,RTEMS_SYSINIT_BSP_WORK_AREAS,RTEMS_SYSINIT_ORDER_MIDDLE );RTEMS_SYSINIT_ITEM(bsp_start,RTEMS_SYSINIT_BSP_START,RTEMS_SYSINIT_ORDER_MIDDLE );RTEMS_SYSINIT_ITEM(bsp_predriver_hook,RTEMS_SYSINIT_BSP_PRE_DRIVERS,RTEMS_SYSINIT_ORDER_MIDDLE );

boot_card函數中,包含rtems_initialize_executive函數,這是初始化管理函數,位于exinit.c文件中:
exinit.c

/*** @file** @brief Initialization Manager** @ingroup ClassicRTEMS*//** COPYRIGHT (c) 1989-2014.* On-Line Applications Research Corporation (OAR).** The license and distribution terms for this file may be* found in the file LICENSE in this distribution or at* http://www.rtems.org/license/LICENSE.*/#if HAVE_CONFIG_H #include "config.h" #endif#include <rtems/system.h> #include <rtems/config.h> #include <rtems/extensionimpl.h> #include <rtems/init.h> #include <rtems/ioimpl.h> #include <rtems/sysinit.h> #include <rtems/score/sysstate.h>#include <rtems/score/apimutex.h> #include <rtems/score/copyrt.h> #include <rtems/score/heap.h> #include <rtems/score/interr.h> #include <rtems/score/isr.h> #include <rtems/score/priority.h> #include <rtems/score/schedulerimpl.h> #include <rtems/score/smpimpl.h> #include <rtems/score/timecounter.h> #include <rtems/score/threadimpl.h> #include <rtems/score/todimpl.h> #include <rtems/score/wkspace.h>const char _Copyright_Notice[] = "COPYRIGHT (c) 1989-2008.\n\ On-Line Applications Research Corporation (OAR).\n";static Objects_Information * _Internal_Objects[ OBJECTS_INTERNAL_CLASSES_LAST + 1 ];static Objects_Information *_RTEMS_Objects[ OBJECTS_RTEMS_CLASSES_LAST + 1 ];static Objects_Information *_POSIX_Objects[ OBJECTS_POSIX_CLASSES_LAST + 1 ];Objects_Information ** const _Objects_Information_table[ OBJECTS_APIS_LAST + 1 ] = {NULL,&_Internal_Objects[ 0 ],&_RTEMS_Objects[ 0 ],&_POSIX_Objects[ 0 ] };API_Mutex_Control *_RTEMS_Allocator_Mutex;API_Mutex_Control *_Once_Mutex;static void rtems_initialize_data_structures(void) {/** Dispatching and interrupts are disabled until the end of the* initialization sequence. This prevents an inadvertent context* switch before the executive is initialized.** WARNING: Interrupts should have been disabled by the BSP and* are disabled by boot_card().*//** Initialize any target architecture specific support as early as possible*/_CPU_Initialize();_Thread_Dispatch_initialization();_ISR_Handler_initialization();_API_Mutex_Initialization( 2 );_API_Mutex_Allocate( &_RTEMS_Allocator_Mutex );_API_Mutex_Allocate( &_Once_Mutex );_Thread_Handler_initialization();_Scheduler_Handler_initialization();_SMP_Handler_initialize(); }RTEMS_LINKER_ROSET( _Sysinit, rtems_sysinit_item );RTEMS_SYSINIT_ITEM(rtems_initialize_data_structures,RTEMS_SYSINIT_DATA_STRUCTURES,RTEMS_SYSINIT_ORDER_MIDDLE );/** No threads should be created before this point!!!* _Thread_Executing and _Thread_Heir are not set.** At this point all API extensions are in place. After the call to* _Thread_Create_idle() _Thread_Executing and _Thread_Heir will be set.** Scheduling can properly occur afterwards as long as we avoid dispatching.*/ RTEMS_SYSINIT_ITEM(_Thread_Create_idle,RTEMS_SYSINIT_IDLE_THREADS,RTEMS_SYSINIT_ORDER_MIDDLE );/* Initialize I/O drivers.** Driver Manager note:* All drivers may not be registered yet. Drivers will dynamically* be initialized when registered in level 2,3 and 4.*/ RTEMS_SYSINIT_ITEM(_IO_Initialize_all_drivers,RTEMS_SYSINIT_DEVICE_DRIVERS,RTEMS_SYSINIT_ORDER_MIDDLE );void rtems_initialize_executive(void) {const volatile rtems_sysinit_item *cur = RTEMS_LINKER_SET_BEGIN(_Sysinit );const volatile rtems_sysinit_item *end = RTEMS_LINKER_SET_END( _Sysinit );/* Invoke the registered system initialization handlers */while ( cur != end ) { ( *cur->handler )(); ++cur;}_System_state_Set( SYSTEM_STATE_UP );_SMP_Request_start_multitasking();_Thread_Start_multitasking();/*************************************************************************************************************************************************************************************************************** APPLICATION RUNS HERE ************ THE FUNCTION NEVER RETURNS ***************************************************************************************************************************************************************************************************************/ }

在該文件中,包含了IO_initialize_all_drivers()函數的調用:

RTEMS_SYSINIT_ITEM(_IO_Initialize_all_drivers,RTEMS_SYSINIT_DEVICE_DRIVERS,RTEMS_SYSINIT_ORDER_MIDDLE );

IO_initialize_all_drivers()函數的定義在io.c文件中

#if HAVE_CONFIG_H #include "config.h" #endif#include <rtems/ioimpl.h>bool _IO_All_drivers_initialized;void _IO_Initialize_all_drivers( void ) {rtems_device_major_number major;_IO_All_drivers_initialized = true;for ( major=0 ; major < _IO_Number_of_drivers ; major ++ )(void) rtems_io_initialize( major, 0, NULL ); }

可以看到,主要是利用for循環rtems_io_initialize函數進行初始化,其中major就是driver的注冊的數量,查找rtems_io_initialize函數的實現,在ioInitialize.c文件中:
ioInitialize.c

#if HAVE_CONFIG_H #include "config.h" #endif#include <rtems/ioimpl.h>rtems_status_code rtems_io_initialize(rtems_device_major_number major,rtems_device_minor_number minor,void *argument ) {rtems_device_driver_entry callout;if ( major >= _IO_Number_of_drivers )return RTEMS_INVALID_NUMBER;callout = _IO_Driver_address_table[major].initialization_entry;return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL; }

從該函數的實現可以看出,其實驅動函數的初始化就是調用_IO_Driver_address_table這個表中驅動設備的初始化入口成員函數,也就是initialization_entry,現在就比較明朗了,只要查找_IO_Driver_address_table表,然后向其中添加設備注冊即可。該表位于confdefs.h文件中。

rtems_driver_address_table_IO_Driver_address_table[ CONFIGURE_MAXIMUM_DRIVERS ] = {#ifdef CONFIGURE_BSP_PREREQUISITE_DRIVERSCONFIGURE_BSP_PREREQUISITE_DRIVERS,#endif#ifdef CONFIGURE_APPLICATION_PREREQUISITE_DRIVERSCONFIGURE_APPLICATION_PREREQUISITE_DRIVERS,#endif#ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVERCONSOLE_DRIVER_TABLE_ENTRY,#endif#ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVERCLOCK_DRIVER_TABLE_ENTRY,#endif#ifdef CONFIGURE_APPLICATION_NEEDS_RTC_DRIVERRTC_DRIVER_TABLE_ENTRY,#endif#ifdef CONFIGURE_APPLICATION_NEEDS_WATCHDOG_DRIVERWATCHDOG_DRIVER_TABLE_ENTRY,#endif#ifdef CONFIGURE_APPLICATION_NEEDS_STUB_DRIVERDEVNULL_DRIVER_TABLE_ENTRY,#endif#ifdef CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVERDEVZERO_DRIVER_TABLE_ENTRY,#endif#ifdef CONFIGURE_APPLICATION_NEEDS_IDE_DRIVERIDE_CONTROLLER_DRIVER_TABLE_ENTRY,#endif#ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVERATA_DRIVER_TABLE_ENTRY,#endif#ifdef CONFIGURE_APPLICATION_NEEDS_FRAME_BUFFER_DRIVERFRAME_BUFFER_DRIVER_TABLE_ENTRY,#endif#ifdef CONFIGURE_APPLICATION_EXTRA_DRIVERSCONFIGURE_APPLICATION_EXTRA_DRIVERS,#endif#ifdef CONFIGURE_APPLICATION_NEEDS_NULL_DRIVERNULL_DRIVER_TABLE_ENTRY#elif !defined(CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER) && \!defined(CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER) && \!defined(CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER) && \!defined(CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER) && \!defined(CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER) && \!defined(CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER) && \!defined(CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER) && \!defined(CONFIGURE_APPLICATION_NEEDS_FRAME_BUFFER_DRIVER) && \!defined(CONFIGURE_APPLICATION_EXTRA_DRIVERS)NULL_DRIVER_TABLE_ENTRY#endif};

可以看到這個table包含了很多外設的宏entry入口,比如console、clock等,接下來以console串口的entry舉例,CONSOLE_DRIVER_TABLE_ENTRY,該宏定義位于console.h中:

#define CONSOLE_DRIVER_TABLE_ENTRY \{ console_initialize, console_open, console_close, \console_read, console_write, console_control }

發現宏中包含了很多console函數的聲明:
console_initialize:

rtems_device_driver console_initialize(rtems_device_major_number major,rtems_device_minor_number minor,void *arg );

參數major:設備驅動的主號碼
參數minor:設備驅動的次號碼
當返回RTEMS_SUCCESSFUL表示初始化成功

這些函數的實現基本都是在具體的處理器和bsp代碼中。所以可移植性很強。只要保證接口函數相同即可。

最后在rtems_initialize_executive函數中,執行_Thread_Start_multitasking();開始多任務模式,rtems的系統初始化工作就結束了。

總結

以上是生活随笔為你收集整理的rtems网络移植-rtems系统初始化过程分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。