Trao đổi với tôi

http://www.buidao.com

8/6/09

[System Info] WINDOWS MEMORY MANAGEMENT



Bài dịch này chỉ để tham khảo hiểu rõ cách quản lý bộ nhớ của hệ điều hành Windows. Các bạn nên in ra mà đọc từ từ , từng chút một . Bản thân tui phải đọc 3 , 4 lần mới nhớ được. Hy vọng nó dễ hiểu. Sau khi đọc tut này, chúng ta sẽ có cách nhìn sâu hơn vào trong Windows. Hiểu nó càng nhiều, chúng ta càng làm chủ được nó. Qua tut này chúng ta sẽ biết thêm nhiều thông tin như : thanh ghi CR3 dùng để làm gì, địa chỉ luân lý (logical address) , địa chỉ vật lý (physical address) là gì, và cách xếp trang (paging) là sao...vân...vân....

Và lời cuối cùng tui muốn nói, nếu ai tìm thấy lỗi trong các tuts, xin hảy cho tôi biết vì tui cũng là dân tò te về IT, xin chân thành cảm ơn.

Author: Pankaj Garg

Tranz by: Benina

1. Introduction:

Windows trên hệ thống 32 bit x86 systems có thể truy xuất (access) trên 4GB bộ nhớ vật lý. Do bởi thực tế bus addr của bộ vi xử lý (processor) là 32 lines hay 32 bits chỉ có thể truy xuất vùng addr từ 0x00000000 đến 0xFFFFFFFF tức chỉ có 4GB. Windows cũng cho phép mỗi process có chính 4GB vùng địa chỉ (address space ) cho nó. 2GB thấp của vùng addr này dành cho cho user mode process và 2GB trên được dành cho Windows Kernel mode code. Windows làm thế nào cấp phát vùng addr 4GB cho nhiều processes khi tổng bộ nhớ của nó có thể truy xuất cũng bị giới hạn bởi 4GB?. Để đạt được điều này, Windows dùng một đặc tính của x86 processer (386 trở lên) được biết đến là “xếp trang” (paging). Paging cho phép phần mềm sử dụng một địa chỉ nhớ (được biết đến như logical address : địa chỉ luân lý) khác với địa chỉ nhớ vật lý (physical memory address). Paging của processor chuyển đổi logical address thành physical address một cách dễ dàng. Điều này cho phép mọi process trong system có vùng addr logical 4GB của chính nó. Để hiểu điều này chi tiết hơn, chúng ta hảy bắt đầu tìm hiểu cách paging trong môi trường làm việc của x86.

2. Paging in x86 Processor.

Bộ xử lý x86 chia physical address space (vùng địa chỉ vật lý) thành các pages có kích thước 4KB. Vì vậy để đánh địa chỉ 4GB bộ nhớ, chúng ta cần 1 Mega (1024x1024) các trang (pages) có kthước 4KB. Bộ vi xử lý dùng 2 lớp cấu trúc để tham chiếu đến 1Mega pages này. Bạn có thể nghĩ nó như là một ma trận 2 phương 1024x1024 các phần tử. Phương thứ nhất được biết đến như là Page Derectory và phương thứ 2 được biết như Page Table. Vì vậy chúng ta cần cài đặt một Page Directory với 1024 thành phần, mỗi thành phần point (trỏ đến) đến một Page Table. Điều này cho phép chúng ta có 1024 Page Table. Mỗi Page Table lại có 1024 thành phần, mỗi thành phần lại trỏ đến 4KB page. Hình minh họa như sau:



Mỗi thành phần Page Directory Entry (PDE) có kích thước 4 bytes và trỏ đến một Page Table. Tương tự , mỗi Page Table Entry (PTE) có kthước 4 bytes và trỏ đến một physical address (địa chỉ vật lý)của 4KB page. Để chứa 1024 PDE mà mỗi thành phần lại chứa 1024 PTE, chúng ta cần tổng bộ nhớ là 4x1024x1024 bytes, có nghĩa là 4MB. Vì vậy chia tòan bộ 4GB vùng addr cho 4KB page, chúng ta cần 4MB vùng nhớ.

Như đã thảo luận ở trên, tòan bộ vùng address space được chia ra 4KB pages. Vậy khi một PDE hay PTE được sử dụng, 20 bits trên của nó dùng cho một addr 4KB page được sắp xếp thứ tự và 12 bits thấp được dùng để chứa thông tin bảo vệ trang (page protection information) và vài thông tin quản lý nội tại cần thiết cho các chức năng thích hợp của OS . 20 bits trên mà nó miêu tả cho addr vật lý thực được biết đến như Page Frame Number (hay PFN). Chi tiết về các protection bits và các bits khác trong lower 12 bits có thể tìm thấy ở tài liệu này.

3. Windows Page Table Management.

Trong Windows, mỗi process có Page Directory và Page Table của chính nó. Vì vậy Windows cấp 4MB của vùng space này cho mỗi process. Khi một process được cài đặt, mỗi thành phần trong Page Directory chứa addr vật lý (physical address) của Page Table. Các thành phần trong Page Table hoặc là valid (hợp lệ) , hoặc là invalid (ko hợp lệ). Các thành phần valid chứa physical address của 4KB page cấp cho process. Một thành phần invalid (ko hợp lệ) chứa một vài bits đặc biệt đánh dấu nó ko hợp lệ và các thành phần này được biết như Invalid PTEs. Khi memory được cấp cho process,các thành phần trong Page Table được lắp các addr vật lý của các pages đã cấp. Bạn nên nhớ một điều ở đây là một process ko biết bất kỳ gì về addr vật lý và nó chỉ sử dụng logical addr (địa chỉ luân lý).Chi tiết về việc logical addr nào tương ứng với physical addr nào được quản lý chuyển đổi bởi Windows Memory Manager và Processor (bộ vi xử lý). Addr tại Page Directory nào của một process được định vị trong physical memory được tham chiếu đến như là Page Directory Base address. Page Directory Base address này được chứa trong một thanh ghi đặc biệt của CPU là CR3 (trên nền x86). Để chuyển đổi context khác, Windows tải một giá trị mới của CR3 để trỏ đến một Page Directory base mới của process. Với cách này mỗi process sẽ lấy được các phần phân chia cả 4GB physical addr space của chính nó. Tất nhiên tổng memory cấp tại một thời điểm cho tất cả các process trong hệ thống là ko thể vượt quá số lượng RAM+ kích thước pagefile nhưng theo lược đồ đã thảo luận ở trên thì cho phép Windows cấp cho mỗi process vùng addr logical (hay Virtual: ảo) 4GB . Chúng ta gọi nó là vùng địa chỉ ảo (Virtual Addres sapce) bởi vì ngay mỗi process có đến cả range (phạm vi) là 4GB addr , nó chỉ có thể sử dụng memory cấp cho nó. Nếu một process thử truy xuất (access) một addr ko được cấp phép, nó sẽ gây ra một access violation (sự vi phạm truy xuất) bởi vì PTE tương ứng với addr trỏ đến một giá trị ko hợp lệ (invalid value). Cũng vậy, process ko thể cấp memory nhiều hơn những gì nó được phép trong system. Phương thức tách riêng logical memory từ physical memory này có nhiều thuận lợi. Một process có được một vùng addr 4GB tuyến tính , do đó các lập trình viên ứng dụng ko còn phải lo lắng về segments và hòan tòan ko giống như những ngày tháng cũ làm việc với DOS. Nó cũng cho phép Windows run nhiều prosses cùng một lúc và cho phép chúng dùng physical memory trên máy tính mà ko phải lo lắng về chúng sẽ đè lên trên vùng addr space của process khác. Một logical addr trong một process sẽ ko bao giờ trỏ đến một physical memory được cấp cho process khác (trừ khi chúng sử dụng phần nào để shared memory). Vì vậy,một process có thể ko bao giờ read hay write vào memory của process khác.

Sự chuyển đổi từ logical addr sang physical addr được thực hiện bởi bộ vi xử lý. Một 32bit logical address được chia thành 3 phần như hình dưới đây.

10 bits

10 bits

12 bits

Vi xử lý loads physical addr của page directory base lưu trử trong CR3. Rồi nó được sử dụng 10 bits thấp từ logical addr như là một chỉ mục trong Page directory. Điều này cho processor một page directory entry (PDE) trỏ đến một Page Table. 10 bits kế đến được sử dụng như một chỉ mục trong Page Table. Sử dụng 10 bits này, nó lấy một page table entry (hay PTE) trỏ đến một 4KB physical page. 12 bits thấp nhất được sử dụng đánh addr các bytes riêng lẻ trên một page.

4. Memory Protection.

Windows hổ trợ sự bảo vệ memory cho tất cả các processes mục đích để một process ko thể truy xuất một vùng memory của process khác. Điều này đảm bảo các họat động của nhiều processes cùng 1 lúc 1 cách trôi trãi. Windows đảm bảo chế độ bảo vệ này bằng cách theo các bước sau:

-Nó chỉ put physical address của memory được định vị trong PTE cho một process. Điều này đảm bảo rằng process bắt được một access violation nếu nó thử truy xuất một addr mà ko được định vị.

-Một rouge process (tiến trình đang thực thi) có thể thử thay đổi page tables của nó mục đích là nó có thể truy xuất physical memory thuộc về một process khác.Windows protect lọai tấn công này bởi cất giữ page tables trong kernel address space. Trở lại thảo luận vấn đề của chúng ta lúc đầu, đó là vấn đề : ngòai phạm vi 4GB logical addr space được cấp cho 1 process, 2GB được cấp cho user mode và 2GB được trữ cho windows kernel. Vì vậy một user mode app (ứng dụng mode người dùng) ko có thể truy xuất trực tiếp hoặc thay đổi page tables. Tất nhiên nếu một kernel mode driver muốn làm điều đó, nó có thể làm được bởi một khi bạn ở trong kernel mode, bạn hầu như làm chủ tòan hệ thống . Để tìm hiểu điều này chi tiết hơn, hảy đọc phần kế tiếp Windows Logical memory layout dưới đây.

5. Windows Logical Memory Layout (sự xếp đặt)

Windows cho khỏang không gian địa chỉ luân lý 2GB thấp (or 3GB dựa trên boot.ini switch) của một process cho user mode và 2GB cao (hay 1GB dựa trên sự chuyển đổi switch (bật/tắt) trong file boot.ini ) cho Windows kernel. Trong số tổng khỏang không kernel address, nó chứa addresses từ 0xC0000000 đến 0xC03FFFFF cho Page Tables và Page Directory. Mọi process có Page Tables của nó được định vị tại logical address 0xC0000000 và Page Directory định vị tại logical address 0xC0300000. Sự sắp xếp logical memory này như sau:


Bạn có thể dùng Windows kernel debugger kd hay windbg để thẩm tra điều này (tham chiếu đến !pte và !vtop debugger extenstions). Physical address của page directory này được trử trong CR3. 1024 addresses bắt đầu từ 0xC0300000 miêu tả Page Directory Entry (PDE). Mỗi PDE chứa một 4 byte physical address mà nó trỏ đến một Page Table. Mỗi Page Table có 1024 entries mà nó hoặc chứa một physical address trỏ đến một physical page của 4KB hoặc chứa một invalid entry (thành phần ko hợp lệ). Điều này cũng đã thảo luận ở trên trong phần processor’s paging và phần Windows page table management nhưng đã được nhắc lại ở đây với mục đích làm rỏ hơn . Vậy tại sao Windows dùng logical address 0xC000000000 để chứa Page Tables và address 0xC0300000 để chứa page directory? Sự cần thiết cho việc chứa đựng page tables trong memory là : một rouge user mode application sẽ ko thể thao tác trên các page tables. Do đó page tables sẽ ở trong vùng không gian địa chỉ của kernel (kernel logical address space). Windows luôn cho khỏang không 2GB thấp cho các processes và chứa 2GB cao cho kernel. Nhưng với một switch (bật/tắt) đặc biệt /3GB trong file boot.ini, nó cho phép user mode process truy xuất vùng nhớ 3GB thấp. 0xC0000000 là address kế tiếp sau 3GB và do vậy tôi đóan rằng tại sao nó được chọn để chứa page directory và page tables. Có một vài phần quan trọng khác cho page tables và page directory layout (sự xếp đặt) trong memory. Để hiểu điều đó, chúng ta hảy nhìn vào page tables và page directory được xếp đặt như thế nào. Để hiểu nó một cách dễ dàng , tôi đã vẽ màu sáng cho các page tables của một process giả với các thành phần (entries) có liên quan . Chú ý rằng mỗi thành phần index entry có kích thước 4 bytes.

P_PT miêu tả physical address của một Page Table.


PDB miêu tả physical address của page directory base của process tương ứng , nghĩa là nó miêu tả physical address tương ứng với logical address 0xC0300000 cho process đó. Giá trị này cũng chứa trong CR3. Hảy nhớ Windows chỉ có thể dùng logical address để truy xuất bất kỳ vị trí memory nào đính vào page directory, vậy để truy xuất page directory và page tables, nó cần thiết đặt vài thành phần tham chiếu trong page directory. Các thành phần physical address chỉ ra ở trên sẽ khác cho mỗi process nhưng mỗi process sẽ có thành phần PDB entry của nó chứa tại index 0x300 của Page directory.

Chúng ta sẽ thực hiện luân lý hóa sự chuyển đổi địa chỉ vật lý (physical address translation) trên 4 addr khác nhau để thấy ý nghĩa của thành phần PDB entry, sự xếp đặt Page tables và chuyển đổi addr làm việc một cách chính xác như thế nào. Các địa chỉ mà chúng ta sẽ chuyển đổi là 0x2034AC54, 0xC0000000, 0xC0300000,0xC0300000[0x300] -nghĩa là 0xC030C00. Địa chỉ trước tiên là một user mode logical address bình thường cho một process, addr thứ hai là logical address trước tiên của page table đầu tiên trong khỏang không địa chỉ luân lý (logical address space), address thứ ba là logical address của page directory base và address thứ tư là logical address của một thành phần entry đặc biệt như bạn sẽ thấy trong suốt quá trình translation (chuyển đổi) . Giả sử CR3 trỏ đến một physical address là 0x13453###. Như nói trước đó, 12 bits thấp được dùng để chứa các thông tin bảo vệ trang (page protection information) và các thông tin cần thiết khác cho hệ điều hành OS. Điều này nằm ngòai phạm vi thảo luận hiện tại của chúng ta, vì vậy tôi đã dùng ### làm ký tự đại diện. 20 bits trên miêu tả Page Frame Number hay PFN mà nó là physical address của một trang 4KB aligned page (trang được xếp hàng liên tục). Physical address thực tương ứng với PFN sẽ là 0x13453000. Chúng ta hảy làm sự chuyển đổi ngay bây giờ :

1. 0x2034AC54

o 0x2034AC54 có thể miêu tả như là : 0010000000 1101001010 110001010100

o 10 bits trên mà nó là 0010000000 cho biết chỉ mục index trong page directory. Chuyển đổi sang số hexadecimal, 10 bits trên cho một giá trị là 0x080

o Từ CR3, chúng ta biết Page Directory được định vị tại physical address 0x13453000 và từ thảo luận trên chúng ta cũng biết rằng Page Directory được định vị tại logical address 0xC0300000

o Vậy 0xC0300000 [0x080] sẽ cho biết address của page table mà nó là P_PT. Từ bảng trên, chúng ta có thể thấy rằng address này được miêu tả bởi page table tại logical address 0xC00001000 (hay physical address 0x45045000). Bây giờ chúng ta dùng 10 bits kế tiếp là 1101001010 (hay 0x34A) để chỉ mục index trong page table.

o address 0xC00001000 [0x34A] sẽ cho chúng ta physical address của một 4KB page mà nó là 0x34005000 từ bảng ở trên .

o Số miêu tả bởi 12 bits thấp, mà nó là 110001010100 (or 0xC54), được dùng để tham chiếu đến byte thất trên 4KB page đã định vị tại 0x34005000. Physical address sau cùng tương ứng 0x2034AC54 trở thành là 0x34005C54

Tôi sẽ bỏ qua sự chuyển đổi addr của 3 addresses khác (đề cập ở trên) như một bài tập cho người đọc. Một khi bạn thực hiện sự chuyển đổi các địa chỉ đó, bạn sẽ hiểu tại sao PDB entry được chứa tại index 0x300 trong bảng trên và nó gây nên việc xử lý đối xử page directory như một page table trong suốt quá trình chuyển đổi address . Cũng vậy sự chuyển đổi (translation) này sẽ cho bạn nhiều thông tin hơn vì sao sự xếp đặt đặc biệt này được chọn lựa bởi các nhà thiết kế Windows.

6. Reference

1. Inside Windows 2000 by David A. Solomon & Mark E. Russinovich

2. Undocumented Windows 2000 secrets by Sven B. Schreiber