Windows驱动开发基础系列,转载请标明出处:http://blog.csdn.net/ikerpeng/article/details/38826159
就32位的计算机来说,他有4G的真实的物理内存。但是这样是不够的,于是引入了虚拟内存的概念。使得每一个进程都有4G的虚拟内存。
虚拟内存实际上就是采用了一种映射的方式。4G的内存实际上被分页。一般来说一个页的大小是4K。也是说它被分为了1M个页。在这么多的页里面,有一部分是对应于物理内存的(可以是多对一的);有一部分是对应于磁盘上的空间,但是这部分的数据会被标记为(Dirty);还有一部分是空的!
没找到太合适的图哈。
虚拟的内存中低2G被称为用户模式地址;高位的2G被称为内核模式地址。所有进程的内核地址映射完全一致,进程切换的时候,只要改变用户模式地址的映射。
Windows驱动程序使用的内存资源非常珍贵,分配内存时要尽量节约。和应用程序一样,局部变量是存放在栈空间中的。但栈空间不会像应用程序那么大,所以驱动程序不适合递归调用或者局部变量是大型数据结构。如果需要大型数据结构,我们可以在堆中申请。
Windows规定有些有些虚拟内存页面是可以交换到文件中的,这类的内存被称为分页内存;反之不能的被称为:非分页内存。
当程序的中断请求在DISPATCH_LEVEL或之上的时候,程序只能使用非分页内存,否则就会出现蓝屏死机。
Windows驱动中使用的链表:
对于单链表,每一个元素中的Next指向下一个元素;对于双链表,每一个元素中有两个指针:BLINK指向前一个元素, FLINK 指向后一个元素. 初始化的时候指向自己。如图所示:
我们看看他的结构体:
<span style="font-family:Microsoft YaHei;font-size:14px;">typedef struct _LIST_ENTRY { struct _LIST_ENTRY *Flink; struct _LIST_ENTRY *Blink; } LIST_ENTRY, *PLIST_ENTRY;</span>
里面没有定义数据,需要程序猿自己定义每一个数据的类型。
例如:
typedef struct _MYDATASTRUCT{
LIST_ENTRY ListEntry;
ULONG x;
ULONG y;
}MYDATASTRUCT,*PMYDATASTRUCT;
在我们对于内存的操作过程中,如果频繁的申请内存,会出现:空洞问题,也就是我们的磁盘碎片。为了避免这个问题,驱动程序中使用Lookaside结构来处理。他就像是一个内存容器,先向Windows申请了一块比较大的内存区域,然后自己可以智能的避免产生空洞的情况。
运行时函数:一般来说是以Rtl开头的,是程序运行时必不可少的。包括:内存间复制(可重叠,不可重叠),填充内存,内存比较等。
本小节完!
参考文献:
《 Windows 驱动开发技术详解 》