Skip to content

Instantly share code, notes, and snippets.

@Themaister
Created June 18, 2011 16:00
Show Gist options
  • Select an option

  • Save Themaister/1033225 to your computer and use it in GitHub Desktop.

Select an option

Save Themaister/1033225 to your computer and use it in GitHub Desktop.
[bits 16]
org 7c00h
jmp 0:start
start:
xor ax, ax
mov ds, ax
mov eax, 80000000h
cpuid
cmp eax, 80000000h
jb no32
mov eax, 80000001h
cpuid
bt edx, 29
jnc no64
mov bx, success_str
call puts
in al, 092h
or al, 2
out 092h, al
xor ax, ax
mov es, ax
mov bx, kernel_sector2
mov ah, 02h
mov al, 01h
mov ch, 0
mov cl, 2
mov dh, 0
mov dl, 0
int 13h
jc fail
jmp 0:kernel_init
puts:
mov si, 0
mov ah, 0eh
puts_loop:
mov al, [bx + si]
cmp al, 0
je puts_end
int 10h
inc si
jmp puts_loop
puts_end:
ret
no32:
mov bx, no32_str
call puts
jmp $
no64:
mov bx, no64_str
call puts
jmp $
fail:
mov bx, fail_str
call puts
jmp $
no32_str: db "No 32-bit! :(", 0ah, 0dh, 00h
no64_str: db "No 64-bit! :(", 0ah, 0dh, 00h
success_str: db "Yay! :D", 0ah, 0dh, 00h
fail_str: db "Failed to load ...", 0ah, 0dh, 00h
# Pad
times 510 - ($-$$) db 0
db 55h
db 0aah
;Sector 2
kernel_sector2:
%macro system_segment_desc 3
dq ((%1 & 0ff000000h) << 20h) | ((%2 & 0ff0000h) << 20h) | (%3 << 20h) | ((%1 & 0ff0000h) << 10h) | ((%1 & 0ffffh) << 10h) | (%2 & 0ffffh)
dq %1 >> 20h
%endmacro
%assign SEL_NULL 0
%assign SEL_CODE (1 << 3)
%assign SEL_LONG (2 << 3)
%assign SEL_DATA (3 << 3)
%assign SEL_USR_32b ((4 << 3) | 3)
%assign SEL_USR_DATA ((5 << 3) | 3)
%assign SEL_USR_LONG ((6 << 3) | 3)
%assign SEL_TSS (8 << 3)
%assign IDENT_MAP 0
%define TSS_LOC ($-$$ + 7c00h)
TSS:
TSS.ign1: dd 0 ; Ignorert
TSS.rsp0: dq 0 ; RSP for CPL=0
TSS.rsp1: dq 0 ; RSP for CPL=1
TSS.rsp2: dq 0 ; RSP for CPL=2
TSS.ign2: dq 0 ; Ignorert
TSS.ist1: dq 0
TSS.ist2: dq 0
TSS.ist3: dq 0
TSS.ist4: dq 0 ; Interrupt stack tabeller.
TSS.ist5: dq 0
TSS.ist6: dq 0
TSS.ist7: dq 0
TSS.ign3: dq 0 ; Ignorert
TSS.ign4: dw 0 ; Ignorert
TSS.iobase: dw 0 ; IO bitmap offset.
GDT:
.size dw 0ah * 8 - 1
.loc: dd .rGDT
dd 0
align 8
.rGDT:
.0: dq 0 ; Ubrukt
.1: dq 0000000011011111100110100000000000000000000000001111111111111111b
.2: dq 0000000000100000100110000000000000000000000000000000000000000000b
; ---------||-----||/|||---------------ignored-in-longmode--------
; || || ||`->Conforming
; |`Long || |`->Code/Data
; | || `->User
; | |`->CPL 0-3
; | `->Present
; `->If long, must be zero (default operand size)
.3: dq 0000000011011111100100100000000000000000000000001111111111111111b
; Usermode:
.4: dq 0
.5: dq 0000000000110000111100100000000000000000000000000000000000000000b
.6: dq 0000000000110000111111000000000000000000000000000000000000000000b
.7: dq 0
.8: system_segment_desc TSS_LOC + IDENT_MAP, 103, 8900h ; Takes 16 bytes
.A:
kernel_init:
mov bx, kernel_init_str
call puts
jmp sanity
sanity:
lgdt [cs:GDT]
mov eax, cr0
bts eax, 0
mov cr0, eax
jmp far SEL_CODE:protmode
[bits 32]
protmode:
mov ax, SEL_DATA
mov ds, ax
mov es, ax
mov ss, ax
mov dword [0b8000h], '3 2 '
mov dword [0b8004h], ' b '
mov dword [0b8008h], 'i t '
mov dword [0b800ch], ' f '
mov dword [0b8010h], 't w '
mov dword [0b8014h], '! '
%assign PAGES 1000h
paging:
mov edi, PAGES
mov ecx, 1024
xor eax, eax
rep stosd
mov dword [PAGES ], PAGES + 1000h + 3
mov dword [PAGES + 1000h], PAGES + 2000h + 3
mov dword [PAGES + 2000h], 000000h + 83h
mov dword [PAGES + 2008h], 200000h + 83h
mov eax, PAGES
mov cr3, eax
set_longmode:
mov eax, cr4
bts eax, 5
mov cr4, eax
mov ecx, 0c0000080h
rdmsr
bts eax, 8
wrmsr
mov eax, cr0
bts eax, 31
mov cr0, eax
jmp far SEL_LONG:longmode
[bits 64]
longmode:
mov eax, 9fff8h
mov esp, eax
mov [TSS.rsp0], rax
mov [TSS.rsp1], rax
mov [TSS.rsp2], rax
mov [TSS.ist1], rax
mov eax, SEL_TSS
ltr ax
mov rax, 'L O N G '
mov [0b8000h], rax
jmp $
kernel_init_str: db "Kernel init!", 0ah, 0dh, 00h
times 1024 - ($-$$) db 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment