global _main
global _pm_bootstrap
global gdt_start
global gdt_null
global gdt_code
global gdt_data
global gdt_user_code
global gdt_user_data
global gdt_end
global gdt_descriptor
[bits 16]
_main:
_pm_bootstrap:
mov dx, msg_title
call putstr
mov dx, msg_ldgdt
call putstr
cli
lgdt [gdt_descriptor]
in al, 0x92
or al, 2
out 0x92, al
mov eax, cr0
or eax, 0x1
mov cr0, eax
jmp dword CODE_SEGMENT:pmkernel
msg_title: db 13, 10, 'YOTOS protected mode loader', 13, 10, 0
msg_ldgdt: db 'Loading Global Descriptor Table (GDT)... ', 0
putstr: ; dx=argument
mov cx, bx ; we must preserve bx
putstr_start:
mov bx, dx ; [dx] is not a effective address
mov al, byte [bx]
test al, al
jz putstr_end
mov ah, 0x0e
mov bx, 0x0007
int 0x10
inc dx
jmp putstr_start
putstr_end:
mov bx, cx
ret
; GDT entry
gdt_start:
gdt_null: ; null descriptor
dd 0x00
dd 0x00
gdt_code: ; code segment descriptor
dw 0xffff ; segment limit (bits 0-15)
dw 0x0 ; base (bits 0-15)
db 0x0 ; base (bits 16-23)
db 10011010b ; (present) 1,
; (privilege) 00,
; (descriptor type) 1,
; type =
; (code) 1,
; (conforming) 0,
; (readable) 1,
; (accessed) 0
db 11001111b ; (granularity) 1,
; (32-bit default) 1,
; (64-bit segment) 0,
; (AVL) 0,
; segment limit (bits 16-19)
db 0x0 ; base (bits 24-31)
gdt_data: ; data segment descriptor
dw 0xffff ; segment limit (bits 0-15)
dw 0x0 ; base (bits 0-15)
db 0x0 ; base (bits 16-23)
db 10010010b ; (present) 1,
; (privilege) 00,
; (descriptor type) 1,
; type =
; (code) 0,
; (expand down) 0,
; (writable) 1,
; (accessed) 0
db 11001111b ; (granularity) 1,
; (32-bit default) 1,
; (64-bit segment) 0,
; (AVL) 0,
; segment limit (bits 16-19)
db 0x0 ; base (bits 24-31)
gdt_user_code: ; user mode code segment descriptor
dw 0xffff
dw 0x0
db 0x0
db 11111010b
db 11001111b
db 0x0
gdt_user_data: ; user mode data segment descriptor
dw 0xffff
dw 0x0
db 0x0
db 11110010b
db 11001111b
db 0x0
gdt_end:
gdt_descriptor:
dw gdt_end - gdt_start - 1
dd load_offset + gdt_start
CODE_SEGMENT equ gdt_code - gdt_start
DATA_SEGMENT equ gdt_data - gdt_start