Page 1 of 1

idt was loaded but isr fail when exception occur[solved]

Posted: Mon Nov 26, 2007 5:41 pm
by shellex
hi, i am new and i meet a strange problem.
i have loaded idt successfully, but when exception occur, cpu can not route interrupt service function.

Code: Select all

void pic_install(){
    // ICW1 
    OUTB(0x11, 0x20);
    OUTB(0x11, 0xA0);
    // ICW2
    OUTB(0x20, 0x21); 
    OUTB(0x28, 0xA1); 
    // ICW3 
    OUTB(0x04, 0x21);
    OUTB(0x02, 0xA1);
    // ICW4 
    OUTB(0x01, 0x21);
    OUTB(0x01, 0xA1);

    OUTB(0xFF, 0x21);   //  IRQ0-IRQ7 
    OUTB(0xFF, 0xA1);   //  IRQ8-IRQ15 

}

void fill_idt(int idx,  int offset, int dpl, int type, short sel) {
    _IDT idt_entry = {
        (sel << 16) | (offset & 0xffff),
        (offset & 0xffff0000) | 0x8000  | (dpl << 13) | (type << 8 )
    };

    g_idt[idx] = idt_entry;
}
void idt_install(){
    /*install defined exception */
    int i = 0;
    for ( ; i < 256; ++i){  
        fill_idt(i, (int)test, 0, INTR_GATE_TYPE, CODE_SEL);    //just a test
    }

    CLI();
    _IDT_descr idt_descr = {IDT_SIZE, (int)g_idt}, t;
    idt_descr.len = IDT_SIZE;
    idt_descr.addr = (int)g_idt;
    asm __volatile__ ("lidt     %0\n\t"::"m"(idt_descr));
    asm __volatile__ ("sidt     %0\n\t"::"m"(t));

    video_display_format("dump idt, len:%X, addr:%X\n", t.len, t.addr);

    asm __volatile__ ("lidt     %0\n\t"::"m"(idt_descr));
}

void test(){
    video_display_str("just a test:\n");

    HALT();
}

and this is my init function:

Code: Select all

void k_init(){
    video_display_str("[!]install idt\n");
    idt_install();
    video_display_str("[!]install pic\n");
    pic_install();
    video_display_str("[!]enable interrupt\n");
    STI();
}
this is bochs output:

Code: Select all

....
 00133138297i[FDD  ] read() on floppy image returns 0
00133161789e[KBD  ] unsupported io write to keyboard port 64, value = bf
00133220750e[CPU  ] interrupt(): not code segment
00133220750e[CPU  ] interrupt(): not code segment
00133220750i[CPU  ] protected mode
00133220750i[CPU  ] CS.d_b = 32 bit
00133220750i[CPU  ] SS.d_b = 32 bit
00133220750i[CPU  ] | EAX=00000004  EBX=00009000  ECX=0009ff3d  EDX=00000000
00133220750i[CPU  ] | ESP=0009ffd0  EBP=0009fff8  ESI=00019200  EDI=00009200
00133220750i[CPU  ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf ZF af PF cf
00133220750i[CPU  ] | SEG selector     base    limit G D
00133220750i[CPU  ] | SEG sltr(index|ti|rpl)     base    limit G D
00133220750i[CPU  ] |  CS:0008( 0001| 0|  0) 00000000 000fffff 1 1
00133220750i[CPU  ] |  DS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00133220750i[CPU  ] |  SS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00133220750i[CPU  ] |  ES:0010( 0002| 0|  0) 00000000 000fffff 1 1
00133220750i[CPU  ] |  FS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00133220750i[CPU  ] |  GS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00133220750i[CPU  ] | EIP=0000011a (0000011a)
00133220750i[CPU  ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00133220750i[CPU  ] | CR3=0x00000000 CR4=0x00000000
00133220750i[CPU  ] >> idiv eax, dword ptr ss:[ebp+0xfffffffc] : F77DFC
00133220750e[CPU  ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00133220750i[SYS  ] bx_pc_system_c::Reset(SOFTWARE) called
00133220750e[CPU  ] CPU_LOOP bx_guard.interrupt_requested=1
Next at t=133220750
(0) [0x0000011a] 0008:011a (unk. ctxt): idiv eax, dword ptr ss:[ebp+0xfffffffc] ; f77dfc

this is bochs display:

Code: Select all

[!]install idt
dump idt, len:0x800, addr:0x10A0
[!]instal pic
[!]install interrupt

Posted: Mon Nov 26, 2007 6:20 pm
by Dandee Yuyo
00133161789e[KBD ] unsupported io write to keyboard port 64, value = bf
Bochs is still complaing about how you try to enable A20:

Code: Select all

enable_a20:        
    inb    $0x64,   %al    
    testb  $0x2,    %al 
    jnz    enable_a20 
    movb   $0xbf,   %al 
    outb   %al,     $0x64 
He doesn't like that 0xbf at all.
00133220750e[CPU ] interrupt(): not code segment
00133220750e[CPU ] interrupt(): not code segment
Your IDT seems to be bad. How are your IDT_descr and IDT structures/types defined?

Posted: Tue Nov 27, 2007 1:45 am
by shellex
the code enable A20 comes from a book named "The Undocumented PC"", :cry:

and i define IDT etc. as follow:
struct _interrupt_descriptor_table {
long low;
long high;
}

typedef struct _interrupt_descriptor_table _IDT;

struct _interrupt_descriptor_table_descr {
short len;
long addr;
} __attribute__((packed));

Posted: Tue Nov 27, 2007 2:49 am
by shellex
Bochs shut up now, i replace the code enable A20.:
enable_a20:
inb $0x92, %al
orb $0x92, %al
outb %al, $0x92

however, i still can not route interrupt service function

Code: Select all

void k_init(){
    video_display_str("[!]install idt\n");
    idt_install();
    video_display_str("[!]install pic\n");
    pic_install();
    video_display_str("[!]enable interrupt\n");
    STI();
    // test div zero exception
    int a = 0;
    video_display_format("test div zero: %d\n", 4 / a);
}

[/code]

Posted: Tue Nov 27, 2007 5:49 am
by JamesM
I'm confused - Dandee Yuyo has quoted code that is not in your post - did you edit it?

Don't edit posts and take out important information- it makes them USELESS to read later!

Posted: Tue Nov 27, 2007 6:33 am
by shellex
JamesM wrote:I'm confused - Dandee Yuyo has quoted code that is not in your post - did you edit it?

Don't edit posts and take out important information- it makes them USELESS to read later!
i am sorry that make you confused. but i didn't remove any importan code from original code and i didn't edit my original post...
i just try to describe my problem better in my last post... :oops:
i add some code to test the div zero exception...

Posted: Tue Nov 27, 2007 7:00 am
by Dandee Yuyo
@James: It's a quote from another post from shellex:

http://www.osdev.org/phpBB2/viewtopic.php?t=15439

@Shellex: Don't have much time right now to debug your code, but the structures are fine. Mainly I wanted to be sure your were not using a short base for the IDT as you were using for the GDT in your previous post.
the code enable A20 comes from a book named "The Undocumented PC"",
Maybe it works on real hardware but not on Bochs, I dunno. You can try this method from the book on real hardware by writing something at 1Mb, and checking that it is not rolling over and being written at 0000:0000 :wink:

Posted: Tue Nov 27, 2007 7:31 am
by shellex
e...well, i enable A20 in another way now. and no error msg about it in the output os bochs.
and what do "short base " mean?
i am sorry that my english is poor.:oops:

Posted: Tue Nov 27, 2007 8:43 am
by Dandee Yuyo
By short base I mean a 16 bits value for the IDT base as you were using for the GDT base in your other post that XCHG noticed. It should be 32 bits, so according to your _interrupt_descriptor_table_descr structure is ok.

Are you sure all the shifts you do for filling the IDT in fill_idt() are ok? Don't have my code here @ work to compare... (nor time to do so) :)

It helped me a lot to code a dumpDescriptor function (together with dumpSelector, dumpGDT, dumpIDT, dumpTSS, dumpMem and so on) that saved me hours of debugging. :wink:

Posted: Tue Nov 27, 2007 9:32 am
by Dandee Yuyo
Use unsigned values in fill_idt and in your structures. The shifting might not be working as you expect due to the sign bit.
INTR_GATE_TYPE should be 14 (0x0e) for interrupt gates.
CODE_SEL ( a multiple of 8 ) must point to a valid code selector in your GDT.

Also, check this out:

http://www.osdever.net/bkerndev/Docs/idt.htm
http://en.wikipedia.org/wiki/Interrupt_descriptor_table
http://www.acm.uiuc.edu/sigops/roll_you ... 6/idt.html

Posted: Thu Nov 29, 2007 6:53 am
by shellex
ï¼ Dandee Yuyo
well, i checked my code. it seems everything are right... :cry:

Posted: Thu Nov 29, 2007 8:46 am
by shellex
I solved it! i did it ! just reset GDT~~~
Thx All, All people here~
@Dandee Yuyo, Thank YOU~

Posted: Sat Dec 01, 2007 6:45 am
by Dandee Yuyo
! just reset GDT
:?: