Implemented Paging! Moved Kernel to 0x100000, Moved TSS above 1M, Moved V86 to 0x8000, Moved Usermode test to 0x400000, Moved lots of things!
This commit is contained in:
parent
43e902e83c
commit
afaf5e1a03
6
Makefile
6
Makefile
@ -1,5 +1,5 @@
|
||||
objects = entry.o kernel.o task.o handler.o interrupt.o v86.o print.o tss.o dosfs/dosfs.o
|
||||
CFLAGS = -target "i686-elf" -m32 -mgeneral-regs-only -ffreestanding -march=pentium-m -fno-stack-protector -nostdlib -c
|
||||
objects = entry.o kernel.o task.o handler.o interrupt.o v86.o print.o tss.o dosfs/dosfs.o gdt.o usermode.o paging.o
|
||||
CFLAGS = -target "i686-elf" -m32 -mgeneral-regs-only -ffreestanding -march=pentium-m -fno-stack-protector -Wno-int-conversion -nostdlib -c
|
||||
|
||||
%.o: %.nasm
|
||||
nasm -f elf32 -o $@ $<
|
||||
@ -9,7 +9,7 @@ CFLAGS = -target "i686-elf" -m32 -mgeneral-regs-only -ffreestanding -march=penti
|
||||
|
||||
all: $(objects)
|
||||
nasm boot.nasm -o boot.bin
|
||||
gcc -Tlink.ld -m32 -ffreestanding -nostartfiles -nostdlib -o kernel.bin\
|
||||
gcc -Tlink.ld -Wl,-M -m32 -ffreestanding -nostartfiles -nostdlib -o kernel.bin\
|
||||
$(objects)
|
||||
dd bs=256 count=1 conv=notrunc if=boot.bin of=virtdisk.bin
|
||||
dd bs=512 seek=1 conv=notrunc if=kernel.bin of=virtdisk.bin
|
||||
|
37
boot.nasm
37
boot.nasm
@ -7,7 +7,7 @@ mov es, ax
|
||||
mov ah, 0x42
|
||||
mov si, addr_packet
|
||||
int 0x13
|
||||
jnc 0x8000
|
||||
jnc entry
|
||||
push 0xb800
|
||||
pop es
|
||||
xor di, di
|
||||
@ -21,6 +21,41 @@ loop err_print
|
||||
hlt_loop:
|
||||
hlt
|
||||
jmp hlt_loop
|
||||
entry:
|
||||
cli ; no interrupts
|
||||
xor ax,ax
|
||||
mov ds, ax
|
||||
lgdt [gdt_desc] ; load gdt register
|
||||
mov eax, cr0 ; set pmode bit
|
||||
or al, 1
|
||||
mov cr0, eax
|
||||
jmp 08h:Pmode
|
||||
[BITS 32]
|
||||
Pmode:
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov esi, 0x8000
|
||||
mov edi, 0x100000
|
||||
mov ecx, 0x10000
|
||||
rep movsb
|
||||
jmp 08h:0x100000
|
||||
gdt_desc:
|
||||
dw gdt_end - gdt
|
||||
dd gdt
|
||||
gdt:
|
||||
gdt_null: dq 0
|
||||
gdt_code: dw 0xFFFF, 0 ; bits 0-15 limit (4GB), bits 0-15 base address
|
||||
db 0 ; bits 16-23 base address
|
||||
db 10011010b ; access byte
|
||||
db 11001111b ; bits 16-19 limit (4GB), 4 bits flags
|
||||
db 0 ; bits 24-31 base address
|
||||
gdt_data: dw 0xFFFF, 0 ; bits 0-15 limit (4GB), bits 0-15 base address
|
||||
db 0 ; bits 16-23 base address
|
||||
db 10010010b ; access byte
|
||||
db 11001111b ; bits 16-19 limit (4GB), 4 bits flags
|
||||
db 0 ; bits 24-31 base address
|
||||
gdt_end:
|
||||
|
||||
string: db 'DISK ERROR'
|
||||
|
||||
|
118
entry.nasm
118
entry.nasm
@ -1,14 +1,9 @@
|
||||
[BITS 16]
|
||||
global entry
|
||||
entry:
|
||||
cli ; no interrupts
|
||||
xor ax,ax
|
||||
mov ds, ax
|
||||
lgdt [gdt_desc] ; load gdt register
|
||||
mov eax, cr0 ; set pmode bit
|
||||
or al, 1
|
||||
mov cr0, eax
|
||||
jmp 08h:Pmodecode
|
||||
jmp Pmodecode
|
||||
|
||||
extern gdt_desc
|
||||
|
||||
[BITS 32]
|
||||
Pmodecode:
|
||||
@ -30,110 +25,3 @@ hlt
|
||||
jmp hlt_loop
|
||||
|
||||
extern start
|
||||
|
||||
; currently unused first 8MB identity paging
|
||||
; taken from Linux 0.01
|
||||
setup_paging:
|
||||
mov ecx, 1024*3 ; 3K?
|
||||
xor eax, eax
|
||||
mov edi, 0x1000
|
||||
rep stosd ; zero first 3K for some reason
|
||||
mov edi, 0x4000
|
||||
mov eax, 0x800007 ; 8MB + 7
|
||||
std ; fill backwards
|
||||
.fill:
|
||||
stosd
|
||||
sub eax, 0x1000
|
||||
jge .fill
|
||||
cld ; fix direction
|
||||
mov dword [0x0000], 0x2000 + 7
|
||||
mov dword [0x0004], 0x3000 + 7
|
||||
mov eax, 0x1000
|
||||
mov cr3, eax ; page dir start 0x1000
|
||||
mov eax, cr0
|
||||
or eax, 0x80000000
|
||||
mov cr0, eax ; set paging bit
|
||||
ret ; flushes pre-fetch queue
|
||||
|
||||
user_test:
|
||||
mov dword [0xb8000], 0x0f000f00 | 'U' | 's' << 16
|
||||
mov dword [0xb8004], 0x0f000f00 | 'e' | 'r' << 16
|
||||
mov dword [0xb8008], 0x0f000f00 | 'm' | 'o' << 16
|
||||
mov dword [0xb800C], 0x0f000f00 | 'd' | 'e' << 16
|
||||
mov word [0xb8010], 0x0f00 | '!'
|
||||
mov edi, 0xA0000
|
||||
xor eax, eax
|
||||
.loop:
|
||||
mov ecx, 320
|
||||
rep stosb
|
||||
inc al
|
||||
cmp eax, 200
|
||||
jl .loop
|
||||
mov eax, 0xA0000
|
||||
int 0x30 ; Exit
|
||||
xor ebx, ebx
|
||||
div bl ; Unhandled DIV0 exception
|
||||
|
||||
global jmp_usermode_test
|
||||
jmp_usermode_test:
|
||||
pop eax ; return address
|
||||
mov ecx, esp ; return stack
|
||||
call save_current_task
|
||||
mov esp, 0x500000 ; usermode stack
|
||||
mov eax, 0x20 | 3
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov eax, esp
|
||||
push 0x20 | 3
|
||||
push eax
|
||||
pushfd
|
||||
push 0x18 | 3
|
||||
push user_test
|
||||
iret
|
||||
|
||||
extern save_current_task
|
||||
|
||||
global flushTSS
|
||||
flushTSS:
|
||||
mov ax, 0x28
|
||||
ltr ax
|
||||
ret
|
||||
|
||||
extern tss_data
|
||||
|
||||
global ivt
|
||||
ivt: dd 0x00000000
|
||||
|
||||
gdt_desc:
|
||||
dw gdt_end - gdt
|
||||
dd gdt
|
||||
gdt:
|
||||
gdt_null: dq 0
|
||||
gdt_code: dw 0xFFFF, 0 ; bits 0-15 limit (4GB), bits 0-15 base address
|
||||
db 0 ; bits 16-23 base address
|
||||
db 10011010b ; access byte
|
||||
db 11001111b ; bits 16-19 limit (4GB), 4 bits flags
|
||||
db 0 ; bits 24-31 base address
|
||||
gdt_data: dw 0xFFFF, 0 ; bits 0-15 limit (4GB), bits 0-15 base address
|
||||
db 0 ; bits 16-23 base address
|
||||
db 10010010b ; access byte
|
||||
db 11001111b ; bits 16-19 limit (4GB), 4 bits flags
|
||||
db 0 ; bits 24-31 base address
|
||||
gdt_r3code: dw 0xFFFF, 0 ; bits 0-15 limit (4GB), bits 0-15 base address
|
||||
db 0 ; bits 16-23 base address
|
||||
db 0xFA ; access byte
|
||||
db 11001111b ; bits 16-19 limit (4GB), 4 bits flags
|
||||
db 0 ; bits 24-31 base address
|
||||
gdt_r3data: dw 0xFFFF, 0 ; bits 0-15 limit (4GB), bits 0-15 base address
|
||||
db 0 ; bits 16-23 base address
|
||||
db 0xF2 ; access byte
|
||||
db 11001111b ; bits 16-19 limit (4GB), 4 bits flags
|
||||
db 0 ; bits 24-31 base address
|
||||
gdt_tss: dw 0x2080, 0x0000;26*4, tss_data ; bits 0-15 limit (4GB), bits 0-15 base address
|
||||
db 0x2 ; bits 16-23 base address
|
||||
db 0x89 ; access byte
|
||||
db 00000000b ; bits 16-19 limit (4GB), 4 bits flags
|
||||
db 0 ; bits 24-31 base address
|
||||
gdt_end:
|
||||
|
35
gdt.nasm
Normal file
35
gdt.nasm
Normal file
@ -0,0 +1,35 @@
|
||||
global ivt
|
||||
ivt: dd 0x00000000
|
||||
|
||||
global gdt_desc
|
||||
gdt_desc:
|
||||
dw gdt_end - gdt
|
||||
dd gdt
|
||||
gdt:
|
||||
gdt_null: dq 0
|
||||
gdt_code: dw 0xFFFF, 0 ; bits 0-15 limit (4GB), bits 0-15 base address
|
||||
db 0 ; bits 16-23 base address
|
||||
db 10011010b ; access byte
|
||||
db 11001111b ; bits 16-19 limit (4GB), 4 bits flags
|
||||
db 0 ; bits 24-31 base address
|
||||
gdt_data: dw 0xFFFF, 0 ; bits 0-15 limit (4GB), bits 0-15 base address
|
||||
db 0 ; bits 16-23 base address
|
||||
db 10010010b ; access byte
|
||||
db 11001111b ; bits 16-19 limit (4GB), 4 bits flags
|
||||
db 0 ; bits 24-31 base address
|
||||
gdt_r3code: dw 0xFFFF, 0 ; bits 0-15 limit (4GB), bits 0-15 base address
|
||||
db 0 ; bits 16-23 base address
|
||||
db 0xFA ; access byte
|
||||
db 11001111b ; bits 16-19 limit (4GB), 4 bits flags
|
||||
db 0 ; bits 24-31 base address
|
||||
gdt_r3data: dw 0xFFFF, 0 ; bits 0-15 limit (4GB), bits 0-15 base address
|
||||
db 0 ; bits 16-23 base address
|
||||
db 0xF2 ; access byte
|
||||
db 11001111b ; bits 16-19 limit (4GB), 4 bits flags
|
||||
db 0 ; bits 24-31 base address
|
||||
gdt_tss: dw 0x2080, 0x0000;26*4, tss_data ; bits 0-15 limit (4GB), bits 0-15 base address
|
||||
db 0x20 ; bits 16-23 base address
|
||||
db 0x89 ; access byte
|
||||
db 00000000b ; bits 16-19 limit (4GB), 4 bits flags
|
||||
db 0 ; bits 24-31 base address
|
||||
gdt_end:
|
16
handler.nasm
16
handler.nasm
@ -9,6 +9,22 @@ mov dword [0xb8008], 0x0f000f00 | 'R' | '!' << 16
|
||||
hlt
|
||||
jmp .hlt
|
||||
|
||||
global pageFaultHandler
|
||||
pageFaultHandler:
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
pop eax ; error code
|
||||
mov ebx, 0x0f000f00 | '0' | '!' << 16
|
||||
and eax, 0x7 ; U/S,R/W,P
|
||||
add ebx, eax
|
||||
mov dword [0xb8000], 0x0f000f00 | 'P' | 'G' << 16
|
||||
mov dword [0xb8004], 0x0f000f00 | 'F' | 'L' << 16
|
||||
mov dword [0xb8008], 0x0f000f00 | 'T' | ':' << 16
|
||||
mov dword [0xb800C], ebx
|
||||
.hlt:
|
||||
hlt
|
||||
jmp .hlt
|
||||
|
||||
extern gpf_handler_v86
|
||||
global gpfHandler
|
||||
gpfHandler:
|
||||
|
@ -237,6 +237,7 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
|
||||
extern void timerHandler();
|
||||
extern void keyboardHandler();
|
||||
extern void gpfHandler();
|
||||
extern void pageFaultHandler();
|
||||
extern void unhandled_handler();
|
||||
extern void picInit();
|
||||
void set_system_gate(uint8_t gate, void (*handler)()) {
|
||||
@ -272,6 +273,7 @@ void setup_interrupts() {
|
||||
set_system_gate(0x21, keyboardHandler);
|
||||
//set_trap_gate(13, gpf_handler_v86);
|
||||
set_trap_gate(13, gpfHandler);
|
||||
set_trap_gate(14, pageFaultHandler);
|
||||
|
||||
asm volatile("lidt %0": : "m"(IDTR));
|
||||
picInit();
|
||||
|
52
kernel.c
52
kernel.c
@ -3,8 +3,8 @@
|
||||
#include "dosfs/dosfs.h"
|
||||
#include "print.h"
|
||||
#include "interrupt.h"
|
||||
|
||||
#include "tss.h"
|
||||
#include "paging.h"
|
||||
|
||||
typedef unsigned short word;
|
||||
|
||||
@ -72,29 +72,49 @@ extern char *jmp_usermode_test();
|
||||
__attribute((__no_caller_saved_registers__))
|
||||
extern void kbd_wait();
|
||||
|
||||
extern char _edata, _v86code, _ev86code, _bstart, _bend, _loadusercode, _usercode, _eusercode;
|
||||
void setup_binary() {
|
||||
// Put V86 code in proper place based on linker
|
||||
char *s = &_edata;
|
||||
char *d = &_v86code;
|
||||
while (d < &_ev86code)
|
||||
*d++ = *s++;
|
||||
|
||||
// Put Usermode code in proper place based on linker
|
||||
s = &_loadusercode;
|
||||
d = &_usercode;
|
||||
while (d < &_eusercode)
|
||||
*d++ = *s++;
|
||||
|
||||
// Clear BSS area
|
||||
for (d = &_bstart; d < &_bend; d++)
|
||||
*d = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Real Mode Accessible (First MB)
|
||||
00000 - 00400 IVT (1kB)
|
||||
00400 - 01000 Unused (3kB)
|
||||
01000 - 04000 Paging (12kB)
|
||||
01000 - 04000 Free (12kB)
|
||||
04000 - 07C00 Free (15kB)
|
||||
07C00 - 08000 Boot (512B)
|
||||
08000 - 20000 Kernel Code (96kB)
|
||||
20000 - 20080 TSS (128B)
|
||||
20080 - 22080 TSS IOMAP (8kB)
|
||||
22080 - 22400 Unused (896B)
|
||||
22400 - 23000 Free (3kB)
|
||||
23000 - 30000 Disk Buffer (52kB)
|
||||
08000 - 20000 V86 Code (96kB)
|
||||
20000 - 30000 Disk Buffer (64kB)
|
||||
30000 - 80000 Free (320kB)
|
||||
80000 - 90000 Real Mode Stack (64kB)
|
||||
90000 - A0000 Free (64kB)
|
||||
A0000 - FFFFF BIOS Area (384kB)
|
||||
A0000 - C0000 VGA (128kB)
|
||||
C0000 - FFFFF BIOS Area (256kB)
|
||||
Protected Only (1MB+)
|
||||
100000 - 300000 Free (2mB)
|
||||
100000 - 200000 Kernel Code (1mB)
|
||||
200000 - 200080 TSS (128B)
|
||||
200080 - 202080 TSS IOMAP (8kB)
|
||||
202080 - 300000 Free (~1mB)
|
||||
300000 - 310000 Task Stack (64kB)
|
||||
310000 - 320000 Interrupt Stack (64kB)
|
||||
320000 - 400000 Kernel Stack (896kB)
|
||||
400000 - 500000 Usermode Stack (1mB)
|
||||
400000 - 700000 Usermode Code (3mB)
|
||||
700000 - 800000 Usermode Stack (1mB)
|
||||
*/
|
||||
|
||||
void TestV86() {
|
||||
@ -218,14 +238,16 @@ void start() {
|
||||
if (!sse) return;
|
||||
enable_sse();
|
||||
|
||||
setup_binary();
|
||||
|
||||
// edit
|
||||
setup_interrupts();
|
||||
setup_tss();
|
||||
print_flags();
|
||||
init_paging();
|
||||
//print_flags();
|
||||
print_cr0();
|
||||
print_cr3();
|
||||
print_cr4();
|
||||
//asm ("xchgw %bx, %bx");
|
||||
//print_cr3();
|
||||
//print_cr4();
|
||||
|
||||
TestV86(); // has int 3 wait in v86
|
||||
TestGfx();
|
||||
|
28
link.ld
28
link.ld
@ -2,18 +2,34 @@ OUTPUT_FORMAT(binary)
|
||||
ENTRY(entry)
|
||||
|
||||
SECTIONS {
|
||||
. = 0x8000;
|
||||
. = 0x100000;
|
||||
|
||||
.text : ALIGN(0x1000) {
|
||||
*(.text)
|
||||
*(.text);
|
||||
}
|
||||
|
||||
.data : ALIGN(0x1000) {
|
||||
*(.data)
|
||||
*(.rodata)
|
||||
*(.data);
|
||||
*(.rodata);
|
||||
*(.rodata*);
|
||||
_edata = .;
|
||||
}
|
||||
|
||||
.bss : ALIGN(0x1000) {
|
||||
*(.bss)
|
||||
.realmode 0x8000 :
|
||||
AT ( ADDR(.data) + SIZEOF(.data) )
|
||||
{ _v86code = .; *(.v86); _ev86code = .; }
|
||||
|
||||
. = ADDR(.data) + SIZEOF(.data) + SIZEOF(.realmode);
|
||||
.thing : { _loadusercode = .; }
|
||||
|
||||
.usermode 0x400000 :
|
||||
AT ( ADDR(.data) + SIZEOF(.data) + SIZEOF(.realmode) )
|
||||
{ _usercode = .; *(.user); _eusercode = .; }
|
||||
|
||||
. = ADDR(.data) + SIZEOF(.data) + SIZEOF(.realmode) + SIZEOF(.usermode);
|
||||
|
||||
.bss : ALIGN(0x1000)
|
||||
{
|
||||
_bstart = .; *(.bss); _bend = .;
|
||||
}
|
||||
}
|
||||
|
50
paging.c
Normal file
50
paging.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include "paging.h"
|
||||
|
||||
uint32_t page_directory[1024] __attribute__((aligned(4096)));
|
||||
uint32_t first_page_table[1024] __attribute__((aligned(4096))); // 0x00000000 - 0x00400000
|
||||
uint32_t second_page_table[1024] __attribute__((aligned(4096))); // 0x00400000 - 0x00800000
|
||||
|
||||
void enable_paging() {
|
||||
asm(
|
||||
"mov %%eax, %%cr3\n"
|
||||
"mov %%cr0, %%eax\n"
|
||||
"or $0x80000001, %%eax\n"
|
||||
"mov %%eax, %%cr0\n"
|
||||
::"a"(page_directory));
|
||||
}
|
||||
|
||||
void init_paging() {
|
||||
for (int i = 0; i < 1024; i++)
|
||||
// Supervisor, R/W, Not Present
|
||||
page_directory[i] = 2;
|
||||
|
||||
// First Page Table
|
||||
// First MB: Real Mode
|
||||
{
|
||||
int i;
|
||||
// Up to 0xC0000
|
||||
// TODO make some areas here Read Only
|
||||
for (i = 0;i < 16*0xC; i++)
|
||||
// User, R/W, Present
|
||||
first_page_table[i] = (i * 0x1000) |4|2|1;
|
||||
// Remainder of first MB BIOS Area (writable?)
|
||||
for (;i < 256; i++)
|
||||
// User, R/W, Present
|
||||
first_page_table[i] = (i * 0x1000) |4|2|1;
|
||||
}
|
||||
// Next 3MB: Kernel
|
||||
for (int i = 256; i < 1024; i++)
|
||||
// Supervisor, R/W, Present
|
||||
first_page_table[i] = (i * 0x1000) |2|1;
|
||||
|
||||
// Usermode Page Table
|
||||
for (int i = 0; i < 1024; i++)
|
||||
// User, R/W, Present
|
||||
second_page_table[i] = (i * 0x1000 + 0x400000) |4|2|1;
|
||||
|
||||
// User, R/W, Present
|
||||
page_directory[0] = ((uintptr_t)first_page_table)|4|2|1;
|
||||
page_directory[1] = ((uintptr_t)second_page_table)|4|2|1;
|
||||
|
||||
enable_paging();
|
||||
}
|
45
task.nasm
45
task.nasm
@ -1,3 +1,9 @@
|
||||
global flushTSS
|
||||
flushTSS:
|
||||
mov ax, 0x28
|
||||
ltr ax
|
||||
ret
|
||||
|
||||
task_ptr: equ (0x310000-4)
|
||||
|
||||
; return address in EAX
|
||||
@ -56,3 +62,42 @@ mov eax, [edx+12+16] ; ds
|
||||
mov ds, ax
|
||||
mov eax, ecx ; restore return value
|
||||
iret
|
||||
|
||||
; extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip);
|
||||
global enter_v86
|
||||
enter_v86:
|
||||
pop eax ; return address
|
||||
mov ecx, esp ; return stack
|
||||
call save_current_task
|
||||
mov ebp, esp ; save stack pointer
|
||||
push dword [ebp+0] ; ss
|
||||
push dword [ebp+4] ; esp
|
||||
pushfd ; eflags
|
||||
or dword [esp], (1 << 17) ; set VM flags
|
||||
;or dword [esp], (3 << 12) ; IOPL 3
|
||||
push dword [ebp+8] ; cs
|
||||
push dword [ebp+12] ; eip
|
||||
iret
|
||||
|
||||
; return address in eax, return stack in ebp
|
||||
;extern save_current_task
|
||||
|
||||
extern user_test
|
||||
global jmp_usermode_test
|
||||
jmp_usermode_test:
|
||||
pop eax ; return address
|
||||
mov ecx, esp ; return stack
|
||||
call save_current_task
|
||||
mov esp, 0x800000 ; usermode stack
|
||||
mov eax, 0x20 | 3
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov eax, esp
|
||||
push 0x20 | 3
|
||||
push eax
|
||||
pushfd
|
||||
push 0x18 | 3
|
||||
push user_test
|
||||
iret
|
||||
|
2
tss.c
2
tss.c
@ -33,7 +33,7 @@ struct __attribute__((__packed__)) tss_entry_struct {
|
||||
};
|
||||
struct tss_entry_struct *tss_data;
|
||||
void write_tss() {
|
||||
tss_data = (struct tss_entry_struct *)0x20000;
|
||||
tss_data = (struct tss_entry_struct *)0x200000;
|
||||
for (int i = 0; i < 0x2080; i++)
|
||||
((uint8_t*)tss_data)[i] = 0;
|
||||
tss_data->ss0 = 0x10;
|
||||
|
20
usermode.nasm
Normal file
20
usermode.nasm
Normal file
@ -0,0 +1,20 @@
|
||||
[SECTION .user]
|
||||
global user_test
|
||||
user_test:
|
||||
mov dword [0xb8000], 0x0f000f00 | 'U' | 's' << 16
|
||||
mov dword [0xb8004], 0x0f000f00 | 'e' | 'r' << 16
|
||||
mov dword [0xb8008], 0x0f000f00 | 'm' | 'o' << 16
|
||||
mov dword [0xb800C], 0x0f000f00 | 'd' | 'e' << 16
|
||||
mov word [0xb8010], 0x0f00 | '!'
|
||||
mov edi, 0xA0000
|
||||
xor eax, eax
|
||||
.loop:
|
||||
mov ecx, 320
|
||||
rep stosb
|
||||
inc al
|
||||
cmp eax, 200
|
||||
jl .loop
|
||||
mov eax, 0xA0000
|
||||
int 0x30 ; Exit
|
||||
xor ebx, ebx
|
||||
div bl ; Unhandled DIV0 exception
|
21
v86.nasm
21
v86.nasm
@ -1,4 +1,5 @@
|
||||
[BITS 16]
|
||||
[SECTION .v86]
|
||||
real_hexprint:
|
||||
xor cx, cx
|
||||
mov bl, al
|
||||
@ -77,23 +78,3 @@ db 0x10, 0x00 ; size, reserved
|
||||
dw 0x1 ; blocks
|
||||
dd 0x23000000 ; transfer buffer 0x23000
|
||||
dq 0x1 ; start block
|
||||
|
||||
[BITS 32]
|
||||
; extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip);
|
||||
global enter_v86
|
||||
enter_v86:
|
||||
pop eax ; return address
|
||||
mov ecx, esp ; return stack
|
||||
call save_current_task
|
||||
mov ebp, esp ; save stack pointer
|
||||
push dword [ebp+0] ; ss
|
||||
push dword [ebp+4] ; esp
|
||||
pushfd ; eflags
|
||||
or dword [esp], (1 << 17) ; set VM flags
|
||||
;or dword [esp], (3 << 12) ; IOPL 3
|
||||
push dword [ebp+8] ; cs
|
||||
push dword [ebp+12] ; eip
|
||||
iret
|
||||
|
||||
; return address in eax, return stack in ebp
|
||||
extern save_current_task
|
||||
|
Loading…
Reference in New Issue
Block a user