Page 1 of 1

Machine resets itself after loading new GDT

Posted: Thu Sep 15, 2011 1:07 pm
by frost
I'm trying a few things with multiboot and I have built a small example that as far as I understand should work. Once the code is called at the start label I set the stack and then load a new GDT. After the GDT is loaded I do a far jump and update the rest of the segment registers. However, at the point of the far jump the virtual machine (qemu 0.14.1) resets and I can't figure out why. Does anyone have an idea on why this happens?

Code: Select all

        .global start

        .set ALIGN, 1 << 0
        .set MEM_INFO, 1 << 1
        .set KLUDGE, 1 << 16
        .set MAGIC, 0x1BADB002
        .set FLAGS, ALIGN | MEM_INFO | KLUDGE
        .set CHECKSUM, -(MAGIC + FLAGS)

        .section .text
        .code32
        
        .align 0x4
multiboot_header:
        .long MAGIC
        .long FLAGS
        .long CHECKSUM
        .long multiboot_header
        .long text
        .long data_end
        .long kernel_end
        .long start

        .set STACKSIZE, 0x4000
        .comm stack, STACKSIZE, 32

start:
        mov $(stack + STACKSIZE), %esp

        lgdt (gdtr)
        ljmp $0x8, $1f
1:
        mov $0x10, %ax
        mov %ax, %ds
        mov %ax, %es
        mov %ax, %fs
        mov %ax, %gs
        mov %ax, %ss
        
hang:   hlt
        jmp hang

        .align 0x10
gdt:
        .quad 0x0
        .quad 0x0000ffff00cf9a00
        .quad 0x0000ffff00cf9200
gdtr:
        .word .-gdt-1
        .quad gdt

Re: Machine resets itself after loading new GDT

Posted: Thu Sep 15, 2011 1:27 pm
by mutex
My guess is

Code: Select all

wbinvd
Had the same problem not so long ago :) I found that jumping to new segment cs:eip without having done a cache invalidation made cpu use old gdt data and that caused triplefault since no IDT was present during this time (boot).

best regards
Thomas

Re: Machine resets itself after loading new GDT

Posted: Thu Sep 15, 2011 3:05 pm
by gerryg400
Where's the ORG statement ? Are you sure 'gdt' represents the linear address of your GDT ?

Re: Machine resets itself after loading new GDT

Posted: Thu Sep 15, 2011 3:21 pm
by Combuster
wbinvd
Bogus suggestion, read your own thread.
Where's the ORG statement ?
It's not a bootloader and it's not NASM syntax. However the question for the actual class of bug is there:
Are you sure 'gdt' represents the linear address of your GDT ?
What's your linker script and other command line instructions?
.quad gdt
Should be .long for correctness. LGDT in 32-bit mode expects a 32-bit address. Not that it will fix your problem though.

Usually in the case of such a crash, the log produced by bochs will provide you with the exact cause of the error. Can you run your kernel under bochs and post the log if that doesn't make your problem obvious?

Re: Machine resets itself after loading new GDT

Posted: Thu Sep 15, 2011 3:41 pm
by Velko
frost wrote:

Code: Select all

gdt:
        .quad 0x0
        .quad 0x0000ffff00cf9a00
        .quad 0x0000ffff00cf9200
You mixed up dwords in GDT entries.

Here's mine:

Code: Select all

        .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00
        .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00

Re: Machine resets itself after loading new GDT

Posted: Sun Sep 18, 2011 7:06 am
by frost
Thanks, those things are sometimes tricky to get right.