1. Trang chủ
  2. » Công Nghệ Thông Tin

Quản lý bộ nhớ (memory management )

16 322 1

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 16
Dung lượng 314,82 KB

Nội dung

Trong số này xem không chắc chắn, nhìn chung chúng tôi phải tuân theo các quy định sau đây trong một chương trình driver: Không bao giờ tốt, mấy khi người trực tiếp tham chiếu-chế độ bộ

Trang 1

Quản lý bộ nhớ (Memory

Management )

Bởi:

Khoa CNTT ĐHSP KT Hưng Yên

Ở chương này, tôi sẽ bàn về chủ đề quản lý bộ nhớ Windows XP chia cắt vùng địa chỉ thực tế chia cắt bên trong bằng vài cách Một cách chia - rất bảo mật và toàn vẹn là địa chỉ người dùng và địa chỉ nhân Một cách chia khác, mà sử dụng hầu hết nhưng không tốt lắm là giữa trang nhớ và không phaitrang nhớ Hầu hết địa chỉ người sử dụng và vài địa chỉ kiểu nhân tham chiếu dến ô nhớ mà Quản lý bộ nhớ đổi tới và từ đĩa trong toàn

bộ thời gian, trong khi một vài địa chỉ kiểu nhân luôn luôn liên kết tới ô nhớ trong bộ nhớ vật lý Từ Windows XP cho phép nhưững phần của trình điều khiển tớ ô nhớ, tôi sẽ giải thích cách làm thế nào điều khiển ô nhớ của trình điều khiển của bạn tại một thời điểm bạn xây dựng trình điều khiển và chạy nó Windows XP cung cấp một số phưoơg thức để quản lý bộ nhớ Tôi sẽ mô tả hai hàm dịch vụ cơ bản —ExAllocatePoolWithTag

và ExFreePool— mà bạn sử dụng để phân chia và giải phóng một cách ngẫu nhiên Tôi

sẽ giải thích nguyên thuỷ mà bạn sử dụng để tổ chức bộ nhớ và trong những danh sách liên kết của cấu trúc Cuối cùng tôi sẽ giải thích khái niệm một danh sách mà cho phép bạn phân chia có hiệu quả

User-Mode and Kernel-Mode Address Spaces

Windows XP và Microsoft Windows 98/Me chạy trên nhữngmáy tính mà hỗ trợ một vùng địa chỉ thực tế nơi mà địa chỉ ảo được vẽ tới bộ nhớ vật lý hoặc một ô nhớ bên

Trang 2

trong file tráo đổi trên dĩa cứng Thủ tục đơn giản hoá những vấn đề, bạn có thể nghĩ về địa chỉ ảo như chia cắt thành hai phần: một phaanf kiêu nhân và một phần kiểu người dùng Nhìn hình 3-6

Hình 3-6 Thành viên-hạt nhân và chế độ-chế độ của phần không gian địa chỉ Mỗi người

sử dụng chế độ xử lý có địa chỉ bối cảnh riêng của mình, mà bản đồ của người sử dụng chế độ ảo-địa chỉ duy nhất cho một bộ sưu tập của vật chất trang khung Nói cách khác,

ý nghĩa của bất kỳ địa chỉ riêng ảo thay đổi từ một chút thời gian để tiếp theo như là Windows XP Scheduler tắc từ một sợi ở một trong quá trình vào một sợi khác trong quá trình Một phần của công việc trong khâu chuyển đổi là để thay đổi các trang bảng được

sử dụng bởi một xử lý để họ giới thiệu đến các luồng của quá trình bối cảnh It's thường không WDM đó, một driver sẽ thực hiện trong cùng một bối cảnh như là sợi xướng của

I / O yêu cầu nó xử lý

Chúng ta nói rằng chúng tôi đang chạy trong bối cảnh arbitrary sợi, nếu chúng ta không biết chắc chắn sẽ cho quá trình mà hiện nay người sử dụng chế độ địa chỉ bối cảnh thuộc Trong bối cảnh arbitrary sợi, chúng tôi chỉ đơn giản có thể không được sử dụng một địa chỉ mà ảo thuộc với người sử dụng chế độ bởi vì chúng tôi có thể không có bất kỳ ý tưởng với những gì vật lý bộ nhớ nó có thể điểm Trong số này xem không chắc chắn, nhìn chung chúng tôi phải tuân theo các quy định sau đây trong một chương trình driver: Không bao giờ (tốt, mấy khi) người trực tiếp tham chiếu-chế độ bộ nhớ

Nói cách khác, không có một địa chỉ mà một người sử dụng chế độ-cung cấp các ứng dụng và chữa trị cho rằng như là một địa chỉ trỏ rằng chúng tôi có thể trực tiếp dereference Tôi sẽ thảo luận trong chương sau một vài kỹ thuật để truy cập dữ liệu đệm

mà bắt nguồn ở chế độ người dùng Tất cả chúng tôi cần phải biết ngay bây giờ, tuy nhiên, chúng tôi đang là (gần như) luôn luôn có được bằng cách sử dụng hạt nhân-chế

độ địa chỉ ảo bất cứ khi nào chúng tôi muốn truy cập vào bộ nhớ của máy tính Bao lớn

Có một trang?

Trong một hệ thống bộ nhớ ảo, hệ điều hành tổ chức vật lý bộ nhớ và các vùng trao đổi vào tập tin như-kích thước trang khung Trong một WDM trình điều khiển, bạn có thể

sử dụng để tỏ cố PAGE_SIZE cho bạn biết làm thế nào là một trang lớn Trong một số máy tính Windows XP, một trang là 4096 bytes dài; trong những người khác, it's 8192 bytes dài A liên quan đến việc đặt tên PAGE_SHIFT kích thước bằng các trang như là một sức mạnh của 2 Đó là:

PAGE_SIZE == 1 << PAGE_SHIFT

Cho sự tiện nghi của bạn, bạn có thể sử dụng một vài preprocessor macros mã của bạn trong khi bạn đang làm việc với các kích thước của một trang web:

Trang 3

• ROUND_TO_PAGES trong vòng một kích thước byte đến trang kế tiếp cao hơn-ranh giới Ví dụ, ROUND_TO_PAGES (1) là 4.096 trên một 4-KB-trang máy tính

• BYTES_TO_PAGES xác định bao nhiêu trang được yêu cầu tổ chức một số byte, bắt đầu từ bắt đầu của một trang Ví dụ, BYTES_TO_PAGES (42) sẽ là 1 trên tất cả các nền tảng, và BYTES_TO_PAGES (5000) sẽ là 2 trên một số nền tảng và 1 về những người khác • BYTE_OFFSET sẽ trả về byte bù đắp phần của một địa chỉ ảo Đó là, tính toán của nó bắt đầu bù đắp trong vòng một số trang khung của một địa chỉ Ngày 4-KB-trang, máy tính, BYTE_OFFSET (0x12345678) sẽ được 0x678

PAGE_ALIGN vòng một ảo địa chỉ xuống để một trang ranh giới Ngày 4-KB-trang, máy tính, PAGE_ALIGN (0x12345678) sẽ được 0x12345000

• ADDRESS_AND_SIZE_TO_SPAN_PAGES trả ra số trang khung chiếm được xác định bởi một số byte, bắt đầu từ một địa chỉ ảo Ví dụ, các tuyên bố ADDRESS_AND_SIZE_TO_SPAN_PAGES (0x12345FFF, 2) là 2 trên một 4-KB-trang máy vì 2 byte chiều dài một 4-KB-trang ranh giới

Đánh số trang và đánh số trang Bộ nhớ

Toàn bộ số điểm của một hệ thống bộ nhớ ảo là bạn có thể có được một không gian địa chỉ ảo đó là nhiều lớn hơn số lượng bộ nhớ vật lý trên máy tính Để thực hiện điều này feat, Trưởng đại diện các Bộ nhớ nhu cầu để trao đổi trang khung trong và ngoài của vật

lý bộ nhớ

Các thể loại "phải được cư dân" công cụ rộng lớn hơn nhiều hơn là chỉ các trang lỗi xử

lý Windows XP cho phép phần cứng interrupts để xảy ra ở gần bất kỳ lúc nào, bao gồm một trang lỗi trong khi đang được phục vụ Nếu điều này không được như vậy, các trang lỗi handler sẽ không thể đọc hoặc viết trang từ một thiết bị sử dụng một gián đoạn

Vì vậy, mỗi phần cứng gián đoạn dịch vụ thường phải được nonpaged trong bộ nhớ Các thiết kế của Windows NT, bao gồm các quyết định ngay cả thêm thói quen trong nonpaged danh mục bằng cách sử dụng một nguyên tắc đơn giản: Mã thi hành tại hoặc gián đoạn ở trên mức yêu cầu (IRQL) DISPATCH_LEVEL trang có thể không gây ra lỗi lầm

Tôi sẽ xây dựng trên nguyên tắc này trong chương kế tiếp Bạn có thể sử dụng PAGED_CODE preprocessor vĩ mô (trong wdm.h) để giúp bạn khám phá các hành vi

vi phạm các quy định này trong kiểm tra xây dựng của driver của bạn Ví dụ:

NTSTATUS DispatchPower(PDEVICE_OBJECT fdo, PIRP Irp)

{

Trang 4

}

PAGED_CODE chứa các điều kiện biên soạn Trong khi kiểm tra-xây dựng, môi trường, nó in một tin nhắn và tạo ra một đồng thất bại nếu IRQL hiện nay là quá cao Trong miễn phí-xây dựng, môi trường, nó không làm bất cứ điều gì Để hiểu lý do tại sao PAGED_CODE rất hữu ích, tưởng tượng rằng DispatchPower nhu cầu cho một số

lý do để được ở nonpaged nhưng bộ nhớ rằng bạn có misplaced nó trong bộ nhớ paged

Nếu hệ thống xảy ra DispatchPower để gọi tại một thời gian khi trang chứa nó không phải là hiện nay, một trang lỗi sẽ xảy ra, theo sau là một lỗi kiểm tra Lỗi mã kiểm tra sẽ được pretty uninformative (IRQL_NOT_LESS_OR_EQUAL hay DRIVER_IRQL_NOT_LESS_OR_EQUAL), nhưng ít nhất bạn sẽ tìm ra rằng bạn có một vấn đề

Nếu bạn kiểm tra trình điều khiển của bạn trong một tình hình trong đó các trang có chứa DispatchPower sẽ xảy ra fortuitously để được trong bộ nhớ, tuy nhiên, sẽ không có một trang lỗi PAGED_CODE sẽ phát hiện ngay cả vấn đề như vậy

Cài đặt các Driver Verifier "IRQL lực lượng kiểm tra" lựa chọn sẽ làm tăng đáng kể

cơ hội khám phá ra rằng bạn đã tan vỡ các quy định về paging và IRQL Tùy chọn lực lượng pageable trang ra khỏi bất cứ khi nào xác nhận trình điều khiển bộ nhớ nâng cao IRQL để DISPATCH_LEVEL hay ngoài

Biên-Thời gian kiểm soát của Pageability

Cho rằng một số phần của trình điều khiển của bạn phải luôn luôn được cư dân và một

số phần có thể được paged, bạn cần một cách để kiểm soát các giao của bạn và mã dữ liệu vào paged và nonpaged pool Bạn pháp phần của công việc này bằng cách hướng dẫn làm thế nào để biên apportion mã của bạn và dữ liệu khác nhau giữa các phần

The run-tải thời gian sử dụng tên của các phần để đưa phần của trình điều khiển của bạn trong những nơi bạn có ý Bạn cũng có thể pháp phần của công việc này tại thời gian chạy bằng cách gọi các bộ nhớ Trưởng đại diện thói quen mà tôi sẽ thảo luận trong phần

kế tiếp

Chú ý:

Win32 executable file, bao gồm cả hạt nhân-chế độ điều khiển, đang có nội bộ thành từ một hay nhiều phần Một phần có thể chứa dữ liệu và mã hay, nói chung, có thêm thuộc tính như là đang được đọc, ghi, shareable, thi hanh, và như vậy trên Một phần nhỏ cũng

là đơn vị mà bạn có thể chỉ khi bạn đã xác định khả năng trang ¬

Trang 5

Khi driver tải một hình ảnh, hệ thống đã nhận phần chữ có tên bắt đầu với Trang hay Eda (bắt đầu EDATA) vào paged pool, trừ khi DisablePagingExecutive giá trị trong HKLM \ System \ CurrentControlSet \ Control \ Session Manager \ Memory Quản lý chủ chốt sẽ xảy ra để được thiết lập (trong đó có trường hợp không có bằng driver paging xảy ra)

) Lưu ý rằng các tên này là trường hợp nhạy cảm! Trong một trong những twists ít

có ảnh hưởng đến số phận của chúng tôi tất cả theo thời gian, chạy mềm-Ice / W trên Windows XP yêu cầu bạn để vô hiệu hóa hạt nhân trong paging bằng cách này Điều này chắc chắn làm cho khó hơn để tìm thấy lỗi gây ra bởi misplacement của driver hoặc mã

dữ liệu vào paged pool! Nếu bạn sử dụng debugger này, tôi khuyên bạn nên religiously

sử dụng PAGED_CODE vĩ mô và Driver Verifier

Cách truyền thống cho các biên để đưa mã vào một phần là để sử dụng những alloc_text pragma Kể từ mỗi biên sẽ không nhất thiết phải hỗ trợ các pragma, các DDK tiêu đề hoặc xác định hay không xác định việc ALLOC_PRAGMA để cho biết nên sử dụng pragma Sau đó bạn có thể gọi các pragma để xác định vị trí của phần subroutines cá nhân của bạn trong trình điều khiển, như sau:

#ifdef ALLOC_PRAGMA

#pragma alloc_text(PAGE, AddDevice)

#pragma alloc_text(PAGE, DispatchPnp)

#endif

Những tài liệu phục vụ cho các nơi AddDevice và DispatchPnp hàm vào paged pool Của Microsoft C / C + + biên nơi hai gây phiền nhiễu hạn chế về việc sử dụng các alloc_text:

• Các pragma phải làm theo các công bố của một hàm nhưng việc định nghĩa Một cách

để phải tuân theo các quy định này là để tuyên bố tất cả các hàm trong trình điều khiển của bạn trong một tiêu chuẩn tiêu đề tập tin và gọi alloc_text tại đầu của các tập tin nguồn có chứa một hàm nhưng sau khi bạn bao gồm các tiêu đề

• Các pragma chỉ có thể được sử dụng với hàm có liên kết C- Nói cách khác, nó sẽ không làm việc cho các thành viên lớp học hoặc hàm cho các hàm trong một C + + mã nguồn tệp tin mà bạn đã không khai báo bằng cách sử dụng extern "C" Để kiểm soát các vị trí của các biến dữ liệu, bạn sử dụng một pragma khác nhau dưới sự kiểm soát của là một biểu tượng khác nhau preprocessor vĩ mô:

#ifdef ALLOC_DATA_PRAGMA

Trang 6

#pragma data_seg("PAGEDATA")

#endif

Data_seg pragma nguyên nhân của tất cả các dữ liệu tĩnh tuyên bố các biến trong một mô-đun nguồn sau khi xuất hiện của pragma để đi vào paged pool Bạn sẽ nhận thấy rằng này pragma khác trong một cách căn bản từ alloc_text Một phần pageable bắt đầu, nơi # pragma data_seg ( "PAGEDATA") xuất hiện và kết thúc, nơi một countervailing

# pragma data_seg () xuất hiện Alloc_text, mặt khác, áp dụng cho một hàm cụ thể

Khởi-Thời gian kiểm soát của Pageability

Bảng 3-3 liệt kê các dịch vụ, bạn có thể sử dụng hàm chạy ở thời gian để tinh chỉnh sự pageability của bạn driver trong tình huống khác nhau Mục đích của các thói quen là để cho bạn phát hành của bộ nhớ vật lý mà có khác được gắn lên do mã của bạn và dữ liệu trong suốt thời gian khi nó sẽ không được cần thiết

Trong Chương 8, ví dụ, tôi sẽ thảo luận làm thế nào bạn có thể đặt điện thoại của bạn vào một ít quyền lực nhà nước trong thời gian không hoạt động Powering xuống có thể

sẽ có một thời gian tốt để phát hành các trang web của bạn bị khóa

Tôi đang đi để mô tả một cách sử dụng các hàm để kiểm soát pageability của mã trong trình điều khiển của bạn Bạn có thể muốn đọc DDK mô tả để tìm hiểu về những cách khác để sử dụng chúng Subroutines trong phân phối đầu tiên của bạn driver vào một cách riêng biệt, tên mã phần, như thế này:

#pragma alloc_text(PAGEIDLE, DispatchRead)

#pragma alloc_text(PAGEIDLE, DispatchWrite)

Trang 7

Đó là, xác định một phần tên bắt đầu với Trang và kết thúc bằng bất cứ bốn ký tự suffix bạn vui lòng Sau đó, sử dụng alloc_text pragma để đặt một số nhóm các thói quen của riêng bạn trong đó phần đặc biệt Bạn có thể có bao nhiêu phần pageable đặc biệt như bạn muốn, nhưng vấn đề hậu của bạn sẽ phát triển như bạn driver của bạn chia theo cách này Trong thời gian sở khởi (nói rằng, trong DriverEntry), khóa của bạn pageable phần như thế này:

PVOID hPageIdleSection;

NTSTATUS DriverEntry( )

{

hPageIdleSection = MmLockPagableCodeSection((PVOID)

DispatchRead);

}

Khi bạn gọi MmLockPagableCodeSection, bạn chỉ định bất kỳ ở tất cả các địa chỉ trong phần bạn đang cố gắng để khóa Thực sự nhằm mục đích thực hiện cuộc gọi trong thời gian này DriverEntry được xử lý để có được giá trị của nó trở về, tôi đã hiển thị mà bạn tiết kiệm trong toàn cầu một biến tên hPageIdleSection Bạn sẽ sử dụng nhiều xử lý sau này, khi bạn quyết định bạn không cần một phần trong bộ nhớ cho một trong khi: MmUnlockPagableImageSection(hPageIdleSection);

Điều này sẽ mở khóa gọi các trang web có chứa các PAGEIDLE phần và cho phép họ

để di chuyển ra và vào bộ nhớ theo yêu cầu Nếu bạn sau này khám phá rằng bạn cần những trang lại một lần nữa, bạn thực hiện cuộc gọi này:

MmLockPagableSectionByHandle(hPageIdleSection);

Sau đây gọi này, các PAGEIDLE phần sẽ lại một lần nữa được nonpaged trong bộ nhớ (nhưng không nhất thiết phải là cùng một vật lý bộ nhớ như trước đó) Lưu ý rằng hàm này gọi là có sẵn cho bạn chỉ trong Windows 2000 và Windows XP, và sau đó chỉ nếu bạn đã bao gồm ntddk.h thay vì wdm.h Trong những tình huống khác, bạn sẽ phải gọi lại MmLockPagableCodeSection

Bạn có thể làm gì đó tương tự để đặt dữ liệu vào các đối tượng pageable phần

PVOID hPageDataSection;

#pragma data_seg("PAGE")

Trang 8

ULONG ulSomething;

#pragma data_seg()

hPageDataSection = MmLockPagableDataSection((PVOID)

&ulSomething);

MmUnlockPagableImageSection(hPageDataSection);

MmLockPagableSectionByHandle(hPageDataSection);

Tôi đã phát nhanh và loose với cú pháp của tôi đây-những tài liệu sẽ xuất hiện trong rộng rãi bị tách phần của trình điều khiển của bạn Những ý tưởng đằng sau những dịch

vụ hàm quản lý bộ nhớ tôi chỉ cần được mô tả là bạn sẽ bước đầu khóa một phần có chứa một hoặc nhiều trang web và có được một xử lý cho sử dụng trong các cuộc gọi.Bottom

of Form

Sau đó bạn có thể mở khóa các trang trong một phần bằng cách gọi điện thoại qua MmUnlockPagableImageSection và xử lý tương ứng Relocking phần sau này đòi hỏi một cuộc gọi đến MmLockPagableSectionByHandle

A nhanh chóng tắt hiện có sẵn nếu bạn chắc chắn rằng không có phần của driver của bạn sẽ cần phải được cho cư dân trong một thời gian MmPageEntireDriver sẽ đánh dấu tất cả các phần trong một hình ảnh như bằng driver đang được pageable Ngược lại, MmResetDriverPaging sẽ khôi phục lại các biên-thời gian pageability thuộc tính cho toàn bộ trình điều khiển Để gọi những thói quen, bạn chỉ cần địa chỉ của một số đoạn

mã hoặc dữ liệu trong trình điều khiển Ví dụ:

MmPageEntireDriver((PVOID) DriverEntry);

MmResetDriverPaging((PVOID) DriverEntry);

Bottom of Form

Ví dụ:

#define DRIVERTAG ''KNUJ''

PVOID p = ExAllocatePoolWithTag(PagedPool, 42, DRIVERTAG);

Trang 9

Handling Low-Memory Situations

Nếu không có đủ bộ nhớ để đáp ứng yêu cầu của bạn, các allocator pool sẽ đem lại một NULL trỏ Bạn nên luôn luôn kiểm tra lại giá trị và làm cái gì hợp lý Ví dụ:

PMYSTUFF p = (PMYSTUFF) ExAllocatePool(PagedPool, sizeof(MYSTUFF));

if (!p)

return STATUS_INSUFFICIENT_RESOURCES;

Các loại pool bao gồm khái niệm phải thành công Nếu không có đủ bộ nhớ heap để satisify một yêu cầu từ phải-pool thành công, hệ thống kiểm tra lỗi Trình điều khiển không nên phân bổ bộ nhớ bằng cách sử dụng một trong những thành công phải-specifiers Điều này là do một driver có thể gần như luôn luôn thất bại nào là hoạt động theo cách

Gây ra một hệ thống sụp đổ trong một bộ nhớ thấp-tình hình không phải là cái gì làm nên một driver Hơn nữa, chỉ có một giới hạn pool phải-thành công của bộ nhớ tồn tại trong toàn bộ hệ thống, và hệ điều hành có thể không có khả năng phân bổ bộ nhớ cần thiết để có thể giữ cho các máy tính chạy nếu trình điều khiển đó lên một số

Nếu bạn HOẶC giá trị POOL_RAISE_IF_ALLOCATION_FAILURE (0x00000010)

STATUS_INSUFFICIENT_RESOURCES ngoại trừ thay vì trở về NULL nếu không có

đủ bộ nhớ Bạn nên sử dụng một cấu trúc ngoại trừ khung để nắm bắt như một ngoại lệ

Ví dụ:

#ifndef POOL_RAISE_IF_ALLOCATION_FAILURE

#define POOL_RAISE_IF_ALLOCATION_FAILURE 16

#endif

#define PagedPoolRaiseException (POOL_TYPE) \

(PagedPool │ POOL_RAISE_IF_ALLOCATION_FAILURE)

#define NonPagedPoolRaiseException (POOL_TYPE) \

(NonPagedPool │ POOL_RAISE_IF_ALLOCATION_FAILURE)

NTSTATUS SomeFunction()

Trang 10

NTSTATUS status;

try

{

PMYSTUFF p = (PMYSTUFF)

ExAllocatePoolWithTag(PagedPoolRaiseException,

sizeof(MYSTUFF), DRIVERTAG);

<Code that uses "p" without checking it for NULL>

status = STATUS_SUCCESS;

}

except(EXCEPTION_EXECUTE_HANDLER)

{

status = GetExceptionCode();

}

return status;

}

NOTE POOL_RAISE_IF_ALLOCATION_FAILURE được định nghĩa trong NTIFS.H, một phần đầu tập tin đó là có sẵn chỉ là một phần của thêm chi phí cài tệp Hệ thống kit Làm bộ nhớ phân với cờ này được thiết lập để phổ biến trong hệ thống tập tin trình điều khiển, tuy nhiên, tôi nghĩ rằng bạn nên biết về điều đó

Incidentally, tôi đề nghị bạn không đi crazy cố gắng để chẩn đoán hoặc phục hồi từ thất bại để bố trí nhỏ, khối bộ nhớ Như là một vấn đề thực tế, một phân bổ cho các yêu cầu, nói rằng, 32 byte là không bao giờ đi đến thất bại Nếu bộ nhớ thường là những mặt, hệ thống sẽ được chạy như vậy sluggishly chắc rằng ai đó sẽ khởi động lại máy

Bạn phải không phải là nguyên nhân của một hệ thống sụp đổ trong tình hình này, tuy nhiên, vì bạn do đó sẽ được các nguồn tiềm năng của một từ chối-của-dịch vụ khai thác

Ngày đăng: 31/12/2015, 22:11

TỪ KHÓA LIÊN QUAN

w