.text
.global asmThunk
asmThunk:
cli # disable interrupts
pusha # save regs and flags
pushf
sgdt ProtectedGDTR # save descriptor tables
sidt ProtectedIDTR
movl %esp, ProtectedESP # save stack pointer
lgdt RealGDTR # load real mode descriptor table
lidt RealIDTR # load real mode interrupt vector table
mov $0x18, %ax # use real mode data segment
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov $RealStack, %ebx # %ebx = base of real mode stack
add $4096, %ebx # %ebx = top of real mode stack
mov %ax, %ss # setup real mode stack segment
mov %ebx, %esp # and stack pointer
# jump to set %cs
ljmp $0x10, $_16bitProtectedMode
.code16 # generate 16-bit friendly opcodes
_16bitProtectedMode:
mov %cr0, %eax # get control register
and $0xFE, %al # clear protected mode bit
mov %eax, %cr0 # set control register
ljmp $0, $_16bitRealMode # jump to set %cs
_16bitRealMode:
xor %ax, %ax # clear segments
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
nop # supposedly interrupts are disabled
# for one instruction after a mov into
# %ss, so this nop lets me enable
# interrupts below.
sti # enable interrupts
mov $0x80, %dl # the CD boot loader expects this
lcall $0, $0x7C00 # jump to the boot loader. good luck.
# in reality, we never make it back
# from the boot loader, so the rest
# of this code is dead, but here for
# completeness.
cli # disable interrupts
xor %ax, %ax # clear segments
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
lgdtl ProtectedGDTR
mov %cr0, %eax # get control register
or $0x1, %al # set protected mode bit
mov %eax, %cr0 # set control register
# jump to set %cs
ljmp $0x10, $_32bitProtectedMode
.code32 # generate 32-bit friendly opcodes
_32bitProtectedMode:
mov $0x18, %ax # restore segment registers
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss # restore stack
movl ProtectedESP, %esp
lidtl ProtectedIDTR # restore interrupt descriptor table
popf # restore flags and
popa # general purpose registers
sti # enable interrupts
ret
.global ThunkTest
.code16
ThunkTest:
mov $1, %ax
mov $2, %bx
mov $3, %cx
mov $4, %dx
int $0x10
mov $11, %ax
mov $12, %bx
mov $13, %cx
mov $14, %dx
int $0x13
mov $11, %ax
mov $12, %bx
mov $13, %cx
mov $14, %dx
int $0x16
lret