Page 1 of 1

Protected Mode problem

Posted: Sat Aug 13, 2011 10:04 am
by mariuszp
I have tried to make a bootloader that reads the first file from a custom filesystem, and then loads it as a kernel. However, something fails when entering Protected Mode. The bootloader does not work in QEMU or VirtualBox, but VirtualBox detects an "unexpected problem" during operation (but the log does not say what instruction caused it). Here is the code:

Code: Select all

; bootloader.asm -- the GigaDOS bootloader
bits 16
org 0x7C00

mov ax, 0
mov ds, ax
jmp 0x0:go

go:
cli
mov si, str_booting
call puts

; the area used for reading the kernel record and finally
; transferring control to the kernel
mov ax, 0x7E0
mov es, ax

; read the file header from floppy
mov ah, 0x02
mov al, 1
mov cx, 1
xor dx, dx
xor bx, bx
int 13h

; now read the file
mov ah, 0x02
mov al, [es:0x10]
mov cl, 2
int 13h

; reset the ES segment
mov ax, 0
mov es, ax

mov si, str_pmode
call puts

; load the GDT
lgdt [gdt_desc]

; enter Protected Mode
mov eax, cr0
or eax, 1
mov cr0, eax

jmp 0x08:clear_pipe

; put a string on the screen
; DS:SI -> NUL-terminated string
; AX = destroyed
puts:
	mov ah, 0x0E

	.loop:
	lodsb
	cmp al, 0
	je .end
	int 10h
	jmp .loop

	.end:
	ret

str_booting db 'GigaDOS booting up....', 0
str_pmode db 'Entering protected mode...', 0

; the default GDT
gdt:

.null dq 0
.code:
	dw 0xFFFF
	dw 0
	db 0
	db 0x9A
	db 0xCF
	db 0

.data:
	dw 0xFFFF
	dw 0
	db 0
	db 0x92
	db 0xCF
	db 0

.end:

; the GDT pointer
gdt_desc:
	db gdt.end - gdt
	dw gdt

[BITS 32]
clear_pipe:
	mov ax, 0x10
	mov ds, ax
	mov ss, ax

	mov ax, 0x4040
	mov [0xB8000], ax

	jmp 0x7E00

times 510 - ($ - $$) db 0
db 0x55, 0xAA
Any help?

Re: Protected Mode problem

Posted: Sat Aug 13, 2011 10:24 am
by Combuster
This looks like the typical driver issues:
- No error checking at all
- DL is modified, drive number might be incorrect
- Sectors are 1-based and not 0-based. You currently seem to be using the bootsector as superblock and the superblock as your second stage

Re: Protected Mode problem

Posted: Sat Aug 13, 2011 11:16 am
by mariuszp
I get a message saying "Entering protected mode...", and I've also checked to make sure that the GDT loads correctly. Anyway, the problem is with actually entering protected mode, because otherwise a symbol would appear right before the jump to kernel (line 106).

Re: Protected Mode problem

Posted: Sat Aug 13, 2011 11:42 am
by egos

Code: Select all

; the GDT pointer
gdt_desc:
   db gdt.end - gdt
   dw gdt
Wow! What is it?

Initialize the stack.

It's no reason to disable interrupts so early.

Re: Protected Mode problem

Posted: Sat Aug 13, 2011 11:48 am
by mariuszp
It's the GDT descriptor. Is there something wrong with it?

Re: Protected Mode problem

Posted: Sat Aug 13, 2011 12:12 pm
by Combuster
mariuszp wrote:because otherwise a symbol would appear right before the jump to kernel
In that timeframe it probably crashes before a video update even happens.

but egos is right, you can't fit 16 bits in one byte and you can't fit 32 bits in two bytes.

Re: Protected Mode problem

Posted: Sat Aug 13, 2011 12:14 pm
by jnc100
mariuszp wrote:It's the GDT descriptor. Is there something wrong with it?
Yes. The limit should be 16 bits and the address 32 bits.

i.e.

Code: Select all

; the GDT pointer
gdt_desc:
   dw gdt.end - gdt - 1
   dd gdt
Regards,
John.

Re: Protected Mode problem

Posted: Sun Aug 14, 2011 11:39 am
by Bietje
mariuszp wrote:

Code: Select all

; the area used for reading the kernel record and finally
; transferring control to the kernel
mov ax, 0x7E0
mov es, ax

; read the file header from floppy
mov ah, 0x02
mov al, 1
mov cx, 1
xor dx, dx
xor bx, bx
int 13h

BIOS interrupt 0x13 function 2 uses a 1-based sector number in al. The extended function, 0x42 uses a 0-based 'sector number' (LBA address) specified in the Disk Addres Packet.

You are reading sector 1 there, which is your mbr. That sector is already loaded and thus, it doesn't make sense. You could try this to read the second sector:

Code: Select all

xor bx, bx
mov es, bx ; seg 0
mov bx, 0x7e00 ; offset
xor dx, dx ; head 0 - drive 0
xor ch, ch ; cyl 0
mov cl, 2
mov ax, 0x201 ; function 2 - read 1 sector