123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- /* drivemap_int13h.S - interrupt handler for the BIOS drive remapper */
- /*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2008, 2009 Free Software Foundation, Inc.
- *
- * GRUB is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GRUB is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <grub/symbol.h>
- #define INT13H_OFFSET(x) ((x) - LOCAL (base))
- .code16
- /* Copy starts here. When deployed, this code must be segment-aligned. */
- /* The replacement int13 handler. Preserve all registers. */
- FUNCTION(grub_drivemap_handler)
- LOCAL (base):
- /* Save %dx for future restore. */
- push %dx
- /* Push flags. Used to simulate interrupt with original flags. */
- pushf
- /* Map the drive number (always in DL). */
- push %ax
- push %bx
- movw $INT13H_OFFSET(LOCAL (mapstart)), %bx
- more_remaining:
- movw %cs:(%bx), %ax
- cmpb %ah, %al
- jz not_found /* DRV=DST => map end - drive not remapped, keep DL. */
- inc %bx
- inc %bx
- cmpb %dl, %al
- jnz more_remaining /* Not found, but more remaining, loop. */
- movb %ah, %dl /* Found - drive remapped, modify DL. */
- not_found:
- pop %bx
- pop %ax
- /* If the call isn't ah=0x8 or ah=0x15 we must restore %dx. */
- cmpb $0x8, %ah
- jz norestore
- cmpb $0x15, %ah
- jz norestore
- /* Restore flags. */
- popf
- pushf
- lcall *%cs:INT13H_OFFSET (LOCAL (oldhandler))
- push %bp
- mov %sp, %bp
- tail:
- /* Save new flags below %esp so the caller will recieve new flags. */
- pushf
- pop %dx
- mov %dx, 8(%bp)
- pop %bp
- /* Restore %dx. */
- pop %dx
- iret
- norestore:
- /* Restore flags. */
- popf
- pushf
- lcall *%cs:INT13H_OFFSET (LOCAL (oldhandler))
- push %bp
- mov %sp, %bp
- /* Save %dx. So it won't be restored to original value. */
- mov %dx, 2(%bp)
- jmp tail
- /* Far pointer to the old handler. Stored as a CS:IP in the style of real-mode
- IVT entries (thus PI:SC in mem). */
- VARIABLE(grub_drivemap_oldhandler)
- LOCAL (oldhandler):
- .word 0x0, 0x0
- /* This label MUST be at the end of the copied block, since the installer code
- reserves additional space for mappings at runtime and copies them over it. */
- .align 2
-
- VARIABLE(grub_drivemap_mapstart)
- LOCAL (mapstart):
- .byte 0
|