Bootloader w pierwszym sektorze dysku:
[bits 16]
[org 07c00h]
start:
jmp short reset_drive
nop
times 0x3B db 0
gdt_desc:
db gdt_end - gdt
dw gdt
gdt:
gdt_null:
dd 0
dd 0
gdt_code:
dw 0ffffh
dw 0
db 0
db 10011010b
db 11001111b
db 0
gdt_data:
dw 0ffffh
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdt_end:
reset_drive:
xor ax,ax
int 13h
cmp ah,0
jnz reset_drive
xor ax,ax
mov es,ax
mov bx,01000h
mov ax,0201h
mov cx,02h
mov dh,0
pusha
int 13h
popa
cmp ah,0
jnz reset_drive
xor ax,ax
mov ds,ax
lgdt [gdt_desc]
cli
mov eax,cr0
or eax,1
mov cr0,eax
jmp 08h:start32
[BITS 32]
start32:
mov ax,08h
mov ds,ax
mov ss,ax
mov esp,090000h
jmp 08h:01000h
times 510-($-$$) db 0
dw 0AA55h
Kernel w ASM i C:
[bits 32]
[extern _main]
call _main
hlt
W C:
void main()
{
*(0xb800)='A'
return;
}
Wyświetla "A" w lewym, górnym rogu. Szybszy jest kernel w ASM, ale łatwiejszy jest w C.
Ten przykładowy kernel powinien być w drugim sektorze dysku. Aby mógł zajmować więcej niż 512 bajtów, należy zmodyfikować bootloader.
Należy pamiętać, że jest to w trybie chronionym, bez IDT, więc przerwanie wywołuje restart. Dopiero po załadowaniu IDT można włączyć przerwania.</cpp></asm>