Sorry for my bad English.
I'm trying to set up initial TSS for my Higher Half Kernel by this code:
Code: Select all
struct tss
{
unsigned long backlink;
unsigned long esp0;
unsigned long ss0;
unsigned long esp1;
unsigned long ss1;
unsigned long esp2;
unsigned long ss2;
unsigned long cr3;
unsigned long eip;
unsigned long eflags;
unsigned long eax;
unsigned long ecx;
unsigned long edx;
unsigned long ebx;
unsigned long esp;
unsigned long ebp;
unsigned long esi;
unsigned long edi;
unsigned long es;
unsigned long cs;
unsigned long ss;
unsigned long ds;
unsigned long fs;
unsigned long gs;
unsigned long ldt;
unsigned long bmoffset;
};
void init_tss( struct tss * tss )
{
printf( "Task State Segment at 0x%X\n", (unsigned long)tss );
tss -> esp0 = get_esp();
tss -> ss0 = 0x10;
tss -> cr3 = get_cr3();
tss -> es = 0x10;
tss -> ds = 0x10;
tss -> fs = 0x10;
tss -> gs = 0x10;
tss -> ss = 0x10;
tss -> cs = 0x08;
tss -> ldt = 0;
tss -> bmoffset = 0xFFFF;
}
Code: Select all
struct gdt_desc {
unsigned short len15_0;
unsigned short base15_0;
unsigned char base23_16;
unsigned char flags1;
unsigned char flags2;
unsigned char base31_24;
};
struct gdtr {
unsigned short size;
unsigned long * addr;
};
#define ltr(n) __asm__("ltr %%ax"::"a" (n))
#define lgdt(n) __asm__("lgdt (%%eax)"::"a" (n))
void gdt_set_segment( struct gdt_desc * desc, unsigned long base, unsigned long len, unsigned char flags1, unsigned char flags2 )
{
desc -> len15_0 = (unsigned short)( len & 0xFFFF );
desc -> base15_0 = (unsigned short)( base & 0xFFFF );
desc -> base23_16 = (unsigned char)( ( base >> 16 ) & 0xFF );
desc -> flags1 = flags1;
desc -> flags2 = flags2 | ( ( len >> 16 ) & 0xF );
desc -> base31_24 = (unsigned char)( ( base ) >> 24 );
}
void init_gdt( void )
{
printf( "GDT at 0x%X\n", (unsigned long *)CPU -> gdt );
gdt_set_segment( &CPU -> gdt[0], 0, 0, 0, 0 ); //Null descriptor
gdt_set_segment( &CPU -> gdt[1], 0x0, 0xFFFFF, GDT_PRESENT | GDT_APP | GDT_WRITE | GDT_CODE | GDT_DPL0, GDT_GRANULARITY | GDT_USE32 );
gdt_set_segment( &CPU -> gdt[2], 0x0, 0xFFFFF, GDT_PRESENT | GDT_APP | GDT_WRITE | GDT_DPL0, GDT_GRANULARITY | GDT_USE32 );
gdt_set_segment( &CPU -> gdt[3], 0x0, 0xFFFFF, GDT_PRESENT | GDT_APP | GDT_WRITE | GDT_CODE | GDT_DPL3, GDT_GRANULARITY | GDT_USE32 );
gdt_set_segment( &CPU -> gdt[4], 0x0, 0xFFFFF, GDT_PRESENT | GDT_APP | GDT_WRITE | GDT_DPL3, GDT_GRANULARITY | GDT_USE32 );
init_tss( &CPU -> tss );
gdt_set_segment( &CPU -> gdt[5], (unsigned long)&CPU -> tss, sizeof( struct tss ), GDT_PRESENT | GDT_SYS | GDT_TSS32, GDT_USE32 );
CPU -> gdtr.size = GDT_MAX * 8 - 1;
CPU -> gdtr.addr = (unsigned long *)&CPU -> gdt;
lgdt( (unsigned long)&CPU -> gdtr );
ltr( 5 << 3 );
}
Code: Select all
00014043604i[CPU0 ] >> ltr ax : 0F00D8
00014043604p[CPU0 ] >>PANIC<< exception(): 3rd (14) exception with no resolution
00014043604i[CPU0 ] CPU is in protected mode (active)
00014043604i[CPU0 ] CS.d_b = 32 bit
00014043604i[CPU0 ] SS.d_b = 32 bit
00014043604i[CPU0 ] | EAX=00000028 EBX=0002b1a0 ECX=00000040 EDX=000007ff
00014043604i[CPU0 ] | ESP=c012b1f0 EBP=c012b224 ESI=00103000 EDI=0002b317
00014043604i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf SF zf af pf cf
00014043604i[CPU0 ] | SEG selector base limit G D
00014043604i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00014043604i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00014043604i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00014043604i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00014043604i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 1
00014043604i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00014043604i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00014043604i[CPU0 ] | EIP=c010122f (c010122f)
00014043604i[CPU0 ] | CR0=0x80000011 CR1=0 CR2=0x00000040
00014043604i[CPU0 ] | CR3=0x0012d000 CR4=0x00000010