Inexplicable GPF

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
asdfsdf
Posts: 4
Joined: Mon Jan 19, 2009 7:42 pm

Inexplicable GPF

Post by asdfsdf »

Hello, I seem to be getting a GPF for some reason at the waiting jmp after I reprogram the PIC's interrupt indicies, here is my code (feel free to point out anything else i might be doing wrong plz):
I'm absolutely stumped.

Code: Select all

[BITS 16]
[ORG 0x8000]
	
	mov si, loadstring
	call DisplayString

	;do some bios stuff while not in pmode
	mov ah, 08h
	mov dl, byte [1000h]
	int 13h
	jnc noerr1308
	
	mov si, errstr01
	call DisplayString
	
noerr1308:
	mov word [1001h], cx
	mov word [1003h], dx
	
	cli
	call disablenmis
	
	lgdt [GDT_DESC]
	lidt [IDT_DESC]
	
	call enableA20
	
	mov eax, cr0
	or eax, 1       ;;;;; bit 31 to enable paging!
	mov cr0, eax

	jmp 08h:enterpmode
	
	;;;;;;;;;;;;;;;;;
	jmp stop ;;;;;;;;
	;;;;;;;;;;;;;;;;;
	
;;;;;;;;;;;;;;;;;;;;;;
enableA20:
	call waiting	
	mov al, 0D1h    
	out 064h, al
	call waiting
	mov al, 0DFh    ;;;;; A20 enable DFh, 110111[1]1, off DDh, 110111[0]1
	out 060h, al
	call waiting
	ret
;;;;;;;;;;;;;;;;;;;;;;
	
;;;;;;;;;;;;;;;;;;;;;;
disablenmis:
	in al, 070h
	or al, 080h
	out 070h, al
	ret
;;;;;;;;;;;;;;;;;;;;;;
	
;;;;;;;;;;;;;;;;;;;;;;
enablenmis:
	in al, 070h
	and al, 07Fh
	out 070h, al
	ret
;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;
waiting:
	in al, 64h
	test al, 2
	jnz waiting
	ret
;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;si = src, bp = len
DumpHex:
	movzx di, byte [si]
	inc si
	
	mov bx, di
	shr bx, 4
	mov al, byte [hexstr + bx]
	mov ah, 0Eh
	mov bx, 000Fh
	int 10h
	
	mov bx, di
	and bx, 0Fh
	mov al, byte [hexstr + bx]
	mov ah, 0Eh
	mov bx, 0000Fh
	int 10h
	
	mov ax, 0E20h
	mov bx, 000Fh
	int 10h
	
	dec bp
	jnz DumpHex
	ret
;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;
CallInt10h: ;;;si = base addr
	mov bx, 000Fh
	mov ah, 0Eh
	int 10h
DisplayString:
	mov al, byte [si]
	inc si
	cmp al, 0
	jne CallInt10h
	ret
;;;;;;;;;;;;;;;;;;
	
stop:
	hlt
	jmp stop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;; PMODE ENTRY POINT AND ISRS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

[BITS 32]

align 4

isr00:      ;;;;just to test
	push ds
	push es
	pushad
	mov byte [0B8000h], 'I'
	mov byte [0B8001h], 015h
	mov byte [0B8002h], 'N'
	mov byte [0B8003h], 015h
	mov byte [0B8004h], 'T'
	mov byte [0B8005h], 015h
	mov byte [0B8006h], ' '
	mov byte [0B8007h], 015h
	mov byte [0B8008h], '0'
	mov byte [0B8009h], 015h
	mov byte [0B800Ah], '!'
	mov byte [0B800Bh], 015h
	popad
	pop es
	pop ds
	iret
	
isr13: 
	;push ds
	;push es
	;pushad
	xchg bx, bx
	mov byte [0B8000h], 'G'
	mov byte [0B8001h], 015h
	mov byte [0B8002h], 'P'
	mov byte [0B8003h], 015h
	mov byte [0B8004h], 'F'
	mov byte [0B8005h], 015h
	mov byte [0B8006h], ' '
	mov byte [0B8007h], 015h
	mov byte [0B8008h], '!'
	mov byte [0B8009h], 015h
	mov byte [0B800Ah], '!'
	mov byte [0B800Bh], 015h
	isr13halt:
	jmp isr13hal
	;popad            ;;;stack:  0x43     0x821f     0x08     0x10202
	;pop es           ;;;           wtf?     eip          cs          efl??
	;pop ds
	iret

enterpmode:
	
	mov ax, 10h
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax
	mov ss, ax
	
	;xchg bx, bx
	call remappic
	
	call enablenmis
	sti
	
	;1 blue			;5 purple		;9 periwinkle		;d pink
	;2 green		;6 orange		;a light green		;e pastel yellow
	;3 light blue	;7 reg gray		;b teal				;f white
	;4 red 			;8 dark gray	;c salmon
	
	mov byte [0B8000h], 21h
	mov byte [0B8001h], 19h
	mov byte [0B8002h], 21h      
	mov byte [0B8003h], 0Ah
	mov byte [0B8004h], 21h
	mov byte [0B8005h], 0Bh
	mov byte [0B8006h], 21h
	mov byte [0B8007h], 0Ch
	mov byte [0B8008h], 21h
	mov byte [0B8009h], 0Dh
	mov byte [0B800Ah], 21h
	mov byte [0B800Bh], 0Eh
	mov byte [0B800Ch], 21h
	mov byte [0B800Dh], 0Fh
	mov byte [0B800Eh], 21h
	mov byte [0B800Fh], 00h
	;in ax, 03F5h ;;;;to get status
	
	mov ebp, 20000h
	mov esp, 20000h

;check 3A page 409
;at 0fefc7h
;typedef struct{
;  unsigned char steprate_headunload;
;  unsigned char headload_ndma;
;  unsigned char motor_delay_off; /*specified in clock ticks*/
;  unsigned char bytes_per_sector;
;  unsigned char sectors_per_track;
;  unsigned char gap_length;
;  unsigned char data_length; /*used only when bytes per sector == 0*/
;  unsigned char format_gap_length;
;  unsigned char filler;
;  unsigned char head_settle_time; /*specified in milliseconds*/
;  unsigned char motor_start_time; /*specified in 1/8 seconds*/
;}__attribute__ ((packed)) floppy_parameters;
	
	mov dx, 03F2h
	mov al, 0
	out dx, al ;;;resetting the floppy disk controller
	mov al, 0Ch
	out dx, al
	;xchg bx, bx
lol:
	jmp lol       ;;;;;here i get the GPF, no idea why... I'm waiting for the irq 6 i'm supposed to get 
                            ;;;;;when the floppy controller is ready, didnt add in that handler yet though
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
remappic:
	in al, 021h ;master
	mov cl, al
	in al, 0A1h ;slave
	mov ch, al
	
	;init
	mov al, 011h
	out 020h, al           
	out 080h, al ;wait
	out 0A0h, al
	out 080h, al
	
	;new pic irq bases
	mov al, 020h
	out 021h, al
	out 080h, al
	mov al, 028h
	out 0A1h, al
	out 080h, al
	
	;continue init
	mov al, 4
	out 021h, al
	out 080h, al
	mov al, 2
	out 0A1h, al
	out 080h, al
	
	mov al, 1
	out 021h, al
	out 080h, al
	out 0A1h, al
	out 080h, al
	
	;reset masks
	mov al, cl
	out 021h, al
	mov al, ch
	out 0A1h, al
	ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;; GDT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

align 4

GDT:
NULL_GDT:
	dw 0000h	;limit_low
	dw 0000h	;base_low	
	db 00h		;base_middle 	
	db 00h		;access
	db 00h		;granularity
	db 00h		;base_high

CS_GDT:
	dw 0FFFFh
	dw 00h
	db 00h
	db 10011010b ;cs access: execute/read 9A
	db 0CFh
	db 00h

DS_GDT:
	dw 0FFFFh
	dw 00h
	db 00h
	db 10010010b ;ds access: read/write 92
	db 0CFh
	db 00h	
	
GDT_DESC:
	dw (GDT_DESC - GDT - 1)
	dd GDT

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;; IDT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;struct IDTDescr{
;   uint16 offset_1; // offset bits 0..15
;   uint16 selector; // a code segment selector in GDT or LDT
;   uint8 zero;      // unused, set to 0
;   uint8 type_attr; // type and attributes, see below
;   uint16 offset_2; // offset bits 16..31
;}

IDT:
INT00_DESC:
	dw isr00
	dw 08h
	db 00h             ;;;pres | priv | sysseg | gatetype
	db 10001110b       ;;;[1]    [00]   [0]      [1110] (32 bit INT GATE)
	dw 0
INT01_DESC:
	dw 0
	dw 08h
	db 00h
	db 10001110b
	dw 0
INT02_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h            
	db 0 ;10001110b  
	dw 0
INT03_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h  
	db 0 ;10001110b   
	dw 0
INT04_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT05_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT06_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT07_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT08_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT09_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT0A_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT0B_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT0C_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT0D_DESC:
	dw isr13
	dw 08h
	db 00h
	db 10001110b
	dw 0
INT0E_DESC:
	dw 0;irq06 ;floppy
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT0F_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT10_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT11_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT12_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT13_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT14_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT15_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT16_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT17_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT18_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT19_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT1A_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT1B_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT1C_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT1D_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT1E_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT1F_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
INT20_DESC:
	dw 0 ;isr00
	dw 08h
	db 00h
	db 0 ;10001110b
	dw 0
	
IDT_DESC:
	dw (IDT_DESC - IDT - 1)
	dd IDT
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;; STRINGS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

loadstring: db 'Stage II Bootloader', 0Ah, 0
errstr01:   db 'int 13h fxn 8 failed!', 0
hexstr:     db '0123456789abcdef'
str01:      db 'Entered protected mode', 0Ah, 0
	
times 2048-($-$$) db 0
User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Re: Inexplicable GPF

Post by 01000101 »

Code: Select all

mov dl, byte [1000h] ; is probably not what you wanted
...
mov byte [0x1000], dl; will store DL into 0x1000, which is probably what you were going for
I think you're getting your destination and source operands mixed up.

Also, on your ISR handlers, you should push a dummy error code value for non-exceptions and increment your stack pointer by 8 at the end of ISR handlers, or your IRET will use the wrong values.
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:

Re: Inexplicable GPF

Post by Combuster »

Your ISRs seem to be pointing nowhere. That means the CPU will do whatever it feels like when an IRQ happens and execution is resumed at 0x00000000
"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 ]
asdfsdf
Posts: 4
Joined: Mon Jan 19, 2009 7:42 pm

Re: Inexplicable GPF

Post by asdfsdf »

01000101 wrote:

Code: Select all

mov dl, byte [1000h] ; is probably not what you wanted
...
mov byte [0x1000], dl; will store DL into 0x1000, which is probably what you were going for
I think you're getting your destination and source operands mixed up.
Sorry, I didn't mention that in my first stage bootloader I store dl at [1000h], since the interrupts would thrash the value.

01000101 wrote: Also, on your ISR handlers, you should push a dummy error code value for non-exceptions and increment your stack pointer by 8 at the end of ISR handlers, or your IRET will use the wrong values.
One question: Why would I need to add 8 to my stack in the first place? I've never seen that done in any example code, and it sounds very unintuitive of a thing to do. Is 43h the error value of the exception then? Is there a listing of errors? Also, these bogus values on the stack resulting from the exception explains a lot (like why I kept getting an LDTR.valid = 0 error if i tried to return).

Combuster wrote: Your ISRs seem to be pointing nowhere. That means the CPU will do whatever it feels like when an IRQ happens and execution is resumed at 0x00000000
Not so. The "present" bit isn't set, so therefore it should be handled by the BIOS. 0x00000000 is never called.
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:

Re: Inexplicable GPF

Post by Combuster »

asdfsdf wrote:The "present" bit isn't set, so therefore it should be handled by the BIOS. 0x00000000 is never called.
So that's why the IDT looked odd... There were more errors in it #-o It is also the exact reason you're getting the GPF (I can even tell you the error code :) )

As for your real problem, your understanding of the IDT is... off. Go read the intel chapters on IDT and GPF to figure why things are screwing up on you :wink:
"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 ]
User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Re: Inexplicable GPF

Post by 01000101 »

lol I appologize for telling you to increment the stack pointer by 8, it should be by 4, I'm used to dealing with 64-bit integers.

But yes, you *should* push dummy error codes (as most exceptions do) to keep a uniform stack on every ISR. And at the end of that ISR, just add 4 to ESP (a fake POP) to get rid of the fake (or real) error code.
asdfsdf
Posts: 4
Joined: Mon Jan 19, 2009 7:42 pm

Re: Inexplicable GPF

Post by asdfsdf »

hehe, i finally found the section on error codes (it's nowhere to be found on google :-( ). It's in manual 3A, chapter 5, topic 13. page 211.
Apparently 43h (what i'm getting) is....
1000011
an Externally Generated General Protection Exception Whos Index Refers to a Gate Descriptor in the IDT, Index 8.
That is, if I comment out the code I use to remap the pic AND request clear the floppy disk state.
Which leads me to believe that it's either one of two things:
- IRQ0 timer interrupt
OR!
- Double fault

I'm hoping that it's the timer interrupt : (

If I don't output stuffs however, I get a different error message (133h)
100110 <-- index (26h!! What IRQ 6 is remapped to! Success!)
011 <-- other bits

@Combuster: Errors? What errors? As far as I can tell i'm doing exactly what the manual says I should be...


EDIT***** AHA!
When i just remap the pic, I get 103h, shr 103h, 3 = 20h, the new IRQ0! That explains why it was triggering during that waiting loop, and nowhere else (since that's taking up like 99.9% of the execution time). Now, question: How did that timer get on? Question 2: Where does windows NT remap the pic to? I know int 2Ah = GetTickCount()... soooo....
JohnnyTheDon
Member
Member
Posts: 524
Joined: Sun Nov 09, 2008 2:55 am
Location: Pennsylvania, USA

Re: Inexplicable GPF

Post by JohnnyTheDon »

How did that timer get on?
Its the internal PIC timer. It is always on until you turn it off.
Where does windows NT remap the pic to? I know int 2Ah = GetTickCount()
Good luck figuring out how Windows does anything specific. Your best bet is just mapping them above the reserved interrupts (above 32). If you are sticking to a standard single processor setup the only vectors that aren't free for your use are the Intel reserved ones and wherever you decide to put your system call interrupt(s) (which can be decided much later). You have 256 vectors, be creative.
asdfsdf
Posts: 4
Joined: Mon Jan 19, 2009 7:42 pm

Re: Inexplicable GPF

Post by asdfsdf »

Ah, thanks.
Well I thought 20h-30h was the unwritten standard for just about all oses ... guess not :p
JohnnyTheDon
Member
Member
Posts: 524
Joined: Sun Nov 09, 2008 2:55 am
Location: Pennsylvania, USA

Re: Inexplicable GPF

Post by JohnnyTheDon »

Nope. Unix uses int 0x80 for system calls.
Post Reply