IDT trouble

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
wen
Posts: 8
Joined: Mon Nov 27, 2006 8:19 pm

IDT trouble

Post by wen »

From my understanding I have the IDT set up correctly, although when I run 'sti', I crash the system. The crash doesn't occur immediately after starting interrupts because the print code I have directly after it works. I also know that none of the code after starting interrupts causes the crash because I have put while(1); after 'sti' and it still crashes.

Here is my main.c file:

Code: Select all

//todo: eventually move printing functions into own module

unsigned char * video_mem = (unsigned char *)0xB8000; //current location of video pointer

void print(char * letter){ //print string
	int i, line, offset;
	for(i = 0; letter[i]; i++){
		if(video_mem >= (unsigned char *)0xB8FA0){
			//this occurs if the text reaches the end of the screen. insert scrolling code here
			break;
		}else if(letter[i] == '\n'){
			offset = (unsigned int)video_mem - 0xB8000;
			line = (offset / 160) + 1;
			video_mem = (unsigned char *)((line * 160) + 0xB8000);
		}else if(letter[i] == '\b'){
			video_mem -= 2;
			video_mem[0] = 0;
		}else if(letter[i] == '\t'){
			video_mem += 8;
		}else{
			video_mem[0] = letter[i];
			video_mem[1] = 2;
			video_mem += 2;
		}
	}
}

struct mb_struct{ //multiboot structure
	unsigned int flags;
	unsigned int mem_lower;
	unsigned int mem_upper;
	unsigned char boot_device_part3;
	unsigned char boot_device_part2;
	unsigned char boot_device_part1;
	unsigned char boot_device_drive;
	unsigned int cmdline;
	unsigned int mods_count;
	unsigned int mods_addr;
}__attribute__ ((packed));

struct gdt{ //gdt table
	short segment_limit;
	short base_address;
	short base_address2:8;
	short type:4;
	short flags:4;
	short segment_limit2:4;
	short flags2:4;
	short base_address3;
}__attribute__ ((packed));

struct segment_r{ //segment register gdt/idt/ldt
	short size;
	int base;
} __attribute__ ((packed));

struct segment_r gdt_register;
struct segment_r idt_register;

struct idt{ //structure of idt table
	short offset;
	short segment_selector;
	short zero:8;
	short flags:8;
	short offset2;
} __attribute__ ((packed));

struct idt idt_table[33]; //idt table

void set_idt(int function, int number, int erase){ //installs isrs
	if(erase){
		idt_table[number].offset = 0;
		idt_table[number].segment_selector = 0;
		idt_table[number].zero = 0;
		idt_table[number].flags = 0;
		idt_table[number].offset2 = 0;
	}else{
		idt_table[number].offset = function & 0xFFFF;
		idt_table[number].segment_selector = 0x18;
		idt_table[number].zero = 0;
		idt_table[number].flags = 0x8E;
		idt_table[number].offset2 = function << 16;
	}
}

void kpanic(){ //test code for interrupts. will be changed later
	print("an interrupt was fired");
	asm("iret");
}

void kernel_entry(struct mb_struct * mb_structure){ //equiv. of int main()
	//load gdt
	struct gdt gdt_table[3];
	
	gdt_table[0].segment_limit = 0;
	gdt_table[0].base_address = 0;
	gdt_table[0].base_address2 = 0;
	gdt_table[0].type = 0;
	gdt_table[0].flags = 0;
	gdt_table[0].segment_limit2 = 0;
	gdt_table[0].flags2 = 0;
	gdt_table[0].base_address3 = 0;
	
	gdt_table[1].segment_limit = 0xFFFF;
	gdt_table[1].base_address = 0;
	gdt_table[1].base_address2 = 0;
	gdt_table[1].type = 2; //data
	gdt_table[1].flags = 8;
	gdt_table[1].segment_limit2 = 0xF;
	gdt_table[1].flags2 = 0xD;
	gdt_table[1].base_address3 = 0;
	
	gdt_table[2].segment_limit = 0xFFFF;
	gdt_table[2].base_address = 0;
	gdt_table[2].base_address2 = 0;
	gdt_table[2].type = 10; //code
	gdt_table[2].flags = 8;
	gdt_table[2].segment_limit2 = 0xF;
	gdt_table[2].flags2 = 0xD;
	gdt_table[2].base_address3 = 0;
	
	gdt_register.size = 24;
	gdt_register.base = (int)&gdt_table;
	
	asm("lgdt gdt_register");
	
	//load idt
	set_idt((int)&kpanic, 0, 0);
	set_idt((int)&kpanic, 1, 0);
	set_idt((int)&kpanic, 2, 0);
	set_idt((int)&kpanic, 3, 0);
	set_idt((int)&kpanic, 4, 0);
	set_idt((int)&kpanic, 5, 0);
	set_idt((int)&kpanic, 6, 0);
	set_idt((int)&kpanic, 7, 0);
	set_idt((int)&kpanic, 8, 0);
	set_idt((int)&kpanic, 9, 0);
	set_idt((int)&kpanic, 10, 0);
	set_idt((int)&kpanic, 11, 0);
	set_idt((int)&kpanic, 12, 0);
	set_idt((int)&kpanic, 13, 0);
	set_idt((int)&kpanic, 14, 0);
	set_idt((int)&kpanic, 15, 0);
	set_idt((int)&kpanic, 16, 0);
	set_idt((int)&kpanic, 17, 0);
	set_idt((int)&kpanic, 18, 0);
	set_idt((int)&kpanic, 19, 0);
	set_idt(0, 20, 1);
	set_idt(0, 21, 1);
	set_idt(0, 22, 1);
	set_idt(0, 23, 1);
	set_idt(0, 24, 1);
	set_idt(0, 25, 1);
	set_idt(0, 26, 1);
	set_idt(0, 27, 1);
	set_idt(0, 28, 1);
	set_idt(0, 29, 1);
	set_idt(0, 30, 1);
	set_idt(0, 31, 1);
	set_idt((int)&kpanic, 32, 0);
	
	idt_register.size = 256; //32 * 8
	idt_register.base = (int)&idt_table;
	
	asm("lidt idt_register");
	asm("sti");

	print("haven't crashed yet!");
}
here is my asm file loader.S:

Code: Select all

.long 0x1BADB002 /* grub multiboot header */
.long 1<<0 | 1<<1
.long -(0x1BADB002 + 1<<0 | 1<<1)
main_loop: /* does nothing */
   hlt
   jmp main_loop
.comm kernel_stack, 0x8000 /* reserves for the kernel stack */
.global kernel_entry
.global entry
entry:
   mov $(kernel_stack + 0x4000), %esp /* sets up stack */
   push %ebx /* push multiboot structure */
   call kernel_entry
   jmp main_loop
If anyone can find out what I'm doing wrong I would be grateful, I've checked over the docs and all the values seem correct to me.


thanks
Mike
Member
Member
Posts: 25
Joined: Tue Oct 17, 2006 7:57 pm

Post by Mike »

idt_table[number].offset2 = function << 16;
Sure you don't mean

Code: Select all

function >> 16
wen
Posts: 8
Joined: Mon Nov 27, 2006 8:19 pm

Post by wen »

Thanks, thats what I meant.

Although I'm still getting the same problem as before.
User avatar
kataklinger
Member
Member
Posts: 381
Joined: Fri Nov 04, 2005 12:00 am
Location: Serbia

Post by kataklinger »

idt_register & gdt_register must be aligned on 16bytes boundery
idt_register.limit i calculated as

Code: Select all

idt_register.limit = number_of_enteries * sizeof (idt) - 1
Are you sure that size of idt structure is 8 bytes?
wen
Posts: 8
Joined: Mon Nov 27, 2006 8:19 pm

Post by wen »

kataklinger wrote:idt_register & gdt_register must be aligned on 16bytes boundery
idt_register.limit i calculated as

Code: Select all

idt_register.limit = number_of_enteries * sizeof (idt) - 1
Are you sure that size of idt structure is 8 bytes?
Thanks for the response. I aligned the tables and the registers on 32 byte boundary, just to be sure. I also changed the size of the tables. If I'm correct in calculating them they should be:
gdt: 23 = (8 * 3 - 1)
idt: 263 = (8 * 32 - 1)

But it is still crashing as if I have made no changes at all. Anyone else see any flaws in this code?

Here is my revised code:

Code: Select all

//--printing code and mb_struct not posted (look above if needed, they aren't changed)

struct gdt{ //gdt table
	short segment_limit;
	short base_address;
	short base_address2:8;
	short type:4;
	short flags:4;
	short segment_limit2:4;
	short flags2:4;
	short base_address3;
} __attribute__((packed));

struct segment_r{ //segment register gdt/idt/ldt
	short size;
	int base;
} __attribute__((packed));

struct segment_r gdt_register __attribute__ ((aligned(32)));
struct segment_r idt_register __attribute__ ((aligned(32)));

struct idt{ //structure of idt table
	short offset;
	short segment_selector;
	short zero:8;
	short flags:8;
	short offset2;
} __attribute__((packed));

struct idt idt_table[33] __attribute__ ((aligned(32))); //idt table

void set_idt(int function, int number, int erase){ //installs isrs
	if(erase){
		idt_table[number].offset = 0;
		idt_table[number].segment_selector = 0;
		idt_table[number].zero = 0;
		idt_table[number].flags = 0;
		idt_table[number].offset2 = 0;
	}else{
		idt_table[number].offset = function & 0xFFFF;
		idt_table[number].segment_selector = 0x18;
		idt_table[number].zero = 0;
		idt_table[number].flags = 0x8E;
		idt_table[number].offset2 = function >> 16;
	}
}

void kpanic(){ //test code for interrupts. will be changed later
	print("an interrupt was fired");
	asm("iret");
}

void kernel_entry(struct mb_struct * mb_structure){ //equiv. of int main()
	//load gdt
	struct gdt gdt_table[3] __attribute__ ((aligned(32)));
	
	gdt_table[0].segment_limit = 0;
	gdt_table[0].base_address = 0;
	gdt_table[0].base_address2 = 0;
	gdt_table[0].type = 0;
	gdt_table[0].flags = 0;
	gdt_table[0].segment_limit2 = 0;
	gdt_table[0].flags2 = 0;
	gdt_table[0].base_address3 = 0;
	
	gdt_table[1].segment_limit = 0xFFFF;
	gdt_table[1].base_address = 0;
	gdt_table[1].base_address2 = 0;
	gdt_table[1].type = 2; //data
	gdt_table[1].flags = 8;
	gdt_table[1].segment_limit2 = 0xF;
	gdt_table[1].flags2 = 0xD;
	gdt_table[1].base_address3 = 0;
	
	gdt_table[2].segment_limit = 0xFFFF;
	gdt_table[2].base_address = 0;
	gdt_table[2].base_address2 = 0;
	gdt_table[2].type = 10; //code
	gdt_table[2].flags = 8;
	gdt_table[2].segment_limit2 = 0xF;
	gdt_table[2].flags2 = 0xD;
	gdt_table[2].base_address3 = 0;
	
	gdt_register.size = 23; //3 * 8  -1
	gdt_register.base = (int)&gdt_table;
	
	asm("lgdt gdt_register");
	
	//load idt
	set_idt((int)&kpanic, 0, 0);
	set_idt((int)&kpanic, 1, 0);
	set_idt((int)&kpanic, 2, 0);
	set_idt((int)&kpanic, 3, 0);
	set_idt((int)&kpanic, 4, 0);
	set_idt((int)&kpanic, 5, 0);
	set_idt((int)&kpanic, 6, 0);
	set_idt((int)&kpanic, 7, 0);
	set_idt((int)&kpanic, 8, 0);
	set_idt((int)&kpanic, 9, 0);
	set_idt((int)&kpanic, 10, 0);
	set_idt((int)&kpanic, 11, 0);
	set_idt((int)&kpanic, 12, 0);
	set_idt((int)&kpanic, 13, 0);
	set_idt((int)&kpanic, 14, 0);
	set_idt((int)&kpanic, 15, 0);
	set_idt((int)&kpanic, 16, 0);
	set_idt((int)&kpanic, 17, 0);
	set_idt((int)&kpanic, 18, 0);
	set_idt((int)&kpanic, 19, 0);
	set_idt(0, 20, 1);
	set_idt(0, 21, 1);
	set_idt(0, 22, 1);
	set_idt(0, 23, 1);
	set_idt(0, 24, 1);
	set_idt(0, 25, 1);
	set_idt(0, 26, 1);
	set_idt(0, 27, 1);
	set_idt(0, 28, 1);
	set_idt(0, 29, 1);
	set_idt(0, 30, 1);
	set_idt(0, 31, 1);
	set_idt((int)&kpanic, 32, 0);
	
	idt_register.size = 263; //33 * 8 -1
	idt_register.base = (int)&idt_table;
	
	asm("lidt idt_register");
	asm("sti");

	print("haven't crashed yet!");
}
User avatar
kataklinger
Member
Member
Posts: 381
Joined: Fri Nov 04, 2005 12:00 am
Location: Serbia

Post by kataklinger »

Well, you have aligned idt table, but did you align idt_register

Code: Select all

struct segment_r gdt_register; 
struct segment_r idt_register;
should like this:

Code: Select all

struct segment_r gdt_register __atribute__(aligned(16)); 
struct segment_r idt_register __atribute__(aligned(16));
wen
Posts: 8
Joined: Mon Nov 27, 2006 8:19 pm

Post by wen »

Yes, I aligned the idt_register and idt_table. I tried aligning to 8, 16, and 32 bytes but it crashes for all of them.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

i think

Code: Select all

idt_table[number].segment_selector = 0x18; 
should be

Code: Select all

idt_table[number].segment_selector = 0x08; 
as you only defined selectors 0 (0x0) 1 (0x08) and 2 (0x10)

And afaik, you dont need to align the gdt or idt, and aligning the corresponding registers is a waste of time. Aligning on 8-byte boundaries is just a trick for speed.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
wen
Posts: 8
Joined: Mon Nov 27, 2006 8:19 pm

Post by wen »

Ok, I tried 0x0, 0x8, and 0x10 (and the 0x18 I already had) and none of them stop the crashing. I think 0x18 is correct though since my code segment is the second one.

I'm curious how are you calculating the selectors that you get 0x10 for the second one?

I set 00 for RPL, 0 for TI and 2 for index = 11000 = 0x18. Am I doing this wrong?

edit: I changed the 'S' descriptor type on the gdt to code/data instead of system. Which changed the 'flags' field in the gdt table to 9 instead of 8. This still didn't solve the crashing problem though.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

0 in binary = 0 0
1 in binary = 0 1
2 in binary = 1 0
3 in binary = 1 1
so a selector of 11000 binary (0x18) picks entry 3 (11b) (missing) of table 0 (GDT) with a RPL of 00 (ring 0),
Consequently using 0x18 as the selector is a bad choice.

On another note, have you ever tried using Bochs' debugger as it can give feedback about what error is occurring exactly.

Maybe someone with knowledge of AT&T syntax could check if mov $(kernel_stack+0x4000), %esp matches MOV esp, kernel_stack+0x4000, as it looks more like MOV esp, [kernel_stack+0x4000] to me. I use only intel syntax and the assignment looks kindof suspicious
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
wen
Posts: 8
Joined: Mon Nov 27, 2006 8:19 pm

Post by wen »

Combuster wrote:0 in binary = 0 0
1 in binary = 0 1
2 in binary = 1 0
3 in binary = 1 1
so a selector of 11000 binary (0x18) picks entry 3 (11b) (missing) of table 0 (GDT) with a RPL of 00 (ring 0),
Consequently using 0x18 as the selector is a bad choice.

On another note, have you ever tried using Bochs' debugger as it can give feedback about what error is occurring exactly.

Maybe someone with knowledge of AT&T syntax could check if mov $(kernel_stack+0x4000), %esp matches MOV esp, kernel_stack+0x4000, as it looks more like MOV esp, [kernel_stack+0x4000] to me. I use only intel syntax and the assignment looks kindof suspicious
Whoops, not sure what I was thinking assuming 11 = 2 in bin. But I will try the bochs debugger in a few hours when I get some time. I have been using vmware which doesn't provide much feedback on crashes.

Thanks for the quick reply.
wen
Posts: 8
Joined: Mon Nov 27, 2006 8:19 pm

Post by wen »

Sorry for bring back this thread again, but I still can't figure out what is causing the crash. The bochs debugger hasn't helped me much because I'm not all that experienced with it and debugging in general. My only expereince is doing basic things in gdb.

Here is the output from bochs debugger:

Code: Select all

C:\msys\1.0\local\bin>bochs -f \bochs_config -q
========================================================================
                      Bochs x86 Emulator 2.3.cvs
              Build from CVS snapshot, after release 2.3
========================================================================
00000000000i[     ] reading configuration from \bochs_config
00000000000i[     ] \bochs_config: vga_update_interval seems awfully small!
00000000000i[     ] installing win32 module as the Bochs GUI
00000000000i[     ] Bochs x86 Emulator 2.3.cvs
00000000000i[     ]   Build from CVS snapshot, after release 2.3
00000000000i[     ] System configuration
00000000000i[     ]   processors: 1 (cores=1, HT threads=1)
00000000000i[     ]   A20 line support: yes
00000000000i[     ]   APIC support: no
00000000000i[     ] CPU configuration
00000000000i[     ]   level: 5
00000000000i[     ]   TLB enabled: yes
00000000000i[     ]   SMP support: no
00000000000i[     ]   FPU support: yes
00000000000i[     ]   MMX support: yes
00000000000i[     ]   SSE support: no
00000000000i[     ]   v8086 mode support: yes
00000000000i[     ]   VME support: yes
00000000000i[     ]   3dnow! support: no
00000000000i[     ]   PAE support: no
00000000000i[     ]   PGE support: no
00000000000i[     ]   PSE support: yes
00000000000i[     ]   x86-64 support: no
00000000000i[     ]   SEP support: no
00000000000i[     ] Optimization configuration
00000000000i[     ]   Guest2HostTLB support: no
00000000000i[     ]   RepeatSpeedups support: no
00000000000i[     ]   Icache support: no
00000000000i[     ]   Host Asm support: yes
00000000000i[     ]   Fast function calls: no
00000000000i[     ] Devices configuration
00000000000i[     ]   NE2000 support: no
00000000000i[     ]   PCI support: no
00000000000i[     ]   SB16 support: no
00000000000i[     ]   USB support: no
00000000000i[     ]   VGA extension support: vbe
00000000000i[MEM0 ] allocated memory at 00C40020. after alignment, vector=00C41000
00000000000i[MEM0 ] 4.00MB
00000000000i[MEM0 ] rom at 0xfffe0000/131072 ('c:\msys\1.0\local\share\bochs\bios-bochs-latest')
00000000000i[MEM0 ] rom at 0xc0000/38400 ('c:\msys\1.0\local\share\bochs\vgabios-lgpl-latest')
00000000000i[CMOS ] Using local time for initial clock
00000000000i[CMOS ] Setting initial clock to: Mon Dec 04 16:52:33 2006 (time0=1165272753)
00000000000i[DMA  ] channel 4 used by cascade
00000000000i[DMA  ] channel 2 used by Floppy Drive
00000000000i[FDD  ] fd0: 'c:\program files\bochs-2.2.6\grub.img' ro=0, h=2,t=80,spt=18
00000000000i[MEM0 ] Register memory access handlers: 000a0000-000bffff
00000000000i[WGUI ] Number of Mouse Buttons = 3
00000000000i[WGUI ] IME disabled
00000000000i[VGA  ] interval=40000
00000000000i[     ] init_mem of 'harddrv' plugin device by virtual method
00000000000i[     ] init_mem of 'keyboard' plugin device by virtual method
00000000000i[     ] init_mem of 'serial' plugin device by virtual method
00000000000i[     ] init_mem of 'parallel' plugin device by virtual method
00000000000i[     ] init_mem of 'extfpuirq' plugin device by virtual method
00000000000i[     ] init_mem of 'speaker' plugin device by virtual method
00000000000i[     ] init_dev of 'harddrv' plugin device by virtual method
00000000000i[HD   ] Using boot sequence floppy, none, none
00000000000i[HD   ] Floppy boot signature check is enabled
00000000000i[     ] init_dev of 'keyboard' plugin device by virtual method
00000000000i[KBD  ] will paste characters every 1000 keyboard ticks
00000000000i[     ] init_dev of 'serial' plugin device by virtual method
00000000000i[SER  ] com1 at 0x03f8 irq 4
00000000000i[     ] init_dev of 'parallel' plugin device by virtual method
00000000000i[PAR  ] parallel port 1 at 0x0378 irq 7
00000000000i[     ] init_dev of 'extfpuirq' plugin device by virtual method
00000000000i[     ] init_dev of 'speaker' plugin device by virtual method
00000000000i[     ] register state of 'harddrv' plugin device by virtual method
00000000000i[     ] register state of 'keyboard' plugin device by virtual method
00000000000i[     ] register state of 'serial' plugin device by virtual method
00000000000i[     ] register state of 'parallel' plugin device by virtual method
00000000000i[     ] register state of 'extfpuirq' plugin device by virtual method
00000000000i[     ] register state of 'speaker' plugin device by virtual method
00000000000i[SYS  ] bx_pc_system_c::Reset(HARDWARE) called
00000000000i[     ] reset of 'harddrv' plugin device by virtual method
00000000000i[     ] reset of 'keyboard' plugin device by virtual method
00000000000i[     ] reset of 'serial' plugin device by virtual method
00000000000i[     ] reset of 'parallel' plugin device by virtual method
00000000000i[     ] reset of 'extfpuirq' plugin device by virtual method
00000000000i[     ] reset of 'speaker' plugin device by virtual method
00000000000i[     ] set SIGINT handler to bx_debug_ctrlc_handler
Next at t=0
(0) [0xfffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b         ; ea5be000f0
<bochs:1> c
00000003867i[BIOS ] $Revision: 1.175 $ $Date: 2006/11/04 18:06:36 $
00000318047i[KBD  ] reset-disable command received
00000352749i[BIOS ] Starting rombios32
00000353546i[BIOS ] ram_size=0x01000000
00000354155i[BIOS ] Found 1 cpu(s)
00000509471i[VBIOS] VGABios $Id: vgabios.c,v 1.66 2006/07/10 07:47:51 vruppert Exp $
00000512478i[VBIOS] VBE Bios $Id: vbe.c,v 1.58 2006/08/19 09:39:43 vruppert Exp $
00000560000i[WGUI ] dimension update x=720 y=400 fontheight=16 fontwidth=9 bpp=8
00012309063e[CPU  ] interrupt(): not code segment
00012309063e[CPU  ] interrupt(): not code segment
00012309063e[CPU  ] interrupt(): not code segment
00012309063i[CPU  ] protected mode
00012309063i[CPU  ] CS.d_b = 32 bit
00012309063i[CPU  ] SS.d_b = 32 bit
00012309063i[CPU  ] | EAX=00100600  EBX=00026260  ECX=00000020  EDX=000b80c6
00012309063i[CPU  ] | ESP=0010501c  EBP=00067edc  ESI=000263d3  EDI=000263e3
00012309063i[CPU  ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf zf af pf cf
00012309063i[CPU  ] | SEG selector     base    limit G D
00012309063i[CPU  ] | SEG sltr(index|ti|rpl)     base    limit G D
00012309063i[CPU  ] |  CS:0008( 0001| 0|  0) 00000000 000fffff 1 1
00012309063i[CPU  ] |  DS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00012309063i[CPU  ] |  SS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00012309063i[CPU  ] |  ES:0010( 0002| 0|  0) 00000000 000fffff 1 1
00012309063i[CPU  ] |  FS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00012309063i[CPU  ] |  GS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00012309063i[CPU  ] | EIP=0010000d (0010000d)
00012309063i[CPU  ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00012309063i[CPU  ] | CR3=0x00000000 CR4=0x00000000
00012309063i[CPU  ] >> jmp .+0xfffffffd (0x0010000c) : EBFD
00012309063e[CPU  ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00012309063i[SYS  ] bx_pc_system_c::Reset(SOFTWARE) called
00012309063e[CPU  ] CPU_LOOP bx_guard.interrupt_requested=1
Next at t=12309063
(0) [0x0010000d] 0008:10000d (unk. ctxt): jmp .+0xfffffffd (0x000f000c) ; ebfd
<bochs:2>
I don't know what it means by "exception with no resolution", this appears to be the problem.

Thanks again for any help that is offered.

edit: I have also tried changing the line:

Code: Select all

idt_table[number].offset2 = function >> 16;
to:

Code: Select all

idt_table[number].offset2 = (function >> 16) & 0xFFFF;
In my set_idt function to ensure that it isn't overflowing. I have also tried changing the interrupt function to a simple asm function which runs hlt to make sure that something added before my C interrupt handler isn't causing the issue.

But none of the changes have worked.
xdopamine
Posts: 6
Joined: Tue Dec 05, 2006 1:02 am

Post by xdopamine »

Hello,

did you define some interrupt stub for calling your kpanic function from an interrupt handler ?

For example i use this code:

Code: Select all

#define DefineInterruptStub(n, t, nr) \
__asm__( \
"" # n ":" \
"pushl $0;" \
"pushl $" # nr ";"\
"pushl %edi\n" 			\
"pushl %esi\n"			\
"pushl %ebp\n"			\
"pushl %ebx\n"			\
"pushl %edx\n"			\
"pushl %ecx\n"			\
"pushl %eax\n"			\
"pushl %ds\n"			\
"pushl %es\n"			\
"pushl %fs\n"			\
"pushl %gs\n"			\
"movw $0x10, %ax;" \ /* you should change $0x10 to your kernel data selector */
"movw %ax, %ds;" \
"movw %ax, %es;" \
"movl %esp, %eax;" \
"pushl %eax;" \
"call " # t ";" \
"popl %eax\n" \
"popl %gs\n"			\
"popl %fs\n"			\
"popl %es\n"			\
"popl %ds\n"			\
"popl %eax\n"			\
"popl %ecx\n"			\
"popl %edx\n"			\
"popl %ebx\n"			\
"popl %ebp\n"			\
"popl %esi\n"			\
"popl %edi\n"			\
"addl $8, %esp;" \
"iret;" \
); \
extern void n(void);


#define DefineInterruptStubWithErrorCode(n, t, nr) \
__asm__( \
"" # n ":" \
"pushl $" # nr ";"\
"pushl %edi\n" 			\
"pushl %esi\n"			\
"pushl %ebp\n"			\
"pushl %ebx\n"			\
"pushl %edx\n"			\
"pushl %ecx\n"			\
"pushl %eax\n"			\
"pushl %ds\n"			\
"pushl %es\n"			\
"pushl %fs\n"			\
"pushl %gs\n"			\
"movw $0x10, %ax;" \ /* you should change $0x10 to your kernel data selector */
"movw %ax, %ds;" \
"movw %ax, %es;" \
"movl %esp, %eax;" \
"pushl %eax;" \
"call " # t ";" \
"popl %eax\n" \
"popl %gs\n"			\
"popl %fs\n"			\
"popl %es\n"			\
"popl %ds\n"			\
"popl %eax\n"			\
"popl %ecx\n"			\
"popl %edx\n"			\
"popl %ebx\n"			\
"popl %ebp\n"			\
"popl %esi\n"			\
"popl %edi\n"			\
"addl $8, %esp;" \
"iret;" \
); \
extern void n(void);


You can use it easily to define some interrupt stub.
In your case you should write:

Code: Select all

DefineInterruptStub(__int0, kpanic, 0)
DefineInterruptStub(__int1, kpanic, 1)
DefineInterruptStub(__int2, kpanic, 2)
DefineInterruptStub(__int3, kpanic, 3)
DefineInterruptStub(__int4, kpanic, 4)
DefineInterruptStub(__int5, kpanic, 5)
DefineInterruptStub(__int6, kpanic, 6)
.......


set_idt((int)&__int0, 0, 0); 
   set_idt((int)&__int1, 1, 0); 
   set_idt((int)&__int2, 2, 0); 
   set_idt((int)&__int3, 3, 0); 
   set_idt((int)&__int4, 4, 0); 
   set_idt((int)&__int5, 5, 0); 
   set_idt((int)&__int6, 6, 0); 

....

void kpanic(){ //test code for interrupts. will be changed later 
   print("an interrupt was fired"); 
} 

User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Bochs reports the exact problem:

Code: Select all

00012309063e[CPU  ] interrupt(): not code segment 
I.e. you are trying to have the processor load CS with the wrong selector upon interrupt. This can be something else than a code segment, or an invalid code segment.

Given the rest of the dump, i think the correct selector should be 0x08. (not the 0x18 currently set in the code)
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply