bootloader/biosboot/biosboot.S
2024-11-27 17:06:47 +09:00

204 lines
3.3 KiB
ArmAsm

.file "biosboot.S"
#include "def.h"
// 0x00000 -> 0x07BFF our stack (to 31k)
// 0x07A00 -> 0x07BFF typical MBR loc (at 30k5)
// 0x07C00 -> 0x07DFF our code biosboot (at 31k)
// 0x07E00 -> ... /boot inode block (at 31k5)
// 0x07E00 -> ... (indirect block if nec)
// 0x40000 -> ... /boot (at 256k)
#define PBR_READ_ERROR 'R'
#define PBR_CANT_BOOT 'X'
#define PBR_BAD_MAGIC 'M'
#define PBR_TOO_MANY_INDIRECTS 'I'
#define CHAR_BLOCK_READ '.'
#define putc(c) movb $c, %al; call Lchr
#define puts(s) movw $s, %si; call Lmessage
.globl start_cluster, dst_seg_off
.globl spc_sqrt, clu_off
.globl part_offset, shift_magic, and_magic
.type start_cluster, @function
.type dst_seg_off, @function
.type spc_sqrt, @function
.type clu_off, @function
.type part_offset, @function
.type shift_magic, @function
.type and_magic, @function
.text
.code16
.globl _start
_start:
jmp begin
nop
. = _start + 0x1c
ebpb: .long 16 /* hidden sectors */
.long 0 /* large sectors */
.word 0 /* physical disk */
.byte 0x29 /* signature, needed by NT */
.space 4, 0 /* volume serial number */
.asciz "YO LABEL"
.asciz "FAT 16"
. = _start + 0x3e
begin:
ljmp $BOOTSEG, $main
cant_boot:
movb $PBR_CANT_BOOT, %al
jmp err_print_crlf
main:
xorw %ax, %ax
movw %ax, %ss
movw $BOOTSTACKOFF, %sp
// data segment == code segment
pushw %cs
popw %ds
movw $load_msg, %si
call Lmessage
testb $0x80, %dl
jz cant_boot
load_boot:
start_cluster = .+1
movw $0x9090, %ax
movw $LOADSEG, %bx // destination
movw %bx, %di
movw $FATSEG, %cx
movw %cx, %es
1:
call read_cluster
read_fat:
pushw %ax
shift_magic = .+1
movb $0x90, %cl
shrw %cl, %ax
addw %ds:0x0e, %ax
movw $FATSEG, %bx
call read_sector
popw %cx
and_magic = .+2
andw $0x9090, %cx
movw %es:(,%ecx, 2), %ax
cmpw $0xFFF7, %ax
jb 1b
jmp done_load
read_cluster:
pushw %ax
spc_sqrt = .+2
shlw $0x90, %ax
clu_off = .+1
addw $0x9090, %ax
movzb %ds:0x0d, %cx
1:
call read_sector
incw %ax
dst_seg_off = .+2
addw $0x9090, %bx
loop 1b
popw %ax
ret
read_sector:
pushw %ax
movw %bx, lba_dst_seg
part_offset = .+1
addw $0x9090, %ax
movl %eax, lba_src_low
movw $lba_command, %si
do_int_13:
movb $0x42, %ah
int $0x13
jc read_error
popw %ax
ret
read_error:
movb $PBR_READ_ERROR, %al
err_print_crlf:
movw $err_txt_crlf, %si
jmp err_print2
call stay_stopped
Lmessage:
cld
1:
lodsb
orb %al, %al
jz 1f
call Lchr
jmp 1b
Lchr:
pushw %bx
movb $0x0e, %ah
xorw %bx, %bx
incw %bx
int $0x10
popw %bx
1:
ret
done_load:
movw $LOADSEG, %ax
movw %ax, %es
cmpl $ELFMAGIC, %es:0(,1)
je exec_boot
movb $PBR_BAD_MAGIC, %al
err_print:
movw $err_txt, %si
err_print2:
movb %al, err_id
err_stop:
call Lmessage
stay_stopped:
sti
hlt
jmp stay_stopped
exec_boot:
movzbl %dl, %eax
pushl %eax
pushl $BOOTMAGIC
ljmp $(LINKADDR >> 4), $0
lba_command:
.byte 0x10 /* size of command packet */
.byte 0x00 /* reserved */
lba_nread_sec:
.word 0x01 // sectors to transfer max 127
lba_dst_offset:
.word 0x00 // target buffer offset
lba_dst_seg:
.word 0x00 // target buffer offset
lba_src_low:
.long 0x00
lba_src_high:
.long 0x00
load_msg: .asciz "Loading"
err_txt_crlf: .ascii "\r\n"
err_txt: .ascii "ERR "
err_id: .ascii "?"
crlf: .asciz "\r\n"
. = 0x200 - 2
.word DOSMBR_SIGNATURE