GAS LISTING /tmp/ccEoxnx5.s page 1 1 # 1 "/var/www/html/boot/syslinux/mbr/mbr.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/ccEoxnx5.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) 49 .macro ADJUST_DRIVE 50 movb $0x80, %dl 51 .endm 52 #else 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 GAS LISTING /tmp/ccEoxnx5.s page 3 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 */ 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 B280 ADJUST_DRIVE 73 0021 52 pushw %dx /* dl -> drive number */ 74 75 /* Check to see if we have EBIOS */ 76 0022 52 pushw %dx /* drive number */ 77 0023 B441 movb $0x41, %ah /* %al == 0 already */ 78 0025 BBAA55 movw $0x55aa, %bx 79 0028 31C9 xorw %cx, %cx 80 002a 30F6 xorb %dh, %dh 81 002c F9 stc 82 002d CD13 int $0x13 83 002f 7213 jc 1f 84 0031 81FB55AA cmpw $0xaa55, %bx 85 0035 750D jne 1f 86 0037 D1E9 shrw %cx /* Bit 0 = fixed disk subset */ 87 0039 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 003b 66C7068F movl $0xeb42b4+((read_common-read_sector_cbios-4) << 24), \ 91 00B442EB 91 15 92 (read_sector_cbios) 93 94 1: 95 0044 5A popw %dx 96 97 /* Get (C)HS geometry */ 98 0045 B408 movb $0x08, %ah 99 0047 CD13 int $0x13 100 0049 83E13F andw $0x3f, %cx /* Sector count */ 101 004c 51 pushw %cx /* Save sectors on the stack */ 102 004d 0FB6C6 movzbw %dh, %ax /* dh = max head */ 103 0050 40 incw %ax /* From 0-based max to count */ 104 0051 F7E1 mulw %cx /* Heads*sectors -> sectors per cylinder */ 105 106 /* Save sectors/cylinder on the stack */ 107 0053 52 pushw %dx /* High word */ 108 0054 50 pushw %ax /* Low word */ GAS LISTING /tmp/ccEoxnx5.s page 4 109 110 0055 6631C0 xorl %eax, %eax /* Base */ 111 0058 6699 cdq /* Root (%edx <- 0) */ 112 005a E86600 call scan_partition_table 113 114 /* If we get here, we have no OS */ 115 missing_os: 116 005d E83501 call error 117 0060 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 007b 6660 pushal 125 007d 6631D2 xorl %edx, %edx 126 0080 BB0000 movw $bootsec, %bx 127 0083 6652 pushl %edx /* MSW of LBA */ 128 0085 6650 pushl %eax /* LSW of LBA */ 129 0087 06 pushw %es /* Buffer segment */ 130 0088 53 pushw %bx /* Buffer offset */ 131 0089 6A01 pushw $1 /* Sector count */ 132 008b 6A10 pushw $16 /* Size of packet */ 133 008d 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 008f 66F736F4 divl (secpercyl) 139 7B 140 0094 C0E406 shlb $6, %ah 141 0097 88E1 movb %ah, %cl 142 0099 88C5 movb %al, %ch 143 009b 92 xchgw %dx, %ax 144 009c F636F87B divb (sectors) 145 00a0 88C6 movb %al, %dh 146 00a2 08E1 orb %ah, %cl 147 00a4 41 incw %cx /* Sectors are 1-based */ 148 00a5 B80102 movw $0x0201, %ax 149 150 read_common: 151 00a8 8A16FA7B movb (driveno), %dl 152 00ac CD13 int $0x13 153 00ae 8D6410 leaw 16(%si), %sp /* Drop DAPA */ 154 00b1 6661 popal 155 00b3 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. GAS LISTING /tmp/ccEoxnx5.s page 5 161 * 162 * Clobbers %si, %di, and %cx, other registers preserved. 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 00b4 E8C4FF call read_sector 171 00b7 BEBE01 movw $bootsec+446, %si 172 00ba BFBE01 movw $ptab, %di 173 00bd B92000 movw $(16*4/2), %cx 174 00c0 F3A5 rep ; movsw 175 00c2 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 00c3 6660 pushal 193 00c5 89E5 movw %sp, %bp 194 195 /* Search for active partitions */ 196 00c7 BBBE01 movw $ptab, %bx 197 00ca B90400 movw $4, %cx 198 00cd 31C0 xorw %ax, %ax 199 00cf 53 push %bx 200 00d0 51 push %cx 201 5: 202 00d1 F60780 testb $0x80, (%bx) 203 00d4 7403 jz 6f 204 00d6 40 incw %ax 205 00d7 89DE movw %bx, %si 206 6: 207 00d9 83C310 addw $16, %bx 208 00dc E2F3 loopw 5b 209 210 00de 48 decw %ax /* Number of active partitions found */ 211 00df 745B jz boot 212 00e1 7939 jns too_many_active 213 214 /* No active partitions found, look for extended partitions */ 215 00e3 59 popw %cx /* %cx <- 4 */ 216 00e4 5B popw %bx /* %bx <- ptab */ 217 7: GAS LISTING /tmp/ccEoxnx5.s page 6 218 00e5 8A4704 movb 4(%bx), %al 219 00e8 3C0F cmpb $0x0f, %al /* 0x0f = Win9x extended */ 220 00ea 7406 je 8f 221 00ec 247F andb $~0x80, %al /* 0x85 = Linux extended */ 222 00ee 3C05 cmpb $0x05, %al /* 0x05 = MS-DOS extended */ 223 00f0 7522 jne 9f 224 225 /* It is an extended partition. Read the extended partition and 226 try to scan it. If the scan returns, re-load the current 227 partition table and resume scan. */ 228 8: 229 00f2 668B4708 movl 8(%bx), %eax /* Partition table offset */ 230 00f6 668B5614 movl 20(%bp), %edx /* "Root" */ 231 00fa 6601D0 addl %edx, %eax /* Compute location of new ptab */ 232 00fd 6621D2 andl %edx, %edx /* Is this the MBR? */ 233 0100 7503 jnz 10f 234 0102 6689C2 movl %eax, %edx /* Offset -> root if this was MBR */ 235 10: 236 0105 E8ACFF call read_partition_table 237 0108 7203 jc 11f 238 010a E8B6FF call scan_partition_table 239 11: 240 /* This returned, so we need to reload the current partition table */ 241 010d 668B461C movl 28(%bp), %eax /* "Base" */ 242 0111 E8A0FF call read_partition_table 243 244 /* fall through */ 245 9: 246 /* Not an extended partition */ 247 0114 83C310 addw $16, %bx 248 0117 E2CC loopw 7b 249 250 /* Nothing found, return */ 251 0119 6661 popal 252 011b C3 ret 253 254 too_many_active: 255 011c E87600 call error 256 011f 4D756C74 .ascii "Multiple active partitions.\r\n" 256 69706C65 256 20616374 256 69766520 256 70617274 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 013c 668B4408 movl 8(%si), %eax 264 0140 6603461C addl 28(%bp), %eax 265 0144 66894408 movl %eax, 8(%si) /* Adjust in-memory partition table entry */ 266 0148 E830FF call read_sector 267 014b 7227 jc disk_error 268 269 /* Check if the read sector is a XFS superblock */ 270 014d 66813E00 cmpl $0x42534658, (bootsec) /* "XFSB" */ GAS LISTING /tmp/ccEoxnx5.s page 7 270 00584653 270 42 271 0156 7509 jne no_xfs 272 273 /* We put the Syslinux boot sector at offset 0x800 (4 sectors), so we 274 * need to adjust %eax (%eax + 4) to read the right sector into 0x7C00. 275 */ 276 0158 6683C004 addl $0x800 >> 0x09, %eax /* plus 4 sectors */ 277 015c E81CFF call read_sector 278 015f 7213 jc disk_error 279 280 no_xfs: 281 0161 813EFE01 cmpw $0xaa55, (bootsec+510) 281 55AA 282 0167 0F85F2FE jne missing_os /* Not a valid boot sector */ 283 016b BCFA7B movw $driveno, %sp /* driveno == bootsec-6 */ 284 016e 5A popw %dx /* dl -> drive number */ 285 016f 5F popw %di /* es:di -> $PnP vector */ 286 0170 07 popw %es 287 0171 FA cli 288 0172 FFE4 jmpw *%sp /* %sp == bootsec */ 289 290 disk_error: 291 0174 E81E00 call error 292 0177 4F706572 .ascii "Operating system load error.\r\n" 292 6174696E 292 67207379 292 7374656D 292 206C6F61 293 294 /* 295 * Print error messages. This is invoked with "call", with the 296 * error message at the return address. 297 */ 298 error: 299 0195 5E popw %si 300 2: 301 0196 AC lodsb 302 0197 B40E movb $0x0e, %ah 303 0199 8A3E6204 movb (BIOS_page), %bh 304 019d B307 movb $0x07, %bl 305 019f CD10 int $0x10 /* May destroy %bp */ 306 01a1 3C0A cmpb $10, %al /* Newline? */ 307 01a3 75F1 jne 2b 308 309 01a5 CD18 int $0x18 /* Boot failure */ 310 die: 311 01a7 F4 hlt 312 01a8 EBFD jmp die GAS LISTING /tmp/ccEoxnx5.s page 8 DEFINED SYMBOLS /var/www/html/boot/syslinux/mbr/mbr.S:46 .bootsec:0000000000000000 bootsec /var/www/html/boot/syslinux/mbr/mbr.S:35 *ABS*:0000000000007c00 stack /var/www/html/boot/syslinux/mbr/mbr.S:36 *ABS*:0000000000007bfa driveno /var/www/html/boot/syslinux/mbr/mbr.S:37 *ABS*:0000000000007bf8 sectors /var/www/html/boot/syslinux/mbr/mbr.S:38 *ABS*:0000000000007bf4 secpercyl /var/www/html/boot/syslinux/mbr/mbr.S:40 *ABS*:0000000000000417 BIOS_kbdflags /var/www/html/boot/syslinux/mbr/mbr.S:41 *ABS*:0000000000000462 BIOS_page /var/www/html/boot/syslinux/mbr/mbr.S:51 .text:0000000000000000 _start /var/www/html/boot/syslinux/mbr/mbr.S:70 .text:000000000000001f next /var/www/html/boot/syslinux/mbr/mbr.S:150 .text:00000000000000a8 read_common /var/www/html/boot/syslinux/mbr/mbr.S:138 .text:000000000000008f read_sector_cbios /var/www/html/boot/syslinux/mbr/mbr.S:191 .text:00000000000000c3 scan_partition_table /var/www/html/boot/syslinux/mbr/mbr.S:115 .text:000000000000005d missing_os /var/www/html/boot/syslinux/mbr/mbr.S:298 .text:0000000000000195 error /var/www/html/boot/syslinux/mbr/mbr.S:123 .text:000000000000007b read_sector /var/www/html/boot/syslinux/mbr/mbr.S:51 .text:00000000000001be ptab /var/www/html/boot/syslinux/mbr/mbr.S:169 .text:00000000000000b4 read_partition_table /var/www/html/boot/syslinux/mbr/mbr.S:262 .text:000000000000013c boot /var/www/html/boot/syslinux/mbr/mbr.S:254 .text:000000000000011c too_many_active /var/www/html/boot/syslinux/mbr/mbr.S:290 .text:0000000000000174 disk_error /var/www/html/boot/syslinux/mbr/mbr.S:280 .text:0000000000000161 no_xfs /var/www/html/boot/syslinux/mbr/mbr.S:310 .text:00000000000001a7 die NO UNDEFINED SYMBOLS