The kernel code:
Code: Select all
[BITS 16]
[ORG 0x0]
jmp start
;print
print:
push ax
.prn:
lodsb
or al,al
jz .end
mov ah,0eh
int 10h
jmp .prn
.end:
pop ax
ret
start:
cli
mov ax, 0x0100
mov ss, ax ;stack segment
mov sp, 0xFFFF ;stack pointer
push cs
pop ax
mov dx,ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
sti
;start
begin:
startmeup:
mov si,starting
call print
cli ; Disable interrupts... again...
xor ax, ax
mov ds, ax ; Set DS-register to 0 - used by lgdt
lgdt [gdt_desc] ; Load the GDT descriptor
xor ax,ax
mov ds,ax
;pmode in a can
mov eax, cr0 ; Copy the contents of CR0 into EAX
or eax, 1 ; Set bit 0
mov cr0, eax ; Copy the contents of EAX into CR0
jmp 0x08:clear_pipe ; Jump to code segment, offset clear_pipe
;old school Pmode tutorial for the sake of testing...
[BITS 32]
clear_pipe:
mov ax, 10h ; Save data segment identifyer
mov ds, ax ; Move a valid data segment into the data segment register
mov ss, ax ; Move a valid data segment into the stack segment register
mov esp, 090000h ; Move the stack pointer to 090000h
;write something
mov byte [ds:0B8000h], 'P' ; Move the ASCII-code of 'P' into first video memory
mov byte [ds:0B8001h], 1Bh ; Assign a color code
cli ; stop interrupts
hlt ; halt the CPU
starting db 'Booting...',13,10,0
gdt: ; Address for the GDT
gdt_null: ; Null Segment
dd 0
dd 0
gdt_code: ; Code segment, read/execute, nonconforming
dw 0FFFFh
dw 0
db 0
db 10011010b
db 11001111b
db 0
gdt_data: ; Data segment, read/write, expand down
dw 0FFFFh
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdt_end:
gdt_desc: ; GDT descriptor
dw gdt_end - gdt - 1 ; Limit (size)
dd gdt ; Address of the GDT
Bochs says:
Code: Select all
00060434533i[BIOS ] Booting from 0000:7C00
00067385591e[CPU0 ] jump_protected: call gate.p == 0
00067385591e[CPU0 ] fetch_raw_descriptor: GDT: index (f007)1e00 > limit (53f0)
00067385591i[CPU0 ] protected mode
00067385591i[CPU0 ] CS.d_b = 16 bit
00067385591i[CPU0 ] SS.d_b = 16 bit
00067385591i[CPU0 ] EFER = 0x00000000
00067385591i[CPU0 ] | RAX=0000000000000011 RBX=0000000000000007
00067385591i[CPU0 ] | RCX=0000000000000017 RDX=0000000000000100
00067385591i[CPU0 ] | RSP=000000000000ffff RBP=0000000000000000
00067385591i[CPU0 ] | RSI=00000000ffff0107 RDI=0000000000080005
00067385591i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00067385591i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00067385591i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00067385591i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00067385591i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00067385591i[CPU0 ] | SEG selector base limit G D
00067385591i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00067385591i[CPU0 ] | CS:0100( 0004| 0| 0) 00001000 0000ffff 0 0
00067385591i[CPU0 ] | DS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00067385591i[CPU0 ] | SS:0100( 0005| 0| 0) 00001000 0000ffff 0 0
00067385591i[CPU0 ] | ES:0100( 0005| 0| 0) 00001000 0000ffff 0 0
00067385591i[CPU0 ] | FS:0100( 0005| 0| 0) 00001000 0000ffff 0 0
00067385591i[CPU0 ] | GS:0100( 0005| 0| 0) 00001000 0000ffff 0 0
00067385591i[CPU0 ] | MSR_FS_BASE:0000000000001000
00067385591i[CPU0 ] | MSR_GS_BASE:0000000000001000
00067385591i[CPU0 ] | RIP=0000000000000084 (0000000000000084)
00067385591i[CPU0 ] | CR0=0x00000011 CR1=0x0 CR2=0x0000000000000000
00067385591i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00067385591i[CPU0 ] >> jmp far 0008:0089 : EA89000800
00067385591e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown
status is 00h, resetting
00067385591i[SYS ] bx_pc_system_c::Reset(SOFTWARE) called
00067385591i[APIC0] local apic in CPU 0 initializing
00067385591e[CPU0 ] CPU_LOOP bx_guard.interrupt_requested=1
Next at t=67385591
<bochs:2> dump_cpu
eax:0x00000000, ebx:0x00000000, ecx:0x00000000, edx:0x00000f20
ebp:0x00000000, esp:0x00000000, esi:0x00000000, edi:0x00000000
eip:0x0000fff0, eflags:0x00000002, inhibit_mask:0
cs:s=0xf000, dl=0x0000ffff, dh=0xff009bff, valid=1
ss:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
ds:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
es:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
fs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
gs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008300, valid=1
gdtr:base=0x00000000, limit=0xffff
idtr:base=0x00000000, limit=0xffff
dr0:0x00000000, dr1:0x00000000, dr2:0x00000000
dr3:0x00000000, dr6:0xffff0ff0, dr7:0x00000400
cr0:0x00000010, cr1:0x00000000, cr2:0x00000000
cr3:0x00000000, cr4:0x00000000
done
I'm guessing that I haven't set up the GDT properly... How to make sure?
I tried adjusting the location of the GDT (since I am using ORG 0x0), but I still get a triple fault in Bochs:
Code: Select all
gdt_desc: ; GDT descriptor
dw gdt_end - gdt - 1 ; Limit (size)
dd gdt + 0x1000 ; Address of the GDT + 0x1000