Page 1 of 1

More PMode Help

Posted: Thu Apr 22, 2004 11:00 pm
by leadZERO
I'm playing around with a bootloader that enables the A20 line and then launches into PM (and eventually will load a 2nd stage loader that will handle loading the kernel from a filesystem).

I can't seem to get the [computer] (using Bochs as an emulator) to go into Pmode, as soon as I set the PE bit the emulator resets. I'm guessing I have something setup wrong in my GDT or how I reference it, but I can't find it. Any help would be greatly appreciated. You'll have to pardon the AT&T syntax, I use gas to assemble:

.code16

.set SEL_DATA, 0x8
.set SEL_LINEAR, 0x10


.globl start
start:
movw $0x7C0, %ax # load known address
movw %ax, %ds # into the segment
movw %ax, %es # registers.
movw %ax, %fs
movw %ax, %gs

xorw %ax, %ax # setup
movw %ax, %ss # ... the
movw $0xffff, %sp # ... stack

movw $bootmessage, %si # put something
call putstr # on the screen
call gateA20 # enable the A20 line

pushw $0x2
popf
lgdt gdt_ptr # Initialize GDTR
movl %cr0, %eax
orb $0x1, %al
movl %eax, %cr0
ljmp $SEL_DATA, $pmode


gateA20:
push %si
push %ax
movw $A20Message, %si
call putstr
inb $0x92, %al
orb $0x02, %al
outb %al, $0x92
pop %ax
pop %si
ret

putstr:
push %ax
push %bx
movb $0x0e, %ah
movw $0x0007, %bx
putstr.0:
lodsb
testb %al, %al
jz putstr.1
int $0x10
jmp putstr.0
putstr.1:
pop %bx
pop %ax
ret

.code32
pmode:
jmp .
movw $pmodemsg, %si
call putstr


# Enter protected mode

bootmessage: .asciz "SOS Bootloader (v.01)\n"
A20Message: .asciz "Enabling A20 line...\n"
pmodemsg: .asciz "Jumping to PMode...\n"


# GDT
# Segment Descriptor Layout:
#
#  31               24 23 22 21 20 19    16 15 14 13 12 11     8 7         0   Byte
#  _________________________________________________________________________
# |                   |  |D |  |A | Seg    |  |  D  |  |        |           |
# |   Base 31:24      |G |/ |O |V | Limit  |P |  P  |S | Type   | Base 23:16|    4
# |                   |  |B |  |L |  19:16 |  |  L  |  |        |           |
# |___________________|__|__|__|__|________|__|_____|__|________|___________|
#
#  31                                    16 15                             0
#  _________________________________________________________________________
# |                                        |                                |
# |         Base Address 15:00             |       Segment Limit 15:00      |    0
# |________________________________________|________________________________|

gdt_ptr: .word (gdt_end-gdt-1)
.word (gdt+0x7C00)
gdt:
gdt.0: # Null selector
.word 0 # [Off. 0] Segment Limit (15:00)
.word 0 # [Off. 2] Base Address (15:00)
.byte 0 # [Off. 4] Base Address (23:16)
.byte 0 # [Off. 5] Flags
.byte 0 # [Off. 6] Seg Limit & Flags
.byte 0 # [Off. 7] Base Address (31:24)

gdt.1: # Code (0x7C00 base)
.word 0xFFFF # [Off. 0] Segment Limit (15:00)
.word 0x7C00 # [Off. 2] Base Address (15:00)
.byte 0x0 # [Off. 4] Base Address (23:16)
.byte 0x8E # [Off. 5] Flags
.byte 0xA7 # [Off. 6] Seg Limit & Flags
.byte 0x0 # [Off. 7] Base Address (31:24)

gdt.2: # Linear (0x0 base)
.word 0xFFFF # [Off. 0] Segment Limit (15:00)
.word 0x0 # [Off. 2] Base Address (15:00)
.byte 0x0 # [Off. 4] Base Address (23:16)
.byte 0x86 # [Off. 5] Flags
.byte 0xA7 # [Off. 6] Seg Limit & Flags
.byte 0x0 # [Off. 7] Base Address (31:24)
gdt_end:

.org 510
.word 0xaa55

-------------

Everything works fine as long as I don't go into protected mode, so I'm building and loading the binary file fine.