GAS LISTING /tmp/ccidVAaT.s page 1 1 # 1 "/var/www/html/boot/syslinux/mbr/altmbr.S" 1 /* ----------------------------------------------------------------------- 1 ... 0 0 2 * 3 * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved 4 * Copyright 2009 Intel Corporation; author: H. Peter Anvin 5 * 6 * Permission is hereby granted, free of charge, to any person 7 * obtaining a copy of this software and associated documentation 8 * files (the "Software"), to deal in the Software without 9 * restriction, including without limitation the rights to use, 10 * copy, modify, merge, publish, distribute, sublicense, and/or 11 * sell copies of the Software, and to permit persons to whom 12 * the Software is furnished to do so, subject to the following 13 * conditions: 14 * 15 * The above copyright notice and this permission notice shall 16 * be included in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 * OTHER DEALINGS IN THE SOFTWARE. 26 * 27 * ----------------------------------------------------------------------- */ 28 29 #include "adjust.h" 1 /* -*- asm -*- ----------------------------------------------------------- 2 * 3 * Copyright 2009-2014 Intel Corporation; author: H. Peter Anvin 4 * 5 * Permission is hereby granted, free of charge, to any person 6 * obtaining a copy of this software and associated documentation 7 * files (the "Software"), to deal in the Software without 8 * restriction, including without limitation the rights to use, 9 * copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom 11 * the Software is furnished to do so, subject to the following 12 * conditions: 13 * 14 * The above copyright notice and this permission notice shall 15 * be included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 * OTHER DEALINGS IN THE SOFTWARE. GAS LISTING /tmp/ccidVAaT.s page 2 25 * 26 * ----------------------------------------------------------------------- */ 27 28 /* 29 * adjust.h 30 * 31 * Macros to adjust the drive number 32 */ 33 34 #ifndef ADJUST_H 35 #define ADJUST_H 36 37 #ifdef CTRL_80 38 .macro ADJUST_DRIVE 39 pusha 40 movb $0x02, %ah 41 int $0x16 42 testb $0x04, %al 43 popa 44 jz 1f 45 movb $0x80, %dl 46 1: 47 .endm 48 #elif defined(FORCE_80) 30 31 .code16 32 .text 33 34 .globl bootsec 35 stack = 0x7c00 36 driveno = (stack-6) 37 sectors = (stack-8) 38 secpercyl = (stack-12) 39 40 BIOS_kbdflags = 0x417 41 BIOS_page = 0x462 42 43 /* gas/ld has issues with doing this as absolute addresses... */ 44 .section ".bootsec", "a", @nobits 45 .globl bootsec 46 bootsec: 47 0000 00000000 .space 512 47 00000000 47 00000000 47 00000000 47 00000000 48 49 .text 50 .globl _start 51 _start: 52 0000 33C0 .byte 0x33, 0xc0 /* xorw %ax, %ax */ 53 0002 FA cli 54 0003 8ED8 movw %ax, %ds 55 0005 8ED0 movw %ax, %ss 56 0007 BC007C movw $stack, %sp 57 000a 89E6 movw %sp, %si 58 000c 06 pushw %es /* es:di -> $PnP header */ GAS LISTING /tmp/ccidVAaT.s page 3 59 000d 57 pushw %di 60 000e 8EC0 movw %ax, %es 61 0010 FB sti 62 0011 FC cld 63 64 /* Copy down to 0:0x600 */ 65 0012 BF0000 movw $_start, %di 66 0015 B90001 movw $(512/2), %cx 67 0018 F3A5 rep; movsw 68 69 001a EA1F0000 ljmpw $0, $next 69 00 70 next: 71 72 001f 60B402CD ADJUST_DRIVE 72 16A80461 72 7402B280 73 002b 52 pushw %dx /* dl -> drive number */ 74 75 /* Check to see if we have EBIOS */ 76 002c 52 pushw %dx /* drive number */ 77 002d B441 movb $0x41, %ah /* %al == 0 already */ 78 002f BBAA55 movw $0x55aa, %bx 79 0032 31C9 xorw %cx, %cx 80 0034 30F6 xorb %dh, %dh 81 0036 F9 stc 82 0037 CD13 int $0x13 83 0039 7213 jc 1f 84 003b 81FB55AA cmpw $0xaa55, %bx 85 003f 750D jne 1f 86 0041 D1E9 shrw %cx /* Bit 0 = fixed disk subset */ 87 0043 7309 jnc 1f 88 89 /* We have EBIOS; patch in the following code at 90 read_sector_cbios: movb $0x42, %ah ; jmp read_common */ 91 0045 66C70699 movl $0xeb42b4+((read_common-read_sector_cbios-4) << 24), \ 91 00B442EB 91 15 92 (read_sector_cbios) 93 94 1: 95 004e 5A popw %dx 96 97 /* Get (C)HS geometry */ 98 004f B408 movb $0x08, %ah 99 0051 CD13 int $0x13 100 0053 83E13F andw $0x3f, %cx /* Sector count */ 101 0056 51 pushw %cx /* Save sectors on the stack */ 102 0057 0FB6C6 movzbw %dh, %ax /* dh = max head */ 103 005a 40 incw %ax /* From 0-based max to count */ 104 005b F7E1 mulw %cx /* Heads*sectors -> sectors per cylinder */ 105 106 /* Save sectors/cylinder on the stack */ 107 005d 52 pushw %dx /* High word */ 108 005e 50 pushw %ax /* Low word */ 109 110 005f 6631C0 xorl %eax, %eax /* Base */ GAS LISTING /tmp/ccidVAaT.s page 4 111 0062 6699 cdq /* Root (%edx <- 0) */ 112 0064 E86600 call scan_partition_table 113 114 /* If we get here, we have no OS */ 115 missing_os: 116 0067 E81001 call error 117 006a 4D697373 .ascii "Missing operating system.\r\n" 117 696E6720 117 6F706572 117 6174696E 117 67207379 118 119 /* 120 * read_sector: read a single sector pointed to by %eax to 0x7c00. 121 * CF is set on error. All registers saved. 122 */ 123 read_sector: 124 0085 6660 pushal 125 0087 6631D2 xorl %edx, %edx 126 008a BB0000 movw $bootsec, %bx 127 008d 6652 pushl %edx /* MSW of LBA */ 128 008f 6650 pushl %eax /* LSW of LBA */ 129 0091 06 pushw %es /* Buffer segment */ 130 0092 53 pushw %bx /* Buffer offset */ 131 0093 6A01 pushw $1 /* Sector count */ 132 0095 6A10 pushw $16 /* Size of packet */ 133 0097 89E6 movw %sp, %si 134 135 /* This chunk is skipped if we have ebios */ 136 /* Do not clobber %eax before this chunk! */ 137 /* This also relies on %bx and %edx as set up above. */ 138 read_sector_cbios: 139 0099 66F736F4 divl (secpercyl) 139 7B 140 009e C0E406 shlb $6, %ah 141 00a1 88E1 movb %ah, %cl 142 00a3 88C5 movb %al, %ch 143 00a5 92 xchgw %dx, %ax 144 00a6 F636F87B divb (sectors) 145 00aa 88C6 movb %al, %dh 146 00ac 08E1 orb %ah, %cl 147 00ae 41 incw %cx /* Sectors are 1-based */ 148 00af B80102 movw $0x0201, %ax 149 150 read_common: 151 00b2 8A16FA7B movb (driveno), %dl 152 00b6 CD13 int $0x13 153 00b8 8D6410 leaw 16(%si), %sp /* Drop DAPA */ 154 00bb 6661 popal 155 00bd C3 ret 156 157 /* 158 * read_partition_table: 159 * Read a partition table (pointed to by %eax), and copy 160 * the partition table into the ptab buffer. 161 * 162 * Clobbers %si, %di, and %cx, other registers preserved. GAS LISTING /tmp/ccidVAaT.s page 5 163 * %cx = 0 on exit. 164 * 165 * On error, CF is set and ptab is overwritten with junk. 166 */ 167 ptab = _start+446 168 169 read_partition_table: 170 00be E8C4FF call read_sector 171 00c1 BEBE01 movw $bootsec+446, %si 172 00c4 BFBE01 movw $ptab, %di 173 00c7 B92000 movw $(16*4/2), %cx 174 00ca F3A5 rep ; movsw 175 00cc C3 ret 176 177 /* 178 * scan_partition_table: 179 * Scan a partition table currently loaded in the partition table 180 * area. Preserve all registers. 181 * 182 * On entry: 183 * %eax - base (location of this partition table) 184 * %edx - root (offset from MBR, or 0 for MBR) 185 * 186 * These get pushed into stack slots: 187 * 28(%bp) - %eax - base 188 * 20(%bp) - %edx - root 189 */ 190 191 scan_partition_table: 192 00cd 6660 pushal 193 00cf 89E5 movw %sp, %bp 194 195 /* Scan the primary partition table */ 196 00d1 BEBE01 movw $ptab, %si 197 00d4 B90400 movw $4, %cx 198 /* Is it a primary partition table? */ 199 00d7 6621D2 andl %edx, %edx 200 00da 750F jnz 7f 201 00dc 56 push %si 202 00dd 51 push %cx 203 204 5: 205 00de FE0EB701 decb (partition) 206 00e2 7449 jz boot 207 00e4 83C610 addw $16, %si 208 00e7 E2F5 loopw 5b 209 210 00e9 59 popw %cx /* %cx <- 4 */ 211 00ea 5E popw %si /* %si <- ptab */ 212 213 /* No primary partitions found, look for extended/logical partitions */ 214 7: 215 00eb 8A4404 movb 4(%si), %al 216 00ee 20C0 andb %al, %al 217 00f0 7433 jz 12f /* Not a valid partition */ 218 00f2 3C0F cmpb $0x0f, %al /* 0x0f = Win9x extended */ 219 00f4 7406 je 8f GAS LISTING /tmp/ccidVAaT.s page 6 220 00f6 247F andb $~0x80, %al /* 0x85 = Linux extended */ 221 00f8 3C05 cmpb $0x05, %al /* 0x05 = MS-DOS extended */ 222 00fa 751E jne 9f 223 224 /* It is an extended partition. Read the extended partition and 225 try to scan it. If the scan returns, re-load the current 226 partition table and resume scan. */ 227 8: 228 00fc 668B4408 movl 8(%si), %eax /* Partition table offset */ 229 0100 6601D0 addl %edx, %eax /* Compute location of new ptab */ 230 0103 6621D2 andl %edx, %edx /* Is this the MBR? */ 231 0106 7503 jnz 10f 232 0108 6689C2 movl %eax, %edx /* Offset -> root if this was MBR */ 233 10: 234 010b E8B0FF call read_partition_table 235 010e 7203 jc 11f 236 0110 E8BAFF call scan_partition_table 237 11: 238 /* This returned, so we need to reload the current partition table */ 239 0113 668B461C movl 28(%bp), %eax /* "Base" */ 240 0117 E8A4FF call read_partition_table 241 242 /* fall through */ 243 9: 244 /* Not an extended partition */ 245 011a 6621D2 andl %edx, %edx /* Are we inside an extended part? */ 246 011d 7406 jz 12f 247 /* If so, this is a logical partition */ 248 011f FE0EB701 decb (partition) 249 0123 7408 je boot 250 12: 251 0125 83C610 addw $16, %si 252 0128 E2C1 loopw 7b 253 254 /* Nothing found, return */ 255 012a 6661 popal 256 012c C3 ret 257 258 /* 259 * boot: invoke the actual bootstrap. (%si) points to the partition 260 * table entry, and 28(%bp) has the partition table base. 261 */ 262 boot: 263 012d 807C0400 cmpb $0, 4(%si) 264 0131 0F8432FF je missing_os 265 0135 668B4408 movl 8(%si), %eax 266 0139 6603461C addl 28(%bp), %eax 267 013d 66894408 movl %eax, 8(%si) /* Adjust in-memory partition table entry */ 268 0141 E841FF call read_sector 269 0144 7213 jc disk_error 270 0146 813EFE01 cmpw $0xaa55, (bootsec+510) 270 55AA 271 014c 0F8517FF jne missing_os /* Not a valid boot sector */ 272 0150 BCFA7B movw $driveno, %sp /* driveno == bootsec-6 */ 273 0153 5A popw %dx /* dl -> drive number */ 274 0154 5F popw %di /* es:di -> $PnP vector */ 275 0155 07 popw %es GAS LISTING /tmp/ccidVAaT.s page 7 276 0156 FA cli 277 0157 FFE4 jmpw *%sp /* %sp == bootsec */ 278 279 disk_error: 280 0159 E81E00 call error 281 015c 4F706572 .ascii "Operating system load error.\r\n" 281 6174696E 281 67207379 281 7374656D 281 206C6F61 282 283 /* 284 * Print error messages. This is invoked with "call", with the 285 * error message at the return address. 286 */ 287 error: 288 017a 5E popw %si 289 2: 290 017b AC lodsb 291 017c B40E movb $0x0e, %ah 292 017e 8A3E6204 movb (BIOS_page), %bh 293 0182 B307 movb $0x07, %bl 294 0184 CD10 int $0x10 /* May destroy %bp */ 295 0186 3C0A cmpb $10, %al /* Newline? */ 296 0188 75F1 jne 2b 297 298 018a CD18 int $0x18 /* Boot failure */ 299 die: 300 018c F4 hlt 301 018d EBFD jmp die 302 303 /* Location of the partition configuration byte */ 304 partition = _start + 439 GAS LISTING /tmp/ccidVAaT.s page 8 DEFINED SYMBOLS /var/www/html/boot/syslinux/mbr/altmbr.S:46 .bootsec:0000000000000000 bootsec /var/www/html/boot/syslinux/mbr/altmbr.S:35 *ABS*:0000000000007c00 stack /var/www/html/boot/syslinux/mbr/altmbr.S:36 *ABS*:0000000000007bfa driveno /var/www/html/boot/syslinux/mbr/altmbr.S:37 *ABS*:0000000000007bf8 sectors /var/www/html/boot/syslinux/mbr/altmbr.S:38 *ABS*:0000000000007bf4 secpercyl /var/www/html/boot/syslinux/mbr/altmbr.S:40 *ABS*:0000000000000417 BIOS_kbdflags /var/www/html/boot/syslinux/mbr/altmbr.S:41 *ABS*:0000000000000462 BIOS_page /var/www/html/boot/syslinux/mbr/altmbr.S:51 .text:0000000000000000 _start /var/www/html/boot/syslinux/mbr/altmbr.S:70 .text:000000000000001f next /var/www/html/boot/syslinux/mbr/altmbr.S:150 .text:00000000000000b2 read_common /var/www/html/boot/syslinux/mbr/altmbr.S:138 .text:0000000000000099 read_sector_cbios /var/www/html/boot/syslinux/mbr/altmbr.S:191 .text:00000000000000cd scan_partition_table /var/www/html/boot/syslinux/mbr/altmbr.S:115 .text:0000000000000067 missing_os /var/www/html/boot/syslinux/mbr/altmbr.S:287 .text:000000000000017a error /var/www/html/boot/syslinux/mbr/altmbr.S:123 .text:0000000000000085 read_sector /var/www/html/boot/syslinux/mbr/altmbr.S:51 .text:00000000000001be ptab /var/www/html/boot/syslinux/mbr/altmbr.S:169 .text:00000000000000be read_partition_table /var/www/html/boot/syslinux/mbr/altmbr.S:51 .text:00000000000001b7 partition /var/www/html/boot/syslinux/mbr/altmbr.S:262 .text:000000000000012d boot /var/www/html/boot/syslinux/mbr/altmbr.S:279 .text:0000000000000159 disk_error /var/www/html/boot/syslinux/mbr/altmbr.S:299 .text:000000000000018c die NO UNDEFINED SYMBOLS