'Better' task management, needs more testing
This commit is contained in:
parent
c80a420da0
commit
606fc37e37
2
Makefile
2
Makefile
@ -1,4 +1,4 @@
|
||||
objects = entry.o kernel.o handler.o interrupt.o v86.o print.o
|
||||
objects = entry.o kernel.o task.o handler.o interrupt.o v86.o print.o tss.o
|
||||
CFLAGS = -target "i686-elf" -m32 -mgeneral-regs-only -ffreestanding -march=pentium-m -fno-stack-protector -nostdlib -c
|
||||
|
||||
%.o: %.nasm
|
||||
|
3
bochsrc
3
bochsrc
@ -1,6 +1,5 @@
|
||||
# configuration file generated by Bochs
|
||||
display_library: x, options="gui_debug"
|
||||
#magic_break: enabled=1
|
||||
plugin_ctrl: unmapped=true, biosdev=true, speaker=true, extfpuirq=true, parallel=true, serial=true, iodebug=true, pcidev=false, usb_uhci=false
|
||||
config_interface: textconfig
|
||||
display_library: x
|
||||
@ -32,7 +31,7 @@ vga: extension=vbe, update_freq=5, realtime=1, ddc=builtin
|
||||
cpu: count=1:1:1, ips=4000000, quantum=16, model=core_duo_t2400_yonah, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
|
||||
print_timestamps: enabled=0
|
||||
debugger_log: -
|
||||
magic_break: enabled=0
|
||||
magic_break: enabled=1
|
||||
port_e9_hack: enabled=0
|
||||
private_colormap: enabled=0
|
||||
clock: sync=none, time0=local, rtc_sync=0
|
||||
|
16
entry.nasm
16
entry.nasm
@ -76,17 +76,9 @@ global jmp_usermode_test
|
||||
jmp_usermode_test:
|
||||
pop eax ; return address
|
||||
mov ebp, esp ; return stack
|
||||
push ss
|
||||
push ebp
|
||||
pushfd
|
||||
push cs
|
||||
push eax ; return address
|
||||
push ds ; other segs, pop
|
||||
push es ; before iret
|
||||
push fs ; in exit handler
|
||||
push gs
|
||||
mov dword [0x20004], esp ; tss ESP0
|
||||
mov ax, 0x20 | 3
|
||||
call save_current_task
|
||||
mov esp, 0x500000 ; usermode stack
|
||||
mov eax, 0x20 | 3
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
@ -99,6 +91,8 @@ push 0x18 | 3
|
||||
push user_test
|
||||
iret
|
||||
|
||||
extern save_current_task
|
||||
|
||||
global flushTSS
|
||||
flushTSS:
|
||||
mov ax, 0x28
|
||||
|
@ -35,12 +35,9 @@ movzx eax, word [eax]
|
||||
cmp eax, 0x30CD ; int 0x30
|
||||
jne gpf_unhandled
|
||||
pop eax ; return value
|
||||
mov esp, dword [0x20004] ; return info
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
iret ; return to original caller
|
||||
jmp return_prev_task
|
||||
|
||||
extern return_prev_task
|
||||
|
||||
scancodesToAscii: db 0, 0 ; 0x00 - 0x01
|
||||
db "1234567890" ; 0x02 - 0x0B
|
||||
|
51
interrupt.c
51
interrupt.c
@ -87,6 +87,8 @@ extern void real_test();
|
||||
__attribute((__no_caller_saved_registers__))
|
||||
extern void kbd_wait();
|
||||
extern void jmp_usermode_test();
|
||||
__attribute((__no_caller_saved_registers__))
|
||||
extern void return_prev_task();
|
||||
#define VALID_FLAGS 0xDFF
|
||||
__attribute__ ((interrupt))
|
||||
void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
|
||||
@ -100,17 +102,17 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
|
||||
stack32 = (uint32_t*)stack;
|
||||
|
||||
char *vga = (char*)0xb8000 + (160 * 10);
|
||||
vga[0] = 'I'; vga[2] = 'P'; int_printWord(frame->eip, (uint16_t*)&vga[4]); vga += 14;
|
||||
vga[0] = 'C'; vga[2] = 'S'; int_printWord(frame->cs, (uint16_t*)&vga[4]); vga += 14;
|
||||
vga[0] = 'F'; vga[2] = 'L'; int_printDword(frame->eflags, (uint16_t*)&vga[4]); vga += 14;
|
||||
vga = (char*)0xb8000 + (160 * 11);
|
||||
vga[0] = 'S'; vga[2] = 'P'; int_printWord(frame->esp, (uint16_t*)&vga[4]); vga += 14;
|
||||
vga[0] = 'S'; vga[2] = 'S'; int_printWord(frame->ss, (uint16_t*)&vga[4]); vga += 14;
|
||||
vga = (char*)0xb8000 + (160 * 12);
|
||||
vga[0] = 'E'; vga[2] = 'S'; int_printWord(frame->es, (uint16_t*)&vga[4]); vga += 14;
|
||||
vga[0] = 'D'; vga[2] = 'S'; int_printWord(frame->ds, (uint16_t*)&vga[4]); vga += 14;
|
||||
vga[0] = 'F'; vga[2] = 'S'; int_printWord(frame->fs, (uint16_t*)&vga[4]); vga += 14;
|
||||
vga[0] = 'G'; vga[2] = 'S'; int_printWord(frame->gs, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga[0] = 'I'; vga[2] = 'P'; int_printWord(frame->eip, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga[0] = 'C'; vga[2] = 'S'; int_printWord(frame->cs, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga[0] = 'F'; vga[2] = 'L'; int_printDword(frame->eflags, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga = (char*)0xb8000 + (160 * 11);
|
||||
//vga[0] = 'S'; vga[2] = 'P'; int_printWord(frame->esp, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga[0] = 'S'; vga[2] = 'S'; int_printWord(frame->ss, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga = (char*)0xb8000 + (160 * 12);
|
||||
//vga[0] = 'E'; vga[2] = 'S'; int_printWord(frame->es, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga[0] = 'D'; vga[2] = 'S'; int_printWord(frame->ds, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga[0] = 'F'; vga[2] = 'S'; int_printWord(frame->fs, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga[0] = 'G'; vga[2] = 'S'; int_printWord(frame->gs, (uint16_t*)&vga[4]); vga += 14;
|
||||
|
||||
//vga[2]++;
|
||||
//printDword(frame, &vga[20]);
|
||||
@ -128,7 +130,6 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
|
||||
// vga += (sizeof(uint8_t)*2)*2;
|
||||
//}
|
||||
vga = (char*)0xb8000 + (160*3);
|
||||
uint32_t *tss_esp0 = (uint32_t*)0x20004;
|
||||
for(;;) {
|
||||
switch (ip[0]) {
|
||||
case 0x66: // O32
|
||||
@ -177,7 +178,7 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
|
||||
vga[0] = 'I'; vga[2]++; if (vga[2] < '0') vga[2] = '0';
|
||||
switch (ip[1]) {
|
||||
case 0x30:
|
||||
asm ("mov %%eax, %%esp\nret"::"a"(*tss_esp0));
|
||||
return_prev_task();
|
||||
for(;;);
|
||||
case 0x3:
|
||||
kbd_wait();
|
||||
@ -219,18 +220,18 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
|
||||
}
|
||||
}
|
||||
done:;
|
||||
vga = (char*)0xb8000 + (160 * 13);
|
||||
vga[0] = 'I'; vga[2] = 'P'; int_printWord(frame->eip, (uint16_t*)&vga[4]); vga += 14;
|
||||
vga[0] = 'C'; vga[2] = 'S'; int_printWord(frame->cs, (uint16_t*)&vga[4]); vga += 14;
|
||||
vga[0] = 'F'; vga[2] = 'L'; int_printDword(frame->eflags, (uint16_t*)&vga[4]); vga += 14;
|
||||
vga = (char*)0xb8000 + (160 * 14);
|
||||
vga[0] = 'S'; vga[2] = 'P'; int_printWord(frame->esp, (uint16_t*)&vga[4]); vga += 14;
|
||||
vga[0] = 'S'; vga[2] = 'S'; int_printWord(frame->ss, (uint16_t*)&vga[4]); vga += 14;
|
||||
vga = (char*)0xb8000 + (160 * 15);
|
||||
vga[0] = 'E'; vga[2] = 'S'; int_printWord(frame->es, (uint16_t*)&vga[4]); vga += 14;
|
||||
vga[0] = 'D'; vga[2] = 'S'; int_printWord(frame->ds, (uint16_t*)&vga[4]); vga += 14;
|
||||
vga[0] = 'F'; vga[2] = 'S'; int_printWord(frame->fs, (uint16_t*)&vga[4]); vga += 14;
|
||||
vga[0] = 'G'; vga[2] = 'S'; int_printWord(frame->gs, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga = (char*)0xb8000 + (160 * 13);
|
||||
//vga[0] = 'I'; vga[2] = 'P'; int_printWord(frame->eip, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga[0] = 'C'; vga[2] = 'S'; int_printWord(frame->cs, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga[0] = 'F'; vga[2] = 'L'; int_printDword(frame->eflags, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga = (char*)0xb8000 + (160 * 14);
|
||||
//vga[0] = 'S'; vga[2] = 'P'; int_printWord(frame->esp, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga[0] = 'S'; vga[2] = 'S'; int_printWord(frame->ss, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga = (char*)0xb8000 + (160 * 15);
|
||||
//vga[0] = 'E'; vga[2] = 'S'; int_printWord(frame->es, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga[0] = 'D'; vga[2] = 'S'; int_printWord(frame->ds, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga[0] = 'F'; vga[2] = 'S'; int_printWord(frame->fs, (uint16_t*)&vga[4]); vga += 14;
|
||||
//vga[0] = 'G'; vga[2] = 'S'; int_printWord(frame->gs, (uint16_t*)&vga[4]); vga += 14;
|
||||
}
|
||||
|
||||
extern void timerHandler();
|
||||
|
39
kernel.c
39
kernel.c
@ -3,7 +3,7 @@
|
||||
#include "print.h"
|
||||
#include "interrupt.h"
|
||||
|
||||
#include "tss.c"
|
||||
#include "tss.h"
|
||||
|
||||
typedef unsigned short word;
|
||||
|
||||
@ -54,23 +54,33 @@ void print_cr4() {
|
||||
|
||||
__attribute((__no_caller_saved_registers__))
|
||||
extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip);
|
||||
extern void v86Code();
|
||||
extern void v86Test();
|
||||
extern void v86GfxMode();
|
||||
__attribute((__no_caller_saved_registers__))
|
||||
extern char *jmp_usermode_test();
|
||||
|
||||
/*
|
||||
Real Mode Accessible (First MB)
|
||||
00000 - 02000 IVT
|
||||
01000 - 04000 Paging
|
||||
04000 - 07C00 Free
|
||||
07C00 - 08000 Boot
|
||||
08000 - 20000 Kernel Code
|
||||
20000 - 22080 TSS
|
||||
80000 - 90000 Real Mode Stack
|
||||
90000 - A0000 Free
|
||||
A0000 - FFFFF BIOS Area
|
||||
00000 - 00400 IVT (1kB)
|
||||
00400 - 01000 Unused (3kB)
|
||||
01000 - 04000 Paging (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 - 80000 Free (372kB)
|
||||
80000 - 90000 Real Mode Stack (64kB)
|
||||
90000 - A0000 Free (64kB)
|
||||
A0000 - FFFFF BIOS Area (384kB)
|
||||
Protected Only (1MB+)
|
||||
100000 - Free
|
||||
100000 - 300000 Free (2mB)
|
||||
300000 - 310000 Task Stack (64kB)
|
||||
310000 - 320000 Interrupt Stack (64kB)
|
||||
320000 - 400000 Kernel Stack (896kB)
|
||||
400000 - 500000 Usermode Stack (1mB)
|
||||
*/
|
||||
|
||||
void start() {
|
||||
@ -107,9 +117,12 @@ void start() {
|
||||
print_cr0();
|
||||
print_cr3();
|
||||
print_cr4();
|
||||
FARPTR v86_entry = i386LinearToFp(v86Code);
|
||||
FARPTR v86_entry = i386LinearToFp(v86Test);
|
||||
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
|
||||
v86_entry = i386LinearToFp(v86GfxMode);
|
||||
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
|
||||
char *vga = jmp_usermode_test();
|
||||
//asm ("xchgw %bx, %bx");
|
||||
|
||||
for (int i = 0; i < 320; i++) {
|
||||
vga[i] = i;
|
||||
|
46
task.nasm
Normal file
46
task.nasm
Normal file
@ -0,0 +1,46 @@
|
||||
task_ptr: equ (0x310000-4)
|
||||
|
||||
global save_current_task
|
||||
save_current_task:
|
||||
push ebx
|
||||
mov ebx, esp
|
||||
mov esp, dword [task_ptr] ; load current task pointer
|
||||
push ss
|
||||
push ebp ; return stack
|
||||
pushfd
|
||||
push cs
|
||||
push eax ; return address
|
||||
push ds ; other segs, pop
|
||||
push es ; before iret
|
||||
push fs ; in exit handler
|
||||
push gs
|
||||
mov dword [task_ptr], esp ; save new task pointer
|
||||
mov esp, ebx
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
global return_prev_task
|
||||
return_prev_task:
|
||||
mov edi, eax ; save for later
|
||||
mov esi, dword [task_ptr] ; load current task pointer
|
||||
add dword [task_ptr], 36 ; adjust to last task pointer
|
||||
mov eax, [esi+0] ; gs
|
||||
mov gs, ax
|
||||
mov eax, [esi+4] ; fs
|
||||
mov fs, ax
|
||||
mov eax, [esi+8] ; es
|
||||
mov es, ax
|
||||
mov ebx, [esi+16] ; eip
|
||||
mov ecx, [esi+20] ; cs
|
||||
mov edx, [esi+24] ; eflags
|
||||
; SS:ESP <- return stack
|
||||
mov esp, [esi+28] ; esp
|
||||
mov eax, [esi+32] ; ss
|
||||
mov ss, ax
|
||||
mov eax, [esi+12] ; ds
|
||||
mov ds, ax
|
||||
push edx ; eflags
|
||||
push ecx ; cs
|
||||
push ebx ; eip
|
||||
mov eax, edi ; restore return value
|
||||
iret
|
9
tss.c
9
tss.c
@ -1,5 +1,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "tss.h"
|
||||
|
||||
struct __attribute__((__packed__)) tss_entry_struct {
|
||||
uint32_t prev_tss;
|
||||
uint32_t esp0;
|
||||
@ -35,8 +37,13 @@ void write_tss() {
|
||||
for (int i = 0; i < 0x2080; i++)
|
||||
((uint8_t*)tss_data)[i] = 0;
|
||||
tss_data->ss0 = 0x10;
|
||||
tss_data->esp0 = 0x400000;
|
||||
tss_data->esp0 = 0x320000;
|
||||
tss_data->iomap_base = 0x80;
|
||||
|
||||
// not technically TSS but set up task pointer
|
||||
uint32_t *current_task_ptr = (uint32_t*)(0x310000-4);
|
||||
*current_task_ptr = 0x310000-40; // each task is 9 dwords, plus 1 for pointer
|
||||
/* TODO setup null recovery task at start */
|
||||
}
|
||||
extern void flushTSS();
|
||||
|
||||
|
42
v86.nasm
42
v86.nasm
@ -26,8 +26,8 @@ call real_hexprint
|
||||
mov ax, dx
|
||||
call real_hexprint
|
||||
ret
|
||||
extern v86Code
|
||||
v86Code:
|
||||
global v86Test
|
||||
v86Test:
|
||||
mov ax, 0xb814
|
||||
mov es, ax
|
||||
mov di, 20
|
||||
@ -41,43 +41,31 @@ mov ax, cs
|
||||
call real_printword
|
||||
.loop:
|
||||
inc byte [0]
|
||||
;mov ax, 0x1111
|
||||
;mov ds, ax
|
||||
;mov ax, 0x2222
|
||||
;mov es, ax
|
||||
;mov ax, 0x3333
|
||||
;mov fs, ax
|
||||
;mov ax, 0x4444
|
||||
;mov gs, ax
|
||||
;mov ax, 0x5555
|
||||
;mov ss, ax
|
||||
;mov ax, 0x6666
|
||||
;mov sp, ax
|
||||
int 3
|
||||
int 3
|
||||
;jmp .loop
|
||||
mov ax, 0x13
|
||||
int 0x10
|
||||
int 0x30 ; exit
|
||||
jmp $
|
||||
extern real_test
|
||||
real_test:
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
global v86GfxMode
|
||||
v86GfxMode:
|
||||
mov ax, 0x13
|
||||
int 0x10
|
||||
int 0x30
|
||||
jmp $
|
||||
[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
|
||||
mov ebp, esp ; save stack pointer
|
||||
mov dword [0x20004], ebp ; tss ESP0
|
||||
push dword [ebp+4] ; ss
|
||||
push dword [ebp+8] ; esp
|
||||
call save_current_task
|
||||
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+12] ; cs
|
||||
push dword [ebp+16] ; eip
|
||||
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