日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

47、Windows驱动程序模型笔记(五),内存管理

發(fā)布時(shí)間:2024/4/17 windows 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 47、Windows驱动程序模型笔记(五),内存管理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

內(nèi)存管理<?xml:namespace prefix = o />

1)內(nèi)核模式與用戶模式地址

圖示 地址空間中用戶模式部分和內(nèi)核模式部分

??? 每個(gè)用戶模式進(jìn)程都有自己的地址上下文,它把用戶模式的虛擬地址映射成一組唯一的物理頁(yè)幀。這意味著,當(dāng)Windows NT調(diào)度器把控制從一個(gè)進(jìn)程的當(dāng)前線程切換到另一個(gè)進(jìn)程的某個(gè)線程時(shí),與進(jìn)程相對(duì)應(yīng)的虛擬地址空間也被更換。線程切換的一個(gè)步驟就是改變處理器當(dāng)前使用的頁(yè)表,以便它能引用新線程的進(jìn)程上下文。

??? 在編寫(xiě)驅(qū)動(dòng)程序時(shí)我們要遵守下面原則:

??? 決不(或幾乎從不)直接引用用戶模式的內(nèi)存地址,無(wú)論何時(shí)我們需要訪問(wèn)計(jì)算機(jī)內(nèi)存,都要使用內(nèi)核模式的虛擬地址。

2)頁(yè)大小

??? 在虛擬內(nèi)存系統(tǒng)中,操作系統(tǒng)以固定大小的頁(yè)幀組織物理內(nèi)存和交換文件。在WDM驅(qū)動(dòng)程序中,常量PAGE_SIZE指出頁(yè)的大小。在某些Windows NT計(jì)算機(jī)中,一頁(yè)有4096字節(jié);在另一些計(jì)算機(jī)中,一頁(yè)有8192字節(jié)。有一個(gè)相關(guān)常量PAGE_SHIFT,你可以從下面語(yǔ)句中看出它的值:

PAGE_SIZE == 1 << PAGE_SHIFT

下面預(yù)處理宏可以簡(jiǎn)化頁(yè)大小的使用:

?ROUND_TO_PAGES 把指定值舍入為下一個(gè)頁(yè)邊界。例如,在4KB頁(yè)的計(jì)算機(jī)上,ROUND_TO_PAGES(1)的結(jié)果為4096,ROUND_TO_PAGES(4097)的結(jié)果為8192。

?BYTES_TO_PAGES 得出給定的字節(jié)量需要多少頁(yè)來(lái)保存。例如,BYTES_TO_PAGES(42)在所有平臺(tái)上都等于1,而B(niǎo)YTES_TO_PAGES(5000)在4KB頁(yè)的平臺(tái)上為2,在8KB頁(yè)的平臺(tái)上為1。

?BYTE_OFFSET 返回虛擬地址的字節(jié)偏移部分。例如,在4KB頁(yè)的計(jì)算機(jī)上,BYTE_OFFSET(0x12345678)的結(jié)果為0x678。

?PAGE_ALIGN 把虛擬地址舍向上一個(gè)頁(yè)邊界。例如,在4KB頁(yè)的計(jì)算機(jī)上,PAGE_ALIGN(0x12345678)的結(jié)果為0x12345000。

?ADDRESS_AND_SIZE_TO_SPAN_PAGES 返回從指定虛擬地址開(kāi)始的指定字節(jié)數(shù)所跨過(guò)的頁(yè)數(shù)。例如,在4KB的計(jì)算機(jī)上, ADDRESS_AND_SIZE_TO_SPAN_PAGES(0x12345FFF,2)的結(jié)果為2,因?yàn)檫@兩個(gè)字節(jié)跨過(guò)了頁(yè)邊界。

3)Windows NT把內(nèi)核模式地址空間分成分頁(yè)內(nèi)存池和非分頁(yè)內(nèi)存池。(用戶模式地址空間總是分頁(yè)的) 必須駐留的代碼和數(shù)據(jù)放在非分頁(yè)池;不必常駐的代碼和數(shù)據(jù)放在分頁(yè)池中。

執(zhí)行在高于或等于DISPATCH_LEVEL級(jí)的代碼不可以引發(fā)頁(yè)故障。

#ifdef ALLOC_DATA_PRAGMA

#pragma data_seg("PAGE")

#endif

data_seg編譯指示使所有在其后聲明的靜態(tài)數(shù)據(jù)變量進(jìn)入分頁(yè)池。這個(gè)編譯指示與alloc_text完全不同。一個(gè)分頁(yè)段可以從#pragma data_seg("PAGE")出現(xiàn)的地方開(kāi)始到#pragma data_seg()出現(xiàn)的地方結(jié)束。而Alloc_text僅應(yīng)用于單個(gè)函數(shù)。

??? 為了檢測(cè)編譯器是否是Microsoft的編譯器,可以測(cè)試預(yù)定義宏_MSC_VER是否存在。

掉電期間是釋放鎖定內(nèi)存頁(yè)的最佳時(shí)期。

服務(wù)函數(shù)

描述

MmLockPagableCodeSection

鎖定含有給定地址的代碼段

MmLockPagableDataSection

鎖定含有給定地址的數(shù)據(jù)段

MmLockPagableSectionByHandle

用MmLockPagableCodeSection返回的句柄鎖定代碼段(僅用于Windows 2000)

MmPageEntireDriver

解鎖所有屬于某驅(qū)動(dòng)程序的頁(yè)

MmResetDriverPaging

恢復(fù)整個(gè)驅(qū)動(dòng)程序的編譯時(shí)分頁(yè)屬性

MmUnlockPagableImageSection

為一個(gè)鎖定代碼段或數(shù)據(jù)段解鎖

服務(wù)函數(shù)或宏

描述

PushEntryList

向鏈表頂加入元素

PopEntryList

刪除最上面的元素

4)把C/C++編程規(guī)范引入驅(qū)動(dòng)編程中

如RemoveHeadList是一個(gè)宏,如果if語(yǔ)句中不用{},則出問(wèn)題。

5)圖示顯示了 lookaside鏈表的概念。假設(shè)有一個(gè)可以在水池中直上直下平衡的玻璃杯子。這個(gè)杯子就代表lookaside鏈表對(duì)象。當(dāng)初始化該對(duì)象時(shí),你告訴系 統(tǒng)需要多大的內(nèi)存塊(杯中的水滴)。在早期版本的Windows NT中,你還要指出杯子的容量,但現(xiàn)在的操作系統(tǒng)可以自動(dòng)適應(yīng)。為了滿足一個(gè)內(nèi)存分配請(qǐng)求,系統(tǒng)首先嘗試著從鏈表中取出(刪除)一塊內(nèi)存(從杯子中取出一 滴水)。如果連一塊內(nèi)存也沒(méi)有,系統(tǒng)就從外面內(nèi)存池中取。相反,釋放內(nèi)存時(shí),系統(tǒng)首先嘗試著放到鏈表上(向杯子中加入一滴水)。但是,如果鏈表滿了,那么 這個(gè)內(nèi)存塊就返回到外界的內(nèi)存池中(杯子中的水溢出到水池)。

圖示. Lookaside鏈表

4、字符串

String Manipulation

http://msdn.microsoft.com/en-us/library/ee479680.aspx

Buffer Manipulation

http://msdn.microsoft.com/en-us/library/ee479504.aspx

P89串處理函數(shù)

操作

ANSI串函數(shù)

Unicode串函數(shù)

Length

strlen

wcslen

Concatenate

strcat, strncat

wcscat, wcsncat,

RtlAppendUnicodeStringToString,

RtlAppendUnicodeToString

Copy

strcpy, strncpy,

RtlCopyString

wcscpy, wcsncpy,

RtlCopyUnicodeString

Reverse

_strrev

_wcsrev

Compare

strcmp, strncmp,

_stricmp, _strnicmp,

RtlCompareString,

RtlEqualString

wcscmp, wcsncmp, _wcsicmp,

_wcsnicmp,

RtlCompareUnicodeString,

RtlEqualUnicodeString,

RtlPrefixUnicodeString

Initialize

_strset, _strnset,

RtlInitAnsiString,

RtlInitString

_wcsnset, RtlInitUnicodeString

Search

strchr, strrchr, strspn,

strstr

wcschr, wcsrchr, wcsspn, wcsstr

Upper/lowercase

_strlwr, _strupr,

RtlUpperString

_wcslwr, _wcsupr,

RtlUpcaseUnicodeString

Character

isdigit, islower, isprint,

isspace, isupper, isxdigit,

tolower, toupper,

RtlUpperChar

towlower, towupper,

RtlUpcaseUnicodeChar

Format

sprintf, vsprintf, _snprintf,

_vsnprintf

swprintf, _snwprintf

String conversion

atoi, atol, _itoa

_itow, RtlIntegerToUnicodeString,

RtlUnicodeStringToInteger

Type conversion

RtlAnsiStringToUnicodeS

ize, RtlAnsiStringToUnicodeS

tring

RtlUnicodeStringToAnsiString

Memory release

RtlFreeAnsiString

RtlFreeUnicodeString

1)處理blob數(shù)據(jù)的服務(wù)函數(shù)

. 處理blob數(shù)據(jù)的服務(wù)函數(shù)

服務(wù)函數(shù)或宏

描述

memchr

blob中尋找一個(gè)字節(jié)

memcpy, RtlCopyBytes, RtlCopyMemory

復(fù)制字節(jié),不允許重疊

memmove, RtlMoveMemory

復(fù)制字節(jié),允許重疊

memset, RtlFillBytes, RtlFillMemory

用給定的值填充blob

memcmp, RtlCompareMemory, RtlEqualMemory

比較兩個(gè)blob

memset, RtlZeroBytes, RtlZeroMemory

blob清零

?內(nèi)存的“copy”和“move”操作之間的區(qū)別在于可否容忍源和目的相重疊。move操作不管源和目的是否重疊。而copy操作在源和目的有任何重疊時(shí)不工作。

?“byte” 操作和“memory”操作的區(qū)別是操作的間隔尺寸。byte操作保證按字節(jié)為單位執(zhí)行。而memory操作可以在內(nèi)部使用更大的塊,所有這些塊的和等于 指定的字節(jié)數(shù)。這個(gè)區(qū)別會(huì)根據(jù)平臺(tái)的不同而改變,在32位Intel計(jì)算機(jī)上,byte操作實(shí)際上是對(duì)應(yīng)memory操作的宏。但在Alpha平臺(tái) 上,RtlCopyBytes與RtlCopyMemory是完全不同的函數(shù)。

5、注冊(cè)表

服務(wù)函數(shù)

描述

IoOpenDeviceRegistryKey

打開(kāi)PDO專用鍵

IoOpenDeviceInterfaceRegistryKey

打開(kāi)與注冊(cè)設(shè)備接口相連的鍵

RtlDeleteRegistryValue

刪除一個(gè)注冊(cè)表值

RtlQueryRegistryValues

從注冊(cè)表中讀取多個(gè)值

RtlWriteRegistryValue

向注冊(cè)表寫(xiě)一個(gè)值

ZwClose

關(guān)閉注冊(cè)表鍵句柄

ZwCreateKey

創(chuàng)建一個(gè)注冊(cè)表鍵

ZwDeleteKey

刪除一個(gè)注冊(cè)表鍵

ZwEnumerateKey

枚舉子鍵

ZwEnumerateValueKey

枚舉某注冊(cè)表鍵中的值

ZwFlushKey

把注冊(cè)表更改提交到磁盤(pán)

ZwOpenKey

打開(kāi)一個(gè)注冊(cè)表鍵

ZwQueryKey

取關(guān)于某注冊(cè)表鍵的信息

ZwQueryValueKey

取某個(gè)注冊(cè)表鍵中的值

ZwSetValueKey

置某個(gè)注冊(cè)表鍵中的值

表示. 注冊(cè)表訪問(wèn)函數(shù)

6、浮點(diǎn)數(shù)

??? 在Intel處理器上,浮點(diǎn)協(xié)處理器還可以執(zhí)行MMX指令。在歷史上,驅(qū)動(dòng)程序在執(zhí)行浮點(diǎn)運(yùn)算上有兩個(gè)問(wèn)題。對(duì)于沒(méi)有浮點(diǎn)協(xié)處理器的計(jì)算機(jī),操作系統(tǒng)將用 軟件仿真一個(gè),但是仿真的浮點(diǎn)協(xié)處理器會(huì)消耗很大的CPU處理能力,并且需要一個(gè)處理器異常來(lái)捕捉浮點(diǎn)指令。在內(nèi)核模式中處理異常,尤其是在提升的 IRQL級(jí)上,是困難的。另外,在有浮點(diǎn)協(xié)處理器的計(jì)算機(jī)上,由于CPU結(jié)構(gòu)上的原因,當(dāng)線程上下文切換時(shí),需要一個(gè)耗時(shí)的操作來(lái)保存和恢復(fù)浮點(diǎn)協(xié)處理器 的狀態(tài)。所以,通常的做法是禁止在內(nèi)核模式驅(qū)動(dòng)程序中使用浮點(diǎn)運(yùn)算。

??? Microsoft建議,除非必要,應(yīng)避免在內(nèi)核模式驅(qū)動(dòng)程序中使用浮點(diǎn)運(yùn)算。

關(guān)于如何使用及更多信息,可以參見(jiàn)《Windows驅(qū)動(dòng)程序模型設(shè)計(jì)》,P99

轉(zhuǎn)載于:https://www.cnblogs.com/mydomain/archive/2011/01/04/1925441.html

總結(jié)

以上是生活随笔為你收集整理的47、Windows驱动程序模型笔记(五),内存管理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。