mm.asm
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· 汇编 代码 · 共 349 行
ASM
349 行
; -----------------------------------------------
; $Id: mm.asm,v 1.2 2004/01/20 19:30:17 epr Exp $
;
; Memory manager
;
; Author : E.Prangsma
; -----------------------------------------------
global Lkernel_esp
global Lsetup_mm
;extern sys_print_str
;extern sys_print_eax
extern vmCurProcessor
pd_paddr equ 0x00001000 ; Physical address of page dir
pg0_paddr equ 0x00002000 ; Physical address of first page table
pg1_paddr equ 0x00003000 ; Physical address of second page table
free_paddr equ 0x00004000 ; First free memory
mem_start dd 0 ; Start of physical memory
mem_size dd 0 ; The total size of memory from address 0 (in bytes)
initJar_start dd 0 ; Start address of initial jarfile
initJar_end dd 0 ; End address of initial jarfile
free_mem_start dd 0 ; Start address of free memory heap
; ---------------------------
; setup the memory manager
; ---------------------------
Lsetup_mm:
mov [mem_size],ebx
mov eax,[rmc_memstart]
; Page align
add eax,0x1000
and eax,~0xfff
mov [mem_start],eax
; Print config
mov eax,mem_start_str
call sys_print_str
mov eax,[mem_start]
call sys_print_eax
mov eax,mem_size_str
call sys_print_str
mov eax,[mem_size]
call sys_print_eax
;
; Fixup the TSS entry in the GDT
;
mov eax,tss
pushf
pop dword [eax+0x24]
mov word [gdt_tss+2],ax
shr eax,16
mov byte [gdt_tss+4],al
mov byte [gdt_tss+7],ah
;
; Fixed the cur Processor entry in the GDT
;
mov eax,vmCurProcessor
mov word [gdt_curProc+2],ax
shr eax,16
mov byte [gdt_curProc+4],al
mov byte [gdt_curProc+7],ah
;
; Now reload our own GDT
;
lgdt [gdt]
jmp dword KERNEL_CS:mm_gdt_flush
mm_gdt_flush:
;
; Now load the TSS into TR
;
mov eax,0x28
ltr ax
; set IOPL to 3
pushf
pop eax
or eax,F_IOPL1 | F_IOPL2
push eax
popf
jmp mm_ltr_flush
mm_ltr_flush:
; Now setup paging mechanism for the all memory in the system
; The first 4Mb is setup using 4Kb pages all mapped such that physical address and virtual
; address is equal. The only exception is the first page (address 0). This page is not present
; in order to detect nullpointer exceptions.
; The remaining addressspace from 4Mb to 4Gb-4Mb is setup using 4Mb pages. The last 4Mb page is
; not present also to detect nullpointer exceptions.
; First setup the page dir (located at 0x00001000)
mov eax,init_pd_msg
call sys_print_str
; Setup the Page Dir. First we will just fill it with 4Mb pages.
cld
mov eax,PF_DEFAULT|iPF_PSE
mov edi,pd_paddr
mov ecx,1024
pd_lp:
stosd ; Set pdir entry
add eax,0x400000 ; Go to next 4Mb.
loop pd_lp
; Now setup page 0
xor eax,eax
mov edi,pg0_paddr
mov ecx,1024
pg0_lp:
and eax,iPF_ADDRMASK ; Clear all pageflags (since this is page0, eax now contains the physical address)
; Compare with kernel limits
cmp eax,kernel_begin
jb pg0_rw
cmp eax,kernel_end
jae pg0_rw
or eax,PF_DEFAULT_RO ; Mark kernel pages readonly
jmp pg0_1
pg0_rw:
or eax,PF_DEFAULT ; Mark non-kernel pages read-write
pg0_1:
stosd ; Set pg0 entry
add eax,0x1000 ; Go to next 4Kb
loop pg0_lp
; Now clear first 4Kb page
mov edi,pg0_paddr
and dword [edi],0
; Now set pg0 in pdir
mov eax,pg0_paddr
mov edi,pd_paddr
or eax,PF_DEFAULT
mov [edi],eax
; Now mark the last 4Mb in pdir empty
mov edi,pd_paddr
and dword [edi+(1023*4)],0
; Now enable paging
mov eax,enable_pg_msg
call sys_print_str
; Set the pdir address
mov eax,pd_paddr
mov cr3,eax
; Set PSE in CR4 to enable 4Mb extensions
mov eax,CR4
or eax,CR4_PSE
mov cr4,eax
; Set PG in CR0 to enable paging
mov eax,cr0
or eax,CR0_PG
mov cr0,eax
; Jump to flush any caches
jmp pg_flush
pg_flush:
; OK now we're going to setup the physical page usage map.
mov eax,done_pg_msg
call sys_print_str
ret
; Initialize a page table
; Input:
; EDI the address of the pagetable
; EDX the base address of the first page in the table
init_pt:
push eax
push ebx
push edx
push edi
;mov eax,edx
;call sys_print_eax
xor eax,eax
init_pt_lp:
; Calculate page address
mov ebx,eax
shl ebx,12
add ebx,edx
; Compare with kernel limits
cmp ebx,kernel_begin
jb init_pt_rw
cmp ebx,kernel_end
jae init_pt_rw
or ebx,PF_DEFAULT_RO ; Mark kernel pages readonly
jmp init_pt_1
init_pt_rw:
or ebx,PF_DEFAULT ; Mark non-kernel pages read-write
init_pt_1:
mov [edi+eax*4],ebx
inc eax
cmp eax,1024
jne init_pt_lp
; Now make the table known in th page directory table
mov ebx,pd_paddr
shr edx,22
or edi,PF_DEFAULT
mov [ebx+edx*4],edi
pop edi
pop edx
pop ebx
pop eax
ret
mem_start_str: db 'mem-start ',0
mem_size_str: db 0xd,0xa,'mem-size ',0
init_pd_msg: db 'init page-dir table',0xd,0xa,0
init_pg0_msg: db 'init page 0 table',0xd,0xa,0
enable_pg_msg: db 'enable paging',0xd,0xa,0
done_pg_msg: db 'paging setup finished',0xd,0xa,0
; -----------------------------------------------
; GDT
; -----------------------------------------------
gdt:
dw 56-1
dd gdtstart
gdtstart:
; Entry 0, should be NULL
dd 0 ;null
dd 0
; Entry 1 (selector 0x08)
; Kernel CS
dw 0ffffh ;limit
dw 0 ;base
db 0 ;more base
db 9ah ;dpl=0,code
db 0cfh ;other stuff (i forget), more limit
db 0 ;base
; Entry 2 (selector 0x10)
; Kernel DS
dw 0ffffh
dw 0
db 0
db 92h ;dpl=0,data
db 0cfh
db 0
; Entry 3 (selector 0x1B)
; User CS
dw 0ffffh ;limit
dw 0 ;base
db 0 ;more base
db 0xFA ;dpl=3,code
db 0xCF ;other stuff (i forget), more limit
db 0 ;base
; Entry 4 (selector 0x23)
; User DS
dw 0ffffh
dw 0
db 0
db 0xF2 ;dpl=3,data
db 0xCF
db 0
; Entry 5 (select 0x28)
; TSS
gdt_tss:
dw tss_e-tss
dw 0 ; Fixed later
db 0 ; Fixed later
db 0x89
db 0
db 0 ; Fixed later
; Entry 6 (select 0x33)
; Current processor
gdt_curProc:
dw VmX86Processor_SIZE
dw 0 ; Fixed later
db 0 ; Fixed later
db 0xF2 ;dpl=3,data
db 0
db 0 ; Fixed later
; -----------------------------------------------
; TSS
; -----------------------------------------------
tss:
; 0x00
dd 0 ; Terugkoppeling
dd Lkernel_esp ; ESP0
dw KERNEL_DS ; SS0
dw 0 ; R
dd 0 ; ESP1
; 0x10
dd 0 ; R - SS1
dd 0 ; ESP2
dd 0 ; R - SS2
dd pd_paddr ; CR3
; 0x20
dd 0 ; EIP
dd 0 ; EFLAGS
dd 0 ; EAX
dd 0 ; ECX
; 0x30
dd 0 ; EDX
dd 0 ; EBX
dd Luser_esp ; ESP
dd 0 ; EBP
; 0x40
dd 0 ; ESI
dd 0 ; EDI
dd USER_DS ; ES
dd USER_CS ; CS
; 0x50
dd USER_DS ; SS
dd USER_DS ; DS
dd USER_DS ; FS
dd USER_DS ; GS
; 0x60
dd 0 ; LDT
dw 0 ; R
dw 0xFFFF ; I/O bitmap basis (0xFFFF means NULL)
tss_e:
kernel_stack:
; Reserve 16K kernel stack space
times 8*1024 dd 0
Lkernel_esp:
dd 0
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?