176d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFILE_LICENCE ( GPL2_OR_LATER ) 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define BOOT_SEG 0x07c0 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define EXEC_SEG 0x0100 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define STACK_SEG 0x0200 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define STACK_SIZE 0x2000 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .text 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .arch i386 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .section ".prefix", "awx", @progbits 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .code16 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Find active partition 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parameters: 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %dl : BIOS drive number 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %bp : Active partition handler routine 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfind_active_partition: 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Set up stack at STACK_SEG:STACK_SIZE */ 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $STACK_SEG, %ax 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw %ax, %ss 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $STACK_SIZE, %sp 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Relocate self to EXEC_SEG */ 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pushw $BOOT_SEG 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman popw %ds 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pushw $EXEC_SEG 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman popw %es 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman xorw %si, %si 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman xorw %di, %di 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $0x200, %cx 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rep movsb 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ljmp $EXEC_SEG, $1f 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman1: pushw %ds 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman popw %es 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pushw %cs 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman popw %ds 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Check for LBA extensions */ 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movb $0x41, %ah 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $0x55aa, %bx 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman stc 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int $0x13 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman jc 1f 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cmpw $0xaa55, %bx 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman jne 1f 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $read_lba, read_sectors 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman1: 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Read and process root partition table */ 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman xorb %dh, %dh 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $0x0001, %cx 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman xorl %esi, %esi 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman xorl %edi, %edi 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman call process_table 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Print failure message */ 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $10f, %si 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman jmp boot_error 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman10: .asciz "Could not locate active partition\r\n" 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Print failure message and boot next device 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parameters: 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %si : Failure string 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanboot_error: 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cld 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $0x0007, %bx 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movb $0x0e, %ah 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman1: lodsb 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman testb %al, %al 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman je 99f 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int $0x10 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman jmp 1b 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman99: /* Boot next device */ 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int $0x18 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Process partition table 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parameters: 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %dl : BIOS drive number 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %dh : Head 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7) 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %ch : Low eight bits of cylinder 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %esi:%edi : LBA address 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %bp : Active partition handler routine 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Returns: 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * CF set on error 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanprocess_table: 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pushal 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman call read_boot_sector 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman jc 99f 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $446, %bx 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman1: call process_partition 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman addw $16, %bx 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cmpw $510, %bx 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman jne 1b 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman99: popal 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ret 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Process partition 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parameters: 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %dl : BIOS drive number 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %dh : Head 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7) 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %ch : Low eight bits of cylinder 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %esi:%edi : LBA address 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %bx : Offset within partition table 11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %bp : Active partition handler routine 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanprocess_partition: 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pushal 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Load C/H/S values from partition entry */ 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movb %es:1(%bx), %dh 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw %es:2(%bx), %cx 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Update LBA address from partition entry */ 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman addl %es:8(%bx), %edi 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman adcl $0, %esi 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Check active flag */ 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman testb $0x80, %es:(%bx) 12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman jz 1f 13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman call read_boot_sector 13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman jc 99f 13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman jmp *%bp 13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman1: /* Check for extended partition */ 13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movb %es:4(%bx), %al 13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cmpb $0x05, %al 13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman je 2f 13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cmpb $0x0f, %al 13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman je 2f 13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cmpb $0x85, %al 14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman jne 99f 14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman2: call process_table 14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman99: popal 14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Reload original partition table */ 14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman call read_boot_sector 14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ret 14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Read single sector to %es:0000 and verify 0x55aa signature 14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parameters: 15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %dl : BIOS drive number 15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %dh : Head 15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7) 15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %ch : Low eight bits of cylinder 15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %esi:%edi : LBA address 15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Returns: 15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * CF set on error 15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanread_boot_sector: 16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pushw %ax 16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $1, %ax 16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman call *read_sectors 16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman jc 99f 16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cmpw $0xaa55, %es:(510) 16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman je 99f 16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman stc 16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman99: popw %ax 16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ret 17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Read sectors to %es:0000 17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Parameters: 17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %dl : BIOS drive number 17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %dh : Head 17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7) 17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %ch : Low eight bits of cylinder 17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %esi:%edi : LBA address 18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %ax : Number of sectors (max 127) 18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Returns: 18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * CF set on error 18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanread_sectors: .word read_chs 18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanread_chs: 18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Read sectors using C/H/S address */ 18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pushal 19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman xorw %bx, %bx 19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movb $0x02, %ah 19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman stc 19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int $0x13 19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sti 19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman popal 19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ret 19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanread_lba: 19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Read sectors using LBA address */ 20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pushal 20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw %ax, (lba_desc + 2) 20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pushw %es 20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman popw (lba_desc + 6) 20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movl %edi, (lba_desc + 8) 20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movl %esi, (lba_desc + 12) 20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $lba_desc, %si 20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movb $0x42, %ah 20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int $0x13 20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman popal 21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ret 21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanlba_desc: 21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .byte 0x10 21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .byte 0 21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .word 1 21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .word 0x0000 21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .word 0x0000 21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .long 0, 0 219