中间耽搁几天,又很久没有认真弄WinCE了。今天继续起航。
操作系统层
主要包括了:进程管理、线程管理、处理机管理、调度、物理内存和虚拟内存管理、文件系统及设备管理等功能。
WinCE是微内核操作系统,系统的基本功能被放在多个独立的进程(EXE)里面实现。
- 内核 NK.EXE
- 图形系统GWES.EXE
- 对象存储FILESYS.EXE
- 设备管理系统DEVICE.EXE
- 服务SERVICES.EXE
CoreDll.Dll
CoreDll.Dll不是一个单独的进程,它会被所有用户进程都加载的动态链接库。应用程序希望访问WinCE所提供的服务,只能通过CoreDll.Dll进行。
主要功能:
负责应用程序与WinCE通信,以及完成WinCE的系统调用。
系统调用过程:
- 应用程序进行系统调用时,直接调用的是CoreDll.Dll中的一个包装(wrapper)函数。
- CoreDll.Dll会发起一个异常(软件中断),异常的作用是把执行权重新由应用程序还给操作系统。
- 操作系统会捕捉所有的异常,当操作系统捕获异常时,也就重新获得了CPU。NK.EXE会处理这个软件中断,这样进行系统调用的应用程序就会挂起,执行进入到NK.EXE
- NK.EXE会根据系统调用的不同,找到具体实现该系统调用的进程(这个进程被称为PSL)。
- 系统调用进程(PSL)得到执行的机会,会根据具体系统调用的不同而完成系统调用希望实现的功能。
进程、线程与调度
WinCE最多只支持32个进程同时运行。每个进程占据32MB的虚拟地址空间,这也被称为一个Slot。
需要注意的是Wince的进程是不支持环境变量和当前目录的。如果文件前面不添加路径,wince会首先查找“\Windows”目录,然后查找根目录“\”。OEM所指定的搜索目录(在系统注册表“HKEY_LOCAL_MACHINE\Loader\SystemPath”下添加,这是一个Multistring的值,可以添加多个搜索路径)。
线程
一个进程可拥有的线程数理论上是没有限制的,只与当前可用的内存有关。
调度
WinCE是一个抢占式多任务操作系统,调度程序使用基于优先级的时间片算法对线程进行调度。
线程的状态:
- 运行 线程正在处理器上执行
- 就绪 线程可以执行,但是此刻没有占有处理器。如果调度的线程被调度程序选中,则占有处理器就进入运行状态
- 挂起 创建线程时指定了CREATE_SUSPENDED参数或者调用SuspendThread函数都可导致线程挂起。挂起的线程不能占用处理器。每个线程都有一个挂起计数,SuspendThread函数用来增加挂起计数,ResumeThread函数使线程的挂起计数减1。当线程的挂起计数为0时,线程转入就绪态。
- 睡眠 调用Sleep函数可使线程进入睡眠状态,处于睡眠状态的线程不能占有处理器。当睡眠时间结束后,线程转入就绪态。
- 阻塞 如果线程申请的资源暂时无法获得,那么线程就进入了阻塞状态了。
解决调度中的优先级反转问题:单级和完全嵌套
完全嵌套:
操作系统将遍历系统中所有的阻塞线程,然后使每个阻塞的线程都能上台执行,直到高优先级的线程可以运行为止。这种方法可以防止死锁,但是操作系统需要在阻塞的线程上执行复杂度为O(n)的搜索。
单级方法:
操作系统只会激活导致高优先级线程阻塞的一个低优先级线程上台执行,直到释放共享资源。这种方法提高了算法的速度,但是可能贸然改变优先级会导致系统死锁。因此需要开发者通过代码控制了。
写了一个下午,下次再写进程间通信与内存管理吧。