More PMode Help

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.
Post Reply
leadZERO

More PMode Help

Post 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.
Post Reply