WinCE Eboot中的OEM控制函数

来源:互联网 发布:源码交易网 编辑:程序博客网 时间:2024/06/06 14:02

作者:ARM-WinCE

 

EBOOT中有很多以OEM开头的函数,这些函数都会直接或间接的被BLCOMMON模块调用,来完成相应的功能。这些OEM函数就是我们需要根据自己的平台来实现的。可以说,实现了这些OEM函数,EBOOT的功能就完成了。

 

EBOOT中有很多OEM函数,有些是必须实现的,有些是不必实现的,而有些是根据你的EBOOT的功能需求来决定是否要实现的。下面会介绍一下直接由BLCOMMON调用的OEM控制函数:

 

1. void OEMDebugInit(void)

这应该是第一个被调用的OEM函数,用来初始化串口来打印调试信息。这里要提一下另一个函数叫OEMInitDebugSerial,是OAL中用于初始化串口的函数。所以一般会实现OEMInitDebugSerial函数,然后在OEMDebugInit中调用它就可以了。实际上这只是一个初始化函数,如果想实现串口调试,还需要实现另外几个函数,如下;

OEMWriteDebugString

OEMWriteDebugByte

OEMReadDebugByte

上述三个函数在我以前的博客“WinCE BSP中打印信息的实现介绍”中有介绍,这里不再重复了。

 

2. BOOL OEMPlatformInit(void)

这个函数用于初始化硬件平台,就是说出实话硬件板子的相关外设。一般会先初始化RTC,然后初始化Nandflash控制器,初始化硬件中断,初始化网卡,如果需要,还可以在这个时候初始化Display,然后显示一个Logo。下面是微软提供的该函数的模板:

  1. BOOL OEMPlatformInit(void)
  2. {
  3.     BOOL                    fRet = FALSE;
  4.     BOOT_ARGS              *pBootArgs; 
  5.     ETH_HARDWARE_SETTINGS  *pEdbgSettings; 
  6.     EDBG_ADDR              *pMyAddr;
  7.     //打印版本号和时间日期信息
  8.     EdbgOutputDebugString("Microsoft Windows Embedded CE Ethernet Bootloader %d.%d for Platform Example (%s %s)/n/n",  EBOOT_VERSION_MAJOR,EBOOT_VERSION_MINOR, __DATE__, __TIME__);
  9.     //初始化Driver Globals区域中的Boot引导参数信息
  10.     pBootArgs = (BOOT_ARGS*)BOOT_ARGS_PHYSICAL_MEMORY_START;
  11.     memset(pBootArgs, 0, sizeof(BOOT_ARGS));
  12.     pBootArgs->dwSig            = BOOTARG_SIG;
  13.     pBootArgs->dwLen            = sizeof(BOOT_ARGS);
  14.     pBootArgs->dwEdbgDebugZone  = EdbgDebugZone;
  15.     //添加按键输入判断,允许用户进入Shell
  16.     if (WaitForKeyPress())
  17.     {
  18.         //允许用户设置网络相关的信息,比如IP地址等
  19.         LoaderMainMenu();     
  20.     }
  21.     //初始化以太网控制器
  22.     pEdbgSettings = &pBootArgs->Edbg;
  23.     fRet          = InitEthernet(pEdbgSettings);
  24.    if (!fRet) 
  25.    {
  26.         EdbgOutputDebugString("ERROR: Ethernet initialization failed/r/n");
  27.         SpinForever();
  28.     }
  29.     pMyAddr = &pEdbgSettings->Adapter.Addr;
  30.     EdbgOutputDebugString("INFO: Debug Ethernet MAC Address: %B:%B:%B:%B:%B:%B/r/n", pMyAddr->wMAC[0] & 0x00FF, pMyAddr->wMAC[0] >> 8,
  31.         pMyAddr->wMAC[1] & 0x00FF, pMyAddr->wMAC[1] >> 8,
  32.         pMyAddr->wMAC[2] & 0x00FF, pMyAddr->wMAC[2] >> 8);
  33.     return(TRUE);
  34. }
  35.  

3. DWORD OEMPreDownload(void)

该函数一般用于初始化网络,初始化用于下载WinCE imageTFTP。首先调用OALKitlCreateName函数根据MAC地址创建设备名称。然后判断是否是DHCP,并分配IP地址。调用EbootInitEtherTransport函数初始化TFTP,该函数属于eboot模块代码,在”/WINCE600/PUBLIC/COMMON/OAK/DRIVERS/ETHDBG/EBOOT”下面可以找到,该函数返回pfJumpImg,返回值作为OEMPreDownload的返回值,决定是下载WinCE image还是直接跳转执行。

 

4. void OEMLaunch(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr, const ROMHDR* pRomHdr)

该函数用于运行WinCE,首先会根据需要将EBOOT的引导参数进行更新,并写入存储设备,然后会判断变量g_DownloadImage的值,有时候可能是g_bWaitForConnect的值,但是意思都是一样的。如果该值为0,则表示不是下载的WinCE image,是从Flashload出来的,就会直接调用Launch函数运行WinCELaunch函数一般是汇编写的,就是直接把PC指针指到WinCE image加载的地址开始运行;如果值为1,则调用EbootWaitForHostConnect函数等待Platform Builder发送信息,把该函数的返回值更新到Driver Globals内存中,这样WinCE启动后,OAL模块的代码可以访问到,然后调用Launch函数运行WinCE image。微软提供了该函数的模板:

  1. void OEMLaunch(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr, const ROMHDR *pRomHdr)
  2. {
  3.     DWORD dwPhysLaunchAddr;
  4.     EDBG_OS_CONFIG_DATA *pCfgData;    
  5.     EDBG_ADDR EshellHostAddr;
  6.     EBOOT_CFG EbootCfg;
  7.     memset(&EshellHostAddr, 0, sizeof(EDBG_ADDR));
  8.     memset(&EbootCfg, 0, sizeof(EBOOT_CFG));
  9.     //从Flash中读取Eboot的参数信息
  10.     ReadEbootConfig(&EbootCfg);
  11.     if (g_bWaitForConnect)
  12.     {//等待Platform Builder发送信息
  13.         if (!(pCfgData = EbootWaitForHostConnect(&pDriverGlobals->eth.TargetAddr, &EshellHostAddr)))
  14.         {
  15.             EdbgOutputDebugString("ERROR: OEMLaunch: EbootWaitForHostConenct failed./r/n");
  16.             SpinForever();
  17.         }
  18.         if (pCfgData->Flags & EDBG_FL_DBGMSG)
  19.         {//支持基于Ethernet的Debug信息,更新Driver Globals中的IP和端口号    
  20.             memcpy(&pDriverGlobals->eth.DbgHostAddr.wMAC,& EshellHostAddr.wMAC, 6);
  21.             pDriverGlobals->eth.DbgHostAddr.dwIP  = pCfgData->DbgMsgIPAddr;
  22.             pDriverGlobals->eth.DbgHostAddr.wPort = pCfgData->DbgMsgPort;
  23.         }
  24.         if (pCfgData->Flags & EDBG_FL_PPSH)
  25.         {//支持基于Ethernet的Target Control,更新Driver Globals中的IP和端口号    
  26.             memcpy(&pDriverGlobals->eth.PpshHostAddr.wMAC, &EshellHostAddr.wMAC, 6);
  27.             pDriverGlobals->eth.PpshHostAddr.dwIP  = pCfgData->PpshIPAddr;
  28.             pDriverGlobals->eth.PpshHostAddr.wPort = pCfgData->PpshPort;
  29.         }
  30.         if (pCfgData->Flags & EDBG_FL_KDBG)
  31.         {//支持基于Ethernet的kernel debugger,更新Driver Globals中的IP和端口号    
  32.             memcpy(&pDriverGlobals->eth.KdbgHostAddr.wMAC, &EshellHostAddr.wMAC, 6);
  33.             pDriverGlobals->eth.KdbgHostAddr.dwIP  = pCfgData->KdbgIPAddr;
  34.             pDriverGlobals->eth.KdbgHostAddr.wPort = pCfgData->KdbgPort;
  35.         }
  36.         memcpy(&pDriverGlobals->eth.DownloadHostAddr, &EshellHostAddr, sizeof(EDBG_ADDR));
  37.         pDriverGlobals->eth.etherFlags    = pCfgData->Flags;
  38.         pDriverGlobals->eth.KitlTransport = pCfgData->KitlTransport;
  39.     }
  40.     //保存WinCE kernel的launch地址
  41.     if (dwLaunchAddr && (EbootCfg.NKRegion.LaunchAddress != dwLaunchAddr))
  42.     {
  43.         EbootCfg.NKRegion.LaunchAddress = dwLaunchAddr;
  44.         WriteEbootConfig(&EbootCfg); 
  45.     }
  46.     else
  47.     {
  48.         dwLaunchAddr= EbootCfg.NKRegion.LaunchAddress;
  49.     }
  50.     // 跳转到WinCE Image的地址开始执行
  51.     Launch(dwPhysLaunchAddr);
  52.     //死循环
  53.     SpinForever();
  54. }
原创粉丝点击