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).