feat: stage0 of a tiny boot loader
This commit is contained in:
parent
3fddd705f8
commit
670a7f3bb4
7
Makefile
7
Makefile
|
@ -4,9 +4,12 @@ TOOLSDIR := $(TOPDIR)/tools
|
|||
|
||||
RM = echo
|
||||
|
||||
SUBDIRS := kernel lib bin
|
||||
SUBDIRS := boot kernel lib bin
|
||||
|
||||
TARGET = stupid.iso stupid.tar.gz
|
||||
TARGET = stupid.tar.gz
|
||||
ifneq ($(OS),Windows_NT)
|
||||
TARGET += stupid.iso
|
||||
endif
|
||||
|
||||
.PHONY: all
|
||||
all: $(TARGET)
|
||||
|
|
22
boot/Makefile
Normal file
22
boot/Makefile
Normal file
|
@ -0,0 +1,22 @@
|
|||
AS = fasm
|
||||
RM = rm
|
||||
|
||||
TARGET = bootcode.bin
|
||||
|
||||
SRCS = boot.asm \
|
||||
const.inc \
|
||||
a20.inc
|
||||
|
||||
.PHONY: all
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(SRCS)
|
||||
$(AS) boot.asm $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(RM) $(TARGET)
|
||||
|
||||
.PHONY: install
|
||||
install: $(TARGET)
|
||||
@ mkdir -p $(DESTDIR)
|
171
boot/a20.inc
Normal file
171
boot/a20.inc
Normal file
|
@ -0,0 +1,171 @@
|
|||
; copy/pasted from https://wiki.osdev.org/A20_Line
|
||||
; .... sorry I was lazy :x
|
||||
|
||||
a20_get_state:
|
||||
pushf
|
||||
push si
|
||||
push di
|
||||
push ds
|
||||
push es
|
||||
|
||||
cli
|
||||
|
||||
xor ax, ax
|
||||
mov ds, ax
|
||||
mov si, 0x500
|
||||
|
||||
not ax
|
||||
mov es, ax
|
||||
mov di, 0x0510
|
||||
|
||||
mov al, [ds:si] ; save old values
|
||||
mov byte [.BufferBelowMB], al
|
||||
mov al, [es:di]
|
||||
mov byte [.BufferOverMB], al
|
||||
|
||||
mov ah, 1 ; check byte [0x00100500] == byte [0x0500]
|
||||
mov byte [ds:si], 0
|
||||
mov byte [es:di], 1
|
||||
mov al, [ds:si]
|
||||
cmp al, [es:di]
|
||||
jne .exit
|
||||
dec ah
|
||||
.exit:
|
||||
mov al, [.BufferBelowMB]
|
||||
mov [ds:si], al
|
||||
mov al, [.BufferOverMB]
|
||||
mov [es:di], al
|
||||
shr ax, 8
|
||||
sti
|
||||
pop es
|
||||
pop ds
|
||||
pop di
|
||||
pop si
|
||||
popf
|
||||
ret
|
||||
|
||||
.BufferBelowMB: db 0
|
||||
.BufferOverMB db 0
|
||||
|
||||
|
||||
a20_query_support:
|
||||
push bx
|
||||
clc
|
||||
|
||||
mov ax, 0x2403
|
||||
int 0x15
|
||||
jc .error
|
||||
|
||||
test ah, ah
|
||||
jnz .error
|
||||
|
||||
mov ax, bx
|
||||
pop bx
|
||||
ret
|
||||
.error:
|
||||
stc
|
||||
pop bx
|
||||
ret
|
||||
|
||||
a20_enable_keyboard_controller:
|
||||
cli
|
||||
|
||||
call .wait_io1
|
||||
mov al, 0xad
|
||||
out 0x64, al
|
||||
|
||||
call .wait_io1
|
||||
mov al, 0xd0
|
||||
out 0x64, al
|
||||
|
||||
call .wait_io2
|
||||
in al, 0x60
|
||||
push eax
|
||||
|
||||
call .wait_io1
|
||||
mov al, 0xd1
|
||||
out 0x64, al
|
||||
|
||||
call .wait_io1
|
||||
pop eax
|
||||
or al, 2
|
||||
out 0x60, al
|
||||
|
||||
call .wait_io1
|
||||
mov al, 0xae
|
||||
out 0x64, al
|
||||
|
||||
call .wait_io1
|
||||
sti
|
||||
ret
|
||||
.wait_io1:
|
||||
in al, 0x64
|
||||
test al, 2
|
||||
jnz .wait_io1
|
||||
ret
|
||||
.wait_io2:
|
||||
in al, 0x64
|
||||
test al, 1
|
||||
jz .wait_io2
|
||||
ret
|
||||
|
||||
; out:
|
||||
; cf - set on error
|
||||
a20_enable:
|
||||
clc ; clear cf
|
||||
pusha
|
||||
mov bh, 0 ; clear bh
|
||||
|
||||
call a20_get_state
|
||||
jc .fast_gate
|
||||
|
||||
test ax, ax
|
||||
jnz .done
|
||||
|
||||
call a20_query_support
|
||||
mov bl, al
|
||||
test bl, 1 ; enable A20 using keyboard controller
|
||||
jnz .keybord_controller
|
||||
|
||||
test bl, 2 ; enable A20 using fast A20 gate
|
||||
jnz .fast_gate
|
||||
.bios_int:
|
||||
mov ax, 0x2401
|
||||
int 0x15
|
||||
jc .fast_gate
|
||||
test ah, ah
|
||||
jnz .failed
|
||||
call a20_get_state
|
||||
test ax, ax
|
||||
jnz .done
|
||||
.fast_gate:
|
||||
in al, 0x92
|
||||
test al, 2
|
||||
jnz .done
|
||||
|
||||
or al, 2
|
||||
and al, 0xfe
|
||||
out 0x92, al
|
||||
|
||||
call a20_get_state
|
||||
test ax, ax
|
||||
jnz .done
|
||||
|
||||
test bh, bh ; test if there was an attempt using the keyboard controller
|
||||
jnz .failed
|
||||
.keybord_controller:
|
||||
call a20_enable_keyboard_controller
|
||||
call a20_get_state
|
||||
test ax, ax
|
||||
jnz .done
|
||||
|
||||
mov bh, 1 ; flag enable attempt with keyboard controller
|
||||
|
||||
test bl, 2
|
||||
jnz .fast_gate
|
||||
jmp .failed
|
||||
.failed:
|
||||
stc
|
||||
.done:
|
||||
popa
|
||||
ret
|
125
boot/boot.asm
Normal file
125
boot/boot.asm
Normal file
|
@ -0,0 +1,125 @@
|
|||
ORG 0x7C00
|
||||
USE16
|
||||
|
||||
jmp short _start
|
||||
nop
|
||||
|
||||
; Boot Record
|
||||
OEM_identifier db 'STUPID '
|
||||
bytes_per_sector dw 512
|
||||
sectors_per_cluster db 1
|
||||
reserved_sectors dw 1
|
||||
FAT_count db 2
|
||||
root_dir_entries dw 224
|
||||
total_sectors dw 2880
|
||||
media_desc_type db 0xF0
|
||||
sectors_per_FAT dw 9
|
||||
sectors_per_track dw 18
|
||||
heads_per_cylinder dw 2
|
||||
hidden_sectors dd 0
|
||||
large_sector_count dd 0
|
||||
|
||||
; Extended Boot Record
|
||||
drive_number db 0
|
||||
reserved db 0x90
|
||||
signature db 0x29 ; 0x28 or 0x29
|
||||
volume_id dd 0xB00B135 ; hope mine will grow :'(
|
||||
volume_label db 'StupidOS '
|
||||
system_id db 'FAT12 '
|
||||
|
||||
|
||||
_start:
|
||||
cli
|
||||
cld
|
||||
jmp 0x0:.canonicalize_cs
|
||||
|
||||
.canonicalize_cs:
|
||||
xor ax, ax
|
||||
mov ds, ax
|
||||
mov ss, ax
|
||||
mov es, ax
|
||||
mov sp, 0x7c00
|
||||
|
||||
; clear screen
|
||||
mov al, 0x03
|
||||
mov ah, 0
|
||||
int 0x10
|
||||
|
||||
mov si, msg_hello
|
||||
call bios_print
|
||||
|
||||
; reset floppy disk
|
||||
@@:
|
||||
xor ah, ah
|
||||
int 0x13
|
||||
jc @b
|
||||
|
||||
mov si, msg_load_stage
|
||||
call bios_print
|
||||
|
||||
; read sector into ES:BX (0100:0000)
|
||||
mov ax, 0x100 ; 100 segment
|
||||
mov es, ax ; 0100:0000 (0000:1000)
|
||||
xor bx, bx
|
||||
|
||||
mov ah, 0x2 ; read
|
||||
mov al, 0x1 ; one sector
|
||||
mov ch, 0x0 ; cylinder 0
|
||||
mov cl, 0x2 ; second sector
|
||||
mov dh, 0x0 ; head 0
|
||||
int 0x13
|
||||
jc .error
|
||||
|
||||
jmp 0x0:0x1000
|
||||
|
||||
.error:
|
||||
mov si, msg_error_sector
|
||||
call bios_print
|
||||
|
||||
hlt
|
||||
jmp $
|
||||
|
||||
bios_print:
|
||||
lodsb
|
||||
or al, al
|
||||
jz @f
|
||||
mov ah, 0x0E
|
||||
int 0x10
|
||||
jmp bios_print
|
||||
@@:
|
||||
ret
|
||||
|
||||
msg_hello db "StupidOS Bootloader", 0x0D, 0x0A, 0
|
||||
msg_load_stage db "Loading next stage", 0x0D, 0x0A, 0
|
||||
msg_error_sector db "ERROR: Can't read sector", 0x0D, 0x0A, 0
|
||||
|
||||
rb 0x7C00+512-2-$
|
||||
db 0x55, 0xAA
|
||||
|
||||
; ---------- stage 1 --------------
|
||||
|
||||
ORG 0x1000
|
||||
stage2:
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov si, msg_stage2
|
||||
call bios_print
|
||||
|
||||
call a20_enable
|
||||
jc .error_a20
|
||||
|
||||
xchg bx, bx
|
||||
|
||||
jmp .hang
|
||||
.error_a20:
|
||||
mov si, msg_error_a20
|
||||
call bios_print
|
||||
.hang:
|
||||
hlt
|
||||
jmp $
|
||||
|
||||
INCLUDE 'a20.inc'
|
||||
|
||||
msg_stage2 db "StupidOS Bootloader (Stage 2)", 0x0D, 0x0A, 0
|
||||
msg_error_a20 db "ERROR: can't enable a20 line", 0x0D, 0x0A, 0
|
8
boot/const.inc
Normal file
8
boot/const.inc
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
; -------- Address ----------
|
||||
STAGE0_BASE = 0x7C00
|
||||
STAGE1_BASE = 0x1000
|
||||
DISK_BUFFER = 0x8000
|
||||
KERNEL_PRELOAD = 0xF000
|
||||
STACK_TOP = 0x7000
|
||||
|
Loading…
Reference in a new issue