Adding debian version 3.60~pre3-2.
[syslinux-debian/hramrach.git] / mbr / mbr.lst
blob9f49a90c9bee6cd356c4aaf398e6388fc4b5933d
1 GAS LISTING /tmp/cc3TQNF4.s                     page 1
4    1                    # 1 "mbr.S"
5    2                    # 1 "<built-in>"
6    1                    /* -----------------------------------------------------------------------
7    0                    
8    0                    
9    2                     *
10    3                     *   Copyright 2007 H. Peter Anvin - All Rights Reserved
11    4                     *
12    5                     *   Permission is hereby granted, free of charge, to any person
13    6                     *   obtaining a copy of this software and associated documentation
14    7                     *   files (the "Software"), to deal in the Software without
15    8                     *   restriction, including without limitation the rights to use,
16    9                     *   copy, modify, merge, publish, distribute, sublicense, and/or
17   10                     *   sell copies of the Software, and to permit persons to whom
18   11                     *   the Software is furnished to do so, subject to the following
19   12                     *   conditions:
20   13                     *
21   14                     *   The above copyright notice and this permission notice shall
22   15                     *   be included in all copies or substantial portions of the Software.
23   16                     *
24   17                     *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25   18                     *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
26   19                     *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27   20                     *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
28   21                     *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
29   22                     *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30   23                     *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
31   24                     *   OTHER DEALINGS IN THE SOFTWARE.
32   25                     *
33   26                     * ----------------------------------------------------------------------- */
34   27                    
35   28                            .code16
36   29                            .text
37   30                    
38   31                            .globl  bootsec
39   32                    stack           = 0x7c00
40   33                    driveno         = (stack-6)
41   34                    sectors         = (stack-8)
42   35                    secpercyl       = (stack-12)
43   36                    
44   37                    BIOS_page = 0x462
45   38                    
46   39                            /* gas/ld has issues with doing this as absolute addresses... */
47   40                            .section ".bootsec", "a", @nobits
48   41                            .globl  bootsec
49   42                    bootsec:
50   43 0000 00000000              .space  512
51   43      00000000 
52   43      00000000 
53   43      00000000 
54   43      00000000 
55   44                    
56   45                            .text
57   46                            .globl  _start
58   47                    _start:
59   48 0000 FA                    cli
60   49 0001 31C0                  xorw    %ax, %ax
61 \fGAS LISTING /tmp/cc3TQNF4.s                    page 2
64   50 0003 8ED8                  movw    %ax, %ds
65   51 0005 8ED0                  movw    %ax, %ss
66   52 0007 BC007C                movw    $stack, %sp
67   53 000a 89E6                  movw    %sp, %si
68   54 000c 06                    pushw   %es             /* es:di -> $PnP header */
69   55 000d 57                    pushw   %di
70   56 000e 52                    pushw   %dx             /* dl -> drive number */
71   57 000f 8EC0                  movw    %ax, %es
72   58 0011 FB                    sti
73   59 0012 FC                    cld
74   60                    
75   61                            /* Copy down to 0:0x600 */
76   62 0013 BF0000                movw    $_start, %di
77   63 0016 B90001                movw    $(512/2), %cx
78   64 0019 F3A5                  rep; movsw
79   65                    
80   66 001b EA200000              ljmpw   $0, $next
81   66      00
82   67                    
83   68                    next:
84   69                            /* Check to see if we have EBIOS */
85   70 0020 52                    pushw   %dx             /* drive number */
86   71 0021 B80041                movw    $0x4100, %ax
87   72 0024 BBAA55                movw    $0x55aa, %bx
88   73 0027 31C9                  xorw    %cx, %cx
89   74 0029 30F6                  xorb    %dh, %dh
90   75 002b F9                    stc
91   76 002c CD13                  int     $0x13
92   77 002e 7213                  jc      1f
93   78 0030 81FB55AA              cmpw    $0xaa55, %bx
94   79 0034 750D                  jne     1f
95   80 0036 D1E9                  shrw    %cx             /* Bit 0 = fixed disk subset */
96   81 0038 7309                  jnc     1f
97   82                    
98   83                            /* We have EBIOS; patch in the following code at
99   84                               read_sector_cbios: movb $0x42, %ah ;  jmp read_common */
100   85 003a 66C7068F              movl    $0xeb42b4+((read_common-read_sector_cbios-4) << 24), \
101   85      00B442EB 
102   85      15
103   86                                    (read_sector_cbios)
104   87                    
105   88                    1:
106   89 0043 5A                    popw    %dx
107   90                    
108   91                            /* Get (C)HS geometry */
109   92 0044 B408                  movb    $0x08, %ah
110   93 0046 CD13                  int     $0x13
111   94 0048 83E13F                andw    $0x3f, %cx      /* Sector count */
112   95 004b 51                    pushw   %cx             /* Save sectors on the stack */
113   96 004c 0FB6C6                movzbw  %dh, %ax        /* dh = max head */
114   97 004f 40                    incw    %ax             /* From 0-based max to count */
115   98 0050 F7E1                  mulw    %cx             /* Heads*sectors -> sectors per cylinder */
116   99                    
117  100                            /* Save sectors/cylinder on the stack */
118  101 0052 52                    pushw   %dx             /* High word */
119  102 0053 50                    pushw   %ax             /* Low word */
120  103                    
121 \fGAS LISTING /tmp/cc3TQNF4.s                    page 3
124  104 0054 6631C0                xorl    %eax, %eax      /* Base */
125  105 0057 6699                  cdq                     /* Root (%edx <- 0) */
126  106 0059 E86700                call    scan_partition_table
127  107                    
128  108                            /* If we get here, we have no OS */
129  109                    missing_os:
130  110 005c E82401                call    error
131  111 005f 4D697373              .ascii  "Missing operating system.\r\n"
132  111      696E6720 
133  111      6F706572 
134  111      6174696E 
135  111      67207379 
136  112 007a 00                    .byte   0
137  113                    
138  114                    /*
139  115                     * read_sector: read a single sector pointed to by %eax to 0x7c00.
140  116                     * CF is set on error.  All registers saved.
141  117                     */
142  118                    read_sector:
143  119 007b 6660                  pushal
144  120 007d 6631D2                xorl    %edx, %edx
145  121 0080 BB0000                movw    $bootsec, %bx
146  122 0083 6652                  pushl   %edx    /* MSW of LBA */
147  123 0085 6650                  pushl   %eax    /* LSW of LBA */
148  124 0087 06                    pushw   %es     /* Buffer segment */
149  125 0088 53                    pushw   %bx     /* Buffer offset */
150  126 0089 6A01                  pushw   $1      /* Sector count */
151  127 008b 6A10                  pushw   $16     /* Size of packet */
152  128 008d 89E6                  movw    %sp, %si
153  129                    
154  130                            /* This chunk is skipped if we have ebios */
155  131                            /* Do not clobber %eax before this chunk! */
156  132                            /* This also relies on %bx and %edx as set up above. */
157  133                    read_sector_cbios:
158  134 008f 66F736F4              divl    (secpercyl)
159  134      7B
160  135 0094 C0E406                shlb    $6, %ah
161  136 0097 88E1                  movb    %ah, %cl
162  137 0099 88C5                  movb    %al, %ch
163  138 009b 92                    xchgw   %dx, %ax
164  139 009c F636F87B              divb    (sectors)
165  140 00a0 88C6                  movb    %al, %dh
166  141 00a2 08E1                  orb     %ah, %cl
167  142 00a4 41                    incw    %cx     /* Sectors are 1-based */
168  143 00a5 B80102                movw    $0x0201, %ax
169  144                    
170  145                    read_common:
171  146 00a8 8A16FA7B              movb    (driveno), %dl
172  147 00ac CD13                  int     $0x13
173  148 00ae 83C410                addw    $16, %sp        /* Drop DAPA */
174  149 00b1 6661                  popal
175  150 00b3 C3                    ret
176  151                    
177  152                    /*
178  153                     * read_partition_table:
179  154                     *      Read a partition table (pointed to by %eax), and copy
180  155                     *      the partition table into the ptab buffer.
181 \fGAS LISTING /tmp/cc3TQNF4.s                    page 4
184  156                     *
185  157                     *      Clobbers %si, %di, and %cx, other registers preserved.
186  158                     *      %cx = 0 on exit.
187  159                     *
188  160                     *      On error, CF is set and ptab is overwritten with junk.
189  161                     */
190  162                    ptab    = _start+446
191  163                    
192  164                    read_partition_table:
193  165 00b4 E8C4FF                call    read_sector
194  166 00b7 BEBE01                movw    $bootsec+446, %si
195  167 00ba BFBE01                movw    $ptab, %di
196  168 00bd B92000                movw    $(16*4/2), %cx
197  169 00c0 F3A5                  rep ; movsw
198  170 00c2 C3                    ret
199  171                    
200  172                    /*
201  173                     * scan_partition_table:
202  174                     *      Scan a partition table currently loaded in the partition table
203  175                     *      area.  Preserve all registers.
204  176                     *
205  177                     *      On entry:
206  178                     *        %eax - base (location of this partition table)
207  179                     *        %edx - root (offset from MBR, or 0 for MBR)
208  180                     *
209  181                     *      These get pushed into stack slots:
210  182                     *        28(%bp) - %eax - base
211  183                     *        20(%bp) - %edx - root
212  184                     */
213  185                    
214  186                    scan_partition_table:
215  187 00c3 6660                  pushal
216  188 00c5 89E5                  movw    %sp, %bp
217  189                    
218  190                            /* Search for active partitions */
219  191 00c7 BBBE01                movw    $ptab, %bx
220  192 00ca B90400                movw    $4, %cx
221  193 00cd 31C0                  xorw    %ax, %ax
222  194 00cf 53                    push    %bx
223  195 00d0 51                    push    %cx
224  196                    5:
225  197 00d1 F60780                testb   $0x80, (%bx)
226  198 00d4 7403                  jz      6f
227  199 00d6 40                    incw    %ax
228  200 00d7 89DE                  movw    %bx, %si
229  201                    6:
230  202 00d9 83C310                addw    $16, %bx
231  203 00dc E2F3                  loopw   5b
232  204                    
233  205 00de 48                    decw    %ax             /* Number of active partitions found */
234  206 00df 745C                  jz      boot
235  207 00e1 7939                  jns     too_many_active
236  208                    
237  209                            /* No active partitions found, look for extended partitions */
238  210 00e3 5B                    popw    %bx             /* %bx <- ptab */
239  211 00e4 59                    popw    %cx             /* %cx <- 4    */
240  212                    7:
241 \fGAS LISTING /tmp/cc3TQNF4.s                    page 5
244  213 00e5 8A4704                movb    4(%bx), %al
245  214 00e8 3C0F                  cmpb    $0x0f, %al      /* 0x0f = Win9x extended */
246  215 00ea 7406                  je      8f
247  216 00ec 247F                  andb    $~0x80, %al     /* 0x85 = Linux extended */
248  217 00ee 3C05                  cmpb    $0x05, %al      /* 0x05 = MS-DOS extended */
249  218 00f0 7522                  jne     9f
250  219                    
251  220                            /* It is an extended partition.  Read the extended partition and
252  221                               try to scan it.  If the scan returns, re-load the current
253  222                               partition table and resume scan. */
254  223                    8:
255  224 00f2 668B4708              movl    8(%bx), %eax            /* Partition table offset */
256  225 00f6 668B5614              movl    20(%bp), %edx           /* "Root" */
257  226 00fa 6601D0                addl    %edx, %eax              /* Compute location of new ptab */
258  227 00fd 6621D2                andl    %edx, %edx              /* Is this the MBR? */
259  228 0100 7503                  jnz     10f
260  229 0102 6689C2                movl    %eax, %edx              /* Offset -> root if this was MBR */
261  230                    10:
262  231 0105 E8ACFF                call    read_partition_table
263  232 0108 7203                  jc      11f
264  233 010a E8B6FF                call    scan_partition_table
265  234                    11:
266  235                            /* This returned, so we need to reload the current partition table */
267  236 010d 668B461C              movl    28(%bp), %eax           /* "Base" */
268  237 0111 E8A0FF                call    read_partition_table
269  238                    
270  239                            /* fall through */
271  240                    9:
272  241                            /* Not an extended partition */
273  242 0114 83C310                addw    $16, %bx
274  243 0117 E2CC                  loopw   7b
275  244                    
276  245                            /* Nothing found, return */
277  246 0119 6661                  popal
278  247 011b C3                    ret
279  248                    
280  249                    too_many_active:
281  250 011c E86400                call    error
282  251 011f 4D756C74              .ascii  "Multiple active partitions.\r\n"
283  251      69706C65 
284  251      20616374 
285  251      69766520 
286  251      70617274 
287  252 013c 00                    .byte   0
288  253                    
289  254                    /*
290  255                     * boot: invoke the actual bootstrap. (%si) points to the partition
291  256                     *       table entry, and 28(%bp) has the partition table base.
292  257                     */
293  258                    boot:
294  259 013d 668B4408              movl    8(%si), %eax
295  260 0141 6603461C              addl    28(%bp), %eax
296  261 0145 66894408              movl    %eax, 8(%si)    /* Adjust in-memory partition table entry */
297  262 0149 E82FFF                call    read_sector
298  263 014c 7213                  jc      disk_error
299  264 014e 813EFE01              cmpw    $0xaa55, (bootsec+510)
300  264      55AA
301 \fGAS LISTING /tmp/cc3TQNF4.s                    page 6
304  265 0154 0F8504FF              jne     missing_os              /* Not a valid boot sector */
305  266 0158 BCFA7B                movw    $driveno, %sp   /* driveno == bootsec-6 */
306  267 015b 5A                    popw    %dx             /* dl -> drive number */
307  268 015c 5F                    popw    %di             /* es:di -> $PnP vector */
308  269 015d 07                    popw    %es
309  270 015e FA                    cli
310  271 015f FFE4                  jmpw    *%sp            /* %sp == bootsec */
311  272                    
312  273                    disk_error:
313  274 0161 E81F00                call    error
314  275 0164 4F706572              .ascii  "Operating system load error.\r\n"
315  275      6174696E 
316  275      67207379 
317  275      7374656D 
318  275      206C6F61 
319  276 0182 00                    .byte   0
320  277                    
321  278                    /*
322  279                     * Print error messages.  This is invoked with "call", with the
323  280                     * error message at the return address.
324  281                     */
325  282                    error:
326  283 0183 5E                    popw    %si
327  284                    2:
328  285 0184 AC                    lodsb
329  286 0185 20C0                  andb    %al, %al
330  287 0187 740C                  jz      3f
331  288 0189 B40E                  movb    $0x0e, %ah
332  289 018b 8A3E6204              movb    (BIOS_page), %bh
333  290 018f B307                  movb    $0x07, %bl
334  291 0191 CD10                  int     $0x10
335  292 0193 EBEF                  jmp     2b
336  293                    3:
337  294 0195 CD18                  int     $0x18           /* Boot failure */
338  295                    die:
339  296 0197 F4                    hlt
340  297 0198 EBFD                  jmp     die
341 \fGAS LISTING /tmp/cc3TQNF4.s                    page 7
344 DEFINED SYMBOLS
345                             *ABS*:0000000000000000 mbr.S
346                mbr.S:42     .bootsec:0000000000000000 bootsec
347                mbr.S:32     *ABS*:0000000000007c00 stack
348                mbr.S:33     *ABS*:0000000000007bfa driveno
349                mbr.S:34     *ABS*:0000000000007bf8 sectors
350                mbr.S:35     *ABS*:0000000000007bf4 secpercyl
351                mbr.S:37     *ABS*:0000000000000462 BIOS_page
352                mbr.S:47     .text:0000000000000000 _start
353                mbr.S:68     .text:0000000000000020 next
354                mbr.S:145    .text:00000000000000a8 read_common
355                mbr.S:133    .text:000000000000008f read_sector_cbios
356                mbr.S:186    .text:00000000000000c3 scan_partition_table
357                mbr.S:109    .text:000000000000005c missing_os
358                mbr.S:282    .text:0000000000000183 error
359                mbr.S:118    .text:000000000000007b read_sector
360                mbr.S:47     .text:00000000000001be ptab
361                mbr.S:164    .text:00000000000000b4 read_partition_table
362                mbr.S:258    .text:000000000000013d boot
363                mbr.S:249    .text:000000000000011c too_many_active
364                mbr.S:273    .text:0000000000000161 disk_error
365                mbr.S:295    .text:0000000000000197 die
367 NO UNDEFINED SYMBOLS