2009-05-14 Pavel Roskin <proski@gnu.org>
[grub2/bean.git] / commands / i386 / pc / drivemap_int13h.S
blob6513411be8597703c4820249ca804bee9a26352a
1 /* drivemap_int13h.S - interrupt handler for the BIOS drive remapper */
2 /*
3  *  GRUB  --  GRand Unified Bootloader
4  *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
5  *
6  *  GRUB is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  GRUB is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
18  */
20 #include <grub/symbol.h>
22 #define INT13H_OFFSET(x) ((x) - grub_drivemap_handler)
24 .code16
26 /* Copy starts here.  When deployed, this code must be segment-aligned.  */
28 /* The replacement int13 handler.  The code must be position independent.
29    Preserve all registers.  */
30 FUNCTION(grub_drivemap_handler)
31         /* Map the drive number (always in DL).  */
32         push    %ax
33         push    %bx
34         movw    $INT13H_OFFSET(grub_drivemap_mapstart), %bx
36 more_remaining:
37         movw    %cs:(%bx), %ax
38         cmpb    %ah, %al
39         jz      not_found /* DRV=DST => map end - drive not remapped, keep DL.  */
40         inc     %bx
41         inc     %bx
42         cmpb    %dl, %al
43         jnz     more_remaining /* Not found, but more remaining, loop.  */
44         movb    %ah, %dl /* Found - drive remapped, modify DL.  */
46 not_found:
47         pop     %bx
48         pop     %ax
50         /* Upon arrival to this point the stack must be exactly like at entry.
51            This long jump will transfer the caller's stack to the old INT13
52            handler, thus making it return directly to the original caller.  */
53         .byte   0xea
55 /* Far pointer to the old handler.  Stored as a CS:IP in the style of real-mode
56    IVT entries (thus PI:SC in mem).  */
57 VARIABLE(grub_drivemap_oldhandler)
58         .word 0x0, 0x0
60 /* This label MUST be at the end of the copied block, since the installer code
61    reserves additional space for mappings at runtime and copies them over it.  */
62 .align 2
63 VARIABLE(grub_drivemap_mapstart)