The multiboot stuff is working fine, but I'm having trouble trying to figure out how to return to real mode. Here is what I'm currently doing:
Code: Select all
# Link this file with "--oformat binary -Ttext 0x00007E00".
.set MAGIC, 0x1BADB002
.set AOUT_KLUDGE, 0x00010000
.set FLAGS, AOUT_KLUDGE
.set CHECKSUM, -(MAGIC + FLAGS)
.set newidt, 0x0632
.intel_syntax noprefix
.section .text
.code32
.global _start # _start declared global so the linker doesn't complain
_start: # This label is here so a 32-bit address is used
.code16
jmp real16
.align 4
.code32
multiboot_header:
.long MAGIC # magic
.long FLAGS # flags
.long CHECKSUM # checksum
.long multiboot_header # header address
.long _start # load address
.long 0x00000000 # load end address
.long 0x00000000 # bss end address
.long multiboot_entry # entry address
multiboot_entry:
cli # disable interrupts
mov eax, cr0
and eax, 0x7FFFFFFE # disable paging and protected mode
mov cr0, eax
xor eax, eax
mov cr3, eax # reset address of page directory
ljmp 0x00:real16 # far jump to real mode
.code16
real16:
cli
mov sp, 0x7C00 # set up stack
xor ax, ax # initialize segment registers
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov ax, 0x03FF # limit of the idt
mov [newidt], ax
xor ax, ax # base of the idt
mov [newidt + 2], ax
mov [newidt + 4], ax
lidt [newidt] # load new idt
sti # enable interrupts
mov si, message
print:
lodsb
or al, al
jz hang
mov ah, 0x0E
int 0x10
jmp print
hang:
jmp hang
message:
.ascii "Hello World!"
.att_syntax prefix
The most suspicious thing is that jump. The 'correct' mnemonic for that should be 'jmp dword' or 'jmp far'. GAS doesn't support either of those, but I had read somewhere that ljmp was an older name for it. Anyhow, the CS register doesn't appear to be changing, so I really think the problem is there.
Can anyone tell me what mistake I'm making here?