2009-05-13 Javier Martín <lordhabbit@gmail.com>
* commands/i386/pc/drivemap.c: New file - implement drivemap command. * commands/i386/pc/drivemap_int13h.S: New file - int13 handler. * conf/i386-pc.rmk: Add drivemap.c and drivemap_int13h.S.
This commit is contained in:
parent
6f6a8b2869
commit
4246b8a9e8
4 changed files with 526 additions and 1 deletions
|
@ -1,3 +1,10 @@
|
|||
2009-05-13 Javier Martín <lordhabbit@gmail.com>
|
||||
|
||||
* commands/i386/pc/drivemap.c: New file - implement drivemap
|
||||
command.
|
||||
* commands/i386/pc/drivemap_int13h.S: New file - int13 handler.
|
||||
* conf/i386-pc.rmk: Add drivemap.c and drivemap_int13h.S.
|
||||
|
||||
2009-05-13 Pavel Roskin <proski@gnu.org>
|
||||
|
||||
* util/i386/pc/grub-setup.c (setup): Remove unused variable
|
||||
|
|
445
commands/i386/pc/drivemap.c
Normal file
445
commands/i386/pc/drivemap.c
Normal file
|
@ -0,0 +1,445 @@
|
|||
/* drivemap.c - command to manage the BIOS drive mappings. */
|
||||
/*
|
||||
* 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/extcmd.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/loader.h>
|
||||
#include <grub/machine/memory.h>
|
||||
|
||||
|
||||
#define MODNAME "drivemap"
|
||||
|
||||
/* Real mode IVT slot (seg:off far pointer) for interrupt 0x13. */
|
||||
static grub_uint32_t *const int13slot = UINT_TO_PTR (4 * 0x13);
|
||||
|
||||
/* Remember to update enum opt_idxs accordingly. */
|
||||
static const struct grub_arg_option options[] = {
|
||||
{"list", 'l', 0, "show the current mappings", 0, 0},
|
||||
{"reset", 'r', 0, "reset all mappings to the default values", 0, 0},
|
||||
{"swap", 's', 0, "perform both direct and reverse mappings", 0, 0},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* Remember to update options[] accordingly. */
|
||||
enum opt_idxs
|
||||
{
|
||||
OPTIDX_LIST = 0,
|
||||
OPTIDX_RESET,
|
||||
OPTIDX_SWAP,
|
||||
};
|
||||
|
||||
/* Realmode far ptr (2 * 16b) to the previous INT13h handler. */
|
||||
extern grub_uint32_t grub_drivemap_oldhandler;
|
||||
|
||||
/* The type "void" is used for imported assembly labels, takes no storage and
|
||||
serves just to take the address with &label. */
|
||||
|
||||
/* The assembly function to replace the old INT13h handler. It does not follow
|
||||
any C callspecs and returns with IRET. */
|
||||
extern const void grub_drivemap_handler;
|
||||
|
||||
/* Start of the drive mappings area (space reserved at runtime). */
|
||||
extern const void grub_drivemap_mapstart;
|
||||
|
||||
typedef struct drivemap_node
|
||||
{
|
||||
struct drivemap_node *next;
|
||||
grub_uint8_t newdrive;
|
||||
grub_uint8_t redirto;
|
||||
} drivemap_node_t;
|
||||
|
||||
typedef struct __attribute__ ((packed)) int13map_node
|
||||
{
|
||||
grub_uint8_t disknum;
|
||||
grub_uint8_t mapto;
|
||||
} int13map_node_t;
|
||||
|
||||
#define INT13H_OFFSET(x) \
|
||||
(((grub_uint8_t *)(x)) - ((grub_uint8_t *)&grub_drivemap_handler))
|
||||
|
||||
static drivemap_node_t *map_head;
|
||||
static void *drivemap_hook;
|
||||
static int drivemap_mmap;
|
||||
|
||||
/* Puts the specified mapping into the table, replacing an existing mapping
|
||||
for newdrive or adding a new one if required. */
|
||||
static grub_err_t
|
||||
drivemap_set (grub_uint8_t newdrive, grub_uint8_t redirto)
|
||||
{
|
||||
drivemap_node_t *mapping = 0;
|
||||
drivemap_node_t *search = map_head;
|
||||
while (search)
|
||||
{
|
||||
if (search->newdrive == newdrive)
|
||||
{
|
||||
mapping = search;
|
||||
break;
|
||||
}
|
||||
search = search->next;
|
||||
}
|
||||
|
||||
/* Check for pre-existing mappings to modify before creating a new one. */
|
||||
if (mapping)
|
||||
mapping->redirto = redirto;
|
||||
else
|
||||
{
|
||||
mapping = grub_malloc (sizeof (drivemap_node_t));
|
||||
if (! mapping)
|
||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||
"cannot allocate map entry, not enough memory");
|
||||
mapping->newdrive = newdrive;
|
||||
mapping->redirto = redirto;
|
||||
mapping->next = map_head;
|
||||
map_head = mapping;
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* Removes the mapping for newdrive from the table. If there is no mapping,
|
||||
then this function behaves like a no-op on the map. */
|
||||
static void
|
||||
drivemap_remove (grub_uint8_t newdrive)
|
||||
{
|
||||
drivemap_node_t *mapping = 0;
|
||||
drivemap_node_t *search = map_head;
|
||||
drivemap_node_t *previous = 0;
|
||||
|
||||
while (search)
|
||||
{
|
||||
if (search->newdrive == newdrive)
|
||||
{
|
||||
mapping = search;
|
||||
break;
|
||||
}
|
||||
previous = search;
|
||||
search = search->next;
|
||||
}
|
||||
|
||||
if (mapping)
|
||||
{
|
||||
if (previous)
|
||||
previous->next = mapping->next;
|
||||
else
|
||||
map_head = mapping->next;
|
||||
grub_free (mapping);
|
||||
}
|
||||
}
|
||||
|
||||
/* Given a device name, resolves its BIOS disk number and stores it in the
|
||||
passed location, which should only be trusted if ERR_NONE is returned. */
|
||||
static grub_err_t
|
||||
parse_biosdisk (const char *name, grub_uint8_t *disknum)
|
||||
{
|
||||
grub_disk_t disk;
|
||||
/* Skip the first ( in (hd0) - disk_open wants just the name. */
|
||||
if (*name == '(')
|
||||
name++;
|
||||
|
||||
disk = grub_disk_open (name);
|
||||
if (! disk)
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown device \"%s\"",
|
||||
name);
|
||||
const enum grub_disk_dev_id id = disk->dev->id;
|
||||
/* The following assignment is only sound if the device is indeed a
|
||||
biosdisk. The caller must check the return value. */
|
||||
if (disknum)
|
||||
*disknum = disk->id;
|
||||
grub_disk_close (disk);
|
||||
if (id != GRUB_DISK_DEVICE_BIOSDISK_ID)
|
||||
return grub_error (GRUB_ERR_BAD_DEVICE, "%s is not a BIOS disk", name);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* Given a BIOS disk number, returns its GRUB device name if it exists.
|
||||
If the call succeeds, the resulting device string must be freed.
|
||||
For nonexisting BIOS disk numbers, this function returns
|
||||
GRUB_ERR_UNKNOWN_DEVICE. */
|
||||
static grub_err_t
|
||||
revparse_biosdisk (const grub_uint8_t dnum, const char **output)
|
||||
{
|
||||
int found = 0;
|
||||
auto int find (const char *name);
|
||||
int find (const char *name)
|
||||
{
|
||||
const grub_disk_t disk = grub_disk_open (name);
|
||||
if (! disk)
|
||||
return 0;
|
||||
if (disk->id == dnum && disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID)
|
||||
{
|
||||
found = 1;
|
||||
if (output)
|
||||
*output = grub_strdup (name);
|
||||
}
|
||||
grub_disk_close (disk);
|
||||
return found;
|
||||
}
|
||||
|
||||
grub_disk_dev_iterate (find);
|
||||
if (found)
|
||||
return GRUB_ERR_NONE;
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "BIOS disk %02x not found",
|
||||
dnum);
|
||||
}
|
||||
|
||||
/* Given a GRUB-like device name and a convenient location, stores the
|
||||
related BIOS disk number. Accepts devices like \((f|h)dN\), with
|
||||
0 <= N < 128. */
|
||||
static grub_err_t
|
||||
tryparse_diskstring (const char *str, grub_uint8_t *output)
|
||||
{
|
||||
/* Skip opening paren in order to allow both (hd0) and hd0. */
|
||||
if (*str == '(')
|
||||
str++;
|
||||
if ((str[0] == 'f' || str[0] == 'h') && str[1] == 'd')
|
||||
{
|
||||
grub_uint8_t bios_num = (str[0] == 'h') ? 0x80 : 0x00;
|
||||
unsigned long drivenum = grub_strtoul (str + 2, 0, 0);
|
||||
if (grub_errno == GRUB_ERR_NONE && drivenum < 128)
|
||||
{
|
||||
bios_num |= drivenum;
|
||||
if (output)
|
||||
*output = bios_num;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "device format \"%s\" "
|
||||
"invalid: must be (f|h)dN, with 0 <= N < 128", str);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
list_mappings (void)
|
||||
{
|
||||
/* Show: list mappings. */
|
||||
if (! map_head)
|
||||
{
|
||||
grub_printf ("No drives have been remapped\n");
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_printf ("OS disk #num ------> GRUB/BIOS device\n");
|
||||
drivemap_node_t *curnode = map_head;
|
||||
while (curnode)
|
||||
{
|
||||
const char *dname = 0;
|
||||
grub_err_t err = revparse_biosdisk (curnode->redirto, &dname);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
return err;
|
||||
grub_printf ("%cD #%-3u (0x%02x) %s\n",
|
||||
(curnode->newdrive & 0x80) ? 'H' : 'F',
|
||||
curnode->newdrive & 0x7F, curnode->newdrive, dname);
|
||||
curnode = curnode->next;
|
||||
grub_free ((char *) dname);
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_drivemap (struct grub_extcmd *cmd, int argc, char **args)
|
||||
{
|
||||
if (cmd->state[OPTIDX_LIST].set)
|
||||
{
|
||||
return list_mappings ();
|
||||
}
|
||||
else if (cmd->state[OPTIDX_RESET].set)
|
||||
{
|
||||
/* Reset: just delete all mappings, freeing their memory. */
|
||||
drivemap_node_t *curnode = map_head;
|
||||
drivemap_node_t *prevnode = 0;
|
||||
while (curnode)
|
||||
{
|
||||
prevnode = curnode;
|
||||
curnode = curnode->next;
|
||||
grub_free (prevnode);
|
||||
}
|
||||
map_head = 0;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
else if (!cmd->state[OPTIDX_SWAP].set && argc == 0)
|
||||
{
|
||||
/* No arguments */
|
||||
return list_mappings ();
|
||||
}
|
||||
|
||||
/* Neither flag: put mapping. */
|
||||
grub_uint8_t mapfrom = 0;
|
||||
grub_uint8_t mapto = 0xFF;
|
||||
grub_err_t err;
|
||||
|
||||
if (argc != 2)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required");
|
||||
|
||||
err = parse_biosdisk (args[0], &mapfrom);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
return err;
|
||||
|
||||
/* When swapping we require both devices to be BIOS disks, but when
|
||||
performing direct mappings we only require the 2nd argument to look
|
||||
like a BIOS disk in order to resolve it into a BIOS disk number. */
|
||||
if (cmd->state[OPTIDX_SWAP].set)
|
||||
err = parse_biosdisk (args[1], &mapto);
|
||||
else
|
||||
err = tryparse_diskstring (args[1], &mapto);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
return err;
|
||||
|
||||
if (mapto == mapfrom)
|
||||
{
|
||||
/* Reset to default. */
|
||||
grub_dprintf (MODNAME, "Removing mapping for %s (%02x)\n",
|
||||
args[0], mapfrom);
|
||||
drivemap_remove (mapfrom);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
/* Set the mapping for the disk (overwrites any existing mapping). */
|
||||
grub_dprintf (MODNAME, "%s %s (%02x) = %s (%02x)\n",
|
||||
cmd->state[OPTIDX_SWAP].set ? "Swapping" : "Mapping",
|
||||
args[1], mapto, args[0], mapfrom);
|
||||
err = drivemap_set (mapto, mapfrom);
|
||||
/* If -s, perform the reverse mapping too (only if the first was OK). */
|
||||
if (cmd->state[OPTIDX_SWAP].set && err == GRUB_ERR_NONE)
|
||||
err = drivemap_set (mapfrom, mapto);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Int13h handler installer - reserves conventional memory for the handler,
|
||||
copies it over and sets the IVT entry for int13h.
|
||||
This code rests on the assumption that GRUB does not activate any kind
|
||||
of memory mapping apart from identity paging, since it accesses
|
||||
realmode structures by their absolute addresses, like the IVT at 0;
|
||||
and transforms a pmode pointer into a rmode seg:off far ptr. */
|
||||
static grub_err_t
|
||||
install_int13_handler (int noret __attribute__ ((unused)))
|
||||
{
|
||||
/* Size of the full int13 handler "bundle", including code and map. */
|
||||
grub_uint32_t total_size;
|
||||
/* Base address of the space reserved for the handler bundle. */
|
||||
grub_uint8_t *handler_base = 0;
|
||||
/* Address of the map within the deployed bundle. */
|
||||
int13map_node_t *handler_map;
|
||||
|
||||
int i;
|
||||
int entries = 0;
|
||||
drivemap_node_t *curentry = map_head;
|
||||
|
||||
/* Count entries to prepare a contiguous map block. */
|
||||
while (curentry)
|
||||
{
|
||||
entries++;
|
||||
curentry = curentry->next;
|
||||
}
|
||||
if (entries == 0)
|
||||
{
|
||||
/* No need to install the int13h handler. */
|
||||
grub_dprintf (MODNAME, "No drives marked as remapped, not installing "
|
||||
"our int13h handler.\n");
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_dprintf (MODNAME, "Installing our int13h handler\n");
|
||||
|
||||
/* Save the pointer to the old handler. */
|
||||
grub_drivemap_oldhandler = *int13slot;
|
||||
grub_dprintf (MODNAME, "Original int13 handler: %04x:%04x\n",
|
||||
(grub_drivemap_oldhandler >> 16) & 0x0ffff,
|
||||
grub_drivemap_oldhandler & 0x0ffff);
|
||||
|
||||
/* Find a rmode-segment-aligned zone in conventional memory big
|
||||
enough to hold the handler and its data. */
|
||||
total_size = INT13H_OFFSET (&grub_drivemap_mapstart)
|
||||
+ (entries + 1) * sizeof (int13map_node_t);
|
||||
grub_dprintf (MODNAME, "Payload is %u bytes long\n", total_size);
|
||||
handler_base = grub_mmap_malign_and_register (16, total_size,
|
||||
&drivemap_mmap,
|
||||
GRUB_MACHINE_MEMORY_RESERVED,
|
||||
GRUB_MMAP_MALLOC_LOW);
|
||||
if (! handler_base)
|
||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not reserve "
|
||||
"memory for the int13h handler");
|
||||
|
||||
/* Copy int13h handler bundle to reserved area. */
|
||||
grub_dprintf (MODNAME, "Reserved memory at %p, copying handler\n",
|
||||
handler_base);
|
||||
grub_memcpy (handler_base, &grub_drivemap_handler,
|
||||
INT13H_OFFSET (&grub_drivemap_mapstart));
|
||||
|
||||
/* Copy the mappings to the reserved area. */
|
||||
curentry = map_head;
|
||||
handler_map = (int13map_node_t *) (handler_base +
|
||||
INT13H_OFFSET (&grub_drivemap_mapstart));
|
||||
grub_dprintf (MODNAME, "Target map at %p, copying mappings\n", handler_map);
|
||||
for (i = 0; i < entries; ++i, curentry = curentry->next)
|
||||
{
|
||||
handler_map[i].disknum = curentry->newdrive;
|
||||
handler_map[i].mapto = curentry->redirto;
|
||||
grub_dprintf (MODNAME, "\t#%d: 0x%02x <- 0x%02x\n", i,
|
||||
handler_map[i].disknum, handler_map[i].mapto);
|
||||
}
|
||||
/* Signal end-of-map. */
|
||||
handler_map[i].disknum = 0;
|
||||
handler_map[i].mapto = 0;
|
||||
grub_dprintf (MODNAME, "\t#%d: 0x00 <- 0x00 (end)\n", i);
|
||||
|
||||
/* Install our function as the int13h handler in the IVT. */
|
||||
*int13slot = ((grub_uint32_t) handler_base) << 12; /* Segment address. */
|
||||
grub_dprintf (MODNAME, "New int13 handler: %04x:%04x\n",
|
||||
(*int13slot >> 16) & 0x0ffff, *int13slot & 0x0ffff);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
uninstall_int13_handler (void)
|
||||
{
|
||||
if (! grub_drivemap_oldhandler)
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
*int13slot = grub_drivemap_oldhandler;
|
||||
grub_mmap_free_and_unregister (drivemap_mmap);
|
||||
grub_drivemap_oldhandler = 0;
|
||||
grub_dprintf (MODNAME, "Restored int13 handler: %04x:%04x\n",
|
||||
(*int13slot >> 16) & 0x0ffff, *int13slot & 0x0ffff);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_extcmd_t cmd;
|
||||
|
||||
GRUB_MOD_INIT (drivemap)
|
||||
{
|
||||
cmd = grub_register_extcmd (MODNAME, grub_cmd_drivemap,
|
||||
GRUB_COMMAND_FLAG_BOTH,
|
||||
MODNAME
|
||||
" -l | -r | [-s] grubdev osdisk",
|
||||
"Manage the BIOS drive mappings",
|
||||
options);
|
||||
drivemap_hook =
|
||||
grub_loader_register_preboot_hook (&install_int13_handler,
|
||||
&uninstall_int13_handler,
|
||||
GRUB_LOADER_PREBOOT_HOOK_PRIO_NORMAL);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI (drivemap)
|
||||
{
|
||||
grub_loader_unregister_preboot_hook (drivemap_hook);
|
||||
drivemap_hook = 0;
|
||||
grub_unregister_extcmd (cmd);
|
||||
}
|
66
commands/i386/pc/drivemap_int13h.S
Normal file
66
commands/i386/pc/drivemap_int13h.S
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* 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) - grub_drivemap_handler)
|
||||
|
||||
.code16
|
||||
|
||||
/* Copy starts here. When deployed, this code must be segment-aligned. */
|
||||
|
||||
/* The replacement int13 handler. The code must be position independent.
|
||||
Preserve all registers. */
|
||||
FUNCTION(grub_drivemap_handler)
|
||||
/* Map the drive number (always in DL). */
|
||||
push %ax
|
||||
push %bx
|
||||
movw $INT13H_OFFSET(grub_drivemap_mapstart), %bx
|
||||
|
||||
more_remaining:
|
||||
movw %cs:(%bx), %ax
|
||||
cmpb %ah, %al
|
||||
jz not_found /* DRV=DST => map end - drive not remapped, keep DL. */
|
||||
cmpb %dl, %al
|
||||
jz found /* Found - drive remapped, modify DL. */
|
||||
inc %bx
|
||||
inc %bx
|
||||
jmp more_remaining /* Not found, but more remaining, loop. */
|
||||
|
||||
found:
|
||||
movb %ah, %dl
|
||||
|
||||
not_found:
|
||||
pop %bx
|
||||
pop %ax
|
||||
|
||||
/* Upon arrival to this point the stack must be exactly like at entry.
|
||||
This long jump will transfer the caller's stack to the old INT13
|
||||
handler, thus making it return directly to the original caller. */
|
||||
.byte 0xea
|
||||
|
||||
/* 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)
|
||||
.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)
|
|
@ -185,7 +185,14 @@ pkglib_MODULES = biosdisk.mod chain.mod \
|
|||
aout.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \
|
||||
datehook.mod lsmmap.mod ata_pthru.mod hdparm.mod \
|
||||
usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod \
|
||||
efiemu.mod mmap.mod acpi.mod
|
||||
efiemu.mod mmap.mod acpi.mod drivemap.mod
|
||||
|
||||
# For drivemap.mod.
|
||||
drivemap_mod_SOURCES = commands/i386/pc/drivemap.c \
|
||||
commands/i386/pc/drivemap_int13h.S
|
||||
drivemap_mod_ASFLAGS = $(COMMON_ASFLAGS)
|
||||
drivemap_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||
drivemap_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
||||
|
||||
# For efiemu.mod.
|
||||
efiemu_mod_SOURCES = efiemu/main.c efiemu/i386/loadcore32.c \
|
||||
|
|
Loading…
Reference in a new issue