读书频道 > 系统 > windows > Windows内核原理与实现
2.2.2 Windows内核中的关键组件
2013-05-18 14:08:03     我来说两句 
收藏    我要投稿   

本文所属图书 > Windows内核原理与实现

本书从操作系统原理的角度,详细解析了Windows如何实现现代操作系统的各个关键部件,包括进程、线程、物理内存和虚拟内存的管理,Windows中的同步和并发性支持,以及Windows的I/O模型。在介绍这些关键部件时,本...  立即去当当网订购

Windows 操作系统虽然算不上真正意义上的微内核结构,但是它的内核部分有良好的设计以及清晰的模块结构,如前面图 2.3所示。现在我们来逐一介绍内核部分的各个关键组件,不过Windows 子系统部分将留到下一小节单独讲述。

HAL (硬件抽象层)

HAL的设计目的是将硬件的差别隐藏起来,从而为操作系统的上层提供一个抽象的、一致的硬件资源模型,以使 Windows 更容易被移植到不同的硬件平台上。理想的情形是,只要硬件厂商能够提供一个HAL,Windows 就能够在相应的硬件平台上运行。因此,HAL使得上层的模块无须考虑硬件的差异,它们通过HAL而不是直接访问硬件。

在Windows 中,HAL是一个独立的动态链接库。尽管 Windows 随带了多个主流机器的HAL,但是在系统安装的时候只有一个会被选中,并拷贝和改名为hal.dll 。HAL提供了一些例程供其他内核模块或设备驱动程序调用,这使得一个驱动程序可以支持同样的设备在各种硬件平台上运行。HAL不仅涵盖了处理器的体系结构,也涉及了中断控制器、单处理器或多处理器等硬件条件。表2.1列出了在Intel x86 机器上Windows Server 2003系统中随带的HAL。


 

内核(或微内核)

这是大内核中的小内核,将其称为微内核更可以说明它在整个内核模式代码中的地位。它是内核模块ntoskrnl.exe 中的下层部分(上层部分为执行体),最接近于HAL层,负责线程调度和中断、异常的处理。对于多处理器系统,它还负责同步处理器之间的行为,以优化系统的性能。这一层的核心任务是,让系统中的所有处理器尽可能地忙和高效。内核层可在多个处理器上并发执行,它的代码以C 语言为主,也包含一部分汇编代码。

Windows 的内核实现了抢占式线程调度机制,按照优先级顺序将线程分配到处理器上,并且允许高优先级的线程中断或抢占低优先级的线程。每个处理器上的线程切换也是由内核来完成,它按照调度规则让处理器放弃当前线程,选择下一个要执行的线程。每个线程有一个基本优先级值(base priority),这是由程序在创建线程时指定的;每个线程还有一个动态优先级值,这是在线程执行过程中根据各种条件在基本优先级基础上由内核来调整的,目的是让系统更快地响应用户的动作,以及在系统服务和其他低优先级进程之间平衡处理器资源的分配。

Windows 的内核按照面向对象的思想来设计,它管理两种类型的对象:分发器对象(dispatcher object )和控制对象。分发器对象实现了各种同步功能,这些对象的状态会影
响线程的调度。Windows 内核实现的分发器对象包括事件(event)、突变体(mutant )、信号量(semaphore)、进程(process)、线程(thread )、队列(queue)、门(gate )和定时器(timer)。控制对象被用于控制内核的操作,但是不影响线程的调度,它包括异步过程调用(APC )、延迟过程调用(DPC ),以及中断对象等。

内核层位于 HAL之上,但鉴于内核所提供功能与硬件体系结构的紧密关联性,它不可避免地需要引入一些与体系结构相关的代码,例如,在切换线程时,保存和恢复线程的执行环境取决于处理器体系结构。不过,如何选择下一个线程,这是与体系结构无关的。内核有义务将Windows 所支持的各种硬件体系结构进行抽象,使得体系结构的差异对Windows 代码的影响尽可能地小,并且有些功能可以通过HAL来完成,毕竟 HAL才是真正的硬件抽象层。例如自旋锁和中断的功能是在HAL中实现的,内核只需简单地使用HAL的导出函数即可。

执行体

执行体是内核模块ntoskrnl.exe 的上层部分,它包含5 种类型的函数:

•  被导出的、可在用户模式下调用的函数。对这些函数的调用接口位于ntdll.dll模块中。应用程序通过Windows API 来间接地调用这些函数。

•  虽已被导出并且可在用户模式下调用,但无法通过任何一个Windows API 来调用的函数。这样的例子包括 LPC (Local Procedure Call,本地过程调用)函数、各种查询函数(如 NtQueryInformation< Xxx> ),以及一些专用的函数,比如NtCreatePagingFile等。对这些函数的调用需要直接链接ntdll.dll来完成。

•  只能在内核模式下调用的导出函数,并且在Windows DDK中有关于这些函数的文档。这些函数可以被设备驱动程序调用。

•  供执行体组件之间相互调用,但未被文档化的函数。这包括执行体内部使用的一组支持函数。

•  属于一个组件的内部函数。

以上提到的组件是指执行体内部的组件,从大的方面来看,执行体包含以下组件(参考图2.3):

•  进程和线程管理器。负责创建进程和线程,以及终止进程和线程。在Windows 中,对于进程和线程的底层支持是在内核层提供的,执行体在内核层的进程和线程对象的基础上,又提供了一些语义和功能。

•  内存管理器。此组件实现了虚拟内存管理,既负责系统地址空间的内存管理,又为每个进程提供了一个私有的地址空间,并且也支持进程之间内存共享。内存管理器也为缓存管理器提供了底层支持。

•  安全引用监视器(SRM,Security Reference Monitor)。该组件强制在本地计算机上实施安全策略,它守护着操作系统的资源,执行对象的保护和审计。

•  I/O 管理器。它实现了与设备无关的输入和输出功能,负责将I/O 请求分发给正确的设备驱动程序以便进一步处理。

•  缓存管理器。它为文件系统提供了统一的数据缓存支持,允许文件系统驱动程序将磁盘上的数据映射到内存中,并通过内存管理器来协调物理内存的分配。

•  配置管理器。它负责系统注册表的实现和管理。

•  即插即用管理器。它负责列举设备,并为每个列举到的设备确定哪些驱动程序是必需的,然后加载并初始化这些驱动程序。当它检测到系统中的设备变化(增加或移除设备)时,负责发送恰当的事件通知。

•  电源管理器。它负责协调电源事件,向设备驱动程序发送电源 I/O 通知。当系统电源状态变化时,通知设备驱动程序处理设备的电源状态。即插即用设备的管理和电源的管理也可以看做是I/O 管理器的扩展功能。

此外,执行体还包含4 组主要的支持函数,供以上这些执行体组件调用。差不多有1/3 的支持函数可以在Windows DDK中找到相应的文档,因为设备驱动程序也要调用它们。这4 类支持函数如下所列:

•  对象管理器。它负责创建、管理和删除Windows 执行体对象,以及用于表达操作系统资源的抽象数据类型,比如进程、线程和各种同步对象。

•  LPC 设施。LPC 设施负责在同一台机器上的客户进程和服务器进程之间传递消息。LPC 是RPC (Remote Procedure Call,远程过程调用,关于网络上客户进程和服务器进程之间通信的工业标准)的一个优化版本。

•  一组运行时库函数。其功能广泛,涵盖字符串处理、算术运算、数据类型转换以及安全结构处理等。

•  执行体支持例程。例如系统内存分配(换页内存池和非换页内存池)、互锁的内存访问,以及对两种特殊类型同步对象(资源和互斥体)的支持。

设备驱动程序

在内核中除了内核模块ntoskrnl.exe 和HAL以外,其他的模块几乎都以设备驱动程序的形式存在。Windows 操作系统中的设备驱动程序,并不一定对应于物理设备;驱动程序既可以创建虚拟设备,也可以完全与设备无关,而仅仅是内核的扩展模块。从软件结构角度而言,我们可以认为设备驱动程序是Windows 内核的一种扩展机制,系统通过设备驱动程序来支持新的物理设备或者扩展功能。

设备驱动程序是可以动态加载到系统中的模块,其文件扩展名为.sys ,其格式是标准的PE文件格式。驱动程序中的代码运行在内核模式下,尽管它们可以直接操纵硬件,但理想的情况是,调用HAL中的函数与硬件打交道,因此,驱动程序往往用C/C++ 语言来编写,从而可以方便地在Windows 所支持的体系结构之间进行源代码层次上的移植。

PE文件格式

PE(Portable Executable)[PE-SPEC]是在Windows NT设计之初,为了建立一种可移植的、能够适应32位操作系统需要的可执行文件格式而设计的。这里“可移植”的目标是指当初Windows NT可在多种处理器(x86、MIPS、Alpha等)上运行,不同体系结构平台上的Windows NT使用相同的二进制可执行文件格式。Windows 发展至今,现在仅支持Intel 的处理器,但 PE文件格式仍然不失为一种定义良好且具有可扩展性的可执行文件格式,非Windows NT内核的操作系统Windows 9x系列也使用PE文件格式,因此,PE仍然是一种可移植的可执行文件格式。

PE格式扩展了COFF(Common Object File Format),这是UNIX(AT&T UNIX System V)中引入的用于描述二进制目标文件的格式规范。尽管 COFF 为目标文件定义了一个很好的框架,比以前的a.out 格式改进了很多,但它仍然有一些限制,比如文件中段(section )的数量有最大限制,段的名称也有长度限制,无法支持像C++ 语言所需要的符号化调试信息等。因此,每一个采用COFF 的操作系统厂商几乎都或多或少地对其进行了扩展,比如AT&T 自己又在COFF 基础上定义了ELF (Extensible Linking Format ),ELF 目前被广泛用于各种UNIX 类操作系统,包括Linux 和FreeBSD ;IBM 在AIX 中使用XCOFF;而Microsoft 则在COFF 格式规范基础上定义了PE格式。在Windows 平台上,可执行文件(扩展名为.exe )、目标文件(扩展名为.obj )、动态链接库(扩展名为.dll )以及设备驱动程序(扩展名为.sys )等多种文件类型使用了 PE文件格式。随着 64位系统的到来,PE文件格式也相应地有了一个扩展的版本,称为PE32+ ,允许使用 64位地址空间;原来的32位PE格式称为PE32。本书中我们仅涉及32位PE格式。

PE文件的基本结构包括DOS头、PE头、段表,以及段数据,如图2.4 所示。DOS头的存在仅仅是为了兼容以前的MS-DOS 系统环境,其中嵌了一段代码可在MS-DOS环境下打印出“This program cannot be run in DOS mode”字样的提示信息。DOS头后面是4 字节的PE标志“PE\0\0 ”,接着是 PE头部分。PE头分两部分:COFF 头和可选头,对于可执行映像文件,可选头也是必需的。PE 头部分包含了有关当前文件的一些全局信息,包括段的数量、符号信息、可执行文件的基地址和入口函数地址、代码段和数据段的大小、版本信息、栈和堆的初始大小,以及数据目录(data directory )等信息。PE头中的数据目录共有16项,这些目录项指示了一个可执行文件的导入表、导出表、资源表、重定位表等。


 

在PE头的后面是段表(section table),段表中的每一项指示了段的名称、段的虚拟地址位置和大小,以及其他一些有关该段的信息。对于可执行映像,段名称的长度不超过8 个ASCII 字符。段的个数由PE头中的一个域指定。在段表后面是段数据,对于每一个段,在文件中的数据量可能小于该段的大小,在这种情况下,段后面的数据补零。例如,未初始化数据部分无须在文件中包含任何有效数据。另一个值得注意的特点是,段的位置按照PE头中指定的边界对齐,所以,在段数据区,段与段之间可能有空隙。

当Windows 系统加载一个可执行映像时,如果可执行映像中指定的基地址处已经被占用,那么该可执行映像将不得不被加载到其他的位置。为了让可执行映像中的代码区和数据区在移动位置以后仍然有效,PE 文件格式中的重定位表可以指示代码段和数据段中哪些位置(这是相对位置)的地址引用需要被重新定位。所以,在加载可执行映像文件时,一旦被加载的内存起始地址与PE头中指定的基地址不一致,则必须要执行重定位操作。所谓重定位操作,是指遍历重定位段表中的每一个重定位项,将当前映像中的代码指令或数据引用按照新的内存起始地址而非原来指定的基地址来引用。

有关PE文件格式的详细信息,请参考PE文件格式规范[PE-SPEC]。另一个有用的参考资料是Matt Pietrek 写的两篇文章[MSDN-PE1][MSDN-PE2],他在文章中通过代码和例子介绍了如何解析一个可执行文件,包括PE头的解析和重定位的概念等。他提供的PEDUMP程序(有源代码)本身也是一份很好的学习和参考材料。

另外,Visual C++ 提供的工具dumpbin 可以列示出一个PE文件的各种信息,例如,下面显示了Windows Server 2003 SP1 系统中的文件notepad.exe 的头信息:
C:\>dumpbin D:\Win2k3-Exe\notepad.exe /headers
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation.  All rights reserved.
 
 
Dump of file notepad.exe
 
PE signature found
 
File Type: EXECUTABLE IMAGE
 
FILE HEADER VALUES
             14C machine (x86)
               3 number of sections
       42435B9A time date stamp Fri Mar 25 08:30:18 2005
               0 file pointer to symbol table
               0 number of symbols
              E0 size of optional header
             10F characteristics
                   Relocations stripped
                   Executable
                   Line numbers stripped
                   Symbols stripped
                   32 bit word machine
 
OPTIONAL HEADER VALUES
……  (这里省略了可选头部分的内容)
 
SECTION HEADER #1
   .text name
    7760 virtual size
    1000 virtual address (01001000 to 0100875F)
    7800 size of raw data
     400 file pointer to raw data (00000400 to 00007BFF)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
60000020 flags
         Code
         Execute Read
 
  Debug Directories
 
Time      Type    Size  RVA        Pointer
-------- ------ ----- -------- --------
42435B9A cv       24    00001910  D10    Format: RSDS, {B4CD0BCE-C210-4
934-8161-DFC07F9870B0}, 1, notepad.pdb
 
……  (这里省略了SECTION HEADER #2和SECTION HEADER #3部分的内容)
 
  Summary
 
            2000 .data
            9000 .rsrc
            8000 .text

概括而言,设备驱动程序有以下三种基本类型:

•  即插即用驱动程序(也称为WDM 驱动程序,见下文介绍)。这一类驱动程序通常是为了驱动硬件设备而由硬件厂商提供,它们与Windows 的I/O 管理器、即插即用管理器和电源管理器一起工作。Windows 自身随带了大量即插即用驱动程序,用于支持各种常见的存储设备、视频适配器、网络适配器、输入设备等。

•  内核扩展驱动程序(也称为非即插即用驱动程序)。这一类驱动程序用于扩展内核的功能,或者提供访问内核模式代码和数据的一种途径。它们并没有集成到即插即用管理器和电源管理器的框架中。在引入即插即用管理机制以前开发的驱动程序都属于这一类型。现在仍然有大量的内核扩展驱动程序。

•  文件系统驱动程序。这一类驱动程序接收针对文件的请求,再进一步将请求转变成真正对于存储设备或网络设备的I/O 请求,从而满足原始的文件请求。

Windows 的即插即用管理器是I/O 系统的一部分,它负责即插即用设备的内核支持,其职责是:自动检测设备的插入和移除;动态地分配硬件资源,例如中断、I/O 端口和I/O寄存器;指示 I/O 管理器为设备加载正确的驱动程序;向内核及应用程序提供有关设备插入和移除的通知机制。即插即用管理器根据总线和设备的功能分工,定义了一个驱动程序模型,让总线和设备的驱动程序协作完成设备的列举、插入和拔除等管理工作。支持这一模型的驱动程序称为WDM(Windows Driver Model)驱动程序,共有三种类型:总线驱动程序、功能驱动程序和过滤驱动程序。总线驱动程序既负责管理总线上的设备(配合即插即用管理器),也为总线上的设备提供了访问总线资源的方法。功能驱动程序负责管理具体的设备,向操作系统提供该设备的功能。过滤驱动程序的用途是监视一个设备的I/O请求及其处理过程,甚至增加或改变一个设备或驱动程序的行为。

在WDM中,每个硬件设备都有一个设备驱动程序栈(简称设备栈),其中包含一个总线驱动程序和一个功能驱动程序,以及零个或多个过滤驱动程序。即插即用管理器在设备列举过程中,依照总线与设备之间的关系,构建起一棵设备树,其中包含当前系统中所有被检测到的总线和设备。设备树的每一个节点都代表一个实际的设备,该设备的设备栈为其提供软件服务,操作系统(实际上是I/O 管理器)通过设备栈来访问或操纵设备。

非即插即用驱动程序的用途多种多样,其中内核扩展是最自然的用法。例如,许多系统工具使用内核扩展类型的驱动程序来获得Windows 内核中的各种系统信息,或者创建系统线程以便在系统进程环境中执行任务。另外,在Windows 内核中,也有一些模块虽然以“.sys ”作为文件扩展名,但它们其实并非设备驱动程序,而是单纯的内核扩展动态链接库,供其他的驱动程序或者内核模块调用。

有关Windows 中I/O 管理器、即插即用管理器、电源管理器以及设备驱动程序的进一步介绍,可参考第6 章。

文件系统/存储管理

在现代操作系统中,文件系统是外部存储设备的标准接口,它为应用程序使用这些设备中的数据提供了统一的抽象,多个应用程序和系统本身可以共享使用这些设备。在Windows 中,文件系统的接口部分由 I/O 管理器定义和实现,但文件系统的实现部分位于专门的一类驱动程序中。当文件系统接收到 I/O 请求时,它会根据文件系统格式规范,将这些请求转变成更低层的对于外部存储设备的I/O 请求,通过它们的设备驱动程序来完成原始的I/O 请求。因此,文件系统的驱动程序定义了外部存储设备中数据的逻辑结构,使得这些数据可直接被操作系统和应用程序使用。

Windows 的原生文件系统是NTFS(NT File System),其驱动程序为 ntfs.sys。NTFS是专门为Windows 设计的文件系统格式,它提供了安全性、可靠性、大容量支持、长文件名支持,以及可恢复性等一系列高级特性,目前广泛应用于Windows 系统。另一个常用的文件系统格式是FAT (File Allocation Table ),这是从 DOS时代发展起来的文件系统格式,格式规范相对比较简单,目前仍在使用,主要用于兼容老版本的操作系统,以及用于移动设备以便跨操作系统传送数据。

在Windows 中,每个文件系统实例有它自己的设备栈,因而通过插入过滤驱动程序可以过滤文件I/O 请求。Windows 支持两种形式的过滤驱动程序:一种直接插入到设备栈中,从而能够看到每一个经过设备栈的文件I/O 请求;另一种基于Windows 提供的过滤管理器驱动程序(FltMgr )的 I/O 过滤框架,称为文件系统小过滤驱动程序,它们并不出现在文件系统设备栈中,而是以回调方式来响应FltMgr 的事件。

文件系统的底层是对存储设备的管理。大容量存储设备以“分区(partition)”和“卷(volume )”来管理整个存储空间。分区是指存储设备上连续的存储区域(连续的扇区),
而卷是指扇区的逻辑集合。一个卷内部的扇区可能来自一个分区,也可能来自多个分区,甚至来自不同的磁盘。文件系统则是卷内部的逻辑结构。因此,Windows 的存储管理形成了一个存储栈,最接近于应用程序的是文件系统,接下来是卷管理部分,最接近于存储设备的是分区管理和磁盘驱动程序。

磁盘设备是典型的即插即用设备,其设备栈和驱动程序符合 WDM规范。即插即用管理器在设备列举过程中建立起每个磁盘设备的设备栈。设备栈的最底下是总线驱动程序,最上方是一个称为分区管理器的驱动程序,负责通知即插即用管理器当前磁盘上有哪些分区,因而系统中的卷管理器可以接收到有关分区创建和删除的通知。这样,每个物理分区与卷管理器联系起来,卷管理器再将卷与文件系统关联起来,就形成了完整的存储栈。

有关Windows 中文件系统和存储管理的进一步介绍,可参考第7 章。

网络

网络虽然并非 Windows 操作系统中必不可少的组成部分,但实际上,它已经成为绝大多数 indows 系统的标准配置。Windows 为应用程序提供了多种网络 API,允许应用软件设计人员根据他们的需求适当选择。以下是Windows 平台上主要的网络 API:

•  Windows 套接字,简称 Winsock。它实现并扩展了 BSD 套接字标准。Winsock 2.0版本支持一些新特性,比如异步网络I/O、服务质量(QoS )规范、可扩展名字空间,以及多点消息传输等。

•  WinInet。这是一个高层网络 API,它支持多个协议,包括Gopher 、FTP 和HTTP。Microsoft Internet Explorer使用 WinInet来完成数据传输。

•  命名管道(named pipe )和邮件槽(mailslot)。用于不同进程之间进行通信。它们支持不同机器上的进程之间相互通信。命名管道支持连接方式的通信模型;邮件槽支持非连接方式的通信模型,客户进程可以发送广播消息。

•  NetBIOS。这是一个早期的网络编程 API,Windows 支持NetBIOS 是为了兼容老的应用程序。NetBIOS 支持有连接的通信和无连接的通信。

•  RPC 。这是网络编程的一个标准,往往是分布式系统基础设施的重要组件。RPC 建立在其他的网络API 基础之上,比如命名管道和Winsock。Windows 的RPC 支持异步调用方式。

这些网络API 都提供了用户模式的动态链接库(DLL ),当应用程序通过这些DLL发出网络I/O 请求时,它们必须将接收到的请求传递给内核模式下的相应驱动程序。通常,这些网络 API 要么通过专门的系统服务切换到内核模式,比如命名管道和邮件槽就有专门的系统服务;要么通过标准的系统服务接口,比如 NtReadFile、NtWriteFile 和NtDeviceIoControlFile,由 I/O 管理器和对象管理器将网络请求转送至对应的驱动程序中。
 
Winsock是Windows 最重要的网络API,它的用户模式部分不仅包含了一个DLL(即ws2_32.dll),还定义了一个可扩展的框架,允许第三方插入传输服务提供者和名字空间服务提供者,以支持更多的传输服务和名称解析或地址映射能力。Winsock 默认支持TCP/IP、IPX/SPX 、AppleTalk和ATM等协议,它提供的传输服务和名字空间服务都通过内核模式驱动程序afd.sys 实现网络通信。

在内核模式部分,网络API 驱动程序(譬如afd.sys )通过传输驱动程序接口(TDI ,Transport Driver Interface )与协议驱动程序进行通信。TDI 实际上是一组预定义的I/O 请求,它描述了各种网络请求,包括名称解析、建立连接、发送和接收数据等。网络API驱动程序是TDI 客户,而传输协议驱动程序实现了TDI 接口,称为TDI 传输器。TDI 客户与TDI 传输器之间是松耦合关系。一个 TDI 传输协议驱动程序可以被多个 TDI 客户使用。例如,TCP/IP驱动程序为tcpip.sys ,它既可以被 Winsock驱动程序afd.sys 使用,也可以被netbt.sys 驱动程序使用。Windows 不仅实现了基本的TCP/IP,还支持 NAT(网络地址转译)、IP 过滤以及IPSec 规范等协议扩展,这些协议扩展也是内核驱动程序,它们通过私有的接口与tcpip.sys 进行通信。

在Windows 中,网络协议与网络适配器驱动程序是分开的,协议驱动程序独立于任何一个网络适配器,而真正发送和接收数据是通过网络适配器进行的。协议驱动程序通过统一的接口与适配器驱动程序进行通信,此接口是 NDIS(Network Driver Interface Specification)。符合 NDIS的网络适配器驱动程序称为NDIS驱动程序,或 NDIS小端口驱动程序(NDIS miniport driver)。Windows 提供了NDIS库,即 ndis.sys,作为协议驱动程序与NDIS驱动程序两者之间的桥梁。随Windows XP和Windows Server 2003一起发行的NDIS库是NDIS 5.1 ;随 Windows Vista一起发行的NDIS库是NDIS 6。

NDIS客户(即TDI 传输器)利用NDIS库提供的功能,对将要发送给NDIS驱动程序的命令进行格式化,并发送给NDIS驱动程序;而NDIS驱动程序则利用NDIS库,接收请求和送回应答。NDIS驱动程序并非标准的设备驱动程序,它们通过 NDIS库与NDIS客户进行通信,I/O 管理器并不介入两者之间的通信过程。

有关Windows 网络体系结构的进一步介绍,可参考9.1节。

点击复制链接 与好友分享!回本站首页
分享到: 更多
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:2.2.1 Windows内核结构
下一篇:2.2.3 Windows子系统
相关文章
图文推荐
3.4.4 进程生命期管
3.4.2 Windows应用商
3.4.1 Windows应用商
3.4 进程生命期管理
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做最好的IT技术学习网站