Setting up a Interrupt Descriptor Table, CPU resets on INT

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
davidx
Posts: 2
Joined: Tue Aug 02, 2011 2:14 am

Setting up a Interrupt Descriptor Table, CPU resets on INT

Post by davidx »

I've been writing a OS stub using the information on the wiki (and trial and error). I've made it to protected mode, and I have basic text output, but I haven't been able to get interupts working. The following code *should* setup all interupts as do-nothing functions, but the CPU resets (presumably triple faults) when I execute a int instruction (or if I enable interupts and wait a bit).

NASM assembly (with most of the unrelated code ommited):

Code: Select all

[bits 16]
[org 0x7c00]

; --- SNIP loading and debug code (segments are 0) ---

    mov di,0x500
  idt_build_loop:
    mov ax,int_null
    stosw
    mov ax,0x0008
    stosw
    mov ax,0x8e00
    stosw
    mov ax,0
    stosw
    test di,0xd00
    jb idt_build_loop
    
    cli
    lgdt [gdtr]
    lidt [idtr]
    mov eax, cr0
    or ax, 1
    mov cr0, eax
    mov   eax, 0x10 ; 0x10 points at the new data selector
    mov   ds, ax
    mov   es, ax
    mov   fs, ax
    mov   gs, ax
    mov   ss, ax
    jmp 0x8:main

gdtr:
    dw 0x27 ; 5 entrys
    dd gdt_data

gdt_data:
    ; null
    dd 0x00000000
    dd 0x00400000 ; size bit set
    ; global code
    dd 0x0000ffff
    dd 0x00cf9a00
    ; global data
    dd 0x0000ffff
    dd 0x00cf9200
    ; 16-bit code
    dd 0x0000ffff
    db 0x00009e00
    ; 16-bit data
    dw 0x0000ffff
    db 0x00009200

idtr:
    dw 0x7ff  ; 100 interupts * 8 bytes - 1 fencepost
    dd 0x0500 ; lowest guaranteed free ram

int_null:
    iret

times 510 - ($ - $$) db 0 ; fill rest of boot sector
dw 0xaa55                 ; boot signature end of bootloader

[bits 32]
main:
    mov dword [0xb8000], 0x07690748
    
    mov eax,0x04
    mov edx,0x04
    mov esi,boothello
    call textat
    
    ;int 0x41 ; uncommenting this causes the CPU to reset
    
    jmp $

; --- SNIP more debug code ---

times 1024 - ($ - $$) db 0 ; fill rest of second sector
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: Setting up a Interrupt Descriptor Table, CPU resets on I

Post by egos »

Put

Code: Select all

  xor ax,ax
  cli
  mov ss,ax
  mov sp,7C00h
  sti
before your code.


Put

Code: Select all

  cld
  mov es,ax
before mov di,500h.

Put

Code: Select all

  cmp di,0D00h
instead test di,0D00h.

Put

Code: Select all

  mov ds,ax
before lgdt [gdtr].

Is good practice to initialize cs before data segment registers when you enter PM.
There is probability that high word of eip does not hold zero therefore use 32-bit far jump when you enter PM.
If you have seen bad English in my words, tell me what's wrong, please.
davidx
Posts: 2
Joined: Tue Aug 02, 2011 2:14 am

Re: Setting up a Interrupt Descriptor Table, CPU resets on I

Post by davidx »

egos wrote:

Code: Select all

  xor ax,ax
  cli
  mov ss,ax
  mov sp,7C00h
  sti
So the IDT was fine, but I didn't have a working stack to call it with, thanks.

Edit: I also fixed the other problems you mentioned, I dont even know why the selector initialization order was backward.
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: Setting up a Interrupt Descriptor Table, CPU resets on I

Post by egos »

Additionally make and esp,0FFFFh or reset esp in PM.
If you have seen bad English in my words, tell me what's wrong, please.
Post Reply