OEMInit详解

来源:互联网 发布:淘宝npm镜像官网 编辑:程序博客网 时间:2024/05/16 14:31
分类: wince2011-04-06 16:52 14人阅读 评论(0) 收藏 举报

OEMInit是OAL中的重要函数,用来初始化板级的硬件设备。实际上,WinCE的内核最开始只做了CPU级的初始化,随后会初始化调试串口,然后就会调用该函数了。

应该说OAL中的OEMInit函数有点像EBOOT中的OEMPlatformInit函数,我说的是有点像,毕竟应用不同。OEMInit函数主要完成以下功能:

1. 初始化相应的硬件外设

2. 根据需要初始化KITL调试

3. 设置一些内核所需的全局变量

//  Function:  OEMInit

//

//  This is Windows CE OAL initialization function. It is called from kernel

//  after basic initialization is made.

//

 

void OEMInit()

{

    BSP_ARGS *pBSPArgs = ((BSP_ARGS *) IMAGE_SHARE_ARGS_UA_START);               

 

    // Set up the debug zones according to the fix-up variable initialOALLogZones

    OALLogSetZones(initialOALLogZones);


    //调用OALMSG(..)函数打印一条信息,这样可以知道WinCE内核已经运行到OEMInit函数中。

    OALMSG(OAL_FUNC, (L"+OEMInit/r/n"));

    

    //读取处理器类型

    // Lie about the Processor Type (we do this so that the visual C tools work)

    // CEProcessorType macro is defined in public/common/oak/inc/nkexport.h

    CEProcessorType = PROCESSOR_STRONGARM;

      

    // Set memory size for DrWatson kernel support

    dwNKDrWatsonSize = 0;

    if (dwOEMDrWatsonSize != DR_WATSON_SIZE_NOT_FIXEDUP) {

        dwNKDrWatsonSize = dwOEMDrWatsonSize;

    }

 

    //调用OALCacheGlobalsInit来初始化一些变量保存Cache的设置参数。该函数应该在其他的Cache和TLB操作函数之前被调用

    // Initialize cache globals

    OALCacheGlobalsInit();

      

    OALLogSerial(

        L"DCache: %d sets, %d ways, %d line size, %d size/r/n",

        g_oalCacheInfo.L1DSetsPerWay, g_oalCacheInfo.L1DNumWays,

        g_oalCacheInfo.L1DLineSize, g_oalCacheInfo.L1DSize

    );

    OALLogSerial(

        L"ICache: %d sets, %d ways, %d line size, %d size/r/n",

        g_oalCacheInfo.L1ISetsPerWay, g_oalCacheInfo.L1INumWays,

        g_oalCacheInfo.L1ILineSize, g_oalCacheInfo.L1ISize

    );

      

    //判断是否是一次干净的引导(clean boot),调用NKForceCleanBoot来迫使操作系统基于一个干净的对象存储系统(object store)来   引导

    // Check whether we should force a clean boot

    if(!pBSPArgs->EmulatorFlags.bit.fSoftReset) {

        OALMSG(OAL_INFO, (L"OEMInit: soft reset flag not set, forcing clean boot/r/n"));

        NKForceCleanBoot();

        pBSPArgs->EmulatorFlags.bit.fSoftReset = 1;        // assume future resets are soft unless told otherwise

        pBSPArgs->pvExtensionRAMFMDBaseAddr = NULL;

        pBSPArgs->dwExtensionRAMFMDSize = 0;

        pBSPArgs->fStorageMounted = FALSE;

    }


    //根据需要初始化显示,一般指LCD,可以在启动时显示一张图片

    // Initialize the display, in case the emulator launched the kernel binary without eboot

    InitDisplay();


    //调用OALIntrInit初始化中断,主要是根据需要打开一些中断,关闭不用的中断,完成一些物理中断(IRQ)到系统逻辑中断(SYSINTR)之间的静态映射

    // Initialize interrupts

    if (!OALIntrInit()) {

        OALMSG(OAL_ERROR, (

            L"ERROR: OEMInit: failed to initialize interrupts/r/n"

        ));

    }


    //调用OALTimerInit来初始化系统时钟,为WinCE内核产生1ms的ticker

    // Initialize system clock

    OALTimerInit(1, S3C2410X_PCLK/2000, 0);

 

    // Make high-res Monte Carlo profiling available to the kernel

    g_pOemGlobal->pfnProfileTimerEnable = OEMProfileTimerEnable;

    g_pOemGlobal->pfnProfileTimerDisable = OEMProfileTimerDisable;

 

    //调用KITLIoctl函数来初始化KITL连接

    // Initialize the KITL connection if required

    KITLIoctl(IOCTL_KITL_STARTUP, NULL, 0, NULL, 0, NULL);

 

    OALMSG(OAL_FUNC, (L"-OEMInit/r/n"));

}