2 * Extended Boot Option ROM
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * Copyright IBM Corporation, 2007
19 * Authors: Anthony Liguori <aliguori@us.ibm.com>
27 .byte (_end - _start) / 512
34 /* setup ds so we can access the IVT */
38 /* save old int 19 at int 2b */
47 /* install out int 19 handler */
49 mov $int19_handler, %ax
75 1: /* hook int13: intb(0x404) == 1 */
76 /* setup ds to access IVT */
80 /* save old int 13 to int 2c */
89 /* install our int 13 handler */
91 mov $int13_handler, %ax
97 2: /* linux boot: intb(0x404) == 2 */
107 ljmp $0x9000 + 0x20, $0
109 3: /* fall through: inb(0x404) == 0 */
117 #define FLAGS_CF 0x01
123 and $(~FLAGS_CF), %ax
143 mov %sp, %bp /* remember the current stack position */
158 mov %sp, %bp /* remember the current stack position */
196 mov %ax, 0(%bx) /* ax */
197 mov 0(%bp), %ax /* bx */
199 mov %cx, 4(%bx) /* cx */
200 mov %dx, 6(%bx) /* dx */
201 mov %si, 8(%bx) /* si */
202 mov %ds, 10(%bx) /* ds */
203 mov %es, 12(%bx) /* ds */
204 movw \value, 14(%bx) /* value */
248 add32: /* lo, hi, lo, hi */
252 movw 4(%bp), %cx /* hi */
253 movw 6(%bp), %dx /* lo */
263 mul32: /* lo, hi, lo, hi */
264 /* 10(%bp), 8(%bp), 6(%bp), 4(%bp) */
273 /* for (i = 0; i < 16;) */
315 /* this really should be a function, not a macro but i'm lazy */
316 .macro read_write_disk_sectors cmd
327 /* save nb_sectors */
356 movw $0, 0(%bx) /* read c,h,s */
361 mov 6(%bx), %ax /* total_sectors */
362 mov 2(%bp), %si /* *= heads */
364 add 4(%bp), %ax /* += sectors - 1 */
366 push 4(%bx) /* total_heads */
368 push 6(%bx) /* total_sectors */
373 push 0(%bp) /* cylinders */
388 movw \cmd, 0(%bx) /* read */
389 movw 6(%bp), %ax /* nb_sectors */
391 movw %es, 4(%bx) /* segment */
392 movw 8(%bp), %ax /* offset */
394 movw %dx, 8(%bx) /* sector */
420 read_write_disk_sectors $0x01
423 read_write_disk_sectors $0x02
425 read_disk_drive_parameters:
428 /* allocate memory for packet, pointer gets returned in bx */
432 movw $0, 0(%bx) /* cmd = 0, read c,h,s */
437 /* normalize sector value */
442 /* normalize cylinders */
445 /* normalize heads */
473 /* do this last since it's the most sensitive */
477 alternate_disk_reset:
482 read_disk_drive_size:
486 movw $0, 0(%bx) /* cmd = 0, read c,h,s */
491 /* cylinders - 1 to cx:dx */
521 check_if_extensions_present:
528 .macro extended_read_write_sectors cmd
539 movw \cmd, 0(%bp) /* read */
540 movw 2(%si), %ax /* nb_sectors */
542 movw 4(%si), %ax /* offset */
544 movw 6(%si), %ax /* segment */
546 movw 8(%si), %ax /* block */
568 extended_read_sectors:
569 extended_read_write_sectors $0x01
571 extended_write_sectors:
572 extended_read_write_sectors $0x02
574 get_extended_drive_parameters:
582 movw $0, 0(%bp) /* read c,h,s */
611 /* set total number of sectors */
621 /* number of bytes per sector */
635 terminate_disk_emulation:
653 call read_disk_sectors
658 call read_disk_drive_parameters
663 call read_disk_drive_size
668 call check_if_extensions_present
673 call extended_read_sectors
678 call get_extended_drive_parameters
683 call terminate_disk_emulation
688 call alternate_disk_reset
693 call write_disk_sectors
698 call extended_write_sectors
701 int $0x18 /* boot failed */