Page 1 of 1

[PMode] Setting up Interrupts

Posted: Sat Feb 06, 2016 7:08 am
by Vakus
So basically I spent already about 3 hours searching how to set up own interrupts. the only thing that told me something was http://wiki.osdev.org/I_Can't_Get_Inter ... rking#NASM
but this example is totally not explained, causing that I can not really rewrite it, making it kind of useless. My problem is that I managed to create int 49, but when i tried to change it to for example int 0x1 it done nothing. I would be really thankful for easy (like for newbie with not good english) explanation how to set up IDT with own interrupts. I also would ask if you want to send some code could it be assembly code (specifically NASM but it doesnt have to be)

My code is:

Code: Select all

;==========
; bootloader - sector 0x1
;==========

org 0x7C00
bits 16

xor ax,ax
mov ds,ax
mov es,ax

mov bx,0x8000
cli
mov ss,bx
mov sp,ax
sti

cld
clc

;setup 0x0500 to be booted hard drive number
mov dl,[0x0500]

xor ah,ah
;set 0x7E00 to 0x0 in case something is already there - needed for futher check
mov BYTE [0x7E00], ah
int 0x13
mov bx,0x07E0
mov es,bx
xor bx,bx
mov ah,0x2 ;function
mov al,0x3 ;sectors to read
mov ch,0x0 ;track
mov cl,0x2 ;sector
mov dh,0x0 ;head
int 0x13
jc error
;simple check is any code at this place
mov ah, [0x7E00]
cmp ah,0x0
je error
;clean screen
mov ah,0x0F
mov al,' '
cld
mov bx,0xb800
mov es,bx
xor bx,bx
mov di,bx
mov cx,0x0FA0
rep stosw
stosw

;setup gdt

cli
pusha
lgdt [toc]
sti
popa

;a20

in al,0x92
or al,0x2
out 0x92, al
call check_a20
jc code
mov ax,0x2401
int 0x15
call check_a20
jc code
mov al,0xdd
out 0x64, al
call check_a20
jc code
jnc error


code:
;suspend interrupts as we did not setted up Interrupt Table Yet - in case we wont stop interrupts computer will crash
cli
mov eax, cr0
or eax, 1
mov cr0, eax

;jump to code
jmp 0x8:0x7E00
jmp error
cli
hlt
	
error:
	mov ah,0x40
	mov al,' '
	cld
	mov bx,0xb800
	mov es,bx
	xor bx,bx
	mov di,bx
	mov cx,0x0FA0
	rep stosw
	stosw
	cli
	hlt
	
check_a20:
	xor ax,ax
	mov es,ax
	not ax
	mov ds,ax
	mov di,0x0500
	mov si,0x0510
	mov al, byte [es:di]
	push ax
	mov al, byte [ds:si]
	push ax
	mov byte [es:di], 0x00
	mov byte [ds:si], 0xFF
	cmp byte [es:di], 0xFF
	pop ax
	mov byte[ds:si],al
	pop ax
	mov byte [es:di],al
	clc ;disabled 	carry flag = 0
	je .exit
	stc ;enabled 	carry flag = 1
	.exit:
		ret

gdt_data: 
	dd 0 				; null descriptor
	dd 0 
 
; gdt code:				; code descriptor
	dw 0FFFFh 			; limit low
	dw 0 				; base low
	db 0 				; base middle
	db 10011010b 		; access
	db 11001111b 		; granularity
	db 0 				; base high
 
; gdt data:				; data descriptor
	dw 0FFFFh 			; limit low (Same as code)
	dw 0 				; base low
	db 0 				; base middle
	db 10010010b 		; access
	db 11001111b 		; granularity
	db 0				; base high
 
end_of_gdt:
toc: 
	dw end_of_gdt - gdt_data - 1 	; limit (Size of GDT)
	dd gdt_data 			; base of GDT
	
times 0x1FE - ($ - $$) db 0x0
db 0x55
db 0xAA

;==========
;sector 0x2
;==========
;cannot start from 0x0
;32 bit code starts here
;a20 enabled (if not system crashed)
;gdt set
;interrupts clear

bits 32

;this is important - if eax not equals to 0x10 and try to move it to ss pc will crash or functions wont work correctly
mov eax,0x10
mov ds,eax
mov es,eax
mov fs,eax
mov gs,eax
mov ss,eax

lidt [idtr]
mov eax,int_01
mov [idt+1*8], ax
mov word [idt+1*8+2],0x4
mov word [idt+1*8+4],0x8E00
shr eax,16
mov [idt+1*8+6],ax
int 0x1

;create interrupt 0x1

int_01:
    mov dword [gs:0xB8000], ') : '
    hlt
   
idt:
    resd 2*2
    
idtr:
    dw (1*8)-1
    dd idt

times 0x600 - ($-$$) db 0x0

Re: [PMode] Setting up Interrupts

Posted: Sat Feb 06, 2016 7:20 am
by BrightLight
Just by looking at your IDTR, the size of your IDT is wrong. Each IDT entry is 8 bytes. You're using INT 1, which means you need two entries: one for INT 0 and one for INT 1. The size of your IDT should be 15 not 7.

Re: [PMode] Setting up Interrupts

Posted: Sat Feb 06, 2016 7:40 am
by Vakus
I changed IDTR size to

Code: Select all

idtr:
    dw (2*8)-1
    dd idt
but the code still generate triple fault on calling int 0x1

Re: [PMode] Setting up Interrupts

Posted: Sat Feb 06, 2016 7:58 am
by Techel
Check your selector put in the entry - it's 0x04.

Re: [PMode] Setting up Interrupts

Posted: Sat Feb 06, 2016 8:01 am
by BrightLight
Something else too: you don't have a stack set up. In real mode, you set up the stack to 0x8000:0x0000. In protected mode, I see you initialize SS but not ESP. SS is 0x10 which is a base 0 segment, and ESP is also 0 and the system writes to non-existent memory on interrupt.

Re: [PMode] Setting up Interrupts

Posted: Sat Feb 06, 2016 8:16 am
by Vakus
omarrx024 wrote:Something else too: you don't have a stack set up. In real mode, you set up the stack to 0x8000:0x0000. In protected mode, I see you initialize SS but not ESP. SS is 0x10 which is a base 0 segment, and ESP is also 0 and the system writes to non-existent memory on interrupt.
I didnt noticed that, but even after i set up ESP to be 0x10, my code still generate triple fault on int 0x1
Roflo wrote:Check your selector put in the entry - it's 0x04.
I dont really know what do you mean, i guess you talking about

Code: Select all

lidt [idtr]
mov eax,int_01
mov [idt+1*8], ax
mov word [idt+1*8+2],0x4           ;This line? instead 0x4 should be 0x04, is this what you mean?
mov word [idt+1*8+4],0x8E00
shr eax,16
mov [idt+1*8+6],ax
int 0x1

Re: [PMode] Setting up Interrupts

Posted: Sat Feb 06, 2016 8:54 am
by BrightLight
Setting ESP to 0x10 is very little stack space. Try setting it to 0x7C00 or something like that.
And your segment should be 0x8, not 0x4. Where did 0x4 come from? The GDT has 8 byte entries, and your code segment is 0x8 as we've seen above when you switch into protected mode.

Code: Select all

;This line? instead 0x4 should be 0x04, is this what you mean?
0x4 and 0x04 are the same thing. Are you sure you have basic programming experience?

Re: [PMode] Setting up Interrupts

Posted: Sat Feb 06, 2016 2:39 pm
by Vakus
omarrx024 wrote:Setting ESP to 0x10 is very little stack space. Try setting it to 0x7C00 or something like that.
And your segment should be 0x8, not 0x4. Where did 0x4 come from? The GDT has 8 byte entries, and your code segment is 0x8 as we've seen above when you switch into protected mode.

Code: Select all

;This line? instead 0x4 should be 0x04, is this what you mean?
0x4 and 0x04 are the same thing. Are you sure you have basic programming experience?

yeah i moved ESP later on, and I didnt get the thing with 0x4 I was sure there was no difference between 0x4 and 0x04, but
Roflo wrote:Check your selector put in the entry - it's 0x04.
put me off a bit.

Btw. Code is working now, it was the problem with 0x4 and 0x8 thank for pointing this out