+++ /dev/null
-#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