Thanks for the responses! alexfru, good catch. That was I mistake in my copying. I am working on getting my current branch up to github to link in this thread.
In the meantime, I will post a code snippet. I kept iterating and might have made a little progress. But things still go wild. Following is a snippet of my code. During my meme820 test, I give three options and describe above each option the strange behavior I see. For each option I have put either some gdb output or qemu crash dump below my code snippet.
Code:
.align 16
gdt:
# Index 0x00
# Required dummy
.quad 0x00
# 0x08
# Unused
.quad 0x00
# 0x10
# protected mode code segment
# bit 63 bit 32
# 000000000000000 | 1001101000000000
# 000000000000000 | 1111111111111111 (limit)
# bit 31 (base) bit 0
#.word 0xFFFF
#.word 0x0000
#.word 0x9A00 # 1001 1010 0000 0000
#.word 0x00CF # 0000 0000 1100 1111
.quad 0x00cf9a000000ffff
# 0x18
# protected mode data segment
#.word 0xFFFF
#.word 0x0000
#.word 0x9200 # 1001 0010 0000 0000
#.word 0x00CF # 0000 0000 1100 1111
.quad 0x00cf92000000ffff
# 0x20
# 16 bit code segment
#.word 0xFFFF limit (0-15)
#.word 0x0000 base (16-31)
#.byte 0x00 base (32-39)
#.byte 0x9a access byte (40-47) - 10011010
#.byte 0x0f flags + limit (48-55)
#.word 0x00 base (56-63)
.quad 0x00009a000000ffff
# 0x28
# 16 bit data segment
#.word 0xFFFF limit (0-15)
#.word 0x0000 base (16-31)
#.byte 0x00 base (32-39)
#.byte 0x92 access byte (40-47) - 10010010
#.byte 0x0f flags + limit (48-55)
#.word 0x00 base (56-63)
.quad 0x000092000000ffff
gdt_end:
gdt_info:
.word gdt_end - gdt - 1 # Size of GDT
.word 0x0000 # Upper 2 Bytes of GDT address.
.word 0x0000 # Lower 2 Bytes of GDT address.
# IDT for protected mode
idt_info:
.word 0x0000
.word 0x0000
.word 0x0000
# IDT for real mode
idt_real_info:
.word 0x03ff
.word 0x0000
.word 0x0000
.code32
.text
.globl setup_32
setup_32:
# Setup stack.
movl $0x00007000, %esp
movl %esp, %ebp
# Set up GDT
movl $gdt, (gdt_info + 2)
# Interrupts should already be disabled...
cli
lgdt gdt_info
# *********************
# Return to real mode *
# *********************
# Load a new segment with a limit of 0xffff
# This is the segment limit required in real-
# address mode.
jmp $0x20, $loadRMSeg
.code16
loadRMSeg:
movl $0x28, %eax
movl %eax, %ds
movl %eax, %gs
movl %eax, %fs
movl %eax, %es
movl %eax, %ss
# This line allows the interrupt to work.
lidt idt_real_info
# Preserve %cr0
movl %cr0, %eax
# Turn off PE bit, bit 0 to return to real mode
andl $0xffffffffe, %eax
movl %eax, %cr0
jmp $0x00, $set_rm_segment_regs
set_rm_segment_regs:
movw $0x0000, %ax
movw %ax, %ds
movw %ax, %gs
movw %ax, %fs
movw %ax, %es
movw %ax, %ss
# Enable interrupts for memory checking.
sti
meme820:
xorl %ebx, %ebx
# Option 1:
# Using GDB and qemu I set a breakpoint at bail820 below.
# I can get past int $0x15 and hit the breakpoint, int %0x15 indicates success.
# (CF not set) and %eax has the magic value that it should.
#
# The code then continues on, and I return to protected mode.
# As I step through the code in GDB every single interrupt begins to
# fire and the code completely goes off the rails. I never see main hit.
# $smapBuffer is defined in another file and at address ~0x6000
movw $smapBuffer, %di
# Options 2:
# Using GDB and qemu I set a breakpoint at bail820 below.
# Interrupt is called and returns. Memory test indicates that it
# failed. Code makes it to my main and life appears to be wonderful.
#
# For some reason, %esp is no longer at $0x7000 as I set it at the top.
#movw $0x500, %es:(%di)
# Options 3:
# Using GDB and qemu I set a breakpoint at bail820 below.
# My breakpoint is never hit. Qemu crashes horribly with the
# dump below.
#movw $0x2d0, %di
movl $0x0000e820, %eax
movl $0x534D4150, %edx
movl $20, %ecx
int $0x15
bail820:
cli
# **************************
# Return to protected mode *
# **************************
< code here >
Option 1 GDB. Notice no carry flag and the correct magic number in eax. But ebx did not increase and the stack went wild.
Code:
(gdb) info reg
eax 0xe820 59424
ecx 0x14 20
edx 0x534d4150 1397571920
ebx 0x0 0
esp 0xfffe 0xfffe
ebp 0x7000 0x7000
esi 0x375 885
edi 0x6840 26688
eip 0x2970 0x2970 <bail820>
eflags 0x200006 [ PF ID ]
cs 0x0 0
ss 0x0 0
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
Option 2 GDB dump. Notice that all signs point to e820 failure, and the stack is slightly off:
Code:
Breakpoint 1, bail820 () at setup_32.s:165
165 cli
(gdb) info reg
eax 0x1e3a 7738
ecx 0x14 20
edx 0x534d4150 1397571920
ebx 0x0 0
esp 0x6ffe 0x6ffe
ebp 0x7000 0x7000
esi 0x1 1
edi 0x0 0
eip 0x2972 0x2972 <bail820>
eflags 0x200013 [ CF AF ID ]
cs 0x0 0
ss 0x0 0
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb) x/32x 0x6ff0
0x6ff0: 0x00000000 0x00000000 0x29720000 0x02460000
0x7000: 0x00000000 0x00000000 0x00000000 0x00000000
0x7010: 0x00000000 0x00000000 0x00000000 0x00000000
Qemu Crash dump from option 3. Break point never hit.
Code:
qemu: fatal: Trying to execute code outside RAM or ROM at 0x00000000000b8600
EAX=00000000 EBX=00004600 ECX=00000046 EDX=534d00ea
ESI=00000111 EDI=0000465c EBP=000000fa ESP=000000ea
EIP=00004600 EFL=00204606 [D----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =00b4 00000b40 0000ffff 00009300
CS =b400 000b4000 0000ffff 00009a00
SS =0000 00000000 0000ffff 00009300
DS =0000 00000000 0000ffff 00009300
FS =0000 00000000 0000ffff 00009300
GS =0000 00000000 0000ffff 00009300
LDT=0000 00000000 0000ffff 00008200
TR =0000 00000000 0000ffff 00008b00
GDT= 00000000 000028f2
IDT= 002153b8 00006000
CR0=00000010 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000
DR3=0000000000000000
DR6=00000000ffff4ff0 DR7=0000000000000400
CCS=00000000 CCD=00000111 CCO=INCW
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000