123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- #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
-
- /* Check for LBA extensions */
- movb $0x41, %ah
- movw $0x55aa, %bx
- stc
- int $0x13
- jc 1f
- cmpw $0xaa55, %bx
- jne 1f
- movw $read_lba, read_sectors
- 1:
- /* 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
- jmp boot_error
- 10: .asciz "Could not locate active partition\r\n"
-
- /*
- * Print failure message and boot next device
- *
- * Parameters:
- * %si : Failure string
- */
- boot_error:
- cld
- movw $0x0007, %bx
- movb $0x0e, %ah
- 1: lodsb
- testb %al, %al
- je 99f
- int $0x10
- jmp 1b
- 99: /* Boot next device */
- int $0x18
-
- /*
- * 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
- call read_boot_sector
- jc 99f
- movw $446, %bx
- 1: 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_boot_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
- /* Reload original partition table */
- call read_boot_sector
- ret
-
- /*
- * Read single sector to %es:0000 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_boot_sector:
- pushw %ax
- movw $1, %ax
- call *read_sectors
- jc 99f
- cmpw $0xaa55, %es:(510)
- je 99f
- stc
- 99: popw %ax
- ret
-
- /*
- * Read sectors to %es:0000
- *
- * 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
- * %ax : Number of sectors (max 127)
- *
- * Returns:
- * CF set on error
- */
- read_sectors: .word read_chs
-
- read_chs:
- /* Read sectors using C/H/S address */
- pushal
- xorw %bx, %bx
- movb $0x02, %ah
- stc
- int $0x13
- sti
- popal
- ret
-
- read_lba:
- /* Read sectors using LBA address */
- pushal
- movw %ax, (lba_desc + 2)
- pushw %es
- popw (lba_desc + 6)
- movl %edi, (lba_desc + 8)
- movl %esi, (lba_desc + 12)
- movw $lba_desc, %si
- movb $0x42, %ah
- int $0x13
- popal
- ret
-
- lba_desc:
- .byte 0x10
- .byte 0
- .word 1
- .word 0x0000
- .word 0x0000
- .long 0, 0
|