123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- #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
|