rendered paste body;*********************************************************
; RootOS - Bootloader / A20
; Author: Simon Wollwage a.k.a. rootnode
;*********************************************************
%ifndef __A20_INCLUDED_
%define __A20_INCLUDED_
bits 16
global _enable_a20
_enable_a20:
pusha
cli
mov cx, 5
.enable_a20_start:
.kbrd_cntrl_wait:
xor ax, ax
in al, 64h
bt ax, 1
jc .kbrd_cntrl_wait
mov al, 0dfh
out 64h, al
.kbrd_cntrl_wait_2:
xor ax, ax
in al, 64h
bt ax, 1
jc .kbrd_cntrl_wait_2
.kbrd_cntrl_get_state:
xor ax, ax
in al, 60h
bt ax, 1
jc .enable_a20_success
loop .enable_a20_start
jmp .enable_a20_fail
.enable_a20_success:
popa
xor eax, eax
ret
.enable_a20_fail:
popa
mov eax, -1
ret
%endif
;*********************************************************
; RootOS - Bootloader / Global Descriptor Table
; Author: Simon Wollwage a.k.a. rootnode
;*********************************************************
%ifndef __GDT_INC_F458AD93BB62943A_INCLUDED_
%define __GDT_INC_F458AD93BB62943A_INCLUDED_
bits 16
install_gdt:
cli
pusha
lgdt [toc]
sti
popa
ret
gdt_data:
dd 0 ; null descriptor
dd 0
; gdt code:
dw 0FFFFh ; limit low
dw 0 ; base low
db 0 ; base middle
db 10011010b ; access
db 11001111b ; granularity
db 0 ; base high
; gdt data: ; data descriptor
dw 0FFFFh ; limit low (Same as code)10:56 AM 7/8/2007
dw 0 ; base low
db 0 ; base middle
db 10010010b ; access
db 11001111b ; granularity
db 0 ; base high
end_of_gdt:
toc:
dw end_of_gdt - gdt_data - 1 ; limit (Size of GDT)
dd gdt_data ; base of GDT
%endif
;*********************************************************
; RootOS - Bootloader / Input-/Output routines
; Author: Simon Wollwage a.k.a. rootnode
;*********************************************************
%ifndef __STDIO_INC_F458AD93BB62943A_INCLUDED_
%define __STDIO_INC_F458AD93BB62943A_INCLUDED_
;*********************************************************
; Output routines for 16 bit unprotected mode
bits 16
puts16:
pusha
.loop_16:
lodsb
or al, al
jz puts16_done
mov ah, 0eh
int 10h
jmp .loop_16
puts16_done:
popa
ret
;*********************************************************
; Output routines for 32 bit PMode
bits 32
%define VIDMEM 0xB8000
%define COLS 80
%define LINES 25
;%define CHAR_ATTRIB 31 ; blue/white
%define CHAR_ATTRIB 10
_cur_x db 0
_cur_y db 0
putch32:
pusha
mov edi, VIDMEM
;*********************************************************
; Retrieve position
xor eax, eax
mov ecx, COLS * 2
mov al, byte [_cur_y]
mul ecx
push eax
mov al, byte [_cur_x]
mov cl, 2
mul cl
pop ecx
add eax, ecx
xor ecx, ecx
add edi, eax
;*********************************************************
; Search for newline
cmp bl, 0x0A
je .row
mov dl, bl
mov dh, CHAR_ATTRIB
mov word [edi], dx
inc byte [_cur_x]
;cmp byte [_cur_x], COLS
;je .row
jmp .done
.row:
mov byte [_cur_x], 0
inc byte [_cur_y]
.done:
popa
ret
bits 32
puts32:
pusha
push ebx
pop edi
.loop:
mov bl, byte [edi]
cmp bl, 0
je .done
call putch32
.next:
inc edi
jmp .loop
.done:
mov bh, byte [_cur_y]
mov bl, byte [_cur_x]
call mov_cur
popa
ret
mov_cur:
pusha
xor eax, eax
mov ecx, COLS
mov al, bh
mul ecx
add al, bl
mov ebx, eax
mov al, 0x0F
mov dx, 0x03D4
out dx, al
mov al, bl
mov dx, 0x03D5
out dx, al
xor eax, eax
mov al, 0x0E
mov dx, 0x03D4
out dx, al
mov al, bh
mov dx, 0x03D5
out dx, al
popa
ret
bits 32
space db ' ', 0x0A, 0
clrscr32:
pusha
mov byte [_cur_x], 0
mov byte [_cur_y], 0
mov ecx, LINES
.loop:
lea ebx, [space]
call puts32
loopz .loop
mov byte [_cur_x], 0
mov byte [_cur_y], 0
popa
ret
%endif
;*********************************************************
; RootOS - Bootloader / Stage 1
; Author: Simon Wollwage a.k.a. rootnode
;*********************************************************
;*********************************************************
; Since we are running on x86, we have to start in
; 16 bit mode
bits 16
;*********************************************************
; Set the origin to the beginning of the bootloader memory section
; Beginning of sector 1
org 0
;*********************************************************
; Jump over the definitions directly to the loader
start: jmp main
;*********************************************************
; fill up to have 512 bytes in size
; TIMES 0Bh - $ + Start db 0
;*********************************************************
bpbOEM db "RootOS " ; This member must be exactly 8 bytes
;*********************************************************
; some constants for a FAT File System
bpbBytesPerSector: dw 512
bpbSectorsPerCluster: db 1
bpbReservedSectors: dw 1
bpbNumberOfFATs: db 2
bpbRootEntries: dw 224
bpbTotalSectors: dw 2880
bpbMeda: db 0xF0
bpbSectorsPerFAT: dw 9
bpbSectorsPerTrack: dw 18
bpbHeadsPerCylinder: dw 2
bpbHiddenSectors: dd 0
bpbTotalSectorsBig: dd 0
bsDriveNumber: db 0
bsUnused: db 0
bsExtBootSignature: db 0x29
bsSerialNumber: dd 0xA0A1A2A3
bsVolumeLabel: db "MOS FLOPPY "
bsFileSystem: db "FAT12 "
print:
lodsb
or al, al
jz printdone
mov ah, 0eh
int 10h
jmp print
printdone:
ret
absoluteSector db 0x00
absoluteHead db 0x00
absoluteTrack db 0x00
;*********************************************************
; Converts CHS to LBA
Cluster2LBA:
sub ax, 0x0002
xor cx, cx
mov cl, BYTE [bpbSectorsPerCluster]
mul cx
add ax, WORD [dataSector]
ret
;*********************************************************
; Converts LBA to CHS
lba2chs:
xor dx, dx
div WORD [bpbSectorsPerTrack]
inc dl
mov BYTE [absoluteSector], dl
xor dx, dx
div WORD [bpbHeadsPerCylinder]
mov BYTE [absoluteHead], dl
mov BYTE [absoluteTrack], al
ret
;*********************************************************
; Read sectors
readsectors:
.main
mov di, 0x0005 ; Allow at most five error retries
.sectorloop
push ax
push bx
push cx
call lba2chs ; convert first sector to LBA format
mov ah, 0x02 ; BIOS read sector
mov al, 0x01 ; read sector
mov ch, BYTE [absoluteTrack] ; get track
mov cl, BYTE [absoluteSector] ; get sector
mov dh, BYTE [absoluteHead] ; get head
mov dl, BYTE [bsDriveNumber] ; get drive
int 0x13 ; call bios
jnc .success ; test for errors
xor ax, ax ; reset the disk
int 0x13 ; call bios
dec di ; dec error count
pop cx ; restore registers
pop bx ; "
pop ax ; "
jnz .sectorloop ; read again
int 0x18
.success
mov si, sProgress
call print
pop cx
pop bx
pop ax
add bx, WORD [bpbBytesPerSector]
inc ax
loop .main
ret
;*********************************************************
; Bootloader Entry point
main:
cli ; turn off interrupts
mov ax, 0x07C0
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
;*********************************************************
; Create the stack
mov ax, 0x0000
mov ss, ax
mov sp, 0xFFFF
sti ; turn on interrupts
;*********************************************************
; Display loading screen
mov si, sLoadingMessage
call print
;*********************************************************
; Load root directory descritpr table
load_root:
xor cx, cx
xor dx, dx
mov ax, 0x0020
mul WORD [bpbRootEntries]
div WORD [bpbBytesPerSector]
xchg ax, cx
mov al, BYTE [bpbNumberOfFATs]
mul WORD [bpbSectorsPerFAT]
add ax, WORD [bpbReservedSectors]
mov WORD [dataSector], ax
add WORD [dataSector], cx
mov bx, 0x0200
call readsectors
;*********************************************************
; Find stage 2 loader
mov cx, WORD [bpbRootEntries]
mov di, 0x0200
.loop:
push cx
mov cx, 0x000B
mov si, ImageName
push di
rep cmpsb
pop di
je load_fat
pop cx
add di, 0x0020
loop .loop
jmp failure
load_fat:
mov si, sCLRF
call print
mov dx, WORD [di + 0x001A]
mov WORD [cluster], dx
xor ax, ax
mov al, BYTE [bpbNumberOfFATs]
mul WORD [bpbSectorsPerFAT]
mov cx, ax
mov ax, WORD [bpbReservedSectors]
mov bx, 0x0200
call readsectors
mov si, sCLRF
call print
mov ax, 0x0050
mov es, ax
mov bx, 0x0000
push bx
;*********************************************************
; Load stage 2
load_image:
mov ax, WORD [cluster]
pop bx
call Cluster2LBA
xor cx, cx
mov cl, BYTE [bpbSectorsPerCluster]
call readsectors
push bx
;*********************************************************
; Process to next cluster
mov ax, WORD [cluster]
mov cx, ax
mov dx, ax
shr dx, 0x0001
add cx, dx
mov bx, 0x0200
add bx, cx
mov dx, WORD [bx]
test ax, 0x0001
jnz .odd_cluster
.even_cluster:
and dx, 0000111111111111b
jmp .done
.odd_cluster:
shr dx, 0x0004
.done:
mov WORD [cluster], dx
cmp dx, 0x0FF0
jb load_image
done:
mov si, sCLRF
call print
push WORD 0x0050
push WORD 0x0000
retf
failure:
mov si, sFailure
call print
mov ah, 0x00
int 0x16
int 0x19
dataSector dw 0x0000
cluster dw 0x0000
ImageName db "STAGE2 SYS"
sLoadingMessage db 0x0D, 0x0A, "Loading boot image ", 0x0D, 0x0A, 0x00
sCLRF db 0x0D, 0x0A, 0x00
sProgress db "*", 0x00
sFailure db 0x0D, 0x0A, "ERROR: Please press any key to reboot", 0x00
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; fill up the rest of the 512 byte
times 510 - ($-$$) db 0
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; This signature is needed!
; Without it, the BIOS won't recognize us as a bootloader
dw 0xAA55