Enterprise Just Builder

Solution for Enterprise Software Architecture

unix

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》,该书可免费获取。

>>> 阅读全文

 

, , , , ,

并行程序中的同步与通讯

在任何程序中,总会有些执行阶段要等待操作系统或者其他进程完成 I/O 操作或者同步操作。这时候,程序就无法处理其它工作,因为实际上是操作系统或者其它进程占用了宝贵的 CPU 时间。这就是滥用文件读/写操作的程序会如此之慢的原因。1

这时候进程不得不等待操作系统服务例程将 CPU 从其他进程那里释放出来。这种等待也被称为进程处于阻塞状态。诸如 EDA 这类串行计算,整个算法作为单个任务被执行,如果该进程在等待任一种阻塞操作,整个算法就会完全停顿。在处于阻塞状态的这段时间里,另一个进程占用了 CPU 的所有权,所以算法根本没办法进行。

并行程序提供了一种手段,能在同一计算中调用另一个进程以提高 CPU 利用率,当一个进程被阻塞的时候(如等待 I/O 操作或者同步操作),另一个进程则继续处理共同工作的其它部分。这种情况在单 CPU 或者多 CPU 机器上皆可发生。

反之,对于串行程序(即非并行算法)来说,而无论有多少可用的 CPU ,在任何情况下都只能用到单个 CPU。除非有编译器将源程序从串行转成并行,不过能实现这一目标的实属特例。 因此如果想同时利用多个 CPU ,编码时要手工运用某种并行技术。(在源代码中采用特殊指令,如 OpenMP)。

并行程序能将工作划分为较小的部分,因此多个进程可以一起工作并互相协作以便能在更短的时间内计算出同样的结果。这时,在等待 I/O 设备完成操作的同时,并行程序能可以继续处理另一部分工作。此外,并行程序还可以同时使用系统所有可用的 CPU。

>>> 阅读全文

 

, , , , , , ,

Flex 和 Bison 简介(一)

文章评价:
我手边有个项目需要编写个对话框编辑器,该编辑器能够加载对话框模板,然后显示出相应的对话框。

实现该设计有简单的办法,也有比较困难的办法。简单的做法只需将资源脚本编译成 .res 文件,就能得到编译过的模板。然后让程序访问这些 .res 文件,由此得到对话框模板的句柄,并传递给 CreateDialogIndirect 函数。这样就可以用代码来检查每个控件的属性。但这种方式要求一旦修改某个模板之后就必须重新编译资源脚本,否则将导致严重的逻辑错误。

为此,我舍易求难,选择了较为困难的方法:实现一个能读取 Visual Studio6 资源文件 (.rc 文件)的解析器,然后返回一系列编译过的对话框模板。

具体要如何实现呢?如果你曾看资源模板文件的源文件,你会发现自己一个人从零开始实现这样一个解析器基本是不可能的。资源文件包含许多文本块,其中有注释、工具栏资源、菜单、对话框等等。每种文本块都有固定的格式。要用面向过程的方法来编写能够解析这些文本块的程序,要解决的问题实在太多了。还好我们有 Flex 和 Bison 可以提供帮助。

什么是 Flex 和 Bison?
既然提到 Flex 和 Bison 就不能不说到其前身 Yacc 和 Lex 。Yacc 和 Lex 起源于 UNIX 世界。Yacc 是 “yet another compiler compiler” 的缩写,而 Lex 则是 ‘lexical analyser’ 的简称。光了解这些名称就已经说明了很多问题 !你可以参阅 compilertools 站点 ,该站点提供了适合不同水平用户的范例,而且还有很详细的说明和解释。

>>> 阅读全文

 

, , , , ,

Linux与Windows进程之比较

进程是现代操作系统的一个最基本的概念。书本上说:进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。它不只是程序的代码,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表示。

详细点说:进程的概念主要有两点:

第一,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。

第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们称其为进程。

在Unix系统中,我们通常用 fork 来创建一个进程,相应的,在 Windows 操作系统里,我们用的是 CreateProcess,如果我们分别用 fork 和 CreateProcess 反复创建1000个进程,你可能会得出 Windows 创建进程比在 Unix 慢许多这样一个结论。然而这是事实吗?

>>> 阅读全文

 

,

详解GNU Make (二) 高级用法

在上一篇文章中,我们了解了 makefile 的基本结构和一些常见用法,在这篇文章中我们会更深入地了解一些“高级用法”,这些用法在实际的例子中相当常见,可以极大地提高 makefile 的编写效率。

Makefile 里有什么?
Makefile 里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。

  • 显式规则。显式规则说明了如何生成一个或多的的目标文件。这是由 Makefile 的编写者显示地指出:要生成的文件、文件的依赖文件和生成命令。
  • 隐晦规则。由于 make 有自动推导的功能,所以隐晦规则可以让编写者比较简略地编写 Makefile,这是 make 所支持的。
  • 变量定义。在 Makefile 中我们可以定义一系列的变量,变量一般都是字符串,有点 C 语言中的宏,当 Makefile 被执行时,其中的变量都会被扩展到相应的引用位置上。
  • 文件指示。其包括了三个部分:一是在 Makefile 中引用另一个 Makefile,类似 C 语言中的 #include;二是指根据某些情况指定 Makefile 中的有效部分,类似 C 语言中的条件编译 #if ;三是定义多行的命令。有关这一部分的内容,我会在后续的部分中讲述。
  • 注释。Makefile 中只有行注释,和 UNIX 的 Shell 脚本一样,其注释是用“#”字符, 类似 C/C++ 中的“//”。如果要在 Makefile 中使用“#”字符,可以用反斜杆进行转义:“\#”。

最后要注意的是,在 Makefile 中的命令,必须要以 Tab 键开始。

Makefile 的文件名

默认的情况下,make 命令会在当前目录下按顺序找寻文件名为 “GNUmakefile”、“makefile”、“Makefile” 的文件,找到了就解释这个文件。在这三个文件名中,最好使用 “Makefile” 这个文件名,因为,这个文件名第一个字符为大写比较显目。最好不要用 “GNUmakefile”,这个文件是 GNU 的 make 识别的。有另外一些 make 只对全小写的 “makefile” 文件名敏感,但是基本上大多数的 make 都支持 “makefile” 和 “Makefile” 这两种默认文件名。

>>> 阅读全文

 

, , , , , ,