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

194 lines
2.7 KiB
ArmAsm

.file "mbr.S"
#include "def.h"
#define CHAR_LBA_READ '.'
#define CHAR_R 'R'
#define CHAR_S 'S'
#define CHAR_L 'L'
#define CHAR_B 'B'
#define CHAR_G 'G'
#define DBGMSG(c) movb $c, %al; call Lchr
#define puts(s) movw $s, %si; call Lmessage
// 0x07C00 - 0x07DFF BIOS load us here
// 0x07E00 - 0x17BFC using stack
// 0x07A00 - 0x07BFF relocate to here
// 0x07C00 - 0x07DFF load PBR here
.text
.code16
.globl start
start:
// Adjust %cs to be right
ljmp $BOOTSEG, $1f
1:
// set up stack
movw %cs, %ax
// cli
movw %ax, %ss
movw $MBRSTACKOFF, %sp
// set up data segment
movw %ax, %ds
DBGMSG(CHAR_S)
// relocate for PBR
// copy to 0x07a0
movw $BOOTRELOCSEG, %ax
movw %ax, %es
xorw %si, %si
xorw %di, %di
movw $0x200, %cx // Move (E)CX words from DS:[(E)SI] to ES:[(E)DI]
cld
rep movsb
// jump to relocated self
ljmp $BOOTRELOCSEG, $reloc
reloc:
DBGMSG(CHAR_R)
pushw %ds
popw %es
pushw %cs
popw %ds
testb $DOSACTIVE, %dl
jnz drive_ok
puts(efdmbr)
jmp stay_stopped
drive_ok:
movw $pt, %si
movw $NDOSPART, %cx
find_active:
DBGMSG(CHAR_L)
movb (%si), %al
cmpb $DOSACTIVE, %al
je found
addw $PARTSZ, %si
loop find_active
no_part:
movw $enoboot, %si
err_stop:
call Lmessage
stay_stopped:
sti
hlt
jmp stay_stopped
found:
DBGMSG(CHAR_B)
movb %dl, %al
andb $0x0f, %al
addb $'0', %al
movb %al, drive_num
movb $'0'+4, %al
subb %cl, %al
movb %al, part_num
pushw %si
movw $info, %si
call Lmessage
popw %si
movw $0, %es:signature(,1)
movb %dl, (%si)
movw $0x55AA, %bx
movb $0x41, %ah
int $0x13
movb (%si), %dl
jc read_error
cmpw $0xAA55, %bx
jne read_error
testb $0x01, %cl
jz read_error
do_lba:
movb $CHAR_LBA_READ, %al
call Lchr
movl 8(%si), %ecx
movl %ecx, lba_sector
pushw %si
movb $0x42, %ah
movw $lba_command, %si
int $0x13
popw %si
jnc booting_os
read_error:
movw $eread, %si
jmp err_stop
booting_os:
puts(crlf)
cmpw $DOSMBR_SIGNATURE, %es:signature(,1)
jne missing_os
ljmp $0, $BOOTSEG << 4
missing_os:
movw $enoos, %si
jmp err_stop
Lmessage:
pushw %ax
cld
1:
lodsb
testb %al, %al
jz 1f
call Lchr
jmp 1b
Lchr:
pushw %ax
pushw %bx
movb $0x0e, %ah
movw $1, %bx
int $0x10
popw %bx
1: popw %ax
ret
lba_command:
.byte 0x10
.byte 0x00
.word 0x0001
.word 0
.word BOOTSEG
lba_sector:
.long 0, 0
info: .ascii "Using drive "
drive_num:
.byte 'X'
.ascii ", partition "
part_num:
.asciz "Y"
efdmbr: .asciz "MBR on floppy of old BIOS\r\n"
eread: .asciz "\r\nRead error\r\n"
enoos: .asciz "No O/S\r\n"
enoboot: .ascii "No active partion"
crlf: .asciz "\r\n"
endofcode:
nop
// partion table
. = DOSPARTOFF // partion table start address
pt: .fill 0x40,1,0
. = 0x1fe
signature:
.short DOSMBR_SIGNATURE
. = 0x200