'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
|
CFLAGS = -target "i686-elf" -m32 -mgeneral-regs-only -ffreestanding -march=pentium-m -fno-stack-protector -nostdlib -c
|
||||||
|
|
||||||
%.o: %.nasm
|
%.o: %.nasm
|
||||||
|
3
bochsrc
3
bochsrc
@ -1,6 +1,5 @@
|
|||||||
# configuration file generated by Bochs
|
# configuration file generated by Bochs
|
||||||
display_library: x, options="gui_debug"
|
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
|
plugin_ctrl: unmapped=true, biosdev=true, speaker=true, extfpuirq=true, parallel=true, serial=true, iodebug=true, pcidev=false, usb_uhci=false
|
||||||
config_interface: textconfig
|
config_interface: textconfig
|
||||||
display_library: x
|
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
|
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
|
print_timestamps: enabled=0
|
||||||
debugger_log: -
|
debugger_log: -
|
||||||
magic_break: enabled=0
|
magic_break: enabled=1
|
||||||
port_e9_hack: enabled=0
|
port_e9_hack: enabled=0
|
||||||
private_colormap: enabled=0
|
private_colormap: enabled=0
|
||||||
clock: sync=none, time0=local, rtc_sync=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:
|
jmp_usermode_test:
|
||||||
pop eax ; return address
|
pop eax ; return address
|
||||||
mov ebp, esp ; return stack
|
mov ebp, esp ; return stack
|
||||||
push ss
|
call save_current_task
|
||||||
push ebp
|
mov esp, 0x500000 ; usermode stack
|
||||||
pushfd
|
mov eax, 0x20 | 3
|
||||||
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
|
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
@ -99,6 +91,8 @@ push 0x18 | 3
|
|||||||
push user_test
|
push user_test
|
||||||
iret
|
iret
|
||||||
|
|
||||||
|
extern save_current_task
|
||||||
|
|
||||||
global flushTSS
|
global flushTSS
|
||||||
flushTSS:
|
flushTSS:
|
||||||
mov ax, 0x28
|
mov ax, 0x28
|
||||||
|
@ -35,12 +35,9 @@ movzx eax, word [eax]
|
|||||||
cmp eax, 0x30CD ; int 0x30
|
cmp eax, 0x30CD ; int 0x30
|
||||||
jne gpf_unhandled
|
jne gpf_unhandled
|
||||||
pop eax ; return value
|
pop eax ; return value
|
||||||
mov esp, dword [0x20004] ; return info
|
jmp return_prev_task
|
||||||
pop gs
|
|
||||||
pop fs
|
extern return_prev_task
|
||||||
pop es
|
|
||||||
pop ds
|
|
||||||
iret ; return to original caller
|
|
||||||
|
|
||||||
scancodesToAscii: db 0, 0 ; 0x00 - 0x01
|
scancodesToAscii: db 0, 0 ; 0x00 - 0x01
|
||||||
db "1234567890" ; 0x02 - 0x0B
|
db "1234567890" ; 0x02 - 0x0B
|
||||||
|
51
interrupt.c
51
interrupt.c
@ -87,6 +87,8 @@ extern void real_test();
|
|||||||
__attribute((__no_caller_saved_registers__))
|
__attribute((__no_caller_saved_registers__))
|
||||||
extern void kbd_wait();
|
extern void kbd_wait();
|
||||||
extern void jmp_usermode_test();
|
extern void jmp_usermode_test();
|
||||||
|
__attribute((__no_caller_saved_registers__))
|
||||||
|
extern void return_prev_task();
|
||||||
#define VALID_FLAGS 0xDFF
|
#define VALID_FLAGS 0xDFF
|
||||||
__attribute__ ((interrupt))
|
__attribute__ ((interrupt))
|
||||||
void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
|
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;
|
stack32 = (uint32_t*)stack;
|
||||||
|
|
||||||
char *vga = (char*)0xb8000 + (160 * 10);
|
char *vga = (char*)0xb8000 + (160 * 10);
|
||||||
vga[0] = 'I'; vga[2] = 'P'; int_printWord(frame->eip, (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] = '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[0] = 'F'; vga[2] = 'L'; int_printDword(frame->eflags, (uint16_t*)&vga[4]); vga += 14;
|
||||||
vga = (char*)0xb8000 + (160 * 11);
|
//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] = '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[0] = 'S'; vga[2] = 'S'; int_printWord(frame->ss, (uint16_t*)&vga[4]); vga += 14;
|
||||||
vga = (char*)0xb8000 + (160 * 12);
|
//vga = (char*)0xb8000 + (160 * 12);
|
||||||
vga[0] = 'E'; vga[2] = 'S'; int_printWord(frame->es, (uint16_t*)&vga[4]); vga += 14;
|
//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] = '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] = '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] = 'G'; vga[2] = 'S'; int_printWord(frame->gs, (uint16_t*)&vga[4]); vga += 14;
|
||||||
|
|
||||||
//vga[2]++;
|
//vga[2]++;
|
||||||
//printDword(frame, &vga[20]);
|
//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 += (sizeof(uint8_t)*2)*2;
|
||||||
//}
|
//}
|
||||||
vga = (char*)0xb8000 + (160*3);
|
vga = (char*)0xb8000 + (160*3);
|
||||||
uint32_t *tss_esp0 = (uint32_t*)0x20004;
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
switch (ip[0]) {
|
switch (ip[0]) {
|
||||||
case 0x66: // O32
|
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';
|
vga[0] = 'I'; vga[2]++; if (vga[2] < '0') vga[2] = '0';
|
||||||
switch (ip[1]) {
|
switch (ip[1]) {
|
||||||
case 0x30:
|
case 0x30:
|
||||||
asm ("mov %%eax, %%esp\nret"::"a"(*tss_esp0));
|
return_prev_task();
|
||||||
for(;;);
|
for(;;);
|
||||||
case 0x3:
|
case 0x3:
|
||||||
kbd_wait();
|
kbd_wait();
|
||||||
@ -219,18 +220,18 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
done:;
|
done:;
|
||||||
vga = (char*)0xb8000 + (160 * 13);
|
//vga = (char*)0xb8000 + (160 * 13);
|
||||||
vga[0] = 'I'; vga[2] = 'P'; int_printWord(frame->eip, (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] = '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[0] = 'F'; vga[2] = 'L'; int_printDword(frame->eflags, (uint16_t*)&vga[4]); vga += 14;
|
||||||
vga = (char*)0xb8000 + (160 * 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] = '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[0] = 'S'; vga[2] = 'S'; int_printWord(frame->ss, (uint16_t*)&vga[4]); vga += 14;
|
||||||
vga = (char*)0xb8000 + (160 * 15);
|
//vga = (char*)0xb8000 + (160 * 15);
|
||||||
vga[0] = 'E'; vga[2] = 'S'; int_printWord(frame->es, (uint16_t*)&vga[4]); vga += 14;
|
//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] = '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] = '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] = 'G'; vga[2] = 'S'; int_printWord(frame->gs, (uint16_t*)&vga[4]); vga += 14;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void timerHandler();
|
extern void timerHandler();
|
||||||
|
39
kernel.c
39
kernel.c
@ -3,7 +3,7 @@
|
|||||||
#include "print.h"
|
#include "print.h"
|
||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
|
|
||||||
#include "tss.c"
|
#include "tss.h"
|
||||||
|
|
||||||
typedef unsigned short word;
|
typedef unsigned short word;
|
||||||
|
|
||||||
@ -54,23 +54,33 @@ void print_cr4() {
|
|||||||
|
|
||||||
__attribute((__no_caller_saved_registers__))
|
__attribute((__no_caller_saved_registers__))
|
||||||
extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip);
|
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__))
|
__attribute((__no_caller_saved_registers__))
|
||||||
extern char *jmp_usermode_test();
|
extern char *jmp_usermode_test();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Real Mode Accessible (First MB)
|
Real Mode Accessible (First MB)
|
||||||
00000 - 02000 IVT
|
00000 - 00400 IVT (1kB)
|
||||||
01000 - 04000 Paging
|
00400 - 01000 Unused (3kB)
|
||||||
04000 - 07C00 Free
|
01000 - 04000 Paging (12kB)
|
||||||
07C00 - 08000 Boot
|
04000 - 07C00 Free (15kB)
|
||||||
08000 - 20000 Kernel Code
|
07C00 - 08000 Boot (512B)
|
||||||
20000 - 22080 TSS
|
08000 - 20000 Kernel Code (96kB)
|
||||||
80000 - 90000 Real Mode Stack
|
20000 - 20080 TSS (128B)
|
||||||
90000 - A0000 Free
|
20080 - 22080 TSS IOMAP (8kB)
|
||||||
A0000 - FFFFF BIOS Area
|
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+)
|
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() {
|
void start() {
|
||||||
@ -107,9 +117,12 @@ void start() {
|
|||||||
print_cr0();
|
print_cr0();
|
||||||
print_cr3();
|
print_cr3();
|
||||||
print_cr4();
|
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));
|
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
|
||||||
char *vga = jmp_usermode_test();
|
char *vga = jmp_usermode_test();
|
||||||
|
//asm ("xchgw %bx, %bx");
|
||||||
|
|
||||||
for (int i = 0; i < 320; i++) {
|
for (int i = 0; i < 320; i++) {
|
||||||
vga[i] = 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 <stdint.h>
|
||||||
|
|
||||||
|
#include "tss.h"
|
||||||
|
|
||||||
struct __attribute__((__packed__)) tss_entry_struct {
|
struct __attribute__((__packed__)) tss_entry_struct {
|
||||||
uint32_t prev_tss;
|
uint32_t prev_tss;
|
||||||
uint32_t esp0;
|
uint32_t esp0;
|
||||||
@ -35,8 +37,13 @@ void write_tss() {
|
|||||||
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;
|
||||||
tss_data->esp0 = 0x400000;
|
tss_data->esp0 = 0x320000;
|
||||||
tss_data->iomap_base = 0x80;
|
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();
|
extern void flushTSS();
|
||||||
|
|
||||||
|
42
v86.nasm
42
v86.nasm
@ -26,8 +26,8 @@ call real_hexprint
|
|||||||
mov ax, dx
|
mov ax, dx
|
||||||
call real_hexprint
|
call real_hexprint
|
||||||
ret
|
ret
|
||||||
extern v86Code
|
global v86Test
|
||||||
v86Code:
|
v86Test:
|
||||||
mov ax, 0xb814
|
mov ax, 0xb814
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov di, 20
|
mov di, 20
|
||||||
@ -41,43 +41,31 @@ mov ax, cs
|
|||||||
call real_printword
|
call real_printword
|
||||||
.loop:
|
.loop:
|
||||||
inc byte [0]
|
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
|
||||||
int 3
|
int 3
|
||||||
;jmp .loop
|
|
||||||
mov ax, 0x13
|
|
||||||
int 0x10
|
|
||||||
int 0x30 ; exit
|
int 0x30 ; exit
|
||||||
jmp $
|
jmp $
|
||||||
extern real_test
|
global v86GfxMode
|
||||||
real_test:
|
v86GfxMode:
|
||||||
nop
|
mov ax, 0x13
|
||||||
nop
|
int 0x10
|
||||||
nop
|
int 0x30
|
||||||
jmp $
|
jmp $
|
||||||
[BITS 32]
|
[BITS 32]
|
||||||
; extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip);
|
; extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip);
|
||||||
global enter_v86
|
global enter_v86
|
||||||
enter_v86:
|
enter_v86:
|
||||||
|
pop eax
|
||||||
mov ebp, esp ; save stack pointer
|
mov ebp, esp ; save stack pointer
|
||||||
mov dword [0x20004], ebp ; tss ESP0
|
call save_current_task
|
||||||
push dword [ebp+4] ; ss
|
push dword [ebp+0] ; ss
|
||||||
push dword [ebp+8] ; esp
|
push dword [ebp+4] ; esp
|
||||||
pushfd ; eflags
|
pushfd ; eflags
|
||||||
or dword [esp], (1 << 17) ; set VM flags
|
or dword [esp], (1 << 17) ; set VM flags
|
||||||
;or dword [esp], (3 << 12) ; IOPL 3
|
;or dword [esp], (3 << 12) ; IOPL 3
|
||||||
push dword [ebp+12] ; cs
|
push dword [ebp+8] ; cs
|
||||||
push dword [ebp+16] ; eip
|
push dword [ebp+12] ; eip
|
||||||
iret
|
iret
|
||||||
|
|
||||||
|
; return address in eax, return stack in ebp
|
||||||
|
extern save_current_task
|
||||||
|
Loading…
Reference in New Issue
Block a user