Electronic Joint Business

Solution for E-Business

平台开发

为 Windows containers 实现资源控制 (一) 作业对象

Windows 可以按容器或者按资源来实施资源控制。默认情况下, 运行的容器受 Windows 资源管理的约束, 以公平分配为原则, 但通过资源控制,开发人员或管理员可以限制或影响资源的使用。可控制的资源包括: CPU/处理器、内存/RAM、磁盘/存储、和网络/吞吐量等等。

Windows 容器利用作业对象(job objects)来对每个容器相关联的进程进行分组和跟踪。资源控制则在与容器关联的父作业对象上实施。 在 Hyper-V 隔离的情况下,系统同时对虚拟机和在虚拟机中运行的容器的作业对象进行自动资源控制,这样即使容器中运行的进程绕过了或逃脱了作业对象控制,虚拟机也会确保其无法越过定义的资源控制。

作业对象
Windows提供一个作业(job)内核对象,它允许我们将进程组合在一起并创建一个“沙箱”来限制进程能够做什么。作业对象允许将进程组作为一个单元进行管理。作业对象是可命名的(namable)、安全的、共享的对象, 可控制与之关联的进程的属性。对作业对象执行的操作会影响和作业对象相关联的所有进程。比如对工作集大小、进程优先级进行强制限制,或终止与作业关联的所有进程。你可以将作业对象想象成一个进程容器。但是,创建只包含一个进程的作业同样非常有用,因为这样可以对进程施加平时不能施加的限制。

作业对象 VS Linux 控制组 cgroups
Linux 的 cgroups 不等同于 Windows 和 VMS 的作业, 它缺乏作业机制的真正功能。这些年来人们一直在抱怨 Systemd 的这个问题,他们非常期待 cgroups 2.0 能提供真正的作业机制,因为现阶段的 Systemd 存在严重的错误,它无法自动终止控制组中的所有内容。

相反,提供“作业”抽象的操作系统内核一般都会提供了能取消/终止整个“作业”的方法,比如 Windows 的 TerminateJobObject()。而对于 Systemd,当其终止 cgroup 中的所有进程时, 它无法执行类似“终止作业”的系统调用,因为根本不存在这种机制。作为替代,Systemd 在应用模式下的某段循环代码中反复扫描 cgroup 中的所有进程 id,它重读一个 PID 列表文件, 并将信号发送到未列其中的新进程。这会带来几个问题:

>>> 阅读全文

 

, , ,

Linux 内核网络之邻接子系统

当两台或者多台设备通过物理链路连接在一起时候,就构成了网络。多个网络之间还可为了信息交换和服务的目的连接在一起,构成网间网。通信网络中的两台主机要进行通信时,发送方一般都需要知道接收方是哪一个站,以确保每一帧都能正确地送到目的站。接受方也应当知道发送方是哪一个站,以便对消息做出应答。为了确认通信主体,参与通信各方一般都用“地址”来进行标识,地址的本质是一种标识符,用来表示系统中的某一个对象。而同一个系统中不允许有 2 个地址相同的通信主体存在,这就是地址的唯一性。所有的网络都要求某种形式的寻址机制,以识别设备。寻址还可以确定网络本身,或者网络的一个网段(例如子网)。

在计算机通信中,每一层协议的编址方式都不同。1。网络、子网和设备可以由 OSI 参考模型的二、三层协议来确定。硬件寻址在数据链路层(第 2 层)来确定设备。例如以太网是以烧录在网络设备中的唯一识别码作为硬件地址,当网络设备从共享的线路侦听到数据帧时,它负责检出数据帧中的目的地址,并与自己的物理地址进行比较,如二者相符,则接收;否则丢弃。而诸如 IP、IPX 协议则工作在 OSI 协议层的网络层(第 3 层)以确定网络和子网。 网络地址是为了方便寻址人为划分的地址格式,也被称为逻辑地址,也被称为3层地址。

以太网址是一种不包含位置信息的简单标识,它只是对网络设备简单加以区分。这种无位置信息的地址对局域网来说就已经足够。但对于广域网这种复杂无规则,采用点到点连线构成的总体结构,有着庞大的主机数目,使用这种无位置的标识符作为地址就面临着巨大的挑战,无论是采用局域网的广播方式,还是逐一试探,无疑都是开销巨大、笨拙不堪的做法。所以广域网必须采用有结构的地址标识符,不但标识主机,还要指出主机的位置。

之所以存在两种寻址方式,这正是 OSI 参考模型的设计初衷之一:每一层的变化都不会影响到其他层。网络层协议也不用关心物理地址的差异,无论其下一层的物理地址是什么类型,都可以被统一到一致的 IP 地址形式上。而当存在一个附加层的地址寻址时,设备更易于移动。例如以太网交换机可以无需了解具体的网络层协议,无论网络采用 IP 协议还是 IPX 协议,都无需更换一台交换机。

为了标识数据链路层的众多设备,IEEE 为 802 协议族定义了如下的寻址方式:网络设备制造商在生产网络设备时,会为每个硬件分配一个全球唯一码,称为 MAC 地址,并被固化到硬件内部,因此也叫物理地址或硬件地址。当网络设备收到数据帧时,它负责检出数据帧中的目的地址,并与自己的物理地址进行比较,如二者相符,则接收;否则丢弃。

>>> 阅读全文

 

, , ,

Windows 网络驱动设计指南 (一)网络模型

现代计算机网络是由通信线路互相连接的许多自主工作的计算机构成的集合体,其网络通信的过程很复杂:数据以电子信号的形式穿越介质到达正确的计算机,然后转换成最初的形式,以便接收者能够阅读。各个部件之间以何种规则进行通信,就是网络模型研究的问题。现在广泛研究的网络模型一般是 OSI 七层参考模型和 TCP/IP 四层参考模型。本章主要讨论 OSI 七层参考模型。

一、OSI 七层参考模型
为了解决不同体系结构的网络的互联问题,国际标准化组织 ISO (注意不要与 OSI 搞混)于1981年制定了开放系统互连参考模型(Open System Interconnection Reference Model,OSI/RM)。这个模型把网络通信的工作分为 7 层,如图1-1 所示,由低到高分别是:

  • 1.物理层(Physical Layer)
  • 2.数据链路层(Data Link Layer)
  • 3.网络层(Network Layer)
  • 4.传输层(Transport Layer)
  • 5.会话层(Session Layer)
  • 6.表示层(Presentation Layer)
  • 7.应用层(Application Layer)。

模型中的每一层都完成网络传输中的一个独立任务。在发送端,用户数据自上而下经过以上七层的流水线,除了物理层之外,每一层都会在原始数据前添加一串属于自己的协议头,最后形成一串0、1组成的二进制流。然后根据物理介质是光纤、电缆、还是空气,二进制流转化为光信号、电信号、电磁波信号在物理介质(物理层)里传输,经过若干个中继交换机(链路层)的交换、经过若干个中继路由器(网络层)的转发,最终到达数据的终点。在接收端,自然有理解这些协议头的对端,逐层来剥离数据头,并最终将原始数据呈现给用户。数据的封装和解封装如图1-2 和图1-3 所示。

在深入讨论 OSI 各层的职责和功能之前,我们来了解一些常见的网络术语。

二、网络节点和链路
一个网络节点是一个连接点,表示一个再分发点 (redistribution point)或一个通信端点(一些终端设备)。节点的定义根据所提及的网络和协议层的不同而不同。

>>> 阅读全文

 

,

探索 Windows 10 的控制流保护机制

得益于系统漏洞补强技术的持续改进,微软在其 Windows10 和 Windows 8.1 Update 3 中默认启用了一个新机制。其技术被称为控制流保护(Control Flow Guard 简称CFG)。1

与其它漏洞补强机制如地址空间布局随机化(ASLR)或者数据执行保护(DEP)一样,该技术提高了漏洞渗透的难度。无疑,它将引发攻击者渗透技术的改变。正如ALSR 催生了堆喷射技术,DEP 催生了return-oriented-programming 技术。

本文的测试程序是在 Windows 10 RS2 (build 15063) 以及 Visual Studio 2017 上编译的。要完全支持 CFG ,编译器和操作系统都必须被正确设置。由于漏洞渗透机制发生在系统层面,CFG 的实现要求编译器、操作系统用户态类库以及内核模块共同协作。MSDN 上有数篇文章介绍如何一步步启用 CFG. 2

微软 CFG 实现主要集中在对间接调用保护上。

请看下面测试代码:

>>> 阅读全文

 

, ,

为 QEMU 虚拟设备编写 Linux PCI 设备驱动

本文将以 QEMU 的 ivshmem 虚拟设备作为硬件平台,逐步演示如何为其编写 Linux PCI 设备驱动。该驱动通过的测试环境为 QEMU 版本V1.0,主机操作系统 Ubuntu 12.04,客户机(VM)操作系统 Linux v3.x,此外它在 QEMU v1.0.1, v2.2.0 和 v2.7.0-rc4 中也表现良好。例子中所引用的头文件和其他源文件如 drivers/pci/pci.c 是以 Linux 内核源文件的根目录为搜索路径的。如 即意指 include/linux/pci.h。

背景
要特别强调的是虚拟平台不能替代实际的物理硬件。但在演示、培训、实验等场景,虚拟平台就特别适合:配置虚拟硬件则相当便捷,且可提供一个一致的可供使用的硬件平台。而且添加、扩展或者移除虚拟平台组件也十分方便。 1

本文选用的是 InterVM SHared MEMory (ivshmem) 这个 QEMU PCI 设备。选择该设备的原因有很多, 包括设备构造简单,可以在主机上使用代码和它进行交互和测试。主机 SHM 共享内存被映射为客户机的 MMIO 区域,通过模拟的物理设备(ivshmem 设备)的 MMIO 访问,客户机操作系统就可以访问主机上的 POSIX SHM 共享内存。此外 ivshmem 框架还允许其他启用 ivshmem 的客户机 (或主机上的程序) 通过 eventfd (2) 机制将 irq 发送给虚拟机。如图1-1 所示。

由于 ivshmem 不是默认启用的 QEMU PC 字符设备, 因此需要在 QEMU 启动命令行中指定相应的设备选项。要查看所支持的设备的列表, 请运行 (以 X64 为例):

$ qemu-system-x86_64 -device ?

注: 编写 PCI 设备驱动所用的 Linux API 通常可以支持 PCI 族,包括 PCI, PCI-X 和 PCI-E。ivshmem 设备模拟的是 PCI 设备。

>>> 阅读全文

 

, , ,

WDF 驱动程序开发

设备驱动程序是硬件设备连接到计算机系统的软件接口,任何设备都必须有相应的驱动程序才能在计算机系统上正常工作。设备驱动程序的优劣直接关系到整个系统的性能和稳定性,因此,设计和开发稳定高效的驱动程序具有重要意义。

WDF (Windows Driver Foundation) 是微软新一代驱动程序模型,它在 WDM (Windows Driver Model) 的基础上发展而来,支持面向对象、事件驱动的驱动程序开发,提供了比 WDM 更高层次的抽象,是高度灵活、可扩展、可诊断的驱动程序框架。WDF 框架接管了驱动和操作系统内核的大多数交互,驱动和操作系统的交互交给框架内封装的方法(函数)完成,从而对二者进行了隔离,这样驱动开发者只需专注处理硬件的行为即可。另外 WDF 还将大多数驱动中都需要处理的 PnP (即插即用)和电源管理封装进了框架,成为了公用的驱动程序功能。

WDF 可以开发内核模式驱动, 也可以开发用户模式驱动,二者采用同一套对象模型构建,即 WDF。对于内核模式对象和用户模式对象来说,WDF 是它们的父对象。换言之两者都是从 WDF 派生而来的。针对内核模式派生出来的对象称为 KMDF;针对于户模式派生出来的对象称为 UMDF。无论何种模式的框架,其内部封装的方法、执行的行为其实还是用 WDM 来完成的。

本文主要针对 KMDF 框架展开讨论。

KMDF 对象模型
KMDF 驱动程序模型支持面向对象、事件驱动。它定义了一系列的对象用于表示设备、驱动、中断等,每个对象有其相应的属性、方法和事件。驱动程序利用这些方法创建对象、设置属性和响应事件。该框架定义的主要对象有:

>>> 阅读全文

 

, , ,

SPB 设备和驱动简介

现在有许多文章介绍 Windows 8 操作系统层级的功能。其中之一就是支持简单外设总线 (SPB) 连接的设备。SPB 总线具有低成本、低功耗、低速度的特点,经常用于连接如传感器之类的相对简单的外设。Windows 8 支持的 SPB 设备包括 I2C 和 SPI。之前这类设备受到 BIOS 的限制而很少使用。从 Windows 8 开始,支持这些设备则成为了主流。

如果你对 SPB 总线以及如何编写 SPB 设备驱动感兴趣,可以跟随本文1来深入探讨这些话题。

SPB 总线 — 拓扑和设备枚举
和 SCSI、 SATA 和 USB 总线一样,SPB 是协议式(protocol-based ) 总线。也就是说,有一个控制器会根据总线定义的规则使用正确的协议来请求开关总线。连接到协议式总线上的设备被称为客户端设备,简称客户端。如图1-1.

SPB 总线最让人困惑的地方是如何发现和枚举总线上的设备。 SPB 总线无法动态枚举,这意味着在运行时接上 SPB 总线的设备都无法被发现。那么 Windows PnP 过程如何侦测 SPB 客户端的呢?答案很简单:哪个 SPB 设备挂在哪条 SPB 总线,这些描述被静态添加到一个表中,作为 ACPI BIOS 一部分。所以,枚举 SPB 客户端是由 ACPI 驱动而不是 SPB 控制器驱动负责的。SPB 控制器是典型的背板总线(backplane-bus )类型的设备,总被 PCI 总线驱动所枚举。详细可以参考图1-2 和图1-3。

包含该描述的 ACPI 表格被称为差异系统描述符表(Differentiated System Descriptor Table)简称 DSDT。DSDT 通常由系统集成商(一般是 OEM ) 随 ROM 一起提供的。由于 SPB 设备通常都被永久集成在系统平台上 — 大部分被焊在主板上,所以无法动态枚举不会有任何问题。 少数情况下,SPB 设备可能会被动态地接上系统(比如平板电脑的 I2C 键盘),此时设备信息仍由 ACPI BIOS 提供并由 ACPI 驱动枚举。

>>> 阅读全文

 

, , , , ,

Windows 连接管理器和 NCM 驱动

从 Windows 8 开始,微软引入了自动连接管理器,它负责查看系统的网络连接如以太网、Wi-Fi 和移动网络,从中选择最合适的网络并自动连接,同时断开其他连接。(注:Windows 会响应以太网,但不会自动管理其连接。另外:拨号上网或者虚拟网络接口如 VPN 不在其管理范围中)。1

连接管理器策略
Windows 内置了许多策略来控制连接管理器,Windows 并未提供用户界面来查看这些策略,但可利用 WcmSetProperty API 或组策略来进行配置。这些策略包括:

最少并发连接数
该策略在 Windows 8 或 8.1 中是默认打开的。如果禁用该策略,操作系统行为将与 Windows 7 类似:每个网络接口都选择其所辖的首选网络,而不管其他接口的连接状态。

如果启动该策略,Windows 会尝试用最小并发连接来提供最佳的可用网络,Windows 将保持下列连接:

  • 任何以太网
  • 当前用户会话中手动连接的任何网络
  • 连接到 Internet 的首选连接
  • 连接到活动目录域的首选网络(入域的机器)

其他的所有网络则被“软”断开,有关“软”断开请见下一节。这也用于评估未被连接的可用网络。Windows will not connect to a new network from which it would immediately soft-disconnect.

>>> 阅读全文

 

,

X64 寄存器、栈帧和汇编

多年以来人们一直使用 X86 汇编编写性能关键代码。随着 32位 CPU 逐渐被 64 位处理器取代,底层汇编代码也随之发生变化。本文将简单介绍 X64 汇编一些相关知识。了解 X86 汇编虽然有助于了解这种过渡,不过不是必要前提。http://www.ejb.cc/wp-admin/profile.php

X64 泛指 Intel/AMD 的 32 位 X86 指令集架构 (ISA) 的 64 位扩展。AMD 率先推出了第一代 X64 指令集。即 X86-64,后来被命名为 AMD64。Intel 的实现称为 IA-32e ,后来又改为 EMT64。这两个版本大致相同,只在一些细微处略有不兼容。详细可以参考 《Intel® 64 and IA-32 Architectures Software Developer’s Manuals》 和 《AMD64 Architecture Tech Docs》。本文中将其统称为 X64 ,以区分 Intel 64 位安腾架构 IA-64。

本文将不涉及缓存、分支预测等等与硬件相关的内容,如果读者感兴趣,可以参考本文列出的一些参考文章。1

汇编常被用来编写程序性能关键部分,虽然大部分程序员还是宁可选择好的 C++ 编译器。掌握汇编对代码调试十分有用,有时候编译器会产生错误的汇编代码,通过调试器单步执行代码可以有助于了解错误的原因;代码优化有时也会产生错误。如果手边没有源代码,你还可以通过汇编/反汇编来了解或修正手边的程序;此外如果你想深入了解语言的内部机制,比如方法 A为什么比方法 B 速度快,这时候汇编就十分必要;最后,在诊断恶意代码时,汇编也不可或缺。

架构
要学习平台汇编,首先就得了解寄存器集。

>>> 阅读全文

 

, ,

Linux和Windows设备驱动架构比较

本文将带你了解广泛使用的 Windows 和 Linux 操作系统的设备驱动架构的差异。文章将首先比较这两个平台上实现设备驱动所需的组件,然后讨论实现驱动程序的过程,包括如何对内核缓冲区执行 I/O 操作等等。最后我们还将了解这两个操作系统所提供的开发环境和基础工具。1

1.引言
现代操作系统一般都包含多个模块,如内存管理器、进程调度器、硬件抽象层和安全管理器等等。这里提供一些参考资料以方便你进一步了解这两种操作系统的内核:关于 Windows 内核的细节,可翻阅 Russinovich 著的《Windows Internal》一书;而 Linux 内核则可以参考 Rusling 的《The Linux Kernel》或者 Beck et al 等合著的《Linux Kernel Internal》。内核可被视为一个黑盒,它知道如何去和市面现有的或将要推出的各种设备交互。能否让内核内建就支持所有市面上的已知设备呢?这是有可能实现的,但没有实际意义,因为这会无谓地消耗过多的系统资源。

1.1. 内核模块化
内核无法在创建伊始就预见到要如何与尚未面世的新设备交互。现代操作系统的内核允许在运行时添加设备驱动模块来扩展系统功能,该模块实现的功能使得内核可以与特定的某种新设备交互。这些模块通常都会实现一个例程供内核在加载模块时调用,此外还有一个例程供移除模块时调用。模块还会实现其他各种不同的例程以便实现 I/O 功能,如将数据传送到设备或从设备接收数据;同时还有例程以便向设备发送 I/O 控制指令。这些对 Linux 和 Windows 两种驱动架构均适用。

1.2. 本文的组织结构
本论文分成下面几节:

  • 对两种驱动架构的一般介绍 (第二节)
  • 详细论述两种驱动架构的各个组件 (第三节)
  • 驱动程序范例,包括如何对内核缓冲区执行 I/O 操作(第四节)
  • 相关驱动开发环境和基础工具(第五节)

1.3. 相关著作
有关 Windows 设备驱动架构相关文档可在 Windows 驱动开发包(DDK)中找到. 此外 Walter Oney 和 Chris Cant 在 《Writing Windows WDM Device Drivers》一书中对 Windows 驱动架构进行了详细介绍。Linux 设备驱动架构可以参考 Rubini 的《Linux Device Drivers》,该书可免费获取。

>>> 阅读全文

 

, , , , ,

理解 ACPI (一) ACPI 简介及加电过程

在引入高级配置和电源接口 (ACPI — Advanced Configuration and Power Interface) 之前, 高级电源管理 (APM) BIOS 被广泛用于电源管理。在 APM 中,大部分的电源管理控制逻辑都驻留在 APM BIOS 代码中。支持 APM 的操作系统通过固定的 BIOS API 与 APM BIOS 进行通信,这些 API 提供了 BIOS 功能的基本访问。支持 APM 的操作系统必须定期轮询 APM 以处理 APM 相关事件。

APM 存在着以下三个缺陷: 首先,除非供应商提供专有程序,否则很多 APM 功能都要在操作系统启动前,进入 BIOS 菜单来配置,比如设置显示器关闭前的空闲时间。而且 APM 电源管理配置的具体策略是由 BIOS 供应商设定的,比如某 APM BIOS 的策略是在关闭显示器的同时降低 CPU 时钟频率或休眠网卡等设备,如果不想这么做,就必须修改 BIOS。 其次,APM 是 BIOS 级别的代码,运行在操作系统之外,因此开发和调试 APM 代码都十分困难,更糟糕的是用户只能通过重刷 ROM 的方式来解决 APM 的错误,而重刷 BIOS 相当危险,一旦发生错误,系统就再无法启动了。最后,由于 APM 是各个供应商专有的,为相同的功能而进行的重复开发投入是种巨大浪费。

不同于 APM 直接基于 BIOS 的管理方式,ACPI 中不再由 BIOS 代码来作出决策,而是通过操作系统内核来统一管理所有设备,从而解决了 APM 配置机制的局限性,换句话说,ACPI 允许操作系统直接对电源和散热进行管理,还允许系统硬件产生的 Hot-Plug 事件,让操作系统从用户的角度上直接支配即插即用设备。因而 ACPI 比其他机制更加灵活。

ACPI 主要提供下列功能:1

  • 系统电源管理(System power management):ACPI 提供了让系统作为一个整体进入或离开睡眠状态的机制,让设备唤醒系统。
  • 设备电源管理(Device power management):ACPI 表描述了电源信息(包括主板设备、设备电源状态以及设备所连接的电源层– Power Planes) 和让设备进入低功耗状态的控制信息,这样操作系统就可根据资源占用来控制设备进入低功耗状态。
  • 处理器电源管理(Processor power management):当操作系统处于空闲且非睡眠状态,可以通过 ACPI 提供的命令让处理器进入低功耗状态。
  • 设备和处理器性能管理(Device and processor performance management):操作系统在工作时可以根据 ACPI 的定义,让设备和处理器进入不同的性能状态
  • 配置/即插即用(Configuration/Plug and Play):ACPI 指定了用来枚举和配置主板设备的信息,这些信息按层次结构排列,当发生诸如 docking/undocking 之类的事件时,操作系统就可准确知道该事件影响了哪个设备。
  • 系统事件(System Event): ACPI 提供了通用的事件机制操作用于处理如散热、电源管理、坞站或设备的插拔等事件。
  • 电池管理(Battery management):兼容 ACPI 的电池设备需要具有智能电池子系统接口(Smart Battery subsystem interface)或者控制型电池接口(Control Method Battery interface),前者通过嵌入式控制器的接口控制,后者则完全由 AML 控制方法进行操控。
  • 温度管理(Thermal management):ACPI 允许 OEM 自由定义散热温度区间。
  • 嵌入式控制器(Embedded Controller):ACPI 提供了标准接口让操作系统和嵌入式控制器进行通讯。
  • SMBus 控制器(SMBus Controller): ACPI 提供了标准接口让操作系统和 SMBus 进行通讯。

当然为此操作系统内核中要添加额外的 ACPI 支持。支持 ACPI 的操作系统就可以叫做 OSPM (Operating System-directed configuration and Power Management) 。 支持 OSPM 的至少要求实现:

>>> 阅读全文

 

, , , ,

Windows CSRSS 详解 (1) 基础概念

微软之所以引入 “Windows 环境子系统” 这一概念,其理念是为了用户程序提供一个严格定义的原生函数子集。这是因为 Windows 操作系统被设计成同时支持原生 Windows 和 POSIX 类型的可执行程序(在 Windows 10 Red Stone 中还新添加了 Windows Subsystem for Linux 子系统),因此对于每一类应用,开发者必须区隔其所调用的 API。每个环境子系统通常包含两个主要部分:1

  • 子系统进程:一个正常的 ring-3 级应用程序,负责处理某些子系统特定的功能。
  • 子系统 DLL: 特定子系统专用的系统类库集,是额外添加在用户程序与原生系统调用间的调用层。

事实上 Windows 子系统 — — 也称为 CSRSS (客户端/服务器运行时子系统 Client/Server Runtime Subsystem) 是系统强制的执行环境,换句话说,如果没有没有 CSRSS.exe 在后台运行, Windows 不能正确工作。由于 CSRSS 所绑定的职责,该子系统对每个 Windows 都是必须的,包括服务器版本 (它可以不处理交互式用户会话)。另一方面,POSIX (psxss.exe) 和 Windows Subsystem for Linux 属于可选子系统 — — 因此,只在需要才启动相关进程。

子系统的启动信息被保存在注册表键 HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems 下面。默认的启动信息配置如下:

  • 名称: Debug 类型: REG_EXPAND_SZ 数据:
  • 名称: Kmode 类型: REG_EXPAND_SZ 数据: \SystemRoot\System32\win32k.sys
  • 名称: Optional 类型: REG_MULTI_SZ 数据: Posix
  • 名称: Posix 类型: REG_EXPAND_SZ 数据: %SystemRoot%\system32\psxss.exe
  • 名称: Required 类型: REG_MULTI_SZ 数据: Debug Windows
  • 名称: Windows 类型: REG_EXPAND_SZ 数据: %SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,20480,768 Windows=On ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ServerDll=sxssrv,4 ProfileC

大多数人对支持 Windows API 的子系统 DLL 都有所耳闻 — 即 kernel32.dll、 user32.dll、 gdi32.dll、 advapi32.dll 等等,无数的 Windows 软件开发者在日常工作中都会用到它们。而对于 POSIX 子系统来说,只需用到 psxdll.dll 这一个模块就可以实现所需的 Unix API。

此外,每一个进程都会与某个特定的子系统关联,该属性是由链接器在编译过程中设置的,并保存在 PE 结构的相关字段中:

>>> 阅读全文

 

, ,

CPU C-State 详解

如果你对计算机电源管理方面有所了解,一定会接触到 S-States、C-States 和 P-States 这三种工作状态。其中S-States (Sleeping states)指系统睡眠状态 ,由 ACPI 规定,C-States(CPU Power state) 则是 CPU 电源状态,而 P-States (CPU Performance states) 则指 CPU 性能状态。当然除了这三种外,还有 G-States(全局状态)和 D-States (设备状态)。

S-States 很好理解,就是用户手动点击“睡眠”,或者达到一定的待机时间(由系统电源管理设置而定)进入睡眠状态,S0 就是指正常运作。而 C-States 和P-States 看起来也很类似,都会调节处理器的核心电压、电流以及频率,因此经常被混淆。我们通过图1-1 来梳理一下上面这三种状态的关系。

S-States 中的 S0 指非睡眠状态,即系统正常运作状态或待机状态(idle)。只有在 S0 状态下,C-States 才会存在。同样的,C0 代表 CPU 正常工作状态,而P-States 正是处理器正常运作时的状态,所以 P-States 只存在于 C0 状态下。

因此简单来说,P-States 是根据系统的负载情况调节处理器核心电压和频率,处理器仍在运作当中;而 C-States 则是改变处理器各个部分的状态,包括核心、缓存、总线以及各种后来集成进来的模块,此时处理器应该是处于工作或待机状态。我们日常使用电脑的时候,系统就是频繁地在这些状态下切换,以达到提高续航和降低功耗的目的。1

C-States 的 11 个工作状态
目前 C-States 有以下这11个状态:

>>> 阅读全文

 

, ,

Windows 驱动开发 <1> 理解 Windows 驱动的执行上下文

要理解 Windows 内核驱动,很重要的是要了解一个驱动函数是在哪一种”上下文”中执行的。如果你从事文件系统的开发、或 Windows 内核驱动的编写,透彻理解执行上下文将使你获益匪浅。了解上下文并小心使用,可以让你设计出高性能、低开销的内核驱动。

本文将探讨执行上下文的概念。在文章末尾,沃恩还会介绍一个驱动作为概念演示,该驱动可以允许用户态程序运行在内核模式中,因此拥有内核模式的所有权限与特权。此外,我们还将讨论设备驱动程序的执行上下文及其实际用途。1

什么是上下文
当提到某个例程的上下文时,其实指的是它的线程和进程执行环境。在 Windows NT 中,该环境是由当前的 TEB (Thread Environment Block) 和 PEB (Processes Environment Block) 所建立的。因此,上下文中将包括虚拟内存配置 ( virtual memory settings — 用于说明物理内存页与虚拟内存地址的对应关系) 、句柄对照表 (handle translations, 因为句柄是特定于进程的)、分发器信息( dispatcher information)、栈(stacks) 、通用和浮点寄存器集等内容。

如果我们问“某个内核例程所运行的上下文是什么”,实际上的问题是“内核分发器所建立的当前线程是什么”。由于每个线程仅可属于一个进程,所以当前线程同时也就意味着某个当前进程。当前线程和当前进程合在一起,就意味着我们前面提到的句柄、虚拟内存、调度状态等等,这些东西使得线程和进程具有唯一性。

对于内核驱动程序员来说, 上下文中最有用的也许就是虚拟内存上下文。如果你还记得 Windows 将用户进程空间映射到低 2GB 的虚拟内存地址中,而操作系统代码则被映射到高 2GB 虚拟内存空间中。当用户进程中的某个线程被执行时,其虚拟地址将位于 0~2GB 的范围中。所有高于 2GB 的地址都被设置为“不可访问”,以防用户直接访问操作系统的代码和数据结构。当操作系统代码被执行时,其虚拟地址范围是 2~4GB。

>>> 阅读全文

 

,

USB 协议详解之一 基础知识

在 USB 出现前,计算机上就已经存在众多接口标准,比如串口、并口、PS2 等等,各接口从硬件形状和软件设置都不兼容,因此 USB 的设计目标之一,就是希望通过它方便地实现设备之间的互联。从而解决接口标准太多的弊端,这也是 USB 中的 Universal 一词的含义。

USB 使用一个 4 针的标准插头,采用菊花瓣形式把所有外设连接起来,它使用串行方式传输数据,支持多数据流和多个设备并行操作并允许外设热插拔。

基础知识
从物理结构上,USB 系统是一个分层的星形结构,它包含三类硬件设备:主机(HOST)、 设备(DEVICE)和集线器(HUB)。处于每个星形拓扑中央的是集线器,而在主机与集线器之间,集线器与集线器之间,集线器与设备之间都是点对点连接。1

各个设备在系统中的作用如下:

  • USB 主机 的主要作用包括: 提供电源,同时进行节电管理;检测设备,包括设备的接入与断开;管理数据传输,包括控制流和数据流;发送配置请求对 USB 设备进行配置操作;对总线上的错误进行管理和恢复等等。
  • USB 设备:在一个 USB 系统中,设备和集线器的总数不能超过 127 个。USB 设备接收 USB 总线上所有数据包,通过数据包的地址域来判断是不是发给自己的数据包:若地址不符,则简单地丢弃该数据包;若地址相符,则通过响应主机的数据包来和 USB 主机进行数据传输。
  • USB 集线器:集线器用于设备扩展连接,所有 USB 设备都连接在 USB 集线器的端口上。一个 USB 主机总与一个根集线器 (USB ROOT HUB)相连。USB 集线器为其每个端口提供 100mA 电流供设备使用。同时,USB 集线器可以通过端口的电气变化来判断出设备的插拔操作,并通过响应 USB 主机的数据包把端口状态汇报给主机。一般来说,USB 设备与USB 集线器间的连线长度不能超过 5米,USB 系统的级联不能超过5层(包括ROOT HUB)。

USB 功能
USB 是一种串行接口协议,它依靠 D+/D- 两条数据线构成的差分线来进行数据传输,这和我们熟悉两线 RS232/485 协议有何区别呢?了解这种区别有助于深入理解 USB 。所以首先让我们回想一下 RS232 的数据是如何传送的,如图1-2:

>>> 阅读全文

 

, ,

Previous Posts