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.