LGDT crashing bootloader

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.
mrnoob
Member
Member
Posts: 26
Joined: Thu Sep 18, 2008 11:45 am

LGDT crashing bootloader

Post by mrnoob »

hi, im having a really annoying problem with getting into protected mode and its been bugging (no pun intended) and delaying my OS development for weeks, and i cant find the problem. everything is fine in my bootloader until it executes lgdt, at which point it triple faults. I cant see anything wrong with the code, maybe someone else can?

[edit] it is compiled with as86, my ld86 instruction includes "-T 0x7c00
Thanks a lot, the bootloader code is as follows:

Code: Select all

entry start
start:
	cli
	call enableA20
	mov ax, #0x0600
	mov bh, #0x0F
	mov cx, #0
	mov dh, #25
	mov dl, #80
	int 0x10
	lgdt[gdtr]
	mov eax, cr0
	or al, 1
	mov cr0, eax
	jmp cleareip
cleareip:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

enableA20:
	call    a20wait
	mov     al,#0xAD
	out     #0x64,al
	call    a20wait
	mov     al,#0xD0
	out     #0x64,al
	call    a20wait2
	in      al,#0x60
	push    eax
	call    a20wait
	mov     al,#0xD1
	out     #0x64,al
	call    a20wait
	pop     eax
	or      al,2
	out     #0x60,al
	call    a20wait
	mov     al,#0xAE
	out     #0x64,al
	call    a20wait
	ret
a20wait:
	in      al,#0x64
	test    al,#2
	jnz     a20wait
	ret
a20wait2:
	in      al,#0x64
	test    al,#1
	jz      a20wait2
	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

gdtr:
	.word gdtend-gdt-1
	.long gdt

gdt:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

nullsel equ *-gdt
.word 0x0000
.word 0x0000
.word 0x0000
.word 0x0000
kcode equ *-gdt
.word 0xFFFF	;limit 0-15
.word 0x0000	;base 0-15
.byte 0x00	;base 16-23
.byte 0x9A	;options
.byte 0xC0	;flags and limit set to 256MB
.byte 0x00	;base set to 0
kdata equ *-gdt
.word 0xFFFF	;limit 0-15
.word 0x0000	;base 0-15
.byte 0x00	;base 16-23
.byte 0x92	;options
.byte 0xC0	;flags and limit set to 256MB
.byte 0x00	;base set to 0
gdtend:
Last edited by mrnoob on Sun Nov 30, 2008 1:43 pm, edited 1 time in total.
User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Re: LGDT crashing bootloader

Post by 01000101 »

You need to setup your segment registers.

normally when you reference memory in ASM, it turns into "ds:[memory_address]", so if ds is 0x1234, then you will be referencing unintended memory.

I'd set up your DS,ES (at least) registers and setup a stack as well before installing a GDT.
mrnoob
Member
Member
Posts: 26
Joined: Thu Sep 18, 2008 11:45 am

Re: LGDT crashing bootloader

Post by mrnoob »

i cant believe i didn't notice that >.>

OK ive now set those up, ill leave setting up the stack til im in protected mode i think.
Thanks!
User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Re: LGDT crashing bootloader

Post by 01000101 »

mrnoob wrote: OK ive now set those up, ill leave setting up the stack til im in protected mode i think.
Thanks!
Then be sure to not use "call" or "push/pop" or anything else that uses the stack as it could either A: trash good memory, or B: get overwritten while on the 'stack' and pop'd incorrectly.

I'd set up a stack, it takes 2 lines of code.
mrnoob
Member
Member
Posts: 26
Joined: Thu Sep 18, 2008 11:45 am

Re: LGDT crashing bootloader

Post by mrnoob »

lol ok, im so used to writing ASM in a linux environment that i expect it all set up already. Duh.

How do you stop the stack from overflowing the code though? i dont want to get further into the development only to realise that my code is now in stack space.
User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Re: LGDT crashing bootloader

Post by 01000101 »

place it below your kernel or bootloader, that way if your kernel gets too big, it won't leech into stack-space.

remember, the stack grows DOWN, and therefor, if you place it below code, then it will never interfere.
mrnoob
Member
Member
Posts: 26
Joined: Thu Sep 18, 2008 11:45 am

Re: LGDT crashing bootloader

Post by mrnoob »

alright, thanks, ill work on that
mrnoob
Member
Member
Posts: 26
Joined: Thu Sep 18, 2008 11:45 am

Re: LGDT crashing bootloader

Post by mrnoob »

argh, its still not working :@
ive set up ds, es, ss, sp and bp and now i have the same problem as i started with, when i move EAX into CR0 it triple faults.

[edit]Heres what i've got now(still doesnt work):

Code: Select all

entry start
start:
	nop
	cli
	mov ax, cs
	mov ds, ax
	mov es, ax
	mov ax, #0x0000
	mov ss, ax
	mov si, #0x7c00
	mov sp, #0x7c00
	mov bp, sp
	call enableA20
	mov ax, #0x0600
	mov bh, #0x0F
	mov cx, #0
	mov dh, #25
	mov dl, #80
	int 0x10
	lgdt [gdtr]
	mov eax, cr0
	or al, #1
	mov cr0, eax
moi:	jmp moi
	jmp kcode:cleareip
cleareip:
repme:	jmp repme
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

enableA20:
	call    a20wait
	mov     al,#0xAD
	out     #0x64,al
	call    a20wait
	mov     al,#0xD0
	out     #0x64,al
	call    a20wait2
	in      al,#0x60
	push    eax
	call    a20wait
	mov     al,#0xD1
	out     #0x64,al
	call    a20wait
	pop     eax
	or      al,2
	out     #0x60,al
	call    a20wait
	mov     al,#0xAE
	out     #0x64,al
	call    a20wait
	ret
a20wait:
	in      al,#0x64
	test    al,#2
	jnz     a20wait
	ret
a20wait2:
	in      al,#0x64
	test    al,#1
	jz      a20wait2
	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

gdtr:
	.word gdtend-gdt-1
	.long gdt

gdt:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

nullsel equ *-gdt
.word 0x0000
.word 0x0000
.word 0x0000
.word 0x0000
kcode equ *-gdt
.word 0xFFFF	;limit 0-15
.word 0x0000	;base 0-15
.byte 0x00	;base 16-23
.byte 0x9A	;options
.byte 0xC0	;flags and limit set to 256MB
.byte 0x00	;base set to 0
kdata equ *-gdt
.word 0xFFFF	;limit 0-15
.word 0x0000	;base 0-15
.byte 0x00	;base 16-23
.byte 0x92	;options
.byte 0xC0	;flags and limit set to 256MB
.byte 0x00	;base set to 0
gdtend:
User avatar
Troy Martin
Member
Member
Posts: 1686
Joined: Fri Apr 18, 2008 4:40 pm
Location: Langley, Vancouver, BC, Canada
Contact:

Re: LGDT crashing bootloader

Post by Troy Martin »

Is this in AT&T (gas) syntax or Intel syntax?
Image
Image
Solar wrote:It keeps stunning me how friendly we - as a community - are towards people who start programming "their first OS" who don't even have a solid understanding of pointers, their compiler, or how a OS is structured.
I wish I could add more tex
mrnoob
Member
Member
Posts: 26
Joined: Thu Sep 18, 2008 11:45 am

Re: LGDT crashing bootloader

Post by mrnoob »

its a bit of a hybrid of both really.
opcode order is [op] [dest], [source]
Mike
Member
Member
Posts: 25
Joined: Tue Oct 17, 2006 7:57 pm

Re: LGDT crashing bootloader

Post by Mike »

One possibility: Some BIOSes load the boot sector at 07C0:0000, others at 0000:7C00. Make sure your CS register and origin are set properly (0000:7C00) so that when the CPU executes the mov cr0, eax instruction, the next instruction is at the same address in both modes.

I'm not 100% this would be the fix due to the caching and other means of dealing with seemingly inconsistent states during the transition to protected mode.

Have you tried running this in bochs? When bochs triple faults, it usually gives a reason in the log file.
User avatar
IanSeyler
Member
Member
Posts: 326
Joined: Mon Jul 28, 2008 9:46 am
Location: Ontario, Canada
Contact:

Re: LGDT crashing bootloader

Post by IanSeyler »

Did you try this:

Code: Select all

lgdt [cs:gdtr]
-Ian
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
mrnoob
Member
Member
Posts: 26
Joined: Thu Sep 18, 2008 11:45 am

Re: LGDT crashing bootloader

Post by mrnoob »

unfortunately bochs doesnt work on my pc, a bunch of PANIC messages come up even with a default installation.
as for lgdt[cs:gdtr], i get a syntax error and i cant seem to get any kind of segment:offset links working :/

could i upload my image or code for someone to debug in bochs or something? ive been trying to fix this for a couple of months now and havent got anywhere, and i just want to get on with developing an OS.
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: LGDT crashing bootloader

Post by Combuster »

This sounds a lot like PEBCAK.

For starters, I would seriously consider getting a modern assembler which can do all the opcodes properly and isn't from the previous century. And read documentation. Lots of it.

Also, how did you manage to break everything when you said it was working a month ago? :shock:
"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 ]
mrnoob
Member
Member
Posts: 26
Joined: Thu Sep 18, 2008 11:45 am

Re: LGDT crashing bootloader

Post by mrnoob »

it wasnt properly working, as soon as i tried any operations after the PM switch it tripled. I might convert the code to nasm actually.
Post Reply