免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: mik
打印 上一主题 下一主题

mouseOS 项目 -- x64 体系的实验品(10.13 更新 -- 实现新的分页管理) [复制链接]

论坛徽章:
0
21 [报告]
发表于 2009-09-11 00:00 |只看该作者
18、内存管理2 --- x64OS 地址空间规划


[ 本帖最后由 mik 于 2009-9-11 00:02 编辑 ]

mouse_space.jpg (56.77 KB, 下载次数: 62)

mouse_space.jpg

论坛徽章:
0
22 [报告]
发表于 2009-09-11 00:20 |只看该作者
接上图,这幅图是 x64os 中的地址空间的规划示意图。


一、整个 256TB (48 bit virtual address) 地址空间划分 7 个区段(segment):

1、kernel 空间:

★ F-segment(0xFFFFF000_00000000 ~):属于 kernel stack & heap 区域。

★ B-segment(0xFFFFB000_00000000 ~):保留为 kernel 的 driver 区域。

★ 8-segment(0xFFFF8000_00000000 ~):属于 system data 以及 kernel 核心执行代码区域



2、user 空间:

★ 7-segment(0x00007000_00000000 ~):属于 user stack 以及 heap 区域

★ 6-segmetn(0x00006000_00000000 ~):存放 user 的共享代码(库代码等)

★ 1-segment(0x00001000_00000000 ~):属于 user 64bit 代码区域

★ 0-segment(0x00000000_00000000 ~):属于 legacy 数据以及 compatibility 代码区域。




二、 page-translation-table 数据结构的规划

每一级 page-translation-table 结构的 size 为 4K (512*8 )

1、PML4T 表

(1)PML4T[0] (0-segment) ----> page-translation-table base      (例如:0x20011000)
(2)PML4T[32] (1-segment) ----> page-translation-table base + 4K
(3)PML4T[192](6-segment) ----> page-translation-table base +8K
(4)PML4T[224](7-segment) ----> page-translation-table base + 12K
(5)PML4T[256](8-segment) ----> page-translation-table base + 16K
(6)PML4T[352](B-segment) ----> page-translation-table base + 20K
(7)PML4T[511](F-segment) ----> page-translation-table base + 24K

-------------------------------------------------------------------------------------------------------
PML4T 只有一个,推导出 PDPT 表有 7 个




2、PDPT 表

 7 个 PDPT 表中,每个 PDPT 最多使用 4 个 entries :PDPT[0] ~ PDPT[3](PDPE0 ~ PDPE3)


kernel 空间

(1)8-segment(0xFFFF8000_XXXXXXXX):

★ system data structure:使用了 0-Entry(PDPT[0])

★ kernel code 使用了 1-Entry ~ 2-Entry (PDPT[1]~PDPT[2]),3-Entry 未使用。
  即 kernel code 使用了 0xFFFF8000_4XXXXXXX ~ 0xFFFF8000_8XXXXXXX 空间,共 1G 空间



(2)B-segment(0xFFFFB000_XXXXXXXX):

★ 保留给 kernel 只使用了 0-Entry(PDPT[0]),即:0xFFFFB000_0XXXXXXX ~ 0xFFFFB000_3XXXXXXX 空间,共 1G 空间



(3)F-segment(0xFFFFF000_XXXXXXXX):

★ 为 kernel stack 只准备了 3-Entry(PDPT[3]),即:0xFFFFF000_CXXXXXXX ~ 0xFFFFF000_FXXXXXX 空间,共 1G 空间



user 空间:

(1)0-segment(0x00000000_XXXXXXXX):

★ legacy(DOS) 数据区只使用了 0-Entry:即 0x00000000_0XXXXXXX ~ 0x00000000_3XXXXXXX 空间,共 1G

★ compatibility code 区域使用了 1-Entry 和 2-Entry,即:0x00000000_ 4XXXXXXX ~ 0x00000000_8XXXXXXX 空间,共 1G 空间


(2)1-segment(0x00001000_XXXXXXXX):
  这个区域供 64bit OS 的 user 代码使用,使用了 1-Entry、2-Entry 以及 3-Entry,从 0x00001000_4XXXXXXX ~ 0x00001000_FXXXXXXX 地址,共 3G 空间

(3)6-segment(0x00006000_XXXXXXXX):
  这个区域供库代码、以及用户共享代码存处,使用 0-Entry,从 0x00006000_0XXXXXXX~ -0x00006000_3XXXXXXX 地址,共 1G 空间


(4)7-segment(0x00007000_XXXXXXXX):

★ user stack 使用 3-Entry,从 0x00007000_CXXXXXXX ~ 0x00007000_FXXXXXXX 地址,共 1G 空间

★ user heap 使用 2-Entry, 从 0x00007000_8XXXXXXX ~ 0x00007000_BXXXXXXX 地址,共 1G 空间


-------------------------------------------------------------------------------------------------

  由于,使用了 7 个 segment,所以 PDPT 表总共有 7 个,从 PDPT0 ~ PDPT6

PDPT0:对应于 0-segment,使用了 3 个 entries,分别为:PDPT0[0] ~ PDPT0[2]
PDPT1: 对应于 1-segment,使用了 3 个 entries ,分别为:PDPT1[1] ~ PDPT1[3]
PDPT2: 对应于 6-segment,使用了 1 个 entry:PDPT2[0]
PDPT3: 对应于 7-segment,使用了 2 个 entries ,分别为:PDPT3[2] ~ PDPT2[3]
PDPT4: 对应于 8-segment,使用了 3 个 entries ,分别为:PDPT4[0] ~ PDPT4[2]
PDPT5: 对应于 B-segment,使用了 1 个 entry:PDPT5[0]
PDPT6: 对应于 F-segment,使用了 1 个 entry:PDPT6[3]



因此,推导出共有 14 个 PDT 表



3、PDT 表

kernel 空间

(1)system data structure 空间保留 2M 空间使用。(PDPT0 的 0-Entry,即:PDPT0[0])

  那么:PDPT0[0] 使用 1 个 entry 的 PDT 表,也就是说 PDPT0[0] 指向的 PDT 使用了 1 个 entris,分别为:PDT0[0]。所以:这里仅需要 1 个 PDT 表即可。

  最终的 system data structure 空间为:0xFFFF8000_00000000 ~ 0xFFFF8000_001FFFFF(2M)



(2)kernel code 空间(PDPT0 的 1-Entry 和 2-Entry,即:PDPT0[1] ~ PDPT0[2])
  这里,暂时为 kernel code 映射 4M 的空间,使用了 2 个 2M-page。
  因此,这里需要 2 个 PDT 表。

  最终的 kernel code 空间为:0xFFFF8000_40000000 ~ 0xFFFF8000_403FFFFF(4M)

  而剩余的1-Entry 以及 2-Entry 将作为保留,即:0xFFFF8000_40400000 ~ 0xFFFF8000_BFFFFFFF 都将保留未用



(3)B-segment 仅象征性的使用 4K 空间
  这里,仅需要 1 个 PDT 表

  最终的 B-segment 空间为:0xFFFFB000_00000000 ~ 0xFFFFB000_00000FFF (4K)



(4)kernel stack 空间(将使用 64 空间)
  kernel stack 空间为 64K

     F-segment kernel stack 空间为:0xFFFFF000_00FE0000 ~ 0xFFFFF000_00FEFFFF (64K)
 
  由于,stack 需要 16 bytes 对齐,因此,rsp 被置成 0xFFFFF000_00FEFFF0。

   取值范围在 0xFFFFF000_00FE0000 ~ 0xFFFFF000_00FEFFFF

  使用了 1 个 PDT:7-Entry。




user 空间

(1)legacy (DOS)数据区(启动代码区),使用 1M 空间

  为 DOS 区域准备 1M 的空间,仅需 1 个 PDT 表。

  最终的空间为:0x00000000_00000000 ~ 0x00000000_000FFFFF (1M)


(2)compatiblity code 代码区,象征性的使用 2M 空间

  这里需要 1 个 PDT 表

  最终的空间为:0x00000000_40000000 ~ 0x00000000_401FFFFF (2M)


(3)user 代码区域,同样使用了 4M 空间
  但是,这里不象 kernel code 使用 2M-page,用户代码区使用普通的 4K-page,因此,需要 2 个 PDT 表

  最终空间为:0x00001000_40000000 ~ 0x00001000_403FFFFF(4M)



(4)共享代码区域,使用 2M 空间
  这里,使用 2M-page,因此,仅需要 1 个 PDT 表

  最终空间为:0x00006000_00000000 ~ 0x00006000_001FFFFF(2M)



(5)user stack 和 user heap 区域(72M)

user stack 使用 8M 空间,最终的空间为:0x00007000_C0000000 ~ 0x00007000_C07FFFFF(4个 PDT 表)

user heap 使用 64M 空间,最终空间:0x00007000_80000000 ~ 0x00007000_840FFFFF(32 个 PDT 表)


--------------------------------------------------------------------------------------

总共需要 46 个 PDT 表。










[ 本帖最后由 mik 于 2009-9-16 21:40 编辑 ]

论坛徽章:
0
23 [报告]
发表于 2009-09-16 22:25 |只看该作者
4、PTE 表


(1) system data structure 空间:0xFFFF8000_00000000 ~ 0xFFFF8000_001FFFFF (2M)

  这里使用的是 4K-page,所以需要 512 个 PTE,但仅需要 1 个 PT 表。


映射过程是:PML4T[256] ---> PDPT[0] ---> PDT[0] ---> PT[0] ~ PT[511]



(2)kernel code 空间:0xFFFF8000_40000000 ~ 0xFFFF8000_403FFFFF(4M)

  kernel 代码使用 2M-page,因此:无需使用 PT 表


映射过程是:PML4T[256] ---> PDPT[1] ---> PDT[0] ~ PDT[1] (2M-pages)




(3)B-segment 保留空间:0xFFFFB000_00000000 ~ 0xFFFFB000_00000FFF (4K)

  使用 4K-page,所以需要1个PTE,仅需 1 个 PT 表


映射过程是:PML4T[352] ---> PDPT[0] ---> PDT[0] ---> PT[0]




(4)kernel stack 空间:0xFFFFF000_00FE0000 ~ 0xFFFFF000_00FEFFFF (64K)
   
  使用 4K-page,所以需要 16 个 PTEs,1 个 PT 表。

映射过程是:PML4T[480] ---> PDPT[0] ---> PDT[7] ---> PT[480] ~ PT[495]



(5)legacy DOS 区域:0x00000000_00000000 ~ 0x00000000_000FFFFF (1M)

  使用 4k-page,需要 256 个 PTEs,1 个 PT 表

映射过程是:PML4T[0] ---> PDPT[0] ---> PDT[0] ---> PT[0] ~ PT[255]



(6)compatibility code 区域:0x00000000_40000000 ~ 0x00000000_401FFFFF (2M)

  使用 4K-page 需要 512 个 PTEs,1 个 PT 表

映射过程:PML4T[0] ---> PDPT[1] ---> PDT[0] ---> PT[0] ~ PT[511]



(7)user code 空间:0x00001000_40000000 ~ 0x00001000_403FFFFF(4M)

  使用 4K-page 需要 2 个 PT 表,每个 PT 表使用 512 个 PTEs

映射过程:PML4T[32] ---> PDPT[1] ---> PDT[0] ~ PDT[1] ---> PT[0] ---> PT[511]



(8)共享库代码空间:0x00006000_00000000 ~ 0x00006000_001FFFFF(2M)

  使用 4K-page 需要 1 个 PT 表,512 个 PTEs

映射过程:PML4T[192] ---> PDPT[0] ---> PDT[0] ---> PT[0] ~ PT[511]




(9)user stack 空间:0x00007000_C0000000 ~ 0x00007000_C07FFFFF(8M)

  使用 4K-page 需要 4 个 PT 表,每个 PT 表使用 512 个 PTEs

映射过程:PML4T[224] ---> PDPT[3] ---> PDT[0] ~ PDT[3] ---> PT[0] ~ PT[511]



(10)user heap 空间:0x00007000_80000000 ~ 0x00007000_840FFFFF(64M)

  使用 4K-page,需要 32 个 PT,每个 PT 表使用 512 个 PTEs

映射过程:PML4T[224] ---> PDPT[2] ---> PDT[0] ~ PDT[31] ---> PT[0] ~ PT[511]






三、各级 page-transltion table 结构的总结


1、总共需要多少个 page-translation table 结构表

(1)PML4T: 只有 1 个

(2)PDPT: 由于使用了 7 个 PML4Es,所以需要 7 个 PDPT 表

(3)PDT:  每个 PDPT 保留使用了 4 个 PDPE,因此:7 * 4 = 28 个 PDT 表(保留情况)

实际情况是:

★ system data struct 区:使用了 PDPT[0],即:1 个 PDPE,因此,因此需要 1 个 PDT 表
★ kernel code 区:使用了 PDPT[1],即:1 个 PDPE,因此需要 1 个 PDT 表
★ B-segment 区:使用了 PDPT[0],1 个 PDPE,需 1 个 PDT 表
★ kernel stack 区:使用了 PDPT[0],1 个 PDPE,需要 1 个 PDT 表
★ legacy DOS 区:使用了 PDPT[0],1 个 PDPE,需要 1 个 PDT 表
★ compatibility code 区:使用 PDPT[1],1 个 PDPE,需要 1 个 PDT 表
★ user code 区:使用 PDPT[1],1 个 PDPE,需要 1 个 PDT 表
★ shared 区:使用 PDPT[0],1 个 PDPE,需 1 个 PDT 表
★ user stack 区:使用 PDPT[3],1 个 PDPE,需 1 个 PDT 表
★ user heap 区:使用 PDPT[2],1 个 PDPE,需 1 个 PDT 表

共需 10  个 PDT 表


(4)PT 表:
★ system data struct 区:要 1 个 PT 表
★ kernel code 区:不需要
★ B-segment 区:需 1 个 PT 表
★ kernel stack 区:需要 1 个 PT 表
★ legacy DOS 区:要 1 个 PT 表
★ compatibility code 区: 要 1 个 PT 表
★ user code 区:需要 2 个 PT 表
★ shared 区:需 1 个 PT 表
★ user stack 区:需 4 个 PT 表
★ user heap 区:需 32 个 PT 表


共需 44 个 PT 表


---------------------------------------------------------------------------

总共所需的 page-transltion table 是:1+7+10+44= 62 个 table




2、共需多少空间描述 page-transltion table

每个 table 需要 512*8 = 4K,因此 62 * 4K = 248 K 空间






:wink:

[ 本帖最后由 mik 于 2009-9-17 00:53 编辑 ]

论坛徽章:
0
24 [报告]
发表于 2009-09-21 00:35 |只看该作者
                                           19、 地址空间规划的实现

源代码如下:
------------------------------------------------------------------------------------

        bits 32


PG_P         equ 0x01
PG_W      equ 0x02
PG_USER  equ 0x04
PG_PWT     equ 0x08
PG_PCD      equ 0x10
PG_PS       equ  0x80


;---------------------------------
; get_kernel_map_base(mem_size)
; return: kernel_map_base
;---------------------------------
get_kernel_maped_base:
        mov eax, [esp+4]                ; mem size
        dec eax
        shr eax, 1
        add eax, 0x00000FFF                ; (4*1024)-1
        and eax, 0xFFFFF000                ; ~(4*1024-1)
        ret 4

; ----------------------------------
; get_PML4E_index(va_hi32, va_low32)
;
; input: virtual address
; out:          PML4E index
; ----------------------------------
get_PML4E_index:
        mov eax, [esp+4]                                ; VA high32
        and eax, 0x0000ff80
        shr eax, 7
        ret 8
        
; ----------------------------------
; get_PDPE_index(va_hi32, va_low32)
;
; input: virtual address
; out:          PDPE index
; ----------------------------------        
get_PDPE_index:
        push ebp
        mov eax, [esp+8]                                ; VA high32
        mov ebp, [esp+12]                                ; VA low32
        and eax, 0x0000007f
        shl eax, 2
        shr ebp, 30
        add eax, ebp
        pop ebp
        ret 8

; ----------------------------------
; get_PDE_index(va_hi32, va_low32)
;
; input: virtual address
; out:          PDE index
; ----------------------------------        
get_PDE_index:
        mov eax, [esp+8]                                ; VA low32
        and eax, 0x3fe00000
        shr eax, 21
        ret 8

; ----------------------------------
; get_PTE_index(va_hi32, va_low32)
;
; input: virtual address
; out:          PTE index
; ----------------------------------        
get_PTE_index:
        mov eax, [esp+8]                                ; VA low32
        and eax, 0x001ff000
        shr eax, 12
        ret 8
        


; ---------------------------------------------------------------------
; int do_init_page_table(pa_address, va_hi32, va_low32, size, is_2M_page)
;
; input: pa_addess  ----- physical address
;        virtual_address --- virtual address
;        size:  xK size
;        is_2M_page: 1-2M_page 0-4K_page
; output: -1: failure
;          0: successed
;-------------------------------------------------------------------
do_init_page_table:
        jmp do_init_page_table_main
        
segment_number         dd 0                                ; 0-segment --- PDPT0
                                dd 1                                ; 1-segment --- PDPT1
                                dd 0                                ; 2-segment --- reserved
                                dd 0                                ; 3-segment --- reserved
                                dd 0                                ; 4-segment --- reserved
                                dd 0                                ; 5-segment --- reserved
                                dd 2                                ; 6-segment --- PDPT2
                                dd 3                                ; 7-segment --- PDPT3
                                dd 4                                ; 8-segment --- PDPT4
                                dd 0                                ; 9-segment --- reserved
                                dd 0                                ; A-segment --- reserved
                                dd 5                                ; B-segment --- PDPT5
                                dd 0                                ; C-segment --- reserved
                                dd 0                                ; D-segment --- reserved
                                dd 0                                ; E-segment --- reserved
                                dd 6                                ; F-segment --- PDPT5
        
do_init_page_table_main:        
        mov edi, [esp+4]                                ; 32-bit physical address
        mov esi, [esp+8]                                ; 64 bit virtual address high 32
        mov ebx, [esp+12]                                ; 64-bit virtual address low 32

        mov eax, [mem_total]
        push eax
        call get_kernel_maped_base                                ; eax <---- kernel_maped_base
        mov ebp, eax
        
        push ebp                                                                ; save kernel_maped_base
        
        
        
; -------------------------------
; set PML4T entry
; -------------------------------
        push ebx
        push esi
        call get_PML4E_index
        push eax
        shr eax, 5
        mov eax, [segment_number + eax *4]                ; get segment number
        push eax                                                        ; save segment number
        shl eax, 12                                                     ; eax = eax * 4K
        mov edx, [ebp + PDPT_BASE_OFFSET]                ; edx <--- PDPT_BASE
        lea edx, [edx + eax]                                        ; edx <--- PDPTx_BASE
        mov ecx, [ebp + PML4T_BASE_OFFSET]
        pop ebp                                                        ; ebp <--- segment number
        pop eax                                                         ; PML4E index
        mov dword [ecx + eax * 8], edx                        ; PML4T[PML4E] <--- PDPTx_BASE
        mov dword [ecx + eax * 8 + 4], 0
        
        cmp eax, 0x100                                                        ; 8-segment ???
        jae do_init_supervisor_page
        or dword [ecx + eax * 8], PG_P | PG_W | PG_USER
        
do_init_supervisor_page:
        or dword [ecx + eax * 8], PG_P | PG_W
;-----------------------------------------------------
; now: edx = PDPTx_base  ebp = segment number
;      eax = PML4E       ecx = PML4T_BASE
;
;      [esp] = kernel_maped_base
;-----------------------------------------------------
        

        mov ecx, ebp                                ; ecx = segment number
        pop ebp
        push ecx                                        ; save segment number
        
; ---------------------------------------------------
; set PDPT entry
; ---------------------------------------------------        
        push ebx                                                        ; low32
        push esi                                                        ; hi32
        call get_PDPE_index
        push eax
        shl ecx, (PDPT_ENTRIES/2)                   ; segment_number * PDPT_ENTRIES (segment_number * 4)
        shl ecx, 12                             ;segment_number * PDPT_ENTRIES * 4K (segment_number * 4 * 4K)
        shl eax, 12                                              ; eax = PDPE_index * 4K
        lea ecx, [ecx + eax]                                ; ecx = PDT_BASE-offset
        mov eax, [ebp + PDT_BASE_OFFSET]        ; eax = PDT_BASE
        lea ecx, [eax + ecx]                                ; PDTx_BASE
        pop eax
        mov [edx + eax * 8], ecx                        ; PDPT[PDPE] = PDTx_BASE
        mov dword [edx + eax * 8 + 4], 0
        
        or dword [edx + eax * 8], PG_P | PG_W | PG_USER


;-----------------------------------------------------------
; Now: eax = PDPE_index                 ecx = PDTx_BASE
;           edx = PDPTx_base                        ebp = kernel_maped_base
;
;      [esp] = segment number
;-----------------------------------------------------------        


        pop edx                                                                ; edx = segment_number
;----------------------------------------------------------
; set PDT entry
;----------------------------------------------------------        
        shl eax, 21                                                        ; PDPE_index * 2M
        shl edx, 23                                                        ; segment_number * 8M
        add edx, eax                                                ; (segment_number * 8M) + (PDPE_index * 2M)
        
        push ebx
        push esi
        call get_PDE_index
        push eax                                                        ; save PDE_index
        shl eax, 12                                                        ; PDE * 4K
        add edx, eax                                      ; PTx_BASE offset (segment * 8M + PDPE * 2M + PDE * 4K)
        mov eax, [ebp + PT_BASE_OFFSET]                ; edx = PT_BASE
        lea edx, [eax + edx]                                ; edx = PTx_BASE
        pop eax                                                                ; eax = PDE
        
        
        push ebp                                                        ; save kernel_maped_base
        push edx                                                        ; save PTx_BASE
               
        mov ebp, [esp + 28]                                        ; is_2M_page
        mov edx, [esp + 24]                                        ; size
        
        test ebp, ebp
        jz set_PDT_entry_4K

        pop ebp
        pop ebp
        
set_PDT_entry_2M_loop:

        and edi, 0xffe00000                                        ; get 2M-page
        mov dword [ecx + eax * 8], edi
        mov dword [ecx + eax * 8 + 4], 0
        or dword [ecx + eax * 8], PG_PS | PG_P | PG_W | PG_USER
        
        sub edx, 2*1024*1024                                ; 2M
        jle do_init_page_table_succeed        
        
        inc eax
        add edi, 2*1024*1024
        jmp set_PDT_entry_2M_loop

        
set_PDT_entry_4K:        
        mov ebp, [esp]                                                ; ebp <--- PTx_BASE
        
set_PDT_entry_4K_loop:
        mov [ecx + eax * 8], ebp                        ; PDT[PDE] <--- PTx_BASE
        mov dword [ecx + eax * 8 + 4], 0
        or dword [ecx + eax * 8], PG_P | PG_W | PG_USER
        
        sub edx, 2*1024*1024
        jle set_PDT_entry_4K_next
        
        inc eax
        add ebp, 4*1024                                                ; next PT
        jmp set_PDT_entry_4K_loop

set_PDT_entry_4K_next:

        pop edx
        pop ebp
        
;-----------------------------------------------------------
; Now: eax = PDE_index                 ecx = PDTx_BASE
;           edx = PTx_base                ebp = kernel_maped_base
;
;      [esp] = segment_number
;-----------------------------------------------------------        
        
;***********************************************
; set PT entry
;***********************************************
        
        push ebx
        push esi
        call get_PTE_index
        
        mov ecx, [esp + 16]                                                ; size
        mov ebp, [esp + 20]                                                ; is_2M_page

        test ebp, ebp
        jnz do_init_page_table_failure

set_PT_entry_loop:        
        and edi, 0xfffff000                                                ; physical address        
        mov dword [edx + eax * 8], edi                        ; PTE <----- page
        mov dword [edx + eax * 8 + 4], 0
        or dword [edx + eax * 8], PG_P | PG_W | PG_USER
        
        sub ecx, 4*1024
        jle do_init_page_table_succeed
        
        inc eax
        add edi, 4*1024
        jmp set_PT_entry_loop
        
do_init_page_table_succeed:
        xor eax, eax
        jmp do_init_page_table_done
        
do_init_page_table_failure:
        mov eax, -1
        
do_init_page_table_done:
        ret 20



;---------------------------------
;
; int init_page_struct(void)
;---------------------------------

init_page_struct:
        mov eax, dword [mem_total]
        mov ebx, eax
        push eax
        call get_kernel_maped_base
        test eax, eax                                                                 ; eax <--- kernel_maped_base
        jz init_page_struct_failure
        cmp eax, KERNEL_EREA_SIZE
        jl init_page_struct_failure
        
    mov dword [eax + KERNEL_MAPED_BASE_OFFSET], eax   ; [KERNEL_MAPED_BASE] <-- kernel_maped_base
    mov dword [eax + MEMORY_SIZE_OFFSET], ebx             ; [MEMORY_SIZE_BASE] <--- memory_size
        lea ebx, [eax + SYSTEM_DATA_SIZE]
        mov dword [eax + PML4T_BASE_OFFSET], ebx            ; [PML4T_BASE] <--- pml4t_base
        lea ebx, [ebx + PML4T_SIZE]
        mov dword [eax + PDPT_BASE_OFFSET], ebx               ; [PDPT_BASE] <--- pdpt_base
        lea ebx, [ebx + PDPT_SIZE]                        
        mov dword [eax + PDT_BASE_OFFSET], ebx                 ; [PDT_BASE] <--- pdt_base
        lea ebx, [ebx + PDT_SIZE]                        
        mov dword [eax + PT_BASE_OFFSET], ebx                   ; [PT_BASE] <--- pt_base
        lea ebx, [ebx + PT_SIZE]
        add ebx, 0x0FFFFF
        and ebx, 0xFFF00000
        mov dword [eax + KERNEL_CODE_BASE_OFFSET], ebx   ; [KERNEL_CODE_BASE] <--- kernel_code_base
        add ebx, KERNEL_CODE_SIZE + 1*1024*1024
        mov dword [eax + B_SEGMENT_BASE_OFFSET], ebx     ; [B_SEGMENT_BASE] <---- b_segment_base
        add ebx, RESERVED_SIZE + 1024*1024
    mov dword [eax + KERNEL_STACK_BASE_OFFSET], ebx ; [KERNEL_STACK_BASE] <---- kernel_stack_base
        add ebx, KERNEL_STACK_SIZE + 1024*1024
        mov dword [eax + KERNEL_HEAP_BASE_OFFSET], ebx    ; [KERNEL_HEAP_BASE] <--- kernel_heap_base
        
        xor ebx, ebx
        mov dword [eax + DOS_BASE_OFFSET], ebx                              ; [DOS_BASE] <--- 0
        add ebx, DOS_SIZE + 1024*1024

;**** [COMPATIBILITY_CODE_BASE] <--- compatibility_code_base

        mov dword [eax + COMPATIBILITY_CODE_BASE_OFFSET], ebx   
        add ebx, COMPATIBILITY_CODE_SIZE + 1024*1024
        mov dword [eax + USER_CODE_BASE_OFFSET], ebx          ; [USER_CODE_BASE] <--- user_code_base
        
        add ebx, USER_CODE_SIZE + 1024*1024                                                
        mov dword [eax + SHARED_LIB_BASE_OFFSET], ebx         ; [SHARED_LIB_BASE] <--- shared lib base
        add ebx, SHARED_LIB_SIZE + 1024*1024                                
        mov dword [eax + USER_STACK_BASE_OFFSET], ebx       ; [USER_STACK_BASE] <--- user stack base
        add ebx, USER_STACK_SIZE + 1024*1024
        mov dword [eax + USER_HEAP_BASE_OFFSET], ebx          ; [USER_HEAP_BASE] <---- user heap base
        
        
        
        push eax                ; save kernel_maped_base
        
; -------------------- system data struct area map -------------------------
;
; the system data struct area: 0xffff8000_00000000 ~ 0xffff8000_039fffff (58M)
; --------------------------------------------------------------------------
        
        push dword 0                                                                        ; 2M_page ? 0-4K_page, 1-2M_page
        push SYSTEM_DATA_SIZE + PAGE_STRUCT_SIZE                ; 58M
        push dword 0                                                                        ; low32
        push dword 0xffff8000                                                        ; high32
        push eax                                                                                ; kernel_maped_base
        call do_init_page_table
        
        test eax, eax
        jnz init_page_struct_failure


;--------------- kernel code area map ------------------------------
;
; the kernel code area: 0xFFFF8000_40000000 ~ 0xFFFF8000_403FFFFF (4M)
;-------------------------------------------------------------------
        mov eax, [esp]
        mov eax, [eax + KERNEL_CODE_BASE_OFFSET]
        
        push dword 1                                                        ; 4M-page
        push dword KERNEL_CODE_SIZE
        push dword 0x40000000
        push dword 0xffff8000
        push eax
        call do_init_page_table
        
        test eax, eax
        jnz init_page_struct_failure
        

        
;--------------- B-segment area map ------------------------------
;
; B-segment area: 0xFFFFB000_00000000 ~ 0xFFFFB000_00000FFF (4K)
;-------------------------------------------------------------------
        mov eax, [esp]
        mov eax, [eax + B_SEGMENT_BASE_OFFSET]
        
        push dword 0                                                        ; 4K-page
        push dword RESERVED_SIZE
        push dword 0x00000000
        push dword 0xffffB000
        push eax
        call do_init_page_table
        
        test eax, eax
        jnz init_page_struct_failure        
        

;--------------- kernel stack area map ------------------------------
;
; the kernel stack area: 0xFFFFF000_FFFE0000 ~ 0xFFFFF000_FFFEFFFF (64K)
;-------------------------------------------------------------------
        mov eax, [esp]
        mov eax, [eax + KERNEL_STACK_BASE_OFFSET]
        
        push dword 0                                                        ; 4K-page
        push dword KERNEL_STACK_SIZE
        push dword 0xfffe0000
        push dword 0xfffff000
        push eax
        call do_init_page_table
        
        test eax, eax
        jnz init_page_struct_failure

        

;------------------------ kernel heap area map -------------------------------        
;
; the kernel heap area: 0xFFFFF000_00000000 ~ 0xFFFFF000_000FFFFF (1M)
;-----------------------------------------------------------------------------
        mov eax, [esp]
        mov eax, [eax + KERNEL_HEAP_BASE_OFFSET]
        
        push dword 0                                                        ; 4K-page
        push dword KERNEL_HEAP_SIZE
        push dword 0x00000000
        push dword 0xfffff000
        push eax
        call do_init_page_table
        
        test eax, eax
        jnz init_page_struct_failure        



;--------------- legacy DOS area map ------------------------------
;
; the legacy DOS area: 0x00000000_00000000 ~ 0x00000000_000FFFFF (1M)
;-------------------------------------------------------------------

        mov eax, [esp]
        mov eax, [eax + DOS_BASE_OFFSET]
        
        push dword 0                                                        ; 4K-page
        push dword DOS_SIZE
        push dword 0x00000000
        push dword 0x00000000
        push eax
        call do_init_page_table
        
        test eax, eax
        jnz init_page_struct_failure        



;--------------- compatibility code area map ------------------------------
;
; the ccompatibility code area: 0x00000000_40000000 ~ 0x00000000_401FFFFF (1M)
;-------------------------------------------------------------------
        
        mov eax, [esp]
        mov eax, [eax + COMPATIBILITY_CODE_BASE_OFFSET]

        push dword 0                                                        ; 4K-page
        push dword COMPATIBILITY_CODE_SIZE
        push dword 0x40000000
        push dword 0x00000000
        push eax
        call do_init_page_table
        
        test eax, eax
        jnz init_page_struct_failure        
        
        
        
;--------------- user code area map ------------------------------
;
; the user code area: 0x00001000_40000000 ~ 0x00001000_403FFFFF (4M)
;-------------------------------------------------------------------
        mov eax, [esp]
        mov eax, [eax + USER_CODE_BASE_OFFSET]

        push dword 0                                                        ; 4K-page
        push dword USER_CODE_SIZE
        push dword 0x40000000
        push dword 0x00001000
        push eax
        call do_init_page_table
        
        test eax, eax
        jnz init_page_struct_failure               
        

;--------------- shared lib area map ------------------------------
;
; the shared lib area: 0x00006000_00000000 ~ 0x00006000_001FFFFF (2M)
;-------------------------------------------------------------------
        mov eax, [esp]
        mov eax, [eax + SHARED_LIB_BASE_OFFSET]
        
        push dword 0                                                        ; 4K-page
        push dword SHARED_LIB_SIZE
        push dword 0x00000000
        push dword 0x00006000
        push eax
        call do_init_page_table
        
        test eax, eax
        jnz init_page_struct_failure               

        
;--------------- user stack area map ------------------------------
;
; the user stack area: 0x00007000_C0000000 ~ 0x00007000_C07FFFFF (8M)
;-------------------------------------------------------------------
        mov eax, [esp]
        mov eax, [eax + USER_STACK_BASE_OFFSET]
        
        push dword 0                                                        ; 4K-page
        push dword USER_STACK_SIZE
        push dword 0xC0000000
        push dword 0x00007000
        push eax
        call do_init_page_table
        
        test eax, eax
        jnz init_page_struct_failure        
        

;--------------- user heap area map ------------------------------
;
; the user stack area: 0x00007000_80000000 ~ 0x00007000_83FFFFFF (64M)
;-------------------------------------------------------------------

        pop eax
        mov eax, [eax + USER_HEAP_BASE_OFFSET]
        
        push dword 0                                                        ; 4K-page
        push dword USER_HEAP_SIZE
        push dword 0x80000000
        push dword 0x00007000
        push eax
        call do_init_page_table
        
        test eax, eax
        jnz init_page_struct_failure               
        
        xor eax, eax
        
init_page_struct_failure:
        mov eax, -1

init_page_struct_done:        
        ret




改天有时间再讲解。

论坛徽章:
0
25 [报告]
发表于 2011-06-12 21:40 |只看该作者
楼主加油

论坛徽章:
0
26 [报告]
发表于 2014-11-28 14:28 |只看该作者
赞一个:wink:

论坛徽章:
0
27 [报告]
发表于 2014-12-10 08:50 |只看该作者
:wink:极度感谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP