Task switching from Ring3 to ring0 (interrupt)
Posted: Fri Jul 06, 2007 9:42 am
I succeed to handle the interrupt in a same ring (ring0->ring0),
but after I change the ring to the 3 from 0, "idle_task", the bochs prints "CPU_LOOP 1" and "Error: (0) print_guard_results: guard_found ? (stop reason 0)" when occurs interrupt.
I copied below text from the bochsout.txt file (dump_cpu)
-----------------------------
00009581469e[CPU0 ] fetch_raw_descriptor: GDT: index (707)e0 > limit (47)
00009581469e[CPU0 ] fetch_raw_descriptor: GDT: index (707)e0 > limit (47)
00009581469e[CPU0 ] fetch_raw_descriptor: GDT: index (707)e0 > limit (47)
00009581469e[CPU0 ] exception(): 3rd (10) exception with no resolution, shutdown status is 00h, resetting
00009581469i[CPU0 ] protected mode
00009581469i[CPU0 ] CS.d_b = 32 bit
00009581469i[CPU0 ] SS.d_b = 32 bit
00009581469i[CPU0 ] | EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000
00009581469i[CPU0 ] | ESP=0000c3fb EBP=0000c3fb ESI=00000000 EDI=00000000
00009581469i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf zf af pf cf
00009581469i[CPU0 ] | SEG selector base limit G D
00009581469i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00009581469i[CPU0 ] | CS:0023( 0004| 0| 3) 00000000 000fffff 1 1
00009581469i[CPU0 ] | DS:002b( 0005| 0| 3) 00000000 000fffff 1 1
00009581469i[CPU0 ] | SS:0033( 0006| 0| 3) 00000000 000fffff 1 1
00009581469i[CPU0 ] | ES:002b( 0005| 0| 3) 00000000 000fffff 1 1
00009581469i[CPU0 ] | FS:002b( 0005| 0| 3) 00000000 000fffff 1 1
00009581469i[CPU0 ] | GS:002b( 0005| 0| 3) 00000000 000fffff 1 1
00009581469i[CPU0 ] | EIP=00009cf2 (00009cf2)
00009581469i[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00009581469i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00009581469i[CPU0 ] >> eb
00009581469i[CPU0 ] >> fe
00009581469i[CPU0 ] >> : jmp .+0xfffffffe
00009581469i[SYS ] bx_pc_system_c::Reset(SOFTWARE) called
00009581469i[APIC0] local apic in CPU 0 initializing
00009581469i[ ] Ctrl-C detected in signal handler.
00009581469i[ ] dbg: Quit
00009581469i[CPU0 ] real mode
00009581469i[CPU0 ] CS.d_b = 16 bit
00009581469i[CPU0 ] SS.d_b = 16 bit
00009581469i[CPU0 ] | EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000f00
00009581469i[CPU0 ] | ESP=00000000 EBP=00000000 ESI=00000000 EDI=00000000
00009581469i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af pf cf
00009581469i[CPU0 ] | SEG selector base limit G D
00009581469i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00009581469i[CPU0 ] | CS:f000( 0000| 0| 0) ffff0000 0000ffff 0 0
00009581469i[CPU0 ] | DS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00009581469i[CPU0 ] | SS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00009581469i[CPU0 ] | ES:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00009581469i[CPU0 ] | FS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00009581469i[CPU0 ] | GS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00009581469i[CPU0 ] | EIP=0000fff0 (0000fff0)
00009581469i[CPU0 ] | CR0=0x00000010 CR1=0 CR2=0x00000000
00009581469i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
------------------------------------------
and, below code is reside on my kernel entry point, it will change the ring.
-----------------------------------------
// Status of CPU will store to the 0x00004E00, 0x00068(104 Bytes)
task_state_segment* tss = (task_state_segment*)0x00004E00;
// Reset the kernel stack. previous stack information isn't need anymore.
cpu_regs* regStack = (cpu_regs*)KERNEL_STACK;
regStack->eax = 0;
regStack->ebx = 0;
regStack->ecx = 0;
regStack->edx = 0;
regStack->ebp = 0;
regStack->esi = 0;
regStack->edi = 0;
regStack->cs = USER_CS;
regStack->ds = USER_DS;
regStack->es = USER_DS;
regStack->fs = USER_DS;
regStack->gs = USER_DS;
regStack->ss = USER_SS;
regStack->eip= (long)idle_task;
regStack->eflags = 0x200;
regStack->esp = (long)(g_idle_stack + 1023);
asm volatile (
// Save current kernel stack pointer to the TSS's ESP0 field
// This field will be read by CPU when interrupt occurs
"movl %%esp, %0\n"
// We should to construct a faked stack to make context switching (userlevel).
"movl $0x7c00, %%esp\n"
// We should to initialize data segments, before go into the user mode task
"popal\n"
// For the data segments
"popl %%ds\n"
"popl %%es\n"
"popl %%fs\n"
"popl %%gs\n"
"iretl\n"
: "=m"(tss->ESP0)
:
);
-------------------------------------
What am I wrong?
------------------------
http://nicesj.com
but after I change the ring to the 3 from 0, "idle_task", the bochs prints "CPU_LOOP 1" and "Error: (0) print_guard_results: guard_found ? (stop reason 0)" when occurs interrupt.
I copied below text from the bochsout.txt file (dump_cpu)
-----------------------------
00009581469e[CPU0 ] fetch_raw_descriptor: GDT: index (707)e0 > limit (47)
00009581469e[CPU0 ] fetch_raw_descriptor: GDT: index (707)e0 > limit (47)
00009581469e[CPU0 ] fetch_raw_descriptor: GDT: index (707)e0 > limit (47)
00009581469e[CPU0 ] exception(): 3rd (10) exception with no resolution, shutdown status is 00h, resetting
00009581469i[CPU0 ] protected mode
00009581469i[CPU0 ] CS.d_b = 32 bit
00009581469i[CPU0 ] SS.d_b = 32 bit
00009581469i[CPU0 ] | EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000
00009581469i[CPU0 ] | ESP=0000c3fb EBP=0000c3fb ESI=00000000 EDI=00000000
00009581469i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf zf af pf cf
00009581469i[CPU0 ] | SEG selector base limit G D
00009581469i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00009581469i[CPU0 ] | CS:0023( 0004| 0| 3) 00000000 000fffff 1 1
00009581469i[CPU0 ] | DS:002b( 0005| 0| 3) 00000000 000fffff 1 1
00009581469i[CPU0 ] | SS:0033( 0006| 0| 3) 00000000 000fffff 1 1
00009581469i[CPU0 ] | ES:002b( 0005| 0| 3) 00000000 000fffff 1 1
00009581469i[CPU0 ] | FS:002b( 0005| 0| 3) 00000000 000fffff 1 1
00009581469i[CPU0 ] | GS:002b( 0005| 0| 3) 00000000 000fffff 1 1
00009581469i[CPU0 ] | EIP=00009cf2 (00009cf2)
00009581469i[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00009581469i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00009581469i[CPU0 ] >> eb
00009581469i[CPU0 ] >> fe
00009581469i[CPU0 ] >> : jmp .+0xfffffffe
00009581469i[SYS ] bx_pc_system_c::Reset(SOFTWARE) called
00009581469i[APIC0] local apic in CPU 0 initializing
00009581469i[ ] Ctrl-C detected in signal handler.
00009581469i[ ] dbg: Quit
00009581469i[CPU0 ] real mode
00009581469i[CPU0 ] CS.d_b = 16 bit
00009581469i[CPU0 ] SS.d_b = 16 bit
00009581469i[CPU0 ] | EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000f00
00009581469i[CPU0 ] | ESP=00000000 EBP=00000000 ESI=00000000 EDI=00000000
00009581469i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af pf cf
00009581469i[CPU0 ] | SEG selector base limit G D
00009581469i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00009581469i[CPU0 ] | CS:f000( 0000| 0| 0) ffff0000 0000ffff 0 0
00009581469i[CPU0 ] | DS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00009581469i[CPU0 ] | SS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00009581469i[CPU0 ] | ES:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00009581469i[CPU0 ] | FS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00009581469i[CPU0 ] | GS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00009581469i[CPU0 ] | EIP=0000fff0 (0000fff0)
00009581469i[CPU0 ] | CR0=0x00000010 CR1=0 CR2=0x00000000
00009581469i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
------------------------------------------
and, below code is reside on my kernel entry point, it will change the ring.
-----------------------------------------
// Status of CPU will store to the 0x00004E00, 0x00068(104 Bytes)
task_state_segment* tss = (task_state_segment*)0x00004E00;
// Reset the kernel stack. previous stack information isn't need anymore.
cpu_regs* regStack = (cpu_regs*)KERNEL_STACK;
regStack->eax = 0;
regStack->ebx = 0;
regStack->ecx = 0;
regStack->edx = 0;
regStack->ebp = 0;
regStack->esi = 0;
regStack->edi = 0;
regStack->cs = USER_CS;
regStack->ds = USER_DS;
regStack->es = USER_DS;
regStack->fs = USER_DS;
regStack->gs = USER_DS;
regStack->ss = USER_SS;
regStack->eip= (long)idle_task;
regStack->eflags = 0x200;
regStack->esp = (long)(g_idle_stack + 1023);
asm volatile (
// Save current kernel stack pointer to the TSS's ESP0 field
// This field will be read by CPU when interrupt occurs
"movl %%esp, %0\n"
// We should to construct a faked stack to make context switching (userlevel).
"movl $0x7c00, %%esp\n"
// We should to initialize data segments, before go into the user mode task
"popal\n"
// For the data segments
"popl %%ds\n"
"popl %%es\n"
"popl %%fs\n"
"popl %%gs\n"
"iretl\n"
: "=m"(tss->ESP0)
:
);
-------------------------------------
What am I wrong?
------------------------
http://nicesj.com