wince os 的启动

原文:http://blog.chinaunix.net/u1/35351/showart_2109847.html

wince os 的启动我们也可以换分为2个阶段,第一个阶段,初始化OAL,一直到FirstSchedule开始调度,第二阶段,开始对文件系统,注册表,driver的
  初始化和加载。
(1)初始化 OAL
 
1.startup.s
  
    初始化一些硬件外设 --> KernelStart

2.KernelStart
   在PRIVATE/WINCEOS/COREOS/NK/LDR/ARM/armstart.s中
   根据OALAddress Table初始化页表 , 打开MMU和初始化Cache和中断向量
   初始化stack
   调用ArmInit
    mov     r12, r0
    ldr     r0, =KData
    mov     pc, r12                          ; jump to entry of kernel.dll
3 ArmInit
   在PRIVATE/WINCEOS/COREOS/NK/LDR/ARM/arminit.c中
   LPVOID ARMInit (struct KDataStruct *pKData)
{
    /* Initialize kernel globals */
    KernelRelocate (pTOC);
    /* The only argument passed to the entry point of kernel.dll is the address */
    /* of KData, we need to put everything we need to pass to in in KData. */
    pKData->dwTOCAddr     = (DWORD) pTOC;
    pKData->dwOEMInitGlobalsAddr = (DWORD) OEMInitGlobals;
    SetOsAxsDataBlockPointer(pKData);
    return FindKernelEntry (pTOC);
}
 主要是内核重定位 .返回kernel.dll的入口位置.
  在上面的KernelStart函数中,mov pc, r12指令跳转到kernel.dll的入口位置.
 
4 FindKernelEntry找到NKStartup
   在PRIVATE/WINCEOS/COREOS/NK/KERNEL/ARM/mdarm.c中
   调用 ARMSetup (PRIVATE/WINCEOS/COREOS/NK/KERNEL/ARM/mdarm.c)to perform addition setup for CPU (vector table, 1st-level PT mappings, etc)
   调用OEMInitDebugSerial 以及    OEMInit
   
5   OEMInit
   在/PLATFORM/SMDK6410/SRC/OAL/OALLIB/init.c中
      OALCacheGlobalsInit();
      .....
    OALArgsInit((BSP_ARGS *)IMAGE_SHARE_ARGS_UA_START);// Check and Initialize the BSP Args area
     .....
      if (!OALIntrInit())// Initialize Interrupts
    {
        OALMSG(OAL_ERROR, (L"[OAL:ERR] OEMInit() : failed to initialize interrupts/n"));
    }
    .......
    OALTimerInit(RESCHED_PERIOD, (OEM_COUNT_1MS ), 0);// Initialize System Clock
    .......
    KITLIoctl(IOCTL_KITL_STARTUP, NULL, 0, NULL, 0, NULL);  // Initialize the KITL connection if required
  
  
6、KernelSstart函数:
    这里的KernelStart函数与前面的KernelStart函数的属于两个完全不同的函数,NKStartup函数中调用的KernelStart 函数为
    $(_PRIVATEROOT)/WINCEOS/COREOS/NK/KERNEL/ARM/armtrap.s文件中的KernelStart 函数,
    主要完成调用内核初始化函数KernelInit,并跳转到操作系统的第一个启动的任务。
LEAF_ENTRY KernelStart
    ldr r4, =KData ; (r4) = ptr to KDataStruct
    ldr r0, =APIRet
    str r0, [r4, #pAPIReturn] ; set API return address
    mov r1, #SVC_MODE
    msr cpsr_c, r1 ; switch to Supervisor Mode w/IRQs enabled
    CALL KernelInit ; initialize scheduler, etc.
    mov r0, #0 ; no current thread
    mov r1, #ID_RESCHEDULE
    b FirstSchedule
ENTRY_END
7、KernelInit函数:
    Windows CE 6.0的内核初始化函数同其他版本的内核初始化函数基本相近,主要完成在启动第一个线程前对内核进行初始化,主要包括API函数集初始化、堆的初始化、初始化内存池、进程初始化、线程初始化和文件映射初始化等操作。
void KernelInit (void)
{
#ifdef DEBUG
    g_pNKGlobal->pfnWriteDebugString (TEXT("Windows CE KernelInit/r/n"));
#endif
    APICallInit ();// setup API set
    HeapInit ();// setup kernel heap
    InitMemoryPool ();// setup physical memory
    PROCInit ();// initialize process
    VMInit (g_pprcNK);// setup VM for kernel
    THRDInit ();// initialize threadsv
    MapfileInit ();
#ifdef DEBUG
    g_pNKGlobal->pfnWriteDebugString (TEXT("Scheduling the first thread./r/n"));
#endif
}
8、FirstSchedule:
    FirstSchedule函数为Windows CE操作系统启动过程中最后无条件跳转的一个函数,windows CE进行第一个调度,实际为一个空闲线程,因为windows CE系统还没有完成启动,只有当windows CE完全启动并进入稳定状态,然后启动文件系统filesys.dll,设备管理device.dll,窗体图像子系统gews.dll和shell程序 explore.exe。
 
(2)系统的其它部分初始化
2.1    FirstSchedule --〉SystemStartupFunc
2.2    而在SystemStartupFunc中,会创立一个内核线程
   CreateKernelThread (RunApps,0,THREAD_RT_PRIORITY_NORMAL,0)
   这样就执行线程的函数RunApps
2.3    在RunApps中,NKLoadLibraryEx (L"filesys.dll", MAKELONG (LOAD_LIBRARY_IN_KERNEL, LLIB_NO_PAGING), NULL);
     进行filesys.dll的加载,
2.4     然后启动一个线程,执行filesys.dll的 WinMain
2.5      等待filesys.dll 的event SYSTEM/FSReady
2.6      收到后: 
            InitMUILanguages();// Initialize MUI-Resource loader (requires registry)
       
            InitSystemSettings (); // Read system settings from registry
   
我们再来看看 FILESYS.DLL 。它相当于Windows CE以前版本中的FILESYS.EXE,负责初始化文件系统、对象存储、注册表、CEDB数据库、设备通知以及其它一些工作。
1  Filesys.dll 检测是冷启动还是热启动
  如果是冷启动,对象存储内存将被初始化并映射给Filesys.dll.对于热启动,不用初始化而直接映射给Filesys.dll
2 Filesys.dll 从ROM中加载 OEM的 Certification DLL .
3 对于热启动,如果系统必须冷启动, Filesys.dll调用OAL函数pNotifyForceCleanboot.
4 对于冷启动, Filesys.dll 初始化RTC,通过调用OEMIoControl函数,控制号为IOCTL_HAL_INIT_RTC I/O.
5 Filesys.dll 按照顺序初始化下列APIs:
   Database APIs
   File system APIs
   Point-to-point message queue APIs
   Event log APIs
   Registry APIs
对于冷启动, Filesys.dll初始化注册表数据.数据初始化过程取决于是hive注册表还是RAM注册表.
如果在注册表里指定了缺省的用户Profile, Filesys.dll加载缺省用户的profile并初始化 HKEY_CURRENT_USER下的数据.
6 如果Device.dll 没有启动并且HKEY_LOCAL_MACHINE/System/StorageManager 指向一个可以加载的DLL, Filesys.dll加载存储管理器.
  如果存储管理器加载了, Filesys.dll创建一个线程来初始化它.
7 Filesys.dll 初始化NLS数据(national language support).
8 对于一个干净的启动,Filesys.dll查阅Initobj.dat文件,然后从ROM中拷贝这些文件到根文件系统.
  比如Initobj.dat内容为:
  root:-Directory("Program Files")
  root:-Directory("My Documents")
  Directory("/Windows"):-Directory("Desktop")
  Directory("/Windows"):-Directory("Programs")
  Directory("/Windows"):-Directory("Recent")
  Directory("/Windows/Desktop"):-File("Media Player.lnk", "/Windows/ceplayer.lnk")
  Directory("/Windows/Programs"):-File("Media Player.lnk", "/Windows/ceplayer.lnk")
  Directory("/Windows/Desktop"):-File("Messenger.lnk", "/Windows/msmsgs.lnk")
  Directory("/Windows/Programs"):-File("Messenger.lnk", "/Windows/msmsgs.lnk")
  它的意思是:
   先用root命令在根目录/下面建立2个文件夹,分别叫Program Files和My Documents.
   然后在/Windows下面建立3个文件夹Desktop,Program,Recent
   最后把Media Player的链接ceplayer.lnk,msmsgs.lnk拷贝到/windows/Desktop,Programs目录下,命名为Media Player.lnk,Messenger.lnk. 
9 如果需要的话,Filesys.dll初始化时区并设置夏令时 (daylight saving time ,DST).
10 对于冷启动, Filesys.dll为用数据库引擎设置区域,对于EDB数据库,通过调用CeChangeDatabaseLCID (EDB)而对于CEDB数据库调用CeChangeDatabaseLCID (CEDB).
   此外,对于冷启动,Filesys.dll从Initdb.ini文件中加载数据来填充对象存储数据库.
  
11 Filesys.dll告诉kernel:Filesys.dll已经好了. Filesys.dll然后等待kernel通知去启动OS的其他部分.
12 Filesys.dll根据HKEY_LOCAL_MACHINE/System/Events注册表创建命名的事件. 这些事件被拥有他们的进程设置.
13 Filesys.dll 启动HKEY_LOCAL_MACHINE/Init所列的应用
如果Device.dll在HKEY_LOCAL_MACHINE/Init中,而它又已经被启动,Filesys.dll会去打开SYSTEM/BOOTPHASE2事件,并会向Device.dll发信号。
该动作使得Device.dll会去重读注册表,并完成最后阶段的驱动初始化。任何驱动都可以去等待该同样的事件,这样驱动就可以去再读一次注册表。
在正常的启动过程中,Filesys.dll建立了一些文件并把他们存储在user storage中. 这些文件将占用 1.8 MB的可用的user storage.
下列文件在启动过程中被创建:
System.hv    /Documents and Settings/system.hv          345 KB   系统注册表hive文件
User.hv       /Documents and Settings/default/user.hv   345 KB    缺省用户的用户注册表hive文件
对于filesys.dll启动过程,参见 http://msdn.microsoft.com/en-us/library/aa912276.aspx
再来看Device.dll,它被加载后,将读取 HKLM/Drivers/BuildIn下面的信息,然后一个一个驱动被加载,加载后相应地在 HKLM/Drivers/Active下面创立相应的键.

猜你喜欢

转载自blog.csdn.net/gsymichael/article/details/5294095