184 lines
3.9 KiB
NASM
184 lines
3.9 KiB
NASM
section .data
|
||
|
||
global io_hlt, io_cli, io_sti, io_stihlt
|
||
global io_in8, io_in16, io_in32
|
||
global io_out8, io_out16, io_out32
|
||
global io_load_eflags, io_store_eflags
|
||
global load_gdtr, load_idtr
|
||
global tss_flush, gdt_flush, switch_to, copy_page_physical
|
||
|
||
section .text
|
||
|
||
[GLOBAL copy_page_physical]
|
||
copy_page_physical:
|
||
push ebx ; According to __cdecl, we must preserve the contents of EBX.
|
||
pushf ; push EFLAGS, so we can pop it and reenable interrupts
|
||
; later, if they were enabled anyway.
|
||
cli ; Disable interrupts, so we aren't interrupted.
|
||
; Load these in BEFORE we disable paging!
|
||
mov ebx, [esp+12] ; Source address
|
||
mov ecx, [esp+16] ; Destination address
|
||
|
||
mov edx, cr0 ; Get the control register...
|
||
and edx, 0x7fffffff ; and...
|
||
mov cr0, edx ; Disable paging.
|
||
|
||
mov edx, 1024 ; 1024*4bytes = 4096 bytes
|
||
|
||
.loop:
|
||
mov eax, [ebx] ; Get the word at the source address
|
||
mov [ecx], eax ; Store it at the dest address
|
||
add ebx, 4 ; Source address += sizeof(word)
|
||
add ecx, 4 ; Dest address += sizeof(word)
|
||
dec edx ; One less word to do
|
||
jnz .loop
|
||
|
||
mov edx, cr0 ; Get the control register again
|
||
or edx, 0x80000000 ; and...
|
||
mov cr0, edx ; Enable paging.
|
||
|
||
popf ; Pop EFLAGS back.
|
||
pop ebx ; Get the original value of EBX back.
|
||
|
||
switch_to:
|
||
mov eax, [esp+4]
|
||
|
||
mov [eax+0], esp
|
||
mov [eax+4], ebp
|
||
mov [eax+8], ebx
|
||
mov [eax+12], esi
|
||
mov [eax+16], edi
|
||
pushf
|
||
pop ecx
|
||
mov [eax+20], ecx
|
||
|
||
mov eax, [esp+8]
|
||
|
||
mov esp, [eax+0]
|
||
mov ebp, [eax+4]
|
||
mov ebx, [eax+8]
|
||
mov esi, [eax+12]
|
||
mov edi, [eax+16]
|
||
mov eax, [eax+20]
|
||
push eax
|
||
popf
|
||
|
||
ret
|
||
|
||
[global inw]
|
||
|
||
inw:
|
||
xor eax, eax
|
||
push dx
|
||
|
||
mov dx, [esp + 4]
|
||
in ax, dx
|
||
pop dx
|
||
ret
|
||
|
||
[global read_port]
|
||
|
||
read_port:
|
||
mov edx, [esp + 4]
|
||
in al, dx
|
||
ret
|
||
|
||
[global idt_flush]
|
||
|
||
idt_flush: ; void idt_flush(uint32_t);
|
||
mov eax, [esp + 4]
|
||
lidt [eax]
|
||
ret
|
||
|
||
[global gdt_flush]
|
||
|
||
gdt_flush: ; void gdt_flush(uint32_t gdtr);
|
||
mov eax, [esp + 4] ; [esp+4]按规定是第一个参数,即gdtr
|
||
lgdt [eax] ; 加载新gdt指针,传入的是地址
|
||
|
||
mov ax, 0x10 ; 新数据段
|
||
mov ds, ax
|
||
mov es, ax
|
||
mov fs, ax
|
||
mov gs, ax
|
||
mov ss, ax ; 各数据段全部划给这一数据段
|
||
jmp 0x08:.flush ; cs没法mov,只能用farjmp/farcall,这里用farjmp刷新cs
|
||
.flush:
|
||
ret ; 刷新完毕,返回
|
||
|
||
tss_flush:
|
||
mov ax, 0x2B
|
||
ltr ax
|
||
ret
|
||
|
||
io_hlt: ; void io_hlt(void);
|
||
HLT
|
||
RET
|
||
|
||
io_cli: ; void io_cli(void);
|
||
CLI
|
||
RET
|
||
io_sti: ; void io_sti(void);
|
||
STI
|
||
RET
|
||
io_stihlt: ; void io_stihlt(void);
|
||
STI
|
||
HLT
|
||
RET
|
||
|
||
io_in8: ; int io_in8(int port);
|
||
MOV EDX,[ESP+4] ; port
|
||
MOV EAX,0
|
||
IN AL,DX
|
||
RET
|
||
io_in16: ; int io_in16(int port);
|
||
MOV EDX,[ESP+4] ; port
|
||
MOV EAX,0
|
||
IN AX,DX
|
||
RET
|
||
|
||
io_in32: ; int io_in32(int port);
|
||
MOV EDX,[ESP+4] ; port
|
||
IN EAX,DX
|
||
RET
|
||
|
||
io_out8: ; void io_out8(int port, int util);
|
||
MOV EDX,[ESP+4] ; port
|
||
MOV AL,[ESP+8] ; util
|
||
OUT DX,AL
|
||
RET
|
||
|
||
io_out16: ; void io_out16(int port, int util);
|
||
MOV EDX,[ESP+4] ; port
|
||
MOV EAX,[ESP+8] ; util
|
||
OUT DX,AX
|
||
RET
|
||
|
||
io_out32: ; void io_out32(int port, int util);
|
||
MOV EDX,[ESP+4] ; port
|
||
MOV EAX,[ESP+8] ; util
|
||
OUT DX,EAX
|
||
RET
|
||
|
||
io_load_eflags: ; int io_load_eflags(void);
|
||
PUSHFD ; PUSH EFLAGS
|
||
POP EAX
|
||
RET
|
||
|
||
io_store_eflags: ; void io_store_eflags(int eflags);
|
||
MOV EAX,[ESP+4]
|
||
PUSH EAX
|
||
POPFD ; POP EFLAGS
|
||
RET
|
||
|
||
load_gdtr: ; void load_gdtr(int limit, int addr);
|
||
MOV AX,[ESP+4] ; limit
|
||
MOV [ESP+6],AX
|
||
LGDT [ESP+6]
|
||
RET
|
||
|
||
load_idtr: ; void load_idtr(int limit, int addr);
|
||
MOV AX,[ESP+4] ; limit
|
||
MOV [ESP+6],AX
|
||
LIDT [ESP+6]
|
||
RET |