Hello all. I am attempting to write a small operating system, just for kicks (i'm a strange person...), only problem is, i can't seem to make the protected mode switch. I am targeting Intel 80386 and better using NASM to assemble the source. Here is that source:
bits 16
org 0x00
jmp start_os
;these lines are the messages to be printed by our OS
switching_msg db "Currently placing processor in 32-bit Protected mode...",0
done_msg db "Done with placing processor in 32-bit Protected mode. I can't believe I finally made it!!!",0
cur_char dw 0x0
;these functions print messages on the screen in 16-bit and 32-bit mode, respectively
print_ln_16:
mov ah,0x0e
mov bx,0x0007
.print_loop
lodsb
or al,al
jz .done
int 0x10
jmp .print_loop
.done
retn
bits 32
print_ln_32:
mov ax,video_selector
mov gs,ax
.print_loop:
lodsb
or al,al
jz .done
mov ah,0x07
mov word [gs:cur_char],ax
inc word [cur_char]
inc word [cur_char]
jmp .print_loop
.done:
retn
bits 16
start_os:
mov ax,0x0050
mov ds,ax
mov es,ax
mov si,switching_msg
call print_ln_16
cli
lgdt [global_descriptor]
mov eax,cr0
or eax,0x01
mov cr0,eax
jmp 0x08:pmode_jmp
bits 32
pmode_jmp:
mov ax,0x10
mov ds,ax
mov es,ax
mov ax,0x18
mov gs,ax
mov word [gs:0],0x0641
jmp pmode_jmp
hang:
jmp hang
bits 16
global_descriptor:
dw gdt_end - gdt_begin -1 ;total length of global descriptor table
dd gdt_begin ;beginning of global descriptor table
gdt_begin:
empty_selector equ $-gdt_begin ;empty selector located at 0x0 in the table
gdt_0 ;first entry is to be a null descriptor
dd 0x0 ;make all the entries in
dd 0x0 ;this descriptor null
code_selector equ $-gdt_begin ;code selector located at 0x08 in the table
gdt_code ;this entry is our code selector
dw 0xFFFF ;4 Gb limit
dw 0x0000 ;base is at 0x0
db 0x00
db 0x9A
db 0xCF
db 0x00
data_selector equ $-gdt_begin ;data selector located at 0x10
gdt_data ;this entry is the data selector
dw 0xFFFF ;4 Gb limit
dw 0x0000 ;base is at 0x0
db 0x00
db 0x92
db 0xCF
db 0x00
video_selector equ $-gdt_begin ;video selector at 0x18
gdt_video ;video selector
dw 3999 ;this selector should have a limit of ((80*25)*2)-1 or 3999 decimal
dw 0x8000 ;and should start at 0xB800, video memory
db 0x0B
db 0x92
db 0x00
db 0x00
gdt_end
Alot of this was borrowed from a tutorial and i would credit them if i could remember the name. This code just makes the processor reset over and over. What is going wrong with this code? I am using bochs to test the code and here is the log file concerning the processor around reset:
00105544372i[BIOS ] Booting from 0000:7c00
00107450657e[CPU0 ] check_cs(0x0008): not a valid code segment !
00107450657i[CPU0 ] CPU is in protected mode (active)
00107450657i[CPU0 ] CS.d_b = 16 bit
00107450657i[CPU0 ] SS.d_b = 16 bit
00107450657i[CPU0 ] EFER = 0x00000000
00107450657i[CPU0 ] | RAX=0000000060000011 RBX=0000000000000007
00107450657i[CPU0 ] | RCX=0000000000000003 RDX=0000000000000fff
00107450657i[CPU0 ] | RSP=000000000000fffb RBP=0000000000000000
00107450657i[CPU0 ] | RSI=00000000ffff003b RDI=0000000000080005
00107450657i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00107450657i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00107450657i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00107450657i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00107450657i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00107450657i[CPU0 ] | SEG selector base limit G D
00107450657i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00107450657i[CPU0 ] | CS:0050( 0004| 0| 0) 00000500 0000ffff 0 0
00107450657i[CPU0 ] | DS:0050( 0005| 0| 0) 00000500 0000ffff 0 0
00107450657i[CPU0 ] | SS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00107450657i[CPU0 ] | ES:0050( 0005| 0| 0) 00000500 0000ffff 0 0
00107450657i[CPU0 ] | FS:07c0( 0005| 0| 0) 00007c00 0000ffff 0 0
00107450657i[CPU0 ] | GS:07c0( 0005| 0| 0) 00007c00 0000ffff 0 0
00107450657i[CPU0 ] | MSR_FS_BASE:0000000000007c00
00107450657i[CPU0 ] | MSR_GS_BASE:0000000000007c00
00107450657i[CPU0 ] | RIP=00000000000000eb (00000000000000eb)
00107450657i[CPU0 ] | CR0=0x60000011 CR1=0x0 CR2=0x0000000000000000
00107450657i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00107450657i[CPU0 ] >> jmp far 0008:00f0 : EAF0000800
00107450657e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00107450657i[SYS ] bx_pc_system_c::Reset(SOFTWARE) called
00107450657i[CPU0 ] cpu software reset
Sorry this is so long but i just can't seem to figure out where i am going wrong. I studied all of intel's documents but cant seem to find out where i am going wrong!!!!