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
|
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 -nostdlib -c
|
CFLAGS = -target "i686-elf" -m32 -mgeneral-regs-only -ffreestanding -march=pentium-m -fno-stack-protector -Wno-int-conversion -nostdlib -c
|
||||||
|
|
||||||
%.o: %.nasm
|
%.o: %.nasm
|
||||||
nasm -f elf32 -o $@ $<
|
nasm -f elf32 -o $@ $<
|
||||||
@ -9,7 +9,7 @@ CFLAGS = -target "i686-elf" -m32 -mgeneral-regs-only -ffreestanding -march=penti
|
|||||||
|
|
||||||
all: $(objects)
|
all: $(objects)
|
||||||
nasm boot.nasm -o boot.bin
|
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)
|
$(objects)
|
||||||
dd bs=256 count=1 conv=notrunc if=boot.bin of=virtdisk.bin
|
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
|
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 ah, 0x42
|
||||||
mov si, addr_packet
|
mov si, addr_packet
|
||||||
int 0x13
|
int 0x13
|
||||||
jnc 0x8000
|
jnc entry
|
||||||
push 0xb800
|
push 0xb800
|
||||||
pop es
|
pop es
|
||||||
xor di, di
|
xor di, di
|
||||||
@ -21,6 +21,41 @@ loop err_print
|
|||||||
hlt_loop:
|
hlt_loop:
|
||||||
hlt
|
hlt
|
||||||
jmp hlt_loop
|
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'
|
string: db 'DISK ERROR'
|
||||||
|
|
||||||
|
118
entry.nasm
118
entry.nasm
@ -1,14 +1,9 @@
|
|||||||
[BITS 16]
|
|
||||||
global entry
|
global entry
|
||||||
entry:
|
entry:
|
||||||
cli ; no interrupts
|
|
||||||
xor ax,ax
|
|
||||||
mov ds, ax
|
|
||||||
lgdt [gdt_desc] ; load gdt register
|
lgdt [gdt_desc] ; load gdt register
|
||||||
mov eax, cr0 ; set pmode bit
|
jmp Pmodecode
|
||||||
or al, 1
|
|
||||||
mov cr0, eax
|
extern gdt_desc
|
||||||
jmp 08h:Pmodecode
|
|
||||||
|
|
||||||
[BITS 32]
|
[BITS 32]
|
||||||
Pmodecode:
|
Pmodecode:
|
||||||
@ -30,110 +25,3 @@ hlt
|
|||||||
jmp hlt_loop
|
jmp hlt_loop
|
||||||
|
|
||||||
extern start
|
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
|
hlt
|
||||||
jmp .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
|
extern gpf_handler_v86
|
||||||
global gpfHandler
|
global gpfHandler
|
||||||
gpfHandler:
|
gpfHandler:
|
||||||
|
@ -237,6 +237,7 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
|
|||||||
extern void timerHandler();
|
extern void timerHandler();
|
||||||
extern void keyboardHandler();
|
extern void keyboardHandler();
|
||||||
extern void gpfHandler();
|
extern void gpfHandler();
|
||||||
|
extern void pageFaultHandler();
|
||||||
extern void unhandled_handler();
|
extern void unhandled_handler();
|
||||||
extern void picInit();
|
extern void picInit();
|
||||||
void set_system_gate(uint8_t gate, void (*handler)()) {
|
void set_system_gate(uint8_t gate, void (*handler)()) {
|
||||||
@ -272,6 +273,7 @@ void setup_interrupts() {
|
|||||||
set_system_gate(0x21, keyboardHandler);
|
set_system_gate(0x21, keyboardHandler);
|
||||||
//set_trap_gate(13, gpf_handler_v86);
|
//set_trap_gate(13, gpf_handler_v86);
|
||||||
set_trap_gate(13, gpfHandler);
|
set_trap_gate(13, gpfHandler);
|
||||||
|
set_trap_gate(14, pageFaultHandler);
|
||||||
|
|
||||||
asm volatile("lidt %0": : "m"(IDTR));
|
asm volatile("lidt %0": : "m"(IDTR));
|
||||||
picInit();
|
picInit();
|
||||||
|
52
kernel.c
52
kernel.c
@ -3,8 +3,8 @@
|
|||||||
#include "dosfs/dosfs.h"
|
#include "dosfs/dosfs.h"
|
||||||
#include "print.h"
|
#include "print.h"
|
||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
|
|
||||||
#include "tss.h"
|
#include "tss.h"
|
||||||
|
#include "paging.h"
|
||||||
|
|
||||||
typedef unsigned short word;
|
typedef unsigned short word;
|
||||||
|
|
||||||
@ -72,29 +72,49 @@ extern char *jmp_usermode_test();
|
|||||||
__attribute((__no_caller_saved_registers__))
|
__attribute((__no_caller_saved_registers__))
|
||||||
extern void kbd_wait();
|
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)
|
Real Mode Accessible (First MB)
|
||||||
00000 - 00400 IVT (1kB)
|
00000 - 00400 IVT (1kB)
|
||||||
00400 - 01000 Unused (3kB)
|
00400 - 01000 Unused (3kB)
|
||||||
01000 - 04000 Paging (12kB)
|
01000 - 04000 Free (12kB)
|
||||||
04000 - 07C00 Free (15kB)
|
04000 - 07C00 Free (15kB)
|
||||||
07C00 - 08000 Boot (512B)
|
07C00 - 08000 Boot (512B)
|
||||||
08000 - 20000 Kernel Code (96kB)
|
08000 - 20000 V86 Code (96kB)
|
||||||
20000 - 20080 TSS (128B)
|
20000 - 30000 Disk Buffer (64kB)
|
||||||
20080 - 22080 TSS IOMAP (8kB)
|
|
||||||
22080 - 22400 Unused (896B)
|
|
||||||
22400 - 23000 Free (3kB)
|
|
||||||
23000 - 30000 Disk Buffer (52kB)
|
|
||||||
30000 - 80000 Free (320kB)
|
30000 - 80000 Free (320kB)
|
||||||
80000 - 90000 Real Mode Stack (64kB)
|
80000 - 90000 Real Mode Stack (64kB)
|
||||||
90000 - A0000 Free (64kB)
|
90000 - A0000 Free (64kB)
|
||||||
A0000 - FFFFF BIOS Area (384kB)
|
A0000 - C0000 VGA (128kB)
|
||||||
|
C0000 - FFFFF BIOS Area (256kB)
|
||||||
Protected Only (1MB+)
|
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)
|
300000 - 310000 Task Stack (64kB)
|
||||||
310000 - 320000 Interrupt Stack (64kB)
|
310000 - 320000 Interrupt Stack (64kB)
|
||||||
320000 - 400000 Kernel Stack (896kB)
|
320000 - 400000 Kernel Stack (896kB)
|
||||||
400000 - 500000 Usermode Stack (1mB)
|
400000 - 700000 Usermode Code (3mB)
|
||||||
|
700000 - 800000 Usermode Stack (1mB)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void TestV86() {
|
void TestV86() {
|
||||||
@ -218,14 +238,16 @@ void start() {
|
|||||||
if (!sse) return;
|
if (!sse) return;
|
||||||
enable_sse();
|
enable_sse();
|
||||||
|
|
||||||
|
setup_binary();
|
||||||
|
|
||||||
// edit
|
// edit
|
||||||
setup_interrupts();
|
setup_interrupts();
|
||||||
setup_tss();
|
setup_tss();
|
||||||
print_flags();
|
init_paging();
|
||||||
|
//print_flags();
|
||||||
print_cr0();
|
print_cr0();
|
||||||
print_cr3();
|
//print_cr3();
|
||||||
print_cr4();
|
//print_cr4();
|
||||||
//asm ("xchgw %bx, %bx");
|
|
||||||
|
|
||||||
TestV86(); // has int 3 wait in v86
|
TestV86(); // has int 3 wait in v86
|
||||||
TestGfx();
|
TestGfx();
|
||||||
|
28
link.ld
28
link.ld
@ -2,18 +2,34 @@ OUTPUT_FORMAT(binary)
|
|||||||
ENTRY(entry)
|
ENTRY(entry)
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
. = 0x8000;
|
. = 0x100000;
|
||||||
|
|
||||||
.text : ALIGN(0x1000) {
|
.text : ALIGN(0x1000) {
|
||||||
*(.text)
|
*(.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.data : ALIGN(0x1000) {
|
.data : ALIGN(0x1000) {
|
||||||
*(.data)
|
*(.data);
|
||||||
*(.rodata)
|
*(.rodata);
|
||||||
|
*(.rodata*);
|
||||||
|
_edata = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bss : ALIGN(0x1000) {
|
.realmode 0x8000 :
|
||||||
*(.bss)
|
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)
|
task_ptr: equ (0x310000-4)
|
||||||
|
|
||||||
; return address in EAX
|
; return address in EAX
|
||||||
@ -56,3 +62,42 @@ mov eax, [edx+12+16] ; ds
|
|||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov eax, ecx ; restore return value
|
mov eax, ecx ; restore return value
|
||||||
iret
|
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;
|
struct tss_entry_struct *tss_data;
|
||||||
void write_tss() {
|
void write_tss() {
|
||||||
tss_data = (struct tss_entry_struct *)0x20000;
|
tss_data = (struct tss_entry_struct *)0x200000;
|
||||||
for (int i = 0; i < 0x2080; i++)
|
for (int i = 0; i < 0x2080; i++)
|
||||||
((uint8_t*)tss_data)[i] = 0;
|
((uint8_t*)tss_data)[i] = 0;
|
||||||
tss_data->ss0 = 0x10;
|
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]
|
[BITS 16]
|
||||||
|
[SECTION .v86]
|
||||||
real_hexprint:
|
real_hexprint:
|
||||||
xor cx, cx
|
xor cx, cx
|
||||||
mov bl, al
|
mov bl, al
|
||||||
@ -77,23 +78,3 @@ db 0x10, 0x00 ; size, reserved
|
|||||||
dw 0x1 ; blocks
|
dw 0x1 ; blocks
|
||||||
dd 0x23000000 ; transfer buffer 0x23000
|
dd 0x23000000 ; transfer buffer 0x23000
|
||||||
dq 0x1 ; start block
|
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