IDT problems after enabling paging

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Gogeta70
Member
Member
Posts: 28
Joined: Thu Jun 06, 2013 11:15 am

IDT problems after enabling paging

Post by Gogeta70 »

So, i just set up a page directory and a couple of page tables so i could start using virtual memory.

I load my kernel at 1mb, and run it at 3gb (0xc0000000). I have identity mapped the first 4mb of memory to make enabling paging easier. The only other page table set up is for 4mb starting at VA 0xC0000000.

I'm not sure this issue is directly related to having enabled paging, but who knows. My problem is when i'm installing the IDT:

Code: Select all

void idt_init()
{
	
	idt_location.offset = (unsigned long) &idt;
	idt_location.size = (sizeof(struct IDT_ENTRY) * 256) - 1;
	
	unsigned char *zero_idt = (unsigned char*) idt;
	
	for(unsigned long i = 0; i <= idt_location.size; i++)
		zero_idt[i] = 0;
	
	unsigned char flags = 0x8E; // standard 32 bit interrupt gate
	unsigned long offset[256] = {0};
	
	offset[0] = (unsigned long) isr_divide_by_zero;
	offset[1] = (unsigned long) isr_debugger;
	offset[2] = (unsigned long) isr_nmi;
	offset[3] = (unsigned long) isr_breakpoint;
	offset[4] = (unsigned long) isr_overflow;
	offset[5] = (unsigned long) isr_bounds;
	offset[6] = (unsigned long) isr_invalid_opcode;
	offset[7] = (unsigned long) isr_coprocessor_not_avail;
	offset[8] = (unsigned long) isr_double_fault;
	offset[9] = (unsigned long) isr_coprocessor_segment_overrun;
	offset[10] = (unsigned long) isr_invalid_tss;
	offset[11] = (unsigned long) isr_segment_not_present;
	offset[12] = (unsigned long) isr_stack_fault;
	offset[13] = (unsigned long) isr_general_protection_fault;
	offset[14] = (unsigned long) isr_page_fault;
	offset[15] = (unsigned long) isr_reserved;
	offset[16] = (unsigned long) isr_math_fault;
	offset[17] = (unsigned long) isr_alignment_check;
	offset[18] = (unsigned long) isr_machine_check;
	offset[19] = (unsigned long) isr_simd_floating_point_exception;
	
	for(int i = 20; i < 256; i++)
		offset[i] = (unsigned long) isr_reserved;
	
	offset[32] = (unsigned long) isr_sys_timer;
	offset[33] = (unsigned long) isr_keyboard;
	offset[34] = (unsigned long) isr_9;
	offset[35] = (unsigned long) isr_3;
	offset[36] = (unsigned long) isr_4;
	offset[37] = (unsigned long) isr_5;
	offset[38] = (unsigned long) isr_6;
	offset[39] = (unsigned long) isr_7;
	offset[40] = (unsigned long) isr_8;
	offset[41] = (unsigned long) isr_9;
	offset[42] = (unsigned long) isr_10;
	offset[43] = (unsigned long) isr_11;
	offset[44] = (unsigned long) isr_12;
	offset[45] = (unsigned long) isr_13;
	offset[46] = (unsigned long) isr_14;
	offset[47] = (unsigned long) isr_15;
	
	for(int i = 0; i < 256; i++)
	{
	//	if(i < 20)
	//	{
	//		printf("setting isr #%d routine address: 0x%.8x\n", i, offset[i]);
	//	}
		
		//uncommenting the above block of code causes the problem
		
		idt[i].offset_low = (offset[i] & 0xFFFF);
		idt[i].offset_high = ((offset[i] >> 16) & 0xFFFF);
		idt[i].selector = 0x08;
		idt[i].zero = 0;
		idt[i].type_attr = flags;
	}
	__asm("xchg %bx, %bx"); // bochs magic breakpoint
	
	install_idt();
}
The problem is when it returns from the install_idt() call:

Code: Select all

extern idt_location
global install_idt

install_idt:
	lidt [idt_location]
	sti
	ret
Shortly after it returns from this function, i get a loop of general protection faults, and double faults. Here's the output from bochs:

Code: Select all

00024837288i[CPU0 ] [24837288] Stopped on MAGIC BREAKPOINT
(0) Magic breakpoint
Next at t=24837288
(0) [0x000000106a63] 0008:00000000c0106a63 (unk. ctxt): add esp, 0x0000041c
  ; 81c41c040000
<bochs:2> s
Next at t=24837289
(0) [0x000000106a69] 0008:00000000c0106a69 (unk. ctxt): pop ebx
  ; 5b
<bochs:3>
Next at t=24837290
(0) [0x000000106a6a] 0008:00000000c0106a6a (unk. ctxt): pop esi
  ; 5e
<bochs:4>
Next at t=24837291
(0) [0x000000106a6b] 0008:00000000c0106a6b (unk. ctxt): pop edi
  ; 5f
<bochs:5>
Next at t=24837292
(0) [0x000000106a6c] 0008:00000000c0106a6c (unk. ctxt): pop ebp
  ; 5d
<bochs:6>
Next at t=24837293
(0) [0x000000106a6d] 0008:00000000c0106a6d (unk. ctxt): jmp .+910 (0xc0106e00) // jump(?) to install_idt()
  ; e98e030000
<bochs:7>
Next at t=24837294
(0) [0x000000106e00] 0008:00000000c0106e00 (unk. ctxt): lidt ds:0xc012a000
  ; 0f011d00a012c0
<bochs:8>
Next at t=24837295
(0) [0x000000106e07] 0008:00000000c0106e07 (unk. ctxt): sti
  ; fb
<bochs:9>
Next at t=24837296
(0) [0x000000106e08] 0008:00000000c0106e08 (unk. ctxt): ret
  ; c3
<bochs:10>
Next at t=24837297
(0) [0x000000101023] 0008:00000000c0101023 (unk. ctxt): mov dword ptr ss:[esp+4]
, 0x00000028 ; c744240428000000
<bochs:11>
Next at t=24837298
(0) [0x000000101023] 0008:00000000c0101023 (unk. ctxt): mov dword ptr ss:[esp+4] // it seems to repeat this instruction twice, and then double faults?
, 0x00000028 ; c744240428000000
<bochs:12>
Next at t=24837299
(0) [0x000000106e19] 0008:00000000c0106e19 (unk. ctxt): iretd
  ; cf
<bochs:13>
00024837299e[CPU0 ] fetch_raw_descriptor: GDT: index (297) 52 > limit (17)
Next at t=24837300
(0) [0x000000106e21] 0008:00000000c0106e21 (unk. ctxt): pop eax
  ; 58
<bochs:14>
Next at t=24837301
(0) [0x000000106e22] 0008:00000000c0106e22 (unk. ctxt): iretd
  ; cf
<bochs:15>
Next at t=24837302
(0) [0x000000106e19] 0008:00000000c0106e19 (unk. ctxt): iretd
  ; cf
I notice that GCC decided to replace my install_idt() function call with a short jump... doesn't that mess up the stack for the return from install_idt()?
Also, why is it executing the same instruction at the same address, twice?

Here's a bochs disassembly of the code:

Code: Select all

c0106a63: (                    ): add esp, 0x0000041c       ; 81c41c040000
c0106a69: (                    ): pop ebx                   ; 5b
c0106a6a: (                    ): pop esi                   ; 5e
c0106a6b: (                    ): pop edi                   ; 5f
c0106a6c: (                    ): pop ebp                   ; 5d
c0106a6d: (                    ): jmp .+910                 ; e98e030000
c0106a72: (                    ): lea esi, dword ptr ds:[esi] ; 8db42600000000
c0106a79: (                    ): lea edi, dword ptr ds:[edi] ; 8dbc2700000000
c0106a80: (                    ): sub esp, 0x0000001c       ; 83ec1c
c0106a83: (                    ): mov dword ptr ss:[esp+8], 0x00000004 ; c744240
804000000
c0106a8b: (                    ): mov dword ptr ss:[esp+4], 0x0000000f ; c744240
40f000000
c0106a93: (                    ): mov dword ptr ss:[esp], 0xc0108438 ; c70424388
410c0
c0106a9a: (                    ): call .-1119               ; e8a1fbffff
c0106a9f: (                    ): add esp, 0x0000001c       ; 83c41c
c0106aa2: (                    ): ret                       ; c3
This is confusing. Before enabling virtual memory, my interrupts worked fine. I even had keyboard input working with a basic command line...

So, why is this happening now?

Edit:

If i replace the install_idt() function call with:
__asm("call install_idt");

It then actually calls the function and returns properly, but i'm still getting those exceptions:

Code: Select all

00027133602i[CPU0 ] [27133602] Stopped on MAGIC BREAKPOINT
(0) Magic breakpoint
Next at t=27133602
(0) [0x000000106a63] 0008:00000000c0106a63 (unk. ctxt): call .+920 (0xc0106e00)
  ; e898030000
<bochs:2> s
Next at t=27133603
(0) [0x000000106e00] 0008:00000000c0106e00 (unk. ctxt): lidt ds:0xc012a000
  ; 0f011d00a012c0
<bochs:3>
Next at t=27133604
(0) [0x000000106e07] 0008:00000000c0106e07 (unk. ctxt): sti
  ; fb
<bochs:4>
Next at t=27133605
(0) [0x000000106e08] 0008:00000000c0106e08 (unk. ctxt): ret
  ; c3
<bochs:5>
Next at t=27133606
(0) [0x000000106a68] 0008:00000000c0106a68 (unk. ctxt): add esp, 0x0000041c
  ; 81c41c040000
<bochs:6>
Next at t=27133607
(0) [0x000000106e19] 0008:00000000c0106e19 (unk. ctxt): iretd
  ; cf
<bochs:7>
00027133607e[CPU0 ] check_cs(0x0246): not a valid code segment !
Next at t=27133608
(0) [0x000000106e21] 0008:00000000c0106e21 (unk. ctxt): pop eax
  ; 58
<bochs:8>
Next at t=27133609
(0) [0x000000106e22] 0008:00000000c0106e22 (unk. ctxt): iretd
  ; cf
<bochs:9>
Next at t=27133610
(0) [0x000000106e19] 0008:00000000c0106e19 (unk. ctxt): iretd
  ; cf
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: IDT problems after enabling paging

Post by sortie »

Note that the compiler is performing a tail-recursive optimization. It simply restores the state as when the function itself was called and then jumps to install_idt and pretends the caller called that function. This works assuming all functions adhere to the ABI (which they do). Compile without optimizations to disable this behavior, but it's actually a good thing and doesn't change semantics.
Gogeta70
Member
Member
Posts: 28
Joined: Thu Jun 06, 2013 11:15 am

Re: IDT problems after enabling paging

Post by Gogeta70 »

Ahh, ok. I thought it might be some form of optimization, i just thought it was odd. But now that i've checked, i can see that it's returning to kernel_main, which calls idt_init.

Still though, i don't understand why it's double faulting, or why i'm getting a general protection fault :/
User avatar
ChristopherSacchi
Posts: 1
Joined: Wed Jun 19, 2013 3:06 pm
Location: Cooperstown, NY
Contact:

Re: IDT problems after enabling paging

Post by ChristopherSacchi »

The way you used call is ok. The problem might be that the CS code segment is invalid, which is when a double fault could happen. It also said

Code: Select all

<bochs:7>
00027133607e[CPU0 ] check_cs(0x0246): not a valid code segment !
, so it could be the answer to your solution. It is accessing a segment that is invalid, so you could maybe try to either change your segment for the CS by pushing the address of your offset onto the stack, and then pop off the top data of the stack into CS.
--Christopher P. Sacchi

"Do you pine for the nice days of Minix-1.1 when men were men and wrote their own device drivers?" --Linus Torvalds
Gogeta70
Member
Member
Posts: 28
Joined: Thu Jun 06, 2013 11:15 am

Re: IDT problems after enabling paging

Post by Gogeta70 »

I had already installed my GDT (obviously) and did a far jump to my code selector, which set CS to 0x08. Considering the idt_init function executes fine under the current code segment (0x08), what causes the CS register to change?
User avatar
Griwes
Member
Member
Posts: 374
Joined: Sat Jul 30, 2011 10:07 am
Libera.chat IRC: Griwes
Location: Wrocław/Racibórz, Poland
Contact:

Re: IDT problems after enabling paging

Post by Griwes »

Why didn't you post definition of IDT_ENTRY...? Did you inspect the IDT after loading it to verify it is correct?
Reaver Project :: Repository :: Ohloh project page
<klange> This is a horror story about what happens when you need a hammer and all you have is the skulls of the damned.
<drake1> as long as the lock is read and modified by atomic operations
Gogeta70
Member
Member
Posts: 28
Joined: Thu Jun 06, 2013 11:15 am

Re: IDT problems after enabling paging

Post by Gogeta70 »

After executing LIDT, this is what my IDT looks like according to bochs:

Code: Select all

<bochs:21> info idt
Interrupt Descriptor Table (base=0x00000000c012a040, limit=2047):
IDT[0x00]=32-Bit Interrupt Gate target=0x0008:0xc0106e09, DPL=0
IDT[0x01]=32-Bit Interrupt Gate target=0x0008:0xc0106e0a, DPL=0
IDT[0x02]=32-Bit Interrupt Gate target=0x0008:0xc0106e0b, DPL=0
IDT[0x03]=32-Bit Interrupt Gate target=0x0008:0xc0106e0c, DPL=0
IDT[0x04]=32-Bit Interrupt Gate target=0x0008:0xc0106e14, DPL=0
IDT[0x05]=32-Bit Interrupt Gate target=0x0008:0xc0106e15, DPL=0
IDT[0x06]=32-Bit Interrupt Gate target=0x0008:0xc0106e16, DPL=0
IDT[0x07]=32-Bit Interrupt Gate target=0x0008:0xc0106e17, DPL=0
IDT[0x08]=32-Bit Interrupt Gate target=0x0008:0xc0106e18, DPL=0
IDT[0x09]=32-Bit Interrupt Gate target=0x0008:0xc0106e1a, DPL=0
IDT[0x0a]=32-Bit Interrupt Gate target=0x0008:0xc0106e1b, DPL=0
IDT[0x0b]=32-Bit Interrupt Gate target=0x0008:0xc0106e1d, DPL=0
IDT[0x0c]=32-Bit Interrupt Gate target=0x0008:0xc0106e1f, DPL=0
IDT[0x0d]=32-Bit Interrupt Gate target=0x0008:0xc0106e21, DPL=0
IDT[0x0e]=32-Bit Interrupt Gate target=0x0008:0xc0106e23, DPL=0
IDT[0x0f]=32-Bit Interrupt Gate target=0x0008:0xc0106e25, DPL=0
IDT[0x10]=32-Bit Interrupt Gate target=0x0008:0xc0106e26, DPL=0
IDT[0x11]=32-Bit Interrupt Gate target=0x0008:0xc0106e27, DPL=0
IDT[0x12]=32-Bit Interrupt Gate target=0x0008:0xc0106e28, DPL=0
IDT[0x13]=32-Bit Interrupt Gate target=0x0008:0xc0106e29, DPL=0
IDT[0x14]=32-Bit Interrupt Gate target=0x0008:0xc0106e25, DPL=0
IDT[0x15]=32-Bit Interrupt Gate target=0x0008:0xc0106e25, DPL=0
IDT[0x16]=32-Bit Interrupt Gate target=0x0008:0xc0106e25, DPL=0
IDT[0x17]=32-Bit Interrupt Gate target=0x0008:0xc0106e25, DPL=0
IDT[0x18]=32-Bit Interrupt Gate target=0x0008:0xc0106e25, DPL=0
IDT[0x19]=32-Bit Interrupt Gate target=0x0008:0xc0106e25, DPL=0
IDT[0x1a]=32-Bit Interrupt Gate target=0x0008:0xc0106e25, DPL=0
IDT[0x1b]=32-Bit Interrupt Gate target=0x0008:0xc0106e25, DPL=0
IDT[0x1c]=32-Bit Interrupt Gate target=0x0008:0xc0106e25, DPL=0
IDT[0x1d]=32-Bit Interrupt Gate target=0x0008:0xc0106e25, DPL=0
IDT[0x1e]=32-Bit Interrupt Gate target=0x0008:0xc0106e25, DPL=0
IDT[0x1f]=32-Bit Interrupt Gate target=0x0008:0xc0106e25, DPL=0
IDT[0x20]=32-Bit Interrupt Gate target=0x0008:0xc0106e35, DPL=0
IDT[0x21]=32-Bit Interrupt Gate target=0x0008:0xc0106e2a, DPL=0
IDT[0x22]=32-Bit Interrupt Gate target=0x0008:0xc0106e6d, DPL=0
IDT[0x23]=32-Bit Interrupt Gate target=0x0008:0xc0106e3d, DPL=0
IDT[0x24]=32-Bit Interrupt Gate target=0x0008:0xc0106e45, DPL=0
IDT[0x25]=32-Bit Interrupt Gate target=0x0008:0xc0106e4d, DPL=0
IDT[0x26]=32-Bit Interrupt Gate target=0x0008:0xc0106e55, DPL=0
IDT[0x27]=32-Bit Interrupt Gate target=0x0008:0xc0106e5d, DPL=0
IDT[0x28]=32-Bit Interrupt Gate target=0x0008:0xc0106e65, DPL=0
IDT[0x29]=32-Bit Interrupt Gate target=0x0008:0xc0106e6d, DPL=0
IDT[0x2a]=32-Bit Interrupt Gate target=0x0008:0xc0106e75, DPL=0
IDT[0x2b]=32-Bit Interrupt Gate target=0x0008:0xc0106e7d, DPL=0
IDT[0x2c]=32-Bit Interrupt Gate target=0x0008:0xc0106e85, DPL=0
IDT[0x2d]=32-Bit Interrupt Gate target=0x0008:0xc0106e8d, DPL=0
IDT[0x2e]=32-Bit Interrupt Gate target=0x0008:0xc0106e95, DPL=0
IDT[0x2f]=32-Bit Interrupt Gate target=0x0008:0xc0106e9d, DPL=0
I don't see any problems with my IDT, so the problem is elsewhere?

These are my IDT structures:

Code: Select all

struct IDT_ENTRY {
	
	unsigned short offset_low;
	unsigned short selector;
	unsigned char zero;
	unsigned char type_attr;
	unsigned short offset_high;
} __attribute__((packed));

struct IDT_DESCRIPTION {
	
	unsigned short size;
	unsigned long offset;
	
} __attribute__((packed));

struct IDT_ENTRY idt[256];
struct IDT_DESCRIPTION idt_location;
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: IDT problems after enabling paging

Post by sortie »

Does the system work if you don't execute the 'sti' instruction? What if you disable interrupts just after enabling them, that is, 'sti\ncli'? I compared your IDT with mine (that I just refactored) and your seems correct assuming your GDT is correct and so.

My magic crystal ball tells me your interrupt handlers are faulty and likely the timer interrupt is killing your kernel.
User avatar
Griwes
Member
Member
Posts: 374
Joined: Sat Jul 30, 2011 10:07 am
Libera.chat IRC: Griwes
Location: Wrocław/Racibórz, Poland
Contact:

Re: IDT problems after enabling paging

Post by Griwes »

No idea why I didn't notice this

Code: Select all

(0) [0x000000106e19] 0008:00000000c0106e19 (unk. ctxt): iretd
  ; cf
<bochs:13>
00024837299e[CPU0 ] fetch_raw_descriptor: GDT: index (297) 52 > limit (17)
before... your stack is clearly broken at one of irets.
Reaver Project :: Repository :: Ohloh project page
<klange> This is a horror story about what happens when you need a hammer and all you have is the skulls of the damned.
<drake1> as long as the lock is read and modified by atomic operations
Gogeta70
Member
Member
Posts: 28
Joined: Thu Jun 06, 2013 11:15 am

Re: IDT problems after enabling paging

Post by Gogeta70 »

Yeah, you're right. I was debugging it for quite a while last night, and it seems the stack is getting muddled. I'm having the same issue elsewhere in my code, where the stack gets fubar'd. From what i can see, the culprit is my printf function. Though, this raises some questions:

The only difference between now and before is that i've set up virtual memory/paging. Printf worked great before. So why would this start happening after enabling paging?

Also, most of my code is C, with an occasional assembly stub function here and there. How is my stack becoming messed up all of a sudden, after enabling paging?


This so confusing and frustrating ](*,)
Gogeta70
Member
Member
Posts: 28
Joined: Thu Jun 06, 2013 11:15 am

Re: IDT problems after enabling paging

Post by Gogeta70 »

Ok, so i've been re-assessing what's going on here. When i had paging disabled, my interrupts worked fine - i could type on the keyboard, the timer interrupt worked, etc. I set up a page directory and a few page tables, and then as soon as i load my IDT and enable interrupts - double fault, followed by a general protection fault (upon returning from a double fault, the EIP is undefined, so that's probably why, i guess).

The only thing that has changed is that i have enabled paging, so perhaps it's double faulting for a reason related to that. Another reason i suspect this is because the only IRQ that works is IRQ0, the system timer. No keyboard input. The odd thing is that sometimes it double faults right after enabling interrupts, and sometimes it proceeds without error.

If anybody wants a look, here's how i set up my page directory and page tables:

Code: Select all

void* vmm_init(void)
void* vmm_init(void)
{
	unsigned long *page_directory = (unsigned long*) 0x300000; // putting at the 3mb memory mark to allow space for kernel to grow
	unsigned long *page_table = (unsigned long*) ((unsigned long) page_directory + 0x1000); // 1kb after page directory
	unsigned long *page_table2 = (unsigned long*) ((unsigned long) page_table + 0x1000); // the first MB of this page is for the kernel stack
	
	unsigned long pt_addr = 0;
	unsigned long stack_addr = 0x400000;
	
	for(int i = 0; i < 1024; i++)
	{
		page_directory[i] = (unsigned long) 2;
		page_table[i] = pt_addr | 3;
		
		if(i < 256)
			page_table2[i] = stack_addr | 3;
		else
			page_table2[i] = 2;
		
		pt_addr += 0x1000; // next 4kb page
		stack_addr += 0x1000;
	}
	
	page_directory[768] = (unsigned long) page_table | 3;
	page_directory[769] = (unsigned long) page_table2 | 3; // stack is at address 0xC0500000 -- grows DOWNWARD
	page_directory[0] = (unsigned long) page_table | 3;
	
	page_table[1023] = (unsigned long) page_table | 3;
	page_directory[1023] = (unsigned long) page_directory | 3;
	
	return (void*) page_directory;
}
That function is called by the assembly routine loaded by grub:

Code: Select all

	mov esp, 0x00500000 ; stack grows DOWNWARD, so stack is 0xC0500000 - 0xC0400000
	
	push ebx ; push grub memory map
	extern kernel_main
	extern vmm_init
	
	mov ebx, vmm_init
	sub ebx, 0xC0000000
	
	call ebx
	
	mov cr3, eax
	mov eax, cr0
	or eax, 0x80000000
	mov cr0, eax
	
	add esp, 0xC0000000
	call kernel_main
.hang:
	hlt
	jmp .hang
Does anybody see anything wrong here? What do you guys think? I'm gonna keep pounding away at it, but honestly i'm a bit stuck :(

Edit:

So, i found out i can make bochs report when an interrupt occurs, along with the address of the interrupt. So, i figured i could cross-reference the address of the interrupt that is causing a double fault (since a double fault tends to happen when the processor can't execute an interrupt), but i found something odd...

The address of the interrupt it's trying to execute isn't in my IDT... O_o

Code: Select all

(0) [0x000000106a4f] 0008:00000000c0106a4f (unk. ctxt): mov dword ptr ss:[esp],
0xc0108404 ; c70424048410c0
<bochs:39> c
02088248346: softint 0008:c0106a56 (0xc0106a56) // this is the interrupt that can't be executed...
02088248346: iret 0008:c0106a56 (0xc0106a56)
02088273710i[CPU0 ] WARNING: HLT instruction with IF=0! // my double fault handler halts the CPU
02606400002i[     ] Ctrl-C detected in signal handler.
Next at t=2606400011
(0) [0x000000106a5c] 0008:00000000c0106a5c (unk. ctxt): jmp .-3 (0xc0106a5b)
  ; ebfd
<bochs:40> info idt 0 20 // exception interrupts
Interrupt Descriptor Table (base=0x00000000c012a040, limit=2047):
IDT[0x00]=32-Bit Interrupt Gate target=0x0008:0xc0106ed9, DPL=0
IDT[0x01]=32-Bit Interrupt Gate target=0x0008:0xc0106eda, DPL=0
IDT[0x02]=32-Bit Interrupt Gate target=0x0008:0xc0106edb, DPL=0
IDT[0x03]=32-Bit Interrupt Gate target=0x0008:0xc0106edc, DPL=0
IDT[0x04]=32-Bit Interrupt Gate target=0x0008:0xc0106ee4, DPL=0
IDT[0x05]=32-Bit Interrupt Gate target=0x0008:0xc0106ee5, DPL=0
IDT[0x06]=32-Bit Interrupt Gate target=0x0008:0xc0106ee6, DPL=0
IDT[0x07]=32-Bit Interrupt Gate target=0x0008:0xc0106ee7, DPL=0
IDT[0x08]=32-Bit Interrupt Gate target=0x0008:0xc0106ee8, DPL=0
IDT[0x09]=32-Bit Interrupt Gate target=0x0008:0xc0106eee, DPL=0
IDT[0x0a]=32-Bit Interrupt Gate target=0x0008:0xc0106eef, DPL=0
IDT[0x0b]=32-Bit Interrupt Gate target=0x0008:0xc0106ef1, DPL=0
IDT[0x0c]=32-Bit Interrupt Gate target=0x0008:0xc0106ef3, DPL=0
IDT[0x0d]=32-Bit Interrupt Gate target=0x0008:0xc0106ef5, DPL=0
IDT[0x0e]=32-Bit Interrupt Gate target=0x0008:0xc0106ef7, DPL=0
IDT[0x0f]=32-Bit Interrupt Gate target=0x0008:0xc0106ef9, DPL=0
IDT[0x10]=32-Bit Interrupt Gate target=0x0008:0xc0106efa, DPL=0
IDT[0x11]=32-Bit Interrupt Gate target=0x0008:0xc0106efb, DPL=0
IDT[0x12]=32-Bit Interrupt Gate target=0x0008:0xc0106efc, DPL=0
IDT[0x13]=32-Bit Interrupt Gate target=0x0008:0xc0106efd, DPL=0
IDT[0x14]=32-Bit Interrupt Gate target=0x0008:0xc0106ef9, DPL=0
<bochs:41> info idt 32 48  // IRQ interrupt addresses
Interrupt Descriptor Table (base=0x00000000c012a040, limit=2047):
IDT[0x20]=32-Bit Interrupt Gate target=0x0008:0xc0106f09, DPL=0
IDT[0x21]=32-Bit Interrupt Gate target=0x0008:0xc0106efe, DPL=0
IDT[0x22]=32-Bit Interrupt Gate target=0x0008:0xc0106f41, DPL=0
IDT[0x23]=32-Bit Interrupt Gate target=0x0008:0xc0106f11, DPL=0
IDT[0x24]=32-Bit Interrupt Gate target=0x0008:0xc0106f19, DPL=0
IDT[0x25]=32-Bit Interrupt Gate target=0x0008:0xc0106f21, DPL=0
IDT[0x26]=32-Bit Interrupt Gate target=0x0008:0xc0106f29, DPL=0
IDT[0x27]=32-Bit Interrupt Gate target=0x0008:0xc0106f31, DPL=0
IDT[0x28]=32-Bit Interrupt Gate target=0x0008:0xc0106f39, DPL=0
IDT[0x29]=32-Bit Interrupt Gate target=0x0008:0xc0106f41, DPL=0
IDT[0x2a]=32-Bit Interrupt Gate target=0x0008:0xc0106f49, DPL=0
IDT[0x2b]=32-Bit Interrupt Gate target=0x0008:0xc0106f51, DPL=0
IDT[0x2c]=32-Bit Interrupt Gate target=0x0008:0xc0106f59, DPL=0
IDT[0x2d]=32-Bit Interrupt Gate target=0x0008:0xc0106f61, DPL=0
IDT[0x2e]=32-Bit Interrupt Gate target=0x0008:0xc0106f69, DPL=0
IDT[0x2f]=32-Bit Interrupt Gate target=0x0008:0xc0106f71, DPL=0
IDT[0x30]=32-Bit Interrupt Gate target=0x0008:0xc0106ef9, DPL=0

All the other interrupts in the table are set to this: - a blank interrupt that just returns
32-Bit Interrupt Gate target=0x0008:0xc0106ef9, DPL=0

What should i make of this?
Gogeta70
Member
Member
Posts: 28
Joined: Thu Jun 06, 2013 11:15 am

Re: IDT problems after enabling paging

Post by Gogeta70 »

Anybody? I'm really stuck here...
Gogeta70
Member
Member
Posts: 28
Joined: Thu Jun 06, 2013 11:15 am

Re: IDT problems after enabling paging

Post by Gogeta70 »

I've solved this issue. It was double faulting because i was enabling interrupts before reprogramming the PIC. The timer interrupt generated by the PIT happens to coincide with interrupt 8 in the bios provided IVT.

Anyone who has the same issue:

Don't enable interrupts until you've loaded your IDT AND reprogrammed your PIC!
Post Reply