IDT table, help :s

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.
White-spirit
Member
Member
Posts: 89
Joined: Sun Mar 23, 2008 2:23 pm
Location: [0x8:0x1000]

IDT table, help :s

Post by White-spirit »

Hello,

I have a little problem with my IDT, Bochs reboots and gives me the following error message :
">> int 0x00 : CD00"

Here's my code ( most of the work is done by JamesM :P ) :

Code: Select all

typedef unsigned int   u32int;
typedef          int   s32int;
typedef unsigned short u16int;
typedef          short s16int;
typedef unsigned char  u8int;
typedef          char  s8int;

typedef struct registers
{
   u32int ds;                  // Data segment selector
   u32int edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha.
   u32int int_no, err_code;    // Interrupt number and error code (if applicable)
   u32int eip, cs, eflags, useresp, ss; // Pushed by the processor automatically.
} registers_t;

struct idt_entry_struct
{
	u16int base_lo;
	u16int sel;
	u8int always0;
	u8int flags;
	u16int base_hi;
} __attribute__ ((packed));
typedef struct idt_entry_struct idt_entry_t;

struct idt_ptr_struct
{
	u16int limit;
	u32int base;
} __attribute__ ((packed));
typedef struct idt_ptr_struct idt_ptr_t;

extern void isr0();
extern void isr1();
extern void isr2();
extern void isr3();
extern void isr4();
extern void isr5();
extern void isr6();
extern void isr7();
extern void isr8();
extern void isr9();
extern void isr10();
extern void isr11();
extern void isr12();
extern void isr13();
extern void isr14();
extern void isr15();
extern void isr16();
extern void isr17();
extern void isr18();
extern void isr19();
extern void isr20();
extern void isr21();
extern void isr22();
extern void isr23();
extern void isr24();
extern void isr25();
extern void isr26();
extern void isr27();
extern void isr28();
extern void isr29();
extern void isr30();
extern void isr31();

extern void idt_flush(u32int);
void isr_handler(registers_t);
static void init_idt();
void *memset(void*, int, unsigned int);
static void idt_set_gate(u8int,u32int,u16int,u8int);
idt_entry_t idt_entries[256];
idt_ptr_t idt_ptr;

int kernel_main(void){
	init_idt();
	printf("Kernel loaded !\n");
	asm volatile ("int $0x0");
	while(1);
}

void *memset (void *buffer, int ch, unsigned int count)
{
	register char *buff = buffer;
	while ( count-- ) *buff++ = ch;
	return buff;
}

static void init_idt()
{
	idt_ptr.limit = sizeof(idt_entry_t) * 256 - 1;
	idt_ptr.base = (u32int)&idt_entries;
	
	memset(&idt_entries, 0, sizeof(idt_entry_t)*256);
	
	idt_set_gate(0 , (u32int)isr0, 0x08, 0x0E);
	idt_set_gate(1 , (u32int)isr1, 0x08, 0x0E);
	idt_set_gate(2 , (u32int)isr2, 0x08, 0x0E);
	idt_set_gate(3 , (u32int)isr3, 0x08, 0x0E);
	idt_set_gate(4 , (u32int)isr4, 0x08, 0x0E);
	idt_set_gate(5 , (u32int)isr5, 0x08, 0x0E);
	idt_set_gate(6 , (u32int)isr6, 0x08, 0x0E);
	idt_set_gate(7 , (u32int)isr7, 0x08, 0x0E);
	idt_set_gate(8 , (u32int)isr8, 0x08, 0x0E);
	idt_set_gate(9 , (u32int)isr9, 0x08, 0x0E);
	idt_set_gate(10, (u32int)isr10, 0x08, 0x0E);
	idt_set_gate(11, (u32int)isr11, 0x08, 0x0E);
	idt_set_gate(12, (u32int)isr12, 0x08, 0x0E);
	idt_set_gate(13, (u32int)isr13, 0x08, 0x0E);
	idt_set_gate(14, (u32int)isr14, 0x08, 0x0E);
	idt_set_gate(15, (u32int)isr15, 0x08, 0x0E);
	idt_set_gate(16, (u32int)isr16, 0x08, 0x0E);
	idt_set_gate(17, (u32int)isr17, 0x08, 0x0E);
	idt_set_gate(18, (u32int)isr18, 0x08, 0x0E);
	idt_set_gate(19, (u32int)isr19, 0x08, 0x0E);
	idt_set_gate(20, (u32int)isr20, 0x08, 0x0E);
	idt_set_gate(21, (u32int)isr21, 0x08, 0x0E);
	idt_set_gate(22, (u32int)isr22, 0x08, 0x0E);
	idt_set_gate(23, (u32int)isr23, 0x08, 0x0E);
	idt_set_gate(24, (u32int)isr24, 0x08, 0x0E);
	idt_set_gate(25, (u32int)isr25, 0x08, 0x0E);
	idt_set_gate(26, (u32int)isr26, 0x08, 0x0E);
	idt_set_gate(27, (u32int)isr27, 0x08, 0x0E);
	idt_set_gate(28, (u32int)isr28, 0x08, 0x0E);
	idt_set_gate(29, (u32int)isr29, 0x08, 0x0E);
	idt_set_gate(30, (u32int)isr30, 0x08, 0x0E);
	idt_set_gate(31, (u32int)isr31, 0x08, 0x0E);
	
	idt_flush((u32int)&idt_ptr);
}

static void idt_set_gate(u8int num, u32int base, u16int sel, u8int flags)
{
	idt_entries[num].base_lo = base & 0xFFFF;
	idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
	idt_entries[num].sel = sel;
	idt_entries[num].always0 = 0;
	idt_entries[num].flags = flags;
	printf("[idt_init] idt_set_gate n%d\n", num);
}

void isr_handler(registers_t regs)
{
	printf("Interrupt: %d \n",regs.int_no);
}
And here's the Fasm code for idt_flush and isrX :

Code: Select all

format elf
public idt_flush

idt_flush:
mov eax, [esp+4]
lidt [eax]
ret

public isr0
isr0:
cli
push 0
push 0
jmp isr_common_stub

rept 31 id
{
public isr#id
isr#id:
cli
if id = 8 | ( id > 9 & id < 15 )
push 0
end if
push id
jmp isr_common_stub
}

isr_common_stub:
pusha
mov ax,ds
push eax
mov ax,0x10				; ax <== 10h
mov ds,ax				; ds <== 10h
mov es,ax				; es <== 10h
mov fs,ax				; fs <== 10h
mov gs,ax				; eg <== 10h
call isr_handler
pop eax					; restores the old values
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
popa
add esp, 8
sti
iret
What's wrong please ?

Thanks :) .
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Ah yes, the art of debugging is slipping away before our very eyes...
White-spirit
Member
Member
Posts: 89
Joined: Sun Mar 23, 2008 2:23 pm
Location: [0x8:0x1000]

Post by White-spirit »

I've added this to debug the idt_set_gate function :

Code: Select all

printf("[idt_init] idt_set_gate n%d, base_lo : %d, base_hi : %d, sel : %d, always0 : %d, flags : %d\n", num, idt_entries[num].base_lo, idt_entries[num].base_hi, idt_entries[num].sel, idt_entries[num].always0, idt_entries[num].flags);
And it seems that base_hi is always set at 0 .
White-spirit
Member
Member
Posts: 89
Joined: Sun Mar 23, 2008 2:23 pm
Location: [0x8:0x1000]

Post by White-spirit »

Here's my bootloader's code if it helps ( I don't use Grub :D ) :

Code: Select all

use16
org 0x7C00

;;;;;;;;; Loading the Kernel from floppy to 0x1000 ;;;;;;;;;
xor ax, ax				; ax <== 0
mov es, ax				; es <== ax <== 0
mov bx, 0x1000      	; destination adress
mov ah, 0x2				; function 02h ( reading sectors )
mov al, 0x10			; 16 sectors
xor ch, ch				;  ch <== 0 ( cylinder 0 )
mov cl, 0x2				; sector 2
xor dx,dx				; ( dh <== 0 , dl <== 0 )
int 0x13
;;;;;;;;; Memory infos ;;;;;;;;;
; coming soon ;

;;;;;;;;; Entering Protected Mode ;;;;;;;;;
cli						; disables interrupts
xor ax,ax				; ax <== 0
mov ds,ax				; ds <== 0
lgdt [gdt_desc]
mov eax,cr0				; eax <== cr0
xor	eax,eax
inc eax					; eax <== 1
mov cr0,eax				; cr0 <== eax

;;;;;;;;; Jumping to Kernel ;;;;;;;;;
jmp dword 0x8:jmp_kernel
use32					; using 32 bits instructions
jmp_kernel:
mov ax,0x10				; ax <== 10h
mov ds,ax				; ds <== 10h
mov ss,ax				; ss <== 10h
mov es,ax				; es <== 10h
mov fs,ax				; fs <== 10h
mov gs,ax				; eg <== 10h
mov esp, 0x90000		; sets stack at 090000h
finit					; initializing FPU registers
jmp dword 0x8:0x1000
jmp $

;;;;;;;;; Initializing GDT ;;;;;;;;;

gdt:

gdt_null:
	dd 0
	dd 0

gdt_code:
	dw 0xFFFF
	dw 0x0
	db 0x0
	db 0x9A
	db 0xCF
	db 0x0
	
gdt_data:
	dw 0xFFFF
	dw 0x0
	db 0x0
	db 0x92
	db 0xCF
	db 0x0

gdt_desc:
	dw gdt_end - gdt - 0x1
	dd gdt
	
gdt_end:
	
times 510-($-$$) db 0x90	; Fills the file with Nop's
dw 0xAA55					; MBR signature
Thanks :)
User avatar
Zenith
Member
Member
Posts: 224
Joined: Tue Apr 10, 2007 4:42 pm

Post by Zenith »

Can you tell us all the values your debug printf prints?
"Sufficiently advanced stupidity is indistinguishable from malice."
exkor
Member
Member
Posts: 111
Joined: Wed May 23, 2007 9:38 pm

Post by exkor »

How about using KISS approach here

Code: Select all

IDT:   ; IRQ #
  dq 0 ; 0
  dq 0 ; 1
  dq 0 ; 2
  dq 0 ; 3
  dq 0 ; 4
  dq 0 ; 5
  dq 0 ; 6
  dq 0 ; 7
  dq 0 ; 8
  dq 0 ; 9
  dq 0 ; 10
  dq 0 ; 11
  dq 0 ; 12
  dw int_GP, 08h, 1000111000000000b, 0   ; 13 #GP, General Protection Fault
  dq 0 ; 14
  dq 0 ; 15
  dq 0 ; 16
  dq 0 ; 17
  dq 0 ; 18
  dq 0 ; 19
  dq 0 ; 20
  dq 0 ; 21
  dq 0 ; 22
  dq 0 ; 23
  dq 0 ; 24
  dq 0 ; 25
  dq 0 ; 26
  dq 0 ; 27
  dq 0 ; 28
  dq 0 ; 29
  dq 0 ; 30
  dq 0 ; 31
              ;selctor   8e00h
  dw int_timer, 08h, 1000111000000000b, 0   ; 32 timer
  dw int_kbd, 08h, 1000111000000000b, 0   ; 33 keyboard
  dq 0   ; 34
  dq 0   ; 35
  dq 0   ; 36
  dq 0   ; 37
  dq 0   ; 38
  dq 0   ; 39

  dq 0   ; 40
  dq 0   ; 41
  dq 0   ; 42
  dq 0   ; 43
  dq 0   ; 44
  dq 0   ; 45
  dq 0   ; 46
  dq 0   ; 47

  dw isr_1, 08h, 1000111000000000b, 0

  .reg:
  .limit  dw $-IDT-1
  .addr   dd IDT      

...

  lidt [IDT.reg]
;code at address bellow 1MB comes here

Code: Select all

isr_1:
iret    ;<--thats all you need
White-spirit
Member
Member
Posts: 89
Joined: Sun Mar 23, 2008 2:23 pm
Location: [0x8:0x1000]

Post by White-spirit »

Here's the output of my printf :

Code: Select all

[idt_init] idt_set_gate n24, base_lo : 8390, base_hi : 0, sel : 8, always0 : 0, flags : 14
[idt_init] idt_set_gate n25, base_lo : 8395, base_hi : 0, sel : 8, always0 : 0, flags : 14
[idt_init] idt_set_gate n26, base_lo : 8400, base_hi : 0, sel : 8, always0 : 0, flags : 14
[idt_init] idt_set_gate n27, base_lo : 8405, base_hi : 0, sel : 8, always0 : 0, flags : 14
[idt_init] idt_set_gate n28, base_lo : 8410, base_hi : 0, sel : 8, always0 : 0, flags : 14
[idt_init] idt_set_gate n29, base_lo : 8415, base_hi : 0, sel : 8, always0 : 0, flags : 14
[idt_init] idt_set_gate n30, base_lo : 8420, base_hi : 0, sel : 8, always0 : 0, flags : 14
[idt_init] idt_set_gate n31, base_lo : 8425, base_hi : 0, sel : 8, always0 : 0, flags : 14
>(cpuid test) CPU Vendor : GenuineIntel
>(printf %.4 test) 28.7896 : 28.7896
>(ftol test) ftol(28.7896) : 28
>(atoi test) atoi("0123456789") : 123456789
>.
>..
>.
>..
>.
>..
>.
>..
>.
>..
>.
>..
>.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Have you tried to narrow the problem down yourself? No. You've just dumped all your* code at us and said "You figure it out". That's not how this forum works...
White-spirit
Member
Member
Posts: 89
Joined: Sun Mar 23, 2008 2:23 pm
Location: [0x8:0x1000]

Post by White-spirit »

If I could, I would not have asked for help here ^^'
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 »

Look at that printf dump:
base_lo : 8390
compare that value with what it is supposed to be, and add more printfs "upstream" to see where those values come from.
"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 ]
White-spirit
Member
Member
Posts: 89
Joined: Sun Mar 23, 2008 2:23 pm
Location: [0x8:0x1000]

Post by White-spirit »

isr0' pointer is 8232 ( 2028 in hex ), so if I disassemble the instructions located between 2028 and 202D, i get the following instructions :

Code: Select all

00002028: (                    ): cli                       ; fa
00002029: (                    ): push 0x0000               ; 6a00
0000202b: (                    ): push 0x0000               ; 6a00
And that's absolutely correct ... :s
White-spirit
Member
Member
Posts: 89
Joined: Sun Mar 23, 2008 2:23 pm
Location: [0x8:0x1000]

Post by White-spirit »

info idt0 gives me :

Code: Select all

<bochs:4> info idt 0
Interrupt Descriptor Table (base=0x0000000000000000, limit=65535):
IDT[0x00]=??? descriptor hi=0x00000000, lo=0x00000000
and base should be 2028 instead of 0 ...
White-spirit
Member
Member
Posts: 89
Joined: Sun Mar 23, 2008 2:23 pm
Location: [0x8:0x1000]

Post by White-spirit »

A better debug output :

Code: Select all

<bochs:2> info idt 0
Interrupt Descriptor Table (base=0x0000000000002280, limit=2047):
IDT[0x00]=32-Bit Interrupt Gate target=0x0008:0x0000203e, DPL=0
White-spirit
Member
Member
Posts: 89
Joined: Sun Mar 23, 2008 2:23 pm
Location: [0x8:0x1000]

Post by White-spirit »

This gives me the same values as "info idt 0" on bochs debugger :

Code: Select all

printf("idt[0] : idt_ptr.base = %h, idt_ptr.limit = %d, base_lo = %h, base_hi = %h, &isr0 = %h \n", idt_ptr.base, idt_ptr.limit, idt_entries[0].base_lo, idt_entries[0].base_hi,isr0);
Can someone help me please ?
White-spirit
Member
Member
Posts: 89
Joined: Sun Mar 23, 2008 2:23 pm
Location: [0x8:0x1000]

Post by White-spirit »

It works, I have only to change 0x0E with 0x8E so it's just a writing error, sorry all for opening this thread :s
Post Reply