Multitasking/Context Switching: Exec outside RAM/ROM
Posted: Wed May 02, 2012 9:05 am
Help! I've been following this tutorial here, it was recommended by someone over here: http://hosted.cjmovie.net/TutMultitask.htm. I've basically finished reading the tutorial; I have finished writing the code, however:
The tutorial says to install the switching code directly into the irq0 asm stub, bypassing the irq_common_stub. As such, the moment I enable interrupts, that code is executed. Which leads to this:
The first thing i see is that EIP matches the address of the faulty code. What can I do?
Such is my code:
start.s
timer.c
Note: I see "TESTAAA" almost immediately after booting the kernel, as expected. What happens next is not. The return statement works fine, however when I return from the "call HandleTimer", qemu crashes with the above report.
Note the line that was "not in the tutorial originally". I examined the code and noticed that esp was never actually popped after it was pushed on the stack, so I added that line. When I do, the kernel hangs instead of crashing.
Help?
EDIT: If I actually initialise the tasks before calling sti(), the reverse of what occurs above happens:
When I include "pop esp", it crashes. When I remove it, it hangs. (In retrospect, the line was probably not meant to be included and was just my itchy fingers).
The tutorial says to install the switching code directly into the irq0 asm stub, bypassing the irq_common_stub. As such, the moment I enable interrupts, that code is executed. Which leads to this:
Code: Select all
qemu: fatal: Trying to execute code outside RAM or ROM at 0xecfeb2ef
EAX=6c78c000 EBX=0010a000 ECX=00000001 EDX=00000001
ESI=00035a7e EDI=00035a83 EBP=00067ec4 ESP=ffffff88
EIP=ecfeb2ef EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 00111040 00000017
IDT= 001110a0 000007ff
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=0000000c CCD=ffffff84 CCO=ADDL
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
The first thing i see is that EIP matches the address of the faulty code. What can I do?
Such is my code:
start.s
Code: Select all
extern HandleTimer
irq0:
; cli
; push byte 0
; push byte 32
; jmp irq_common_stub
pusha ;; Push standard regs
push ds ;; Push segment d
push es ;; Segment e
push fs ;; Segment f
push gs ;; Segment g
mov eax, 0x10 ;; Kernel data segment
mov ds, eax ;; Place it in data segment regs
mov es, eax
mov fs, eax
mov gs, eax
push esp ;; Push pointer to things already on stack
call HandleTimer ;; Hardcoded timer interrupt, timer.c
mov esp, eax ;; Replace stack with what HandleTimer returns
mov al, 0x20 ;; ACK Interrupt
out 0x20, al
pop esp ;; Was not in tutorial originally
pop gs ;; Put data segments back
pop fs
pop es
pop ds
popa ;; Put standard regs back
iret ;; Interrupt return
timer.c
Code: Select all
unsigned int HandleTimer(unsigned int OldEsp)//struct regs *r)
{
clear_screen();
kprintf("TEST");
timer_ticks++;
if(timer_ticks % 1000 == 0)
{
time_increment_seconds();
}
if(wait != 0)
{
wait--;
}
kprintf("AAA");
return Schedule(OldEsp);
}
Note the line that was "not in the tutorial originally". I examined the code and noticed that esp was never actually popped after it was pushed on the stack, so I added that line. When I do, the kernel hangs instead of crashing.
Help?
EDIT: If I actually initialise the tasks before calling sti(), the reverse of what occurs above happens:
When I include "pop esp", it crashes. When I remove it, it hangs. (In retrospect, the line was probably not meant to be included and was just my itchy fingers).