學習筆記
《x86匯編語言:從實模式到保護模式》
http://www.lxweimin.com/p/d481cb547e9f
本篇內容
- 一、如何訪問頁目錄自己的表項
- 二、如何訪問頁表自己的頁表項
- 三、頁映射位串與物理內存的對應關系
一、如何訪問頁目錄自己的表項
頁目錄的線性地址是 0x FFFF F000
線性地址高20位全是1 即0xFFFFXXX 形式就可以把訪問到頁目錄自己的表項.png
二、如何訪問頁表自己的頁表項
頁表的線性首地址是 0x FFC0 0000
- 代碼段位于過程alloc_inst_a_page
- 完整的過程alloc_inst_a_page的作用是:分配一個頁,并安裝在當前活動的層級分頁結構中(輸入:
EBX=頁的線性地址
)
; EBX寄存器 此時 存著 頁的線性地址
;開始訪問該線性地址所對應的頁表
mov esi,ebx
shr esi,10
and esi,0x003ff000 ;或者0xfffff000,因高10位是零
or esi,0xffc00000 ;得到該頁表的線性地址
;得到該線性地址在頁表內的對應條目(頁表項)
and ebx,0x003ff000
shr ebx,10 ;相當于右移12位,再乘以4
or esi,ebx ;頁表項的線性地址
call allocate_a_4k_page ;分配一個頁,這才是要安裝的頁
or eax,0x00000007
mov [esi],eax
如何訪問頁表自己的頁表項.png
代碼段的作用
-
固定地讓高10位成為
0x3ff
,從而讓頁目錄表當一次自己,再當一次“頁表”
; - 會將 EBX 傳入的頁的線性地址,保留并移到中10位,從而找到真正的頁表的物理地址;
- 會將 EBX 傳入的頁的線性地址,保留并移到低12位,作為
“頁”
的偏移量,此時,頁表作為“頁”,相當于就找到了頁表自己的頁表項;
三、頁映射位串與物理內存的對應關系
- 在內核公用數據段 core_data ,聲明了一個標號
page_bit_map
,這連續的64字節長度(512比特),表示物理地址從0x0000 0000到0x0020 0000
之間的每個4KB頁的分配情況,對應的位比特值是1,表示頁面已經被分配使用;
page_bit_map db 0xff,0xff,0xff,0xff,0xff,0x55,0x55,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
頁映射位串 與 物理內存 的對應關系.png
源碼補充
- alloc_inst_a_page 分配一個頁 填寫頁目錄表 頁表
alloc_inst_a_page: ;分配一個頁,并安裝在當前活動的
;層級分頁結構中
;輸入:EBX=頁的線性地址
push eax
push ebx
push esi
push ds
mov eax,mem_0_4_gb_seg_sel
mov ds,eax
;檢查該線性地址所對應的頁表是否存在
mov esi,ebx
and esi,0xffc00000
shr esi,20 ;得到頁目錄索引,并乘以4
or esi,0xfffff000 ;頁目錄自身的線性地址+表內偏移
test dword [esi],0x00000001 ;P位是否為“1”。檢查該線性地址是
jnz .b1 ;否已經有對應的頁表
;創建該線性地址所對應的頁表
call allocate_a_4k_page ;分配一個頁做為頁表
or eax,0x00000007
mov [esi],eax ;在頁目錄中登記該頁表
.b1:
;開始訪問該線性地址所對應的頁表
mov esi,ebx
shr esi,10
and esi,0x003ff000 ;或者0xfffff000,因高10位是零
or esi,0xffc00000 ;得到該頁表的線性地址
;得到該線性地址在頁表內的對應條目(頁表項)
and ebx,0x003ff000
shr ebx,10 ;相當于右移12位,再乘以4
or esi,ebx ;頁表項的線性地址
call allocate_a_4k_page ;分配一個頁,這才是要安裝的頁
or eax,0x00000007
mov [esi],eax
pop ds
pop esi
pop ebx
pop eax
retf
- allocate_a_4k_page 分配一個4KB的頁
allocate_a_4k_page: ;分配一個4KB的頁
;輸入:無
;輸出:EAX=頁的物理地址
push ebx
push ecx
push edx
push ds
mov eax,core_data_seg_sel
mov ds,eax
xor eax,eax
.b1:
bts [page_bit_map],eax
jnc .b2
inc eax
cmp eax,page_map_len*8
jl .b1
mov ebx,message_3
call sys_routine_seg_sel:put_string
hlt ;沒有可以分配的頁,停機
.b2:
shl eax,12 ;乘以4096(0x1000)
pop ds
pop edx
pop ecx
pop ebx
ret
;-------------------------------------------------------------------------------