Code: Select all
[BITS 16]
[ORG 0x7C00]
reset_drive:
mov ah, 0 ; RESET-command
int 13h ; Call interrupt 13h
or ah, ah ; Check for error code
jnz reset_drive ; Try again if ah != 0
mov ax, 0x1000
mov es, ax
mov bx, 0x0 ; Destination address = 0x10000
mov ah, 02h ; READ SECTOR-command
mov al, 36 ; Number of sectors to read = 36
mov ch, 0 ; Cylinder = 0
mov cl, 02h ; Sector = 2
mov dh, 0 ; Head = 0
int 13h ; Call interrupt 13h
or ah, ah ; Check for error code
jnz reset_drive ; Try again if ah != 0
cli ; Disable interrupts, we want to be alone
xor ax, ax
mov ds, ax ; Set DS-register to 0 - used by lgdt
lgdt [gdt_desc]
call enable_A20
mov ax, 0x9C00
mov es, ax
xor di, di
mov ax, 0
mov bx, 3
init_1st_page:
mov cx, 0x100
stosw
xchg bx, ax
stosw
add bx, 0x1000
xchg ax, bx
loop init_1st_page
mov cx, 0x200
xor ax, ax
rep stosd
init_2nd_page:
mov cx, 0x10
rep stosd
mov cx, 0x3F0
mov eax, 0x10000
mov ebx, 3
stosw
xchg ebx, eax
stosw
xchg eax, ebx
add eax, 0x1000
loop init_2nd_page
mov eax, 0x9C003
stosd
mov ax, 767
xchg ax, cx
rep stosd
mov eax, 0x9D003
stosd
mov eax, 0x9E000
mov cr3, eax
mov eax, cr0
or eax, 0x80000001 ; enables paging and Pmode
mov cr0, eax
jmp 08h:clear_pipe ; Jump to code segment, offset clear_pipe
enable_A20:
in al, 0x64
test al, 2
jnz enable_A20
mov al, 0xD1
out 0x64, al
.6:
in al, 0x64
and ax, byte 2
jnz .6
mov al, 0xDF
out 0x60, al
[BITS 32]
clear_pipe:
mov eax, 0x10
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
mov ss, eax
jmp 8:0x10000
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: ; Used to calculate the size of the GDT
gdt_desc: ; The GDT descriptor
dw gdt_end - gdt - 1 ; Limit (size)
dd gdt ; Address of the GDT
times 510-($-$$) db 0
dw 0AA55h ; Boot sector identifyer