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:
		
							
								
								
									
										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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user