V86
RE:V86
TheUbu I think you are wrong.
The manual says it is possible to switch to V86 mode only by an interrupt return with a stack that has the proper layout and VM bit set in the EFLAG on the Stack.(and some other methods, I dont have the manual here)
so if you are using software task switching, the stack that you want to use for the V86 task has to have its VM bit set in the EFLAG dword on the stack.
Besides, even if you use software task switching,you still need at least 1 TSS so that the CPU can get the stack pointer to use for Ring 0 and 3.
so with 1 TSS, you have to patch the tss fields for a task to be switched to before the switch.
The manual says it is possible to switch to V86 mode only by an interrupt return with a stack that has the proper layout and VM bit set in the EFLAG on the Stack.(and some other methods, I dont have the manual here)
so if you are using software task switching, the stack that you want to use for the V86 task has to have its VM bit set in the EFLAG dword on the stack.
Besides, even if you use software task switching,you still need at least 1 TSS so that the CPU can get the stack pointer to use for Ring 0 and 3.
so with 1 TSS, you have to patch the tss fields for a task to be switched to before the switch.
RE:V86
You need to also RELOAD THE TSR before you do the stack switch
Here is my C code to do that
void patch_tss()
{
sys_tss.ss0 = running_task->stack0_sel;
sys_tss.esp0 =(unsigned long)running_task->stack0_ptr;
sys_tss.ss = running_task->stack3_sel;
sys_tss.esp = (unsigned long)running_task->stack3_ptr;
sys_tss.eflags = running_task->eflags;
update_gdt_entry(KERNEL_TSS_SEL,KERNEL_TSS|TSS_NOT_BUSY);
load_task_reg(KERNEL_TSS_SEL);
return;
}
after this function returns, I then switch tasking using the software stack method
Here is my C code to do that
void patch_tss()
{
sys_tss.ss0 = running_task->stack0_sel;
sys_tss.esp0 =(unsigned long)running_task->stack0_ptr;
sys_tss.ss = running_task->stack3_sel;
sys_tss.esp = (unsigned long)running_task->stack3_ptr;
sys_tss.eflags = running_task->eflags;
update_gdt_entry(KERNEL_TSS_SEL,KERNEL_TSS|TSS_NOT_BUSY);
load_task_reg(KERNEL_TSS_SEL);
return;
}
after this function returns, I then switch tasking using the software stack method
RE:V86
Mius:
For each task have a TSS structure the format of the structure you can pull out of the Intel docs...
Set up your first TSS when your scheduler comes around just have it update the TSS entry in your GDT and do a far jmp to it here is a quick sample code that would be in your scheduler..
GDT[4].descriptor.baseLow = (memAddr & 0xFFFF);
GDT[4].descriptor.baseMed = ((memAddr >> 16) & 0xFF);
GDT[4].descriptor.baseHigh = (memAddr >> 24);
GDT[4].descriptor.access = '\x89';
asm("ljmp $0x20,$0\n");
In your kernel initialization code you would hat ltr 0x20
-Christopher
For each task have a TSS structure the format of the structure you can pull out of the Intel docs...
Set up your first TSS when your scheduler comes around just have it update the TSS entry in your GDT and do a far jmp to it here is a quick sample code that would be in your scheduler..
GDT[4].descriptor.baseLow = (memAddr & 0xFFFF);
GDT[4].descriptor.baseMed = ((memAddr >> 16) & 0xFF);
GDT[4].descriptor.baseHigh = (memAddr >> 24);
GDT[4].descriptor.access = '\x89';
asm("ljmp $0x20,$0\n");
In your kernel initialization code you would hat ltr 0x20
-Christopher