Page 1 of 3

segmentation fault

Posted: Tue Jan 20, 2009 4:43 pm
by yemista
What kinds of things cause segmentation faults? I am having a lot of trouble debugging my initialization code and dont quit know what to do. What I have realized is that I wont get it with interrupts off, and when I type info idt at bochs, I get

Code: Select all

Interrupt Descriptor Table (base=0x00ff53f0, limit=255):
IDT[0x00]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x01]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x02]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x03]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x04]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x05]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x06]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x07]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x08]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x09]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x0a]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x0b]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x0c]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x0d]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x0e]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x0f]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x10]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x11]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x12]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x13]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x14]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x15]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x16]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x17]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x18]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x19]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x1a]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x1b]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x1c]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x1d]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x1e]=??? descriptor hi=0x00000000, lo=0x00000000
IDT[0x1f]=??? descriptor hi=0x00000000, lo=0x00000000
I dont know what the question marks are, but there probably not good

Re: segmentation fault

Posted: Tue Jan 20, 2009 5:07 pm
by ru2aqare
yemista wrote:What kinds of things cause segmentation faults? I am having a lot of trouble debugging my initialization code and dont quit know what to do. What I have realized is that I wont get it with interrupts off, and when I type info idt at bochs, I get

Code: Select all

Interrupt Descriptor Table (base=0x00ff53f0, limit=255): <<<
snip snip snip
I dont know what the question marks are, but there probably not good
It means you loader IDTR with a bogus value. Check the base address. Its 0x00FF53F0, clearly not what you wanted. I would guess you dereferenced a null pointer, which loaded IDTR from address zero.

Re: segmentation fault

Posted: Tue Jan 20, 2009 5:08 pm
by Combuster
I don't think
base=0x00ff53f0
is good either... Try tracking what it should be. Right now its somewhere in unused memory

Bochs prints ?s because they aren't valid IDT entries. (rather, they are empty)

Re: segmentation fault

Posted: Tue Jan 20, 2009 6:08 pm
by yemista
Ive been looking at other peoples code and I cant see what is really different about mine. I also did some debugging from bochs and it looks like its loading the correct idt

Code: Select all

[bits 32]			;[org 0x0011]			
[org 0x00000001]
align 4
	
global _idt_install
	
start:
	jmp setup_idt
	

KERNEL_CODE_SEL    	equ		0x08
	
;;;;;;;;;;;;;;;;;;;;;;   JUST FOR NOW
_common_stub:
	; ack the pic
	mov al, 0x20
	out 0x20, al

	iret		

	
%macro CREATE_ISR 1 
	isr#%1:
	jmp _common_stub
%endmacro

%assign 	i 	0
%rep 51
	CREATE_ISR i
	%assign i (i + 1)
%endrep


%macro make_idt_entry 0
	dw 0 ; isr0 and 0xFFFF
	dw KERNEL_CODE_SEL
	db 0
	db 0x8E ; Access flags: Running in kernel mode (| 0x60 for usermode)
	dw 0 ; (isr#num shr 16) and 0xFFFF
%endmacro

_idt: 
	%rep  51  
		make_idt_entry         ;(32+16+3) ; exceptions+interrupts+syscall
	%endrep
idt_end:

	
idtp: 	dw 	idt_end - _idt -1	 	; IDT limit
	dd	 _idt 				; address of IDT
	
	
setup_idt:	

; IDT -> ISR installation
%macro set_idt_entry 1 
	; base_lo = isr0 and 0xFFFF
	mov eax, isr#%1
	mov [_idt+ (%1 * 8)], ax
	; base_hi = (isr0 >> 16) and 0xFFFF
	shr eax, 16
	mov [_idt + %1 * 8 + 6], ax
%endmacro

%assign 	i 	0

%rep 50
	set_idt_entry i
	%assign i (i+1)
%endrep

_idt_install:

	cli
	
lidt [idtp]
	
; remap irq here

mov al, 0x11		; send ICW1
out 0x20, al
out 0xA0, al 

; ICW2
mov al, 0x20		; remap 1st half of PIC
out 0x21, al
mov al, 0x28		; then 2nd half
out 0xA1, al

; ICW3
mov al, 4
out 0x21, al
mov al, 2
out 0xA1, al

; ICW4
mov al, 0x01
out 0x21, al
out 0xA1, al

; disable interrupts
; mov al, 0xFF
; out 0x21, al

jmp setup_kbd

;;;	CUSTOM TEST CODE


kbd_int:
	pusha
	in al, 0x60
	mov ecx, [counter]
	mov ebx, 0xb8000
	mov [es:ebx+ecx], al
	inc ecx
	mov [counter], ecx
	popa
	jmp _common_stub

; set 9th idt descriptor to point to kdb_int
setup_kbd:
	mov eax, kbd_int
	mov [idt + 9 * 8], ax
	; base_hi = (isr0 >> 16) and 0xFFFF
	shr eax, 16
	mov [idt + 9 * 8 + 6], ax
	mov ax, 0x18
	mov es, ax

	;; disable time
	mov al, 0xfe
	out 0x21, al
	sti


;; hang here to see if everything(or anything) works
wait_and_see:
	nop
	nop
	jmp wait_and_see
	
	
counter		db	0
If its helpful at all, I tried to change the code to

Code: Select all

idtp: 	dw 	idt_end - _idt -1	 	; IDT limit
	dd	0xaaaaaaaa

lidt [idtp]
but still I get this from bochs

<bochs:3> info idt 0x00
Interrupt Descriptor Table (base=0xf000ff53, limit=40896):
bx_dbg_read_linear: physical memory read error (phy=0xf000ff53, lin=0xf000ff53)
error: IDTR+8*0 points to invalid linear address 0xf000ff53

Shouldnt the base now we 0xaaaaaaaa? Maybe there is something wrong with bochs?

Re: segmentation fault

Posted: Wed Jan 21, 2009 9:30 am
by yemista
Also, I traced down and I am not dereferencing a null pointer. The lidt instruction is loading from the correct place in memory

Re: segmentation fault

Posted: Wed Jan 21, 2009 1:39 pm
by Combuster
yemista wrote:The lidt instruction is loading from the correct place in memory
The results show it isn't.

Seriously, show us a CPU dump before and after the LIDT, and show a dump of virtual memory at the specified address to prove bochs is wrong.

Re: segmentation fault

Posted: Wed Jan 21, 2009 2:14 pm
by yemista
Well the reason I said lidt is loading the write address, is that the disassembled code shows
lidt ds:0x6, and this is after I moved the idt to be right after the first jump instruction, which is at 0x1. But sure, as soon as I get home I will show a cpu dump and virtual memory dump. Now that I think of it, its possible there is something wrong with the data segment, but I doubt it because it is exactly the same as the code segment, only it is marked as data rather than code, and since the other instructions execute properly, I dont think there is anything wrong with the code segment.

Re: segmentation fault

Posted: Wed Jan 21, 2009 2:33 pm
by stlw
yemista wrote:Well the reason I said lidt is loading the write address, is that the disassembled code shows
lidt ds:0x6, and this is after I moved the idt to be right after the first jump instruction, which is at 0x1. But sure, as soon as I get home I will show a cpu dump and virtual memory dump. Now that I think of it, its possible there is something wrong with the data segment, but I doubt it because it is exactly the same as the code segment, only it is marked as data rather than code, and since the other instructions execute properly, I dont think there is anything wrong with the code segment.
You could use 'trace-mem on' command and see online which memory it reads and from where.

Stanislav

Re: segmentation fault

Posted: Wed Jan 21, 2009 2:46 pm
by ru2aqare
yemista wrote:Well the reason I said lidt is loading the write address, is that the disassembled code shows
lidt ds:0x6
Don't you think that this ds:6 address is strange? If your ds segment register is set to zero, the instruction will read the IDTR from the real-mode IVT, and the processor will try to interpret a real-mode interrupt vector as a base address (which I think it does, hence the bogus values shown by Bochs).
yemista wrote:and this is after I moved the idt to be right after the first jump instruction, which is at 0x1.
If the jump instruction is the first instruction, it is at offset zero, not at offset one. Or did you prefix the jump instruction with a nop instruction?

Re: segmentation fault

Posted: Wed Jan 21, 2009 2:58 pm
by yemista
well my ds is set to point to 0x00100000, and this part of the code is at [org 0x00100001], and that where it is loaded to and jmps to. The code works fine, because from the bochs statistics I can see that the pic is remapped and I have a few smaller ways to confirm changes where made to the cpu to verify my code is loaded and executes as it should. ds:0x6 should equal 0x00100006. I think I should get the statistics combuster asked for and I will make sure to do that as soon as I get a chance.

Re: segmentation fault

Posted: Wed Jan 21, 2009 10:50 pm
by yemista
ok here is the dump before and after the lidt instruction, and also the contents of memory at 0x00100006 that the instruction loads from

Code: Select all

(0) [0x00100601] 0008:00000601 (unk. ctxt): lidt ds:0x9               ; 0f011d09000000
<bochs:3> r
eax: 0x00000000 0
ecx: 0x00000002 2
edx: 0x00000000 0
ebx: 0x00000011 17
esp: 0x0000ffd6 65494
ebp: 0x00000000 0
esi: 0x000e7c17 949271
edi: 0x0000ffac 65452
eip: 0x00000601
eflags 0x00000046
id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:4> info idt 0x00
Interrupt Descriptor Table (base=0x00000000, limit=1023):
IDT[0x00]=Code segment, laddr=f053f000, limit=0ff53 bytes, Execute/Read, Conforming, Accessed, 16-bit
<bochs:5> s
Next at t=171041918
(0) [0x00100608] 0008:00000608 (unk. ctxt): mov al, 0x11              ; b011
<bochs:6> r
eax: 0x00000000 0
ecx: 0x00000002 2
edx: 0x00000000 0
ebx: 0x00000011 17
esp: 0x0000ffd6 65494
ebp: 0x00000000 0
esi: 0x000e7c17 949271
edi: 0x0000ffac 65452
eip: 0x00000608
eflags 0x00000046
id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf
<bochs:7> info idt 0x00
Interrupt Descriptor Table (base=0x00255af0, limit=255):
IDT[0x00]=??? descriptor hi=0x00000000, lo=0x00000000
<bochs:8> x 0x00100006
[bochs]:
0x00100006 <bogus+       0>:	0x97909090

<bochs:9> x /10 0x00100001
[bochs]:
0x00100001 <bogus+       0>:	0x000213e9	0x90909000	0x00810197	0x90900000
0x00100011 <bogus+      16>:	0x20e620b0	0xebf9ebcf	0xebf5ebf7	0xebf1ebf3
0x00100021 <bogus+      32>:	0xebedebef	0xebe9ebeb


Re: segmentation fault

Posted: Wed Jan 21, 2009 10:58 pm
by 01000101
you should dump your segment registers and examine DS/ES.

in bochs you can use "sregs" to see them, or I think "info cpu" will do the trick as well.

Re: segmentation fault

Posted: Thu Jan 22, 2009 6:29 pm
by yemista
here is the before lidt and after dump of the segment registers.

Code: Select all

cs:s=0x0008, dl=0x0000ffff, dh=0x004f9810, valid=1
ds:s=0x0010, dl=0x0100ffff, dh=0x00009300, valid=7
ss:s=0x0010, dl=0x0100ffff, dh=0x00009300, valid=1
es:s=0x0010, dl=0x0100ffff, dh=0x00009300, valid=1
fs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
gs:s=0x0010, dl=0x0100ffff, dh=0x00009300, valid=1
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008b00, valid=1
gdtr:base=0x00007c35, limit=0x20
idtr:base=0x00000000, limit=0x3ff
<bochs:5> s
Next at t=171041918
(0) [0x00100608] 0008:00000608 (unk. ctxt): mov al, 0x11              ; b011
<bochs:6> sreg
cs:s=0x0008, dl=0x0000ffff, dh=0x004f9810, valid=1
ds:s=0x0010, dl=0x0100ffff, dh=0x00009300, valid=7
ss:s=0x0010, dl=0x0100ffff, dh=0x00009300, valid=1
es:s=0x0010, dl=0x0100ffff, dh=0x00009300, valid=1
fs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
gs:s=0x0010, dl=0x0100ffff, dh=0x00009300, valid=1
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008b00, valid=1
gdtr:base=0x00007c35, limit=0x20
idtr:base=0x00255af0, limit=0xff
so its obviously loading the wrong thing, but i dont see what could be wrong from the code. Its the same as everyone elses for declaring and loading it.

Re: segmentation fault

Posted: Fri Jan 23, 2009 1:49 am
by stlw
yemista wrote:here is the before lidt and after dump of the segment registers.

Code: Select all

cs:s=0x0008, dl=0x0000ffff, dh=0x004f9810, valid=1
ds:s=0x0010, dl=0x0100ffff, dh=0x00009300, valid=7
ss:s=0x0010, dl=0x0100ffff, dh=0x00009300, valid=1
es:s=0x0010, dl=0x0100ffff, dh=0x00009300, valid=1
fs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
gs:s=0x0010, dl=0x0100ffff, dh=0x00009300, valid=1
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008b00, valid=1
gdtr:base=0x00007c35, limit=0x20
idtr:base=0x00000000, limit=0x3ff
<bochs:5> s
Next at t=171041918
(0) [0x00100608] 0008:00000608 (unk. ctxt): mov al, 0x11              ; b011
<bochs:6> sreg
cs:s=0x0008, dl=0x0000ffff, dh=0x004f9810, valid=1
ds:s=0x0010, dl=0x0100ffff, dh=0x00009300, valid=7
ss:s=0x0010, dl=0x0100ffff, dh=0x00009300, valid=1
es:s=0x0010, dl=0x0100ffff, dh=0x00009300, valid=1
fs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
gs:s=0x0010, dl=0x0100ffff, dh=0x00009300, valid=1
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008b00, valid=1
gdtr:base=0x00007c35, limit=0x20
idtr:base=0x00255af0, limit=0xff
so its obviously loading the wrong thing, but i dont see what could be wrong from the code. Its the same as everyone elses for declaring and loading it.
Once again I would suggest you to use 'trace-mem' commad to see what are you actually loading and from where.
Also instead of 'sregs' you could use 'show "DS"' command and see the segment expanded.

stanislav

Re: segmentation fault

Posted: Fri Jan 23, 2009 5:29 pm
by Combuster
broken things:
- [org 0x00000001] (guaranteed to fail sanity checks and you knew about it)
- non-4G-segments
- nonzero base in the data selectors

i.e. fix your bootloader.