Это происходит именно в переключалке
Код:
void switch_task(void)
{
if (multi_task)
{
/* Disable all interrupts */
asm volatile ("pushf; cli");
/* Remember current thread state */
asm volatile ("mov %%esp, %0":"=a"(current_thread->esp));
/* Get next task, find next task while it is not suspended */
do
{
current_thread = (thread_t*) current_thread->list_item.next;
current_proc = (process_t*) current_proc->list_item.next;
} while ( (current_thread->suspend) || (current_proc->suspend) );
/* Set current page directory */
asm volatile ("mov %0, %%cr3"::"a"(current_proc->page_dir));
/* Set stack */
asm volatile ("mov %0, %%esp"::"a"(current_thread->esp));
set_kernel_stack_in_tss((u32int) current_thread->stack + current_thread->stack_size);
/* Enable interrupts */
asm volatile ("popf");
}
}
Если set_kernel_stack_in_tss() вызвать в любом другом месте - всё ок
Сама виновница
Код:
/*------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------*/
void set_kernel_stack_in_tss(u32int stack)
{
tss.esp0 = stack;
}
Дескриптор TSS
Код:
struct tss_descriptor
{
u16int limit_15_0;
u16int base_15_0;
u8int base_23_16;
u8int type:4;
u8int sys:1;
u8int DPL:2;
u8int present:1;
u8int limit_19_16:4;
u8int AVL:1;
u8int allways_zero:2;
u8int gran:1;
u8int base_31_24;
}__attribute__((packed));
typedef struct tss_descriptor tss_descriptor_t;
Так он инициализируется
Код:
/*------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------*/
void write_tss(s32int num, u32int ss0, u32int esp0)
{
u32int base = (u32int) &tss;
u32int limit = sizeof(tss);
debug_msg("Size of TSS: ", sizeof(tss));
debug_msg("Size of tss descriptor: ", sizeof(tss_descriptor_t));
tss_descriptor_t* tss_d = (tss_descriptor_t*) &gdt_entries[num];
tss_d->base_15_0 = base & 0xFFFF;
tss_d->base_23_16 = (base >> 16) & 0xFF;
tss_d->base_31_24 = (base >> 8) & 0xFF;
tss_d->limit_15_0 = limit & 0xFFFF;
tss_d->limit_19_16 = (limit >> 16) & 0xFF;
tss_d->present = 1;
tss_d->sys = 0;
tss_d->DPL = 3;
tss_d->type = 9;
tss_d->AVL = 0;
tss_d->allways_zero = 0;
tss_d->gran = 0;
memset(&tss, 0, sizeof(tss_entry_t));
tss.ss0 = ss0;
tss.esp0 = esp0;
tss.cs = 0x0b;
tss.ss = tss.ds = tss.es = tss.fs = tss.gs = 0x13;
}
Так формируется таблица GDT
Код:
/*------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------*/
void init_gdt(void)
{
gdt_ptr.limit = (sizeof(gdt_entry_t)*6);
gdt_ptr.base = (u32int) &gdt_entries;
gdt_set_gate(0, 0, 0, 0, 0); /* Null segment */
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); /* Code segment */
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); /* Data segment */
gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); /* User mode code segment */
gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); /* User mode code segment */
write_tss(5, 0x10, init_esp); /* TSS */
gdt_flush( (u32int) &gdt_ptr);
print_dump((u32int*) gdt_entries, 48);
print_text("\n");
}