~ilya-yanok/ubuntu/precise/grub2/fix-for-948716

« back to all changes in this revision

Viewing changes to boot/i386/pc/diskboot.S

  • Committer: Bazaar Package Importer
  • Author(s): Robert Millan
  • Date: 2009-07-25 19:00:53 UTC
  • mfrom: (1.6.3 upstream)
  • mto: (17.4.13 sid)
  • mto: This revision was merged to the branch mainline in revision 53.
  • Revision ID: james.westby@ubuntu.com-20090725190053-uv3lm6ya3zxs77ep
ImportĀ upstreamĀ versionĀ 1.96+20090725

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
17
17
 */
18
18
 
19
 
#include <grub/symbol.h>
20
19
#include <grub/machine/boot.h>
21
20
 
22
21
/*
23
22
 *  defines for the code go here
24
23
 */
25
24
 
26
 
#define MSG(x)  movw $x, %si; call LOCAL(message)
 
25
        /* Absolute addresses
 
26
           This makes the assembler generate the address without support
 
27
           from the linker. (ELF can't relocate 16-bit addresses!) */
 
28
#define ABS(x) (x-_start+GRUB_BOOT_MACHINE_KERNEL_ADDR)
 
29
 
 
30
        /* Print message string */
 
31
#ifdef APPLE_CC
 
32
#define MSG(x)  x ## _abs = ABS(x); mov $x ## _abs, %esi; call message
 
33
#else
 
34
#define MSG(x)  movw $ABS(x), %si; call message
 
35
#endif
27
36
 
28
37
        .file   "diskboot.S"
29
38
 
56
65
        popw    %si
57
66
 
58
67
        /* this sets up for the first run through "bootloop" */
59
 
        movw    $(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE), %di
 
68
#ifdef APPLE_CC
 
69
        firstlist_off_abs = ABS (firstlist - GRUB_BOOT_MACHINE_LIST_SIZE)
 
70
        movl    $firstlist_off_abs, %edi
 
71
#else
 
72
        movw    $ABS(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE), %di
 
73
#endif
60
74
 
61
75
        /* save the sector number of the second sector in %ebp */
62
76
        movl    (%di), %ebp
63
77
 
64
78
        /* this is the loop for reading the rest of the kernel in */
65
 
LOCAL(bootloop):
 
79
bootloop:
66
80
 
67
81
        /* check the number of sectors to read */
68
82
        cmpw    $0, 8(%di)
69
83
 
70
84
        /* if zero, go to the start function */
71
 
        je      LOCAL(bootit)
 
85
        je      bootit
72
86
 
73
 
LOCAL(setup_sectors):
 
87
setup_sectors:
74
88
        /* check if we use LBA or CHS */
75
89
        cmpb    $0, -1(%si)
76
90
 
77
 
        /* use CHS if zero, LBA otherwise */
78
 
        je      LOCAL(chs_mode)
 
91
        /* jump to chs_mode if zero */
 
92
        je      chs_mode
79
93
 
 
94
lba_mode:
80
95
        /* load logical sector start */
81
96
        movl    (%di), %ebx
82
97
        movl    4(%di), %ecx
135
150
        movb    $0x42, %ah
136
151
        int     $0x13
137
152
 
138
 
        jc      LOCAL(read_error)
 
153
        jc      read_error
139
154
 
140
155
        movw    $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
141
 
        jmp     LOCAL(copy_buffer)
 
156
        jmp     copy_buffer
142
157
 
143
 
LOCAL(chs_mode):
 
158
chs_mode:
144
159
        /* load logical sector start (top half) */
145
160
        movl    4(%di), %eax
146
161
        orl     %eax, %eax
147
 
        jnz     LOCAL(geometry_error)
 
162
        jnz     geometry_error
148
163
 
149
164
        /* load logical sector start (bottom half) */
150
165
        movl    (%di), %eax
169
184
 
170
185
        /* do we need too many cylinders? */
171
186
        cmpw    8(%si), %ax
172
 
        jge     LOCAL(geometry_error)
 
187
        jge     geometry_error
173
188
 
174
189
        /* determine the maximum sector length of this read */
175
190
        movw    (%si), %ax      /* get number of sectors per track/head */
239
254
        movb    $0x2, %ah       /* function 2 */
240
255
        int     $0x13
241
256
 
242
 
        jc      LOCAL(read_error)
 
257
        jc      read_error
243
258
 
244
259
        /* save source segment */
245
260
        movw    %es, %bx
246
261
 
247
 
LOCAL(copy_buffer):
 
262
copy_buffer:
248
263
 
249
264
        /* load addresses for copy from disk buffer to destination */
250
265
        movw    10(%di), %es    /* load destination segment */
284
299
 
285
300
        /* check if finished with this dataset */
286
301
        cmpw    $0, 8(%di)
287
 
        jne     LOCAL(setup_sectors)
 
302
        jne     setup_sectors
288
303
 
289
304
        /* update position to load from */
290
305
        subw    $GRUB_BOOT_MACHINE_LIST_SIZE, %di
291
306
 
292
307
        /* jump to bootloop */
293
 
        jmp     LOCAL(bootloop)
 
308
        jmp     bootloop
294
309
 
295
310
/* END OF MAIN LOOP */
296
311
 
297
 
LOCAL(bootit):
 
312
bootit:
298
313
        /* print a newline */
299
314
        MSG(notification_done)
300
315
        popw    %dx     /* this makes sure %dl is our "boot" drive */
304
319
/*
305
320
 * BIOS Geometry translation error (past the end of the disk geometry!).
306
321
 */
307
 
LOCAL(geometry_error):
 
322
geometry_error:
308
323
        MSG(geometry_error_string)
309
 
        jmp     LOCAL(general_error)
 
324
        jmp     general_error
310
325
 
311
326
/*
312
327
 * Read error on the disk.
313
328
 */
314
 
LOCAL(read_error):
 
329
read_error:
315
330
        MSG(read_error_string)
316
331
 
317
 
LOCAL(general_error):
 
332
general_error:
318
333
        MSG(general_error_string)
319
334
 
320
335
/* go here when you need to stop the machine hard after an error condition */
321
 
LOCAL(stop):    jmp     LOCAL(stop)
 
336
stop:   jmp     stop
322
337
 
323
338
notification_string:    .asciz "loading"
324
339
 
346
361
        int     $0x10           /* display a byte */
347
362
 
348
363
        incw    %si
349
 
LOCAL(message):
 
364
message:
350
365
        movb    (%si), %al
351
366
        cmpb    $0, %al
352
367
        jne     1b      /* if not end of string, jmp to display */
353
368
        ret
 
369
lastlist:
354
370
 
355
371
/*
356
372
 *  This area is an empty space between the main body of code below which