Far Jump in Protected Mode to clear the prefetch queue
Posted: Wed Nov 14, 2012 5:08 pm
Hello,
my OS is tripple faulting at 'ljmp $0x8, $ExecKMain'.
If I leave out the far jump the processor is halted.
Here is my code which is loaded to 0x50:0x0 by MBR using BIOS interrupts:
my OS is tripple faulting at 'ljmp $0x8, $ExecKMain'.
If I leave out the far jump the processor is halted.
Code: Select all
00056533559i[BIOS ] Booting from 0000:7c00
00056656013e[CPU0 ] check_cs(0x0008): not a valid code segment !
00056656013e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00056656013e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
00056656013i[CPU0 ] CPU is in protected mode (active)
00056656013i[CPU0 ] CS.d_b = 16 bit
00056656013i[CPU0 ] SS.d_b = 16 bit
00056656013i[CPU0 ] EFER = 0x00000000
00056656013i[CPU0 ] | RAX=0000000060000011 RBX=0000000000000003
00056656013i[CPU0 ] | RCX=000000000009000a RDX=0000000000000301
00056656013i[CPU0 ] | RSP=000000000000ffd6 RBP=0000000000000117
00056656013i[CPU0 ] | RSI=00000000000e474c RDI=000000000000ffac
00056656013i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00056656013i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00056656013i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00056656013i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00056656013i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00056656013i[CPU0 ] | SEG selector base limit G D
00056656013i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00056656013i[CPU0 ] | CS:0050( 0004| 0| 0) 00000500 0000ffff 0 0
00056656013i[CPU0 ] | DS:0050( 0005| 0| 0) 00000500 0000ffff 0 0
00056656013i[CPU0 ] | SS:0050( 0005| 0| 0) 00000500 0000ffff 0 0
00056656013i[CPU0 ] | ES:0050( 0005| 0| 0) 00000500 0000ffff 0 0
00056656013i[CPU0 ] | FS:0050( 0005| 0| 0) 00000500 0000ffff 0 0
00056656013i[CPU0 ] | GS:0050( 0005| 0| 0) 00000500 0000ffff 0 0
00056656013i[CPU0 ] | MSR_FS_BASE:0000000000000500
00056656013i[CPU0 ] | MSR_GS_BASE:0000000000000500
00056656013i[CPU0 ] | RIP=0000000000000030 (0000000000000030)
00056656013i[CPU0 ] | CR0=0x60000011 CR2=0x0000000000000000
00056656013i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00056656013i[CPU0 ] 0x0000000000000030>> jmp far 0008:0035 : EA35000800
00056656013e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00056656013i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
00056656013i[CPU0 ] cpu hardware reset
Code: Select all
.section .rodata
msg:
.asciz "kernel..."
msgend:
msglen:
.word (msgend - msg)
gdt:
# Null Descriptor
.word 0x0000
.word 0x0000
.byte 0x00
.byte 0x00
.byte 0x00
.byte 0x00
# Code Descriptor
.word 0xffff
.word 0x0000
.byte 0x00
.byte 0x9a
.byte 0xcf
.byte 0x00
# Data Descriptor
.word 0xffff
.word 0x0000
.byte 0x00
.byte 0x92
.byte 0xcf
.byte 0x00
gdt_end:
gdtptr:
.word (gdt_end - gdt - 1)
.long gdt
.section .text
.globl Start
Start:
.code16
PrintMsg:
mov $0x0050, %ax
mov %ax, %es # Set Extra Segment to 0x0050
mov $msg, %bp # Set base pointer to msg location
mov $0x13, %ah # Print String
mov $0x01, %al # Char only - Cursor moved
clr %bh # Page Number
mov $0x03, %bl # Color Black Blue
mov msglen, %cx # Message Length
mov $3, %dh # Row 3
mov $1, %dl # Column 1
int $0x10 # Video Interrupt
cli
SetA20:
inb $0x92, %al # Enable A20 Gate
testb $0x2, %al # to access to more than
outb %al, $0x92 # 1 Mega Byte of memory
LoadGDT:
lgdt gdtptr # Load Global Descriptor Table
EnterProtectedMode:
movl %cr0, %eax # Read from Control Register CR0
orl $0x1, %eax # Set Protected Mode Bit
movl %eax, %cr0 # Write to Control Register CR
# In Real Mode : ljmp Segment, Offset
# In Protected Mode : ljmp Selector, Offset
# Selector:
# 0x0 = NullDescriptor
# 0x8 = CodeDescriptor
# 0x10 = DataDescriptor
ljmp $0x8, $ExecKMain
.code32
ExecKMain:
sti
call kmain
cli
Hang:
hlt
jmp Hang