Page 1 of 1

Nasm 64 bits IDT

Posted: Mon Jun 08, 2020 1:18 pm
by aiglematth
Hi everyone

(Sorry for my bad english, I'm french...)

I have a problem with the creation of my IDT in my little 64 bits OS... I don't see the error...please help me ^^
I can load IDT but can't call int 128... I want to create an IDT with the 0x80 int which print ":)" in the screen (thats an adaptation of the osdev 32 bits idt)

If you have exemple of 64 bits hello world interruption I take ^^

Thats my files :

long.asm :

Code: Select all

;Auteur --> aiglematth

;RAPPEL : 
;La pile est de 0x1e00 à 0x2000

%include	"memory.inc"

bits	32

org	toLongMode

_start:
	call	longModeUp
	cmp	eax,0
	je	enterLongMode

	call	printBlockLongMode
	jmp	$


enterLongMode:
	;On entre en mode long !
	%include	"interractGdt64.inc"

bits	64

;Inludes Macros utiles + données !
%include	"irq.inc"

longMode:
	;On est enfin en mode long !!

	;Un bon contexte
	cli                           
	mov	ax, GDT64.Data            
	mov 	ds, ax                    
	mov 	es, ax                    
	mov 	fs, ax                    
	mov 	gs, ax                   
	mov 	ss, ax
	
	mov	rbp,stack
	mov	rsp,rbp
	sub	rsp,sizeOfStack     
	
	;On load la idt !
	%include	"lidt.inc"             

    	mov	dx,[l_blue]
    	call	clear
	
	int	128
	
	;mov	dl,[l_blue]
	;mov	dh,[black]
	;mov	rdi,longModeBitch
	;mov	esi,screenBuffer
	;xor	rax,rax
	;call	print64
	
	jmp	$

;Fonctions utiles
%include	"output64.inc"

bits	32
;Fonctions utiles
%include	"output32.inc"
%include	"output.inc"
%include	"longMode.inc"

printBlockLongMode:

	call	get_cursor
	mov	dl,[l_magenta]
	mov	dh,[black]
	mov	edi,blockMode
	mov	esi,screenBuffer
	xor	al,al
	mov	ah,1
	call	print

	ret
	
;DATA
%include	"gdt64.inc"
%include	"constantes.inc"

blockMode	db	"On ne peut pas passer en 64 bits...", 0
longModeBitch	db	"On est en 64 bits !", 0

times	32768 - ($ - $$)	db	0
lidt.inc :

Code: Select all

;Auteur --> aiglematth

bits	64

;On va remapp les 15 IRQ par "défaut" dans le PIC
sendCommandAll		0x11 ;On demande un remapp
sendDataMaster		0x20 
sendDataSlave		0x28 
sendDataMaster		0x04 ;On met en place la gestion en cascade
sendDataSlave		0x02
sendDataAll		0x01
sendDataAll		0x00

;On va load notre table d'interruptions !
lidt	[irdt]
call	remplitIdt
irq.inc :

Code: Select all

;Auteur --> aiglematth

;IRQS
;0 -->  Timer
;1 -->  Clavier
;2 -->  Cascade
;3 -->  Com2
;4 -->  Com1
;5 -->  Lpt2
;6 -->  Disquettes
;7 -->  Lpt1
;8 -->  Temps réel
;9 -->  Libre
;10 --> Libre
;11 --> Libre
;12 --> Ps2 souris
;13 --> Inter processeurs
;14 --> Disque dur 1
;15 --> Disque dur 2

;PORTS
;0x20 --> PIC maitre pour les commandes
;0x21 --> PIC maitre pour les données
;0xA0 --> PIC esclave pour les commandes
;0xA1 --> PIC esclave pour les données
;0x60 --> Port de données du clavier
;0x64 --> Port de commande du clavier

;Constantes
EOI		equ	0x20
commandMaster	equ	0x20
dataMaster	equ	0x21
commandSlave	equ	0xa0
dataSlave	equ	0xa1

bits	64

;Includes
%include	"utils.inc"

;Fonctions
delay:
	jmp	.done
	.done:
		nop
	ret

;Macros
%macro	sendCommandMaster	1
	mov	al,%1
	out	commandMaster,al
	call	delay
%endmacro

%macro	sendCommandSlave	1
	mov	al,%1
	out	commandSlave,al
	call	delay
%endmacro

%macro	sendCommandAll	1
	mov	al,%1
	out	commandMaster,al
	out	commandSlave,al
	call	delay
%endmacro

%macro	sendDataMaster	1
	mov	al,%1
	out	dataMaster,al
	call	delay
%endmacro

%macro	sendDataSlave	1
	mov	al,%1
	out	dataSlave,al
	call	delay
%endmacro

%macro	sendDataAll	1
	mov	al,%1
	out	dataMaster,al
	out	dataSlave,al
	call	delay
%endmacro

%macro	eoiMaster	0
	sendCommandMaster	EOI
%endmacro

%macro	eoiSlave	0
	sendCommandSlave	EOI
%endmacro

%macro	eoiAll	0
	eoiMaster
	eoiSlave
%endmacro

%macro	idtEntry	1
	mov	rax,irq%1
	mov	[idtStart + 16*%1],ax
	mov	word [idtStart + 16*%1 + 2],0x0000
	mov	word [idtStart + 16*%1 + 4],0x8e00
	shr	rax,16
	mov	[idtStart + 16*%1 + 6],ax
	shr	rax,16
	mov	[idtStart + 16*%1 + 8],eax
	mov	[idtStart + 16*%1 + 12],dword 0x00
%endmacro

;Implementation
irq32:
	cli
	pusha64
	eoiMaster
	popa64
	sti
	iretq

irq33:
	cli
	pusha64
	eoiMaster
	popa64
	sti
	iretq

irq34:
	cli
	pusha64
	eoiMaster
	popa64
	sti
	iretq

irq35:
	cli
	pusha64
	eoiMaster
	popa64
	sti
	iretq

irq36:
	cli
	pusha64
	eoiMaster
	popa64
	sti
	iretq

irq37:
	cli
	pusha64
	eoiMaster
	popa64
	sti
	iretq

irq38:
	cli
	pusha64
	eoiMaster
	popa64
	sti
	iretq

irq39:
	cli
	pusha64
	eoiMaster
	popa64
	sti
	iretq

irq40:
	cli
	pusha64
	eoiAll
	popa64
	sti
	iretq

irq41:
	cli
	pusha64
	eoiAll
	popa64
	sti
	iretq

irq42:
	cli
	pusha64
	eoiAll
	popa64
	sti
	iretq

irq43:
	cli
	pusha64
	eoiAll
	popa64
	sti
	iretq

irq44:
	cli
	pusha64
	eoiAll
	popa64
	sti
	iretq

irq45:
	cli
	pusha64
	eoiAll
	popa64
	sti
	iretq

irq46:
	cli
	pusha64
	eoiAll
	popa64
	sti
	iretq

irq47:
	cli
	pusha64
	eoiAll
	popa64
	sti
	iretq

;MES INT !!!
irq128:
	cli
	pusha64
	mov dword [0xB8000],') : '
	eoiAll
	popa64
	iretq

remplitIdt:
	;IMPORTANT
	idtEntry	32
	idtEntry	33
	idtEntry	34
	idtEntry	35
	idtEntry	36
	idtEntry	37
	idtEntry	38
	idtEntry	39
	idtEntry	40
	idtEntry	41
	idtEntry	42
	idtEntry	43
	idtEntry	44
	idtEntry	45
	idtEntry	46
	idtEntry	47
	
	;MES INT !!!
	idtEntry	128
	
	ret

;Implementation de l'IDT
idtStart:
	times	4096	db	0
idtEnd:

irdt:
	dw	idtEnd - idtStart - 1
	dq	idtStart
utils.inc :

Code: Select all

;Auteur --> aiglematth

%macro	pusha64	$0
	push	rax
	push	rbx
	push	rcx
	push	rdx
	push	rsi
	push	rdi
	push	rbp
	push	rsp
	push	r8
	push	r9
	push	r10
	push	r11
	push	r12
	push	r13
	push	r14
	push	r15
%endmacro

%macro	popa64	$0
	pop	r15
	pop	r14
	pop	r13
	pop	r12
	pop	r11
	pop	r10
	pop	r9
	pop	r8
	pop	rsp
	pop	rbp
	pop	rdi
	pop	rsi
	pop	rdx
	pop	rcx
	pop	rbx
	pop	rax
%endmacro
Thanks for your help !!
I'm a noob ^^ (just 1 week of osdev experience ^^)
good night !

Re: Nasm 64 bits IDT

Posted: Thu Jun 11, 2020 11:56 pm
by Octocontrabass
aiglematth wrote:I can load IDT but can't call int 128...
What happens when you try to call INT 128?

Re: Nasm 64 bits IDT

Posted: Fri Jun 12, 2020 3:36 am
by bzt
Probably nothing, but I always build IDT first, then I call lidt. Other than that run your code in bochs. When the problem occurs, it will drop you in a debugger. Not only will it say what went wrong (interrupt 0x80 then what exception), but you can also type "info idt" which will tell you if you've loaded its entries correctly.

About an IDT hello world, I don't have one, but here's how I do it. The code that builds up IDT:

Code: Select all

    /*** generate Interrupt Descriptor Table ***/
    idt = kalloc(1);
    ptr = &isr_exc00divzero;
    // 0-31 exception handlers
    for(i=0;i<32;i++) {
        idt[i*2+0] = IDT_GATE_LO(i==2||i==8?IDT_NMI:(i==1||i==3?IDT_DBG:IDT_EXC), ptr);
        idt[i*2+1] = IDT_GATE_HI(ptr);
        ptr+=ISR_EXCMAX;
    }
    // 32-255 irq handlers
    ptr = &isr_irq0;
    for(i=32;i<ISR_NUMIRQ+32;i++) {
        idt[i*2+0] = IDT_GATE_LO(IDT_INT, ptr);
        idt[i*2+1] = IDT_GATE_HI(ptr);
        ptr+=ISR_IRQMAX;
    }
I align exception handlers at 64 bytes (ISR_EXCMAX) and interrupt handlers at 128 (ISR_IRQMAX). Then the routines (isr_* in ASM) are generated by a shell script here (that's because the number of IRQs are configurable so is PIC/IOAPIC). The lidt instruction is in the isr_inithw function.

Cheers,
bzt

Re: Nasm 64 bits IDT

Posted: Fri Jun 12, 2020 4:41 am
by iansjack
I can't see in your code where you set up page tables and enable paging. Am I missing something?