TSS (ring 3) [SOLVED]
Posted: Wed Aug 27, 2008 8:07 am
I'm trying to get protection in to my micro kernel and I'm not too familiar with the GDT and TSSes.
I want a flat memory layout (from a segmentation P.O.V., not paging), and basically, I have 6 entries in my GDT:
each one of those entries is set up using:
I'm only initialising a few of the static (the name the Intel docs give them) values of my TSS, other than that my TSS is completely 0'ed out. The values I'm initialising are cr0, esp0 (located > 3GB), and the bitmap, then I load the TSS using
ltr 5<<3.
All page table entries and page directory entries > 3GB (my kernel's base address) have the user bit unset, while all below have it set.
Now, when an interrupt occurs (actually only tested with the timer, since it's the first interrupt that fires) bochs reports:
Which is a GPF (at least I know it's protecting me... against myself). However, this isn't the behavior I'm looking for
I also have an interrupt handler for GPF, which too isn't picking it up (hence the triple fault).
What might I be doing wrong?
Also, can I make it so ESP does not change when an interrupt is called (I use software multitasking and save esi and esp manually, which I'm not sure how to get if my esp changes to tss->esp0)?
I want a flat memory layout (from a segmentation P.O.V., not paging), and basically, I have 6 entries in my GDT:
Code: Select all
- null descriptor
entry 0: base: 0, limit: 0, access: 0, granularity: 0
- ring 0 code (for kernel)
entry 1: base: 0x00000000, limit: 0xFFFFFFFF, access: 0x9A, granularity: 0xCF
- ring 0 data (for kernel)
entry 2: base: 0x00000000, limit: 0xFFFFFFFF, access: 0x92, granularity: 0xCF
- ring 3 code (for processes)
entry 3: base: 0x00000000, limit: 0xFFFFFFFF, access: 0xFA, granularity: 0xCF
- ring 3 data (for processes)
entry 4: base: 0x00000000, limit: 0xFFFFFFFF, access: 0xF2, granularity: 0xCF
- tss entry:
entry 5: base: vir addr of TSS, limit: base + size of TSS, access: 0x89, granularity: 0xCF
Code: Select all
void IDTGDT::SetGDTGate(int num, size_t base, size_t limit, unsigned
char access, unsigned char gran)
{
gdtEntry[num].BaseLow = (base & 0xFFFF);
gdtEntry[num].BaseMiddle = (base >> 16) & 0xFF;
gdtEntry[num].BaseHigh = (base >> 24) & 0xFF;
gdtEntry[num].LimitLow = (limit & 0xFFFF);
gdtEntry[num].Granularity = ((limit >> 16) & 0x0F);
gdtEntry[num].Granularity |= (gran & 0xF0);
gdtEntry[num].Access = access;
}
ltr 5<<3.
All page table entries and page directory entries > 3GB (my kernel's base address) have the user bit unset, while all below have it set.
Now, when an interrupt occurs (actually only tested with the timer, since it's the first interrupt that fires) bochs reports:
Code: Select all
00051171719i[CPU0 ] CS.d_b = 32 bit
00051171719i[CPU0 ] SS.d_b = 32 bit
00051171719i[CPU0 ] EFER = 0x00000000
00051171719i[CPU0 ] | RAX=00000000c0109080 RBX=00000000c0104baa
00051171719i[CPU0 ] | RCX=00000000c00b8000 RDX=00000000c01003d5
00051171719i[CPU0 ] | RSP=00000000c010d03c RBP=00000000c010d068
00051171719i[CPU0 ] | RSI=00000000c0104bb6 RDI=000000000005457d
00051171719i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00051171719i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00051171719i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00051171719i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00051171719i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df IF tf SF zf AF PF cf
00051171719i[CPU0 ] | SEG selector base limit G D
00051171719i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00051171719i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00051171719i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00051171719i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00051171719i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 1
00051171719i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00051171719i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00051171719i[CPU0 ] | MSR_FS_BASE:0000000000000000
00051171719i[CPU0 ] | MSR_GS_BASE:0000000000000000
00051171719i[CPU0 ] | RIP=00000000c0100f23 (00000000c0100f23)
00051171719i[CPU0 ] | CR0=0xe0000011 CR1=0x0 CR2=0x0000000000000000
00051171719i[CPU0 ] | CR3=0x00420000 CR4=0x00000010
00051171719i[CPU0 ] >> ret : C3
00051171719e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown
status is 00h, resetting
I also have an interrupt handler for GPF, which too isn't picking it up (hence the triple fault).
What might I be doing wrong?
Also, can I make it so ESP does not change when an interrupt is called (I use software multitasking and save esi and esp manually, which I'm not sure how to get if my esp changes to tss->esp0)?