|
|
1.1 ! root 1: FILE_LICENCE ( GPL2_OR_LATER ) ! 2: ! 3: #define BOOT_SEG 0x07c0 ! 4: #define EXEC_SEG 0x0100 ! 5: #define STACK_SEG 0x0200 ! 6: #define STACK_SIZE 0x2000 ! 7: ! 8: .text ! 9: .arch i386 ! 10: .section ".prefix", "awx", @progbits ! 11: .code16 ! 12: ! 13: /* ! 14: * Find active partition ! 15: * ! 16: * Parameters: ! 17: * %dl : BIOS drive number ! 18: * %bp : Active partition handler routine ! 19: */ ! 20: find_active_partition: ! 21: /* Set up stack at STACK_SEG:STACK_SIZE */ ! 22: movw $STACK_SEG, %ax ! 23: movw %ax, %ss ! 24: movw $STACK_SIZE, %sp ! 25: ! 26: /* Relocate self to EXEC_SEG */ ! 27: pushw $BOOT_SEG ! 28: popw %ds ! 29: pushw $EXEC_SEG ! 30: popw %es ! 31: xorw %si, %si ! 32: xorw %di, %di ! 33: movw $0x200, %cx ! 34: rep movsb ! 35: ljmp $EXEC_SEG, $1f ! 36: 1: pushw %ds ! 37: popw %es ! 38: pushw %cs ! 39: popw %ds ! 40: ! 41: /* Check for LBA extensions */ ! 42: movb $0x41, %ah ! 43: movw $0x55aa, %bx ! 44: stc ! 45: int $0x13 ! 46: jc 1f ! 47: cmpw $0xaa55, %bx ! 48: jne 1f ! 49: movw $read_lba, read_sectors ! 50: 1: ! 51: /* Read and process root partition table */ ! 52: xorb %dh, %dh ! 53: movw $0x0001, %cx ! 54: xorl %esi, %esi ! 55: xorl %edi, %edi ! 56: call process_table ! 57: ! 58: /* Print failure message */ ! 59: movw $10f, %si ! 60: jmp boot_error ! 61: 10: .asciz "Could not locate active partition\r\n" ! 62: ! 63: /* ! 64: * Print failure message and boot next device ! 65: * ! 66: * Parameters: ! 67: * %si : Failure string ! 68: */ ! 69: boot_error: ! 70: cld ! 71: movw $0x0007, %bx ! 72: movb $0x0e, %ah ! 73: 1: lodsb ! 74: testb %al, %al ! 75: je 99f ! 76: int $0x10 ! 77: jmp 1b ! 78: 99: /* Boot next device */ ! 79: int $0x18 ! 80: ! 81: /* ! 82: * Process partition table ! 83: * ! 84: * Parameters: ! 85: * %dl : BIOS drive number ! 86: * %dh : Head ! 87: * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7) ! 88: * %ch : Low eight bits of cylinder ! 89: * %esi:%edi : LBA address ! 90: * %bp : Active partition handler routine ! 91: * ! 92: * Returns: ! 93: * CF set on error ! 94: */ ! 95: process_table: ! 96: pushal ! 97: call read_boot_sector ! 98: jc 99f ! 99: movw $446, %bx ! 100: 1: call process_partition ! 101: addw $16, %bx ! 102: cmpw $510, %bx ! 103: jne 1b ! 104: 99: popal ! 105: ret ! 106: ! 107: /* ! 108: * Process partition ! 109: * ! 110: * Parameters: ! 111: * %dl : BIOS drive number ! 112: * %dh : Head ! 113: * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7) ! 114: * %ch : Low eight bits of cylinder ! 115: * %esi:%edi : LBA address ! 116: * %bx : Offset within partition table ! 117: * %bp : Active partition handler routine ! 118: */ ! 119: process_partition: ! 120: pushal ! 121: /* Load C/H/S values from partition entry */ ! 122: movb %es:1(%bx), %dh ! 123: movw %es:2(%bx), %cx ! 124: /* Update LBA address from partition entry */ ! 125: addl %es:8(%bx), %edi ! 126: adcl $0, %esi ! 127: /* Check active flag */ ! 128: testb $0x80, %es:(%bx) ! 129: jz 1f ! 130: call read_boot_sector ! 131: jc 99f ! 132: jmp *%bp ! 133: 1: /* Check for extended partition */ ! 134: movb %es:4(%bx), %al ! 135: cmpb $0x05, %al ! 136: je 2f ! 137: cmpb $0x0f, %al ! 138: je 2f ! 139: cmpb $0x85, %al ! 140: jne 99f ! 141: 2: call process_table ! 142: 99: popal ! 143: /* Reload original partition table */ ! 144: call read_boot_sector ! 145: ret ! 146: ! 147: /* ! 148: * Read single sector to %es:0000 and verify 0x55aa signature ! 149: * ! 150: * Parameters: ! 151: * %dl : BIOS drive number ! 152: * %dh : Head ! 153: * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7) ! 154: * %ch : Low eight bits of cylinder ! 155: * %esi:%edi : LBA address ! 156: * ! 157: * Returns: ! 158: * CF set on error ! 159: */ ! 160: read_boot_sector: ! 161: pushw %ax ! 162: movw $1, %ax ! 163: call *read_sectors ! 164: jc 99f ! 165: cmpw $0xaa55, %es:(510) ! 166: je 99f ! 167: stc ! 168: 99: popw %ax ! 169: ret ! 170: ! 171: /* ! 172: * Read sectors to %es:0000 ! 173: * ! 174: * Parameters: ! 175: * %dl : BIOS drive number ! 176: * %dh : Head ! 177: * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7) ! 178: * %ch : Low eight bits of cylinder ! 179: * %esi:%edi : LBA address ! 180: * %ax : Number of sectors (max 127) ! 181: * ! 182: * Returns: ! 183: * CF set on error ! 184: */ ! 185: read_sectors: .word read_chs ! 186: ! 187: read_chs: ! 188: /* Read sectors using C/H/S address */ ! 189: pushal ! 190: xorw %bx, %bx ! 191: movb $0x02, %ah ! 192: stc ! 193: int $0x13 ! 194: sti ! 195: popal ! 196: ret ! 197: ! 198: read_lba: ! 199: /* Read sectors using LBA address */ ! 200: pushal ! 201: movw %ax, (lba_desc + 2) ! 202: pushw %es ! 203: popw (lba_desc + 6) ! 204: movl %edi, (lba_desc + 8) ! 205: movl %esi, (lba_desc + 12) ! 206: movw $lba_desc, %si ! 207: movb $0x42, %ah ! 208: int $0x13 ! 209: popal ! 210: ret ! 211: ! 212: lba_desc: ! 213: .byte 0x10 ! 214: .byte 0 ! 215: .word 1 ! 216: .word 0x0000 ! 217: .word 0x0000 ! 218: .long 0, 0
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.