2
0
mirror of https://github.com/xcat2/xNBA.git synced 2024-12-15 15:51:44 +00:00
xNBA/src/arch/i386/prefix/bootpart.S

190 lines
3.2 KiB
ArmAsm
Raw Normal View History

#define BOOT_SEG 0x07c0
#define EXEC_SEG 0x0100
#define STACK_SEG 0x0200
#define STACK_SIZE 0x2000
.text
.arch i386
.section ".prefix", "awx", @progbits
.code16
/*
* Find active partition
*
* Parameters:
* %dl : BIOS drive number
* %bp : Active partition handler routine
*/
find_active_partition:
/* Set up stack at STACK_SEG:STACK_SIZE */
movw $STACK_SEG, %ax
movw %ax, %ss
movw $STACK_SIZE, %sp
/* Relocate self to EXEC_SEG */
pushw $BOOT_SEG
popw %ds
pushw $EXEC_SEG
popw %es
xorw %si, %si
xorw %di, %di
movw $0x200, %cx
rep movsb
ljmp $EXEC_SEG, $1f
1: pushw %ds
popw %es
pushw %cs
popw %ds
/* Read and process root partition table */
xorb %dh, %dh
movw $0x0001, %cx
xorl %esi, %esi
xorl %edi, %edi
call process_table
/* Print failure message */
movw $10f, %si
movw $(20f-10f), %cx
1: movw $0x0007, %bx
movb $0x0e, %ah
lodsb
int $0x10
loop 1b
/* Boot next device */
int $0x18
10: .ascii "Could not locate active partition\r\n"
20:
/*
* Process partition table
*
* Parameters:
* %dl : BIOS drive number
* %dh : Head
* %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
* %ch : Low eight bits of cylinder
* %esi:%edi : LBA address
* %bp : Active partition handler routine
*
* Returns:
* CF set on error
*/
process_table:
pushal
movw $446, %bx
1: call read_sector
jc 99f
call process_partition
addw $16, %bx
cmpw $510, %bx
jne 1b
99: popal
ret
/*
* Process partition
*
* Parameters:
* %dl : BIOS drive number
* %dh : Head
* %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
* %ch : Low eight bits of cylinder
* %esi:%edi : LBA address
* %bx : Offset within partition table
* %bp : Active partition handler routine
*/
process_partition:
pushal
/* Load C/H/S values from partition entry */
movb %es:1(%bx), %dh
movw %es:2(%bx), %cx
/* Update LBA address from partition entry */
addl %es:8(%bx), %edi
adcl $0, %esi
/* Check active flag */
testb $0x80, %es:(%bx)
jz 1f
call read_sector
jc 99f
jmp *%bp
1: /* Check for extended partition */
movb %es:4(%bx), %al
cmpb $0x05, %al
je 2f
cmpb $0x0f, %al
je 2f
cmpb $0x85, %al
jne 99f
2: call process_table
99: popal
ret
/*
* Read single sector to 0000:7c00 and verify 0x55aa signature
*
* Parameters:
* %dl : BIOS drive number
* %dh : Head
* %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
* %ch : Low eight bits of cylinder
* %esi:%edi : LBA address
*
* Returns:
* CF set on error
*/
read_sector:
pushal
/* Check for LBA extensions */
call check_lba
jnc read_lba
read_chs:
/* Read sector using C/H/S address */
movw $0x0201, %ax
xorw %bx, %bx
stc
int $0x13
sti
jmp 99f
read_lba:
/* Read sector using LBA address */
movb $0x42, %ah
movl %esi, (lba_desc + 12)
movl %edi, (lba_desc + 8)
movw $lba_desc, %si
int $0x13
99: /* Check for 55aa signature */
jc 99f
cmpw $0xaa55, %es:(510)
je 99f
stc
99: popal
ret
lba_desc:
.byte 0x10
.byte 0
.word 1
.word 0x0000
.word 0x07c0
.long 0, 0
/*
* Check for LBA extensions
*
* Parameters:
* %dl : BIOS drive number
*
* Returns:
* CF clear if LBA extensions supported
*/
check_lba:
pushal
movb $0x41, %ah
movw $0x55aa, %bx
stc
int $0x13
jc 99f
cmpw $0xaa55, %bx
je 99f
stc
99: popal
ret