mirror of
https://github.com/xcat2/xNBA.git
synced 2024-12-15 15:51:44 +00:00
844d088c51
(including logical partitions).
191 lines
3.3 KiB
ArmAsm
191 lines
3.3 KiB
ArmAsm
#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:
|
|
xchgw %bx,%bx
|
|
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
|