Allow override Plan9 device names

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-12-21 00:22:11 +01:00
parent da94d203d9
commit 645b8cd99f

View file

@ -32,6 +32,7 @@
#include <grub/video.h> #include <grub/video.h>
#include <grub/mm.h> #include <grub/mm.h>
#include <grub/cpu/relocator.h> #include <grub/cpu/relocator.h>
#include <grub/extcmd.h>
static grub_dl_t my_mod; static grub_dl_t my_mod;
static struct grub_relocator *rel; static struct grub_relocator *rel;
@ -43,6 +44,14 @@ static grub_uint32_t eip = 0xffffffff;
#define GRUB_PLAN9_CONFIG_PATH_SIZE 0x000040 #define GRUB_PLAN9_CONFIG_PATH_SIZE 0x000040
#define GRUB_PLAN9_CONFIG_MAGIC "ZORT 0\r\n" #define GRUB_PLAN9_CONFIG_MAGIC "ZORT 0\r\n"
static const struct grub_arg_option options[] =
{
{"map", 'm', GRUB_ARG_OPTION_REPEATABLE,
N_("Override guessed mapping of Plan9 devices."), "GRUBDEVICE=PLAN9DEVICE",
ARG_TYPE_STRING},
{0, 0, 0, 0, 0, 0}
};
struct grub_plan9_header struct grub_plan9_header
{ {
grub_uint32_t magic; grub_uint32_t magic;
@ -85,8 +94,7 @@ grub_plan9_unload (void)
} }
static grub_err_t static grub_err_t
grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
int argc, char *argv[])
{ {
grub_file_t file = 0; grub_file_t file = 0;
void *mem; void *mem;
@ -94,7 +102,6 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)),
struct grub_plan9_header hdr; struct grub_plan9_header hdr;
char *config, *configptr; char *config, *configptr;
grub_size_t configsize; grub_size_t configsize;
int i;
char *pmap = NULL; char *pmap = NULL;
grub_size_t pmapalloc = 256; grub_size_t pmapalloc = 256;
grub_size_t pmapptr = 0; grub_size_t pmapptr = 0;
@ -193,6 +200,7 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)),
grub_device_t dev; grub_device_t dev;
int file_disk; int file_disk;
char *plan9name = NULL; char *plan9name = NULL;
unsigned i;
dev = grub_device_open (name); dev = grub_device_open (name);
if (!dev) if (!dev)
@ -207,55 +215,50 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)),
} }
file_disk = file->device->disk && dev->disk->id == file->device->disk->id file_disk = file->device->disk && dev->disk->id == file->device->disk->id
&& dev->disk->dev->id == file->device->disk->dev->id; && dev->disk->dev->id == file->device->disk->dev->id;
switch (dev->disk->dev->id) for (i = 0; ctxt->state[0].args && ctxt->state[0].args[i]; i++)
{ if (grub_strncmp (name, ctxt->state[0].args[i], grub_strlen (name)) == 0
case GRUB_DISK_DEVICE_BIOSDISK_ID: && ctxt->state[0].args[i][grub_strlen (name)] == '=')
if (dev->disk->id & 0x80)
plan9name = grub_xasprintf ("sdB%u",
(unsigned) (dev->disk->id & 0x7f));
else
plan9name = grub_xasprintf ("fd%u",
(unsigned) (dev->disk->id & 0x7f));
break; break;
/* Shouldn't happen as Plan9 doesn't work on these platforms. */ if (ctxt->state[0].args && ctxt->state[0].args[i])
case GRUB_DISK_DEVICE_OFDISK_ID: plan9name = grub_strdup (ctxt->state[0].args[i] + grub_strlen (name) + 1);
case GRUB_DISK_DEVICE_EFIDISK_ID: else
switch (dev->disk->dev->id)
/* Plan9 doesn't see those. */
case GRUB_DISK_DEVICE_LOOPBACK_ID:
case GRUB_DISK_DEVICE_RAID_ID:
case GRUB_DISK_DEVICE_LVM_ID:
case GRUB_DISK_DEVICE_HOST_ID:
case GRUB_DISK_DEVICE_MEMDISK_ID:
case GRUB_DISK_DEVICE_LUKS_ID:
/* Not sure how to handle those. */
case GRUB_DISK_DEVICE_PXE_ID:
case GRUB_DISK_DEVICE_NAND_ID:
if (!file_disk)
{
grub_device_close (dev);
return 0;
}
/* if it's the disk the kernel is loaded from we need to name
it nevertheless. */
plan9name = grub_strdup ("sdZ0");
break;
case GRUB_DISK_DEVICE_ATA_ID:
{ {
int unit; case GRUB_DISK_DEVICE_BIOSDISK_ID:
if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) if (dev->disk->id & 0x80)
unit = 0; plan9name = grub_xasprintf ("sdB%u",
(unsigned) (dev->disk->id & 0x7f));
else else
unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0); plan9name = grub_xasprintf ("fd%u",
plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); (unsigned) (dev->disk->id & 0x7f));
} break;
break; /* Shouldn't happen as Plan9 doesn't work on these platforms. */
case GRUB_DISK_DEVICE_SCSI_ID: case GRUB_DISK_DEVICE_OFDISK_ID:
if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff) case GRUB_DISK_DEVICE_EFIDISK_ID:
== GRUB_SCSI_SUBSYSTEM_ATAPI)
/* Plan9 doesn't see those. */
case GRUB_DISK_DEVICE_LOOPBACK_ID:
case GRUB_DISK_DEVICE_RAID_ID:
case GRUB_DISK_DEVICE_LVM_ID:
case GRUB_DISK_DEVICE_HOST_ID:
case GRUB_DISK_DEVICE_MEMDISK_ID:
case GRUB_DISK_DEVICE_LUKS_ID:
/* Not sure how to handle those. */
case GRUB_DISK_DEVICE_PXE_ID:
case GRUB_DISK_DEVICE_NAND_ID:
if (!file_disk)
{
grub_device_close (dev);
return 0;
}
/* if it's the disk the kernel is loaded from we need to name
it nevertheless. */
plan9name = grub_strdup ("sdZ0");
break;
case GRUB_DISK_DEVICE_ATA_ID:
{ {
int unit; int unit;
if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1)
@ -263,16 +266,30 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)),
else else
unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0); unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0);
plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2);
break;
} }
break;
case GRUB_DISK_DEVICE_SCSI_ID:
if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff)
== GRUB_SCSI_SUBSYSTEM_ATAPI)
{
int unit;
if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1)
unit = 0;
else
unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1,
0, 0);
plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2);
break;
}
/* FIXME: how does Plan9 number controllers? /* FIXME: how does Plan9 number controllers?
We probably need save the SCSI devices and sort them */ We probably need save the SCSI devices and sort them */
plan9name plan9name
= grub_xasprintf ("sd0%u", (unsigned) = grub_xasprintf ("sd0%u", (unsigned)
((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT) & 0xf)); ((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT)
break; & 0xf));
} break;
}
if (!plan9name) if (!plan9name)
{ {
grub_print_error (); grub_print_error ();
@ -347,8 +364,11 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)),
configsize = GRUB_PLAN9_CONFIG_PATH_SIZE; configsize = GRUB_PLAN9_CONFIG_PATH_SIZE;
/* magic */ /* magic */
configsize += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1; configsize += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1;
for (i = 1; i < argc; i++) {
configsize += grub_strlen (argv[i]) + 1; int i;
for (i = 1; i < argc; i++)
configsize += grub_strlen (argv[i]) + 1;
}
configsize += pmapptr; configsize += pmapptr;
/* Terminating \0. */ /* Terminating \0. */
configsize++; configsize++;
@ -368,11 +388,14 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)),
grub_memcpy (configptr, GRUB_PLAN9_CONFIG_MAGIC, grub_memcpy (configptr, GRUB_PLAN9_CONFIG_MAGIC,
sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1); sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1);
configptr += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1; configptr += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1;
for (i = 1; i < argc; i++) {
{ int i;
configptr = grub_stpcpy (configptr, argv[i]); for (i = 1; i < argc; i++)
*configptr++ = '\n'; {
} configptr = grub_stpcpy (configptr, argv[i]);
*configptr++ = '\n';
}
}
configptr = grub_stpcpy (configptr, pmap); configptr = grub_stpcpy (configptr, pmap);
{ {
@ -429,16 +452,18 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)),
return grub_errno; return grub_errno;
} }
static grub_command_t cmd; static grub_extcmd_t cmd;
GRUB_MOD_INIT(plan9) GRUB_MOD_INIT(plan9)
{ {
cmd = grub_register_command ("plan9", grub_cmd_plan9, cmd = grub_register_extcmd ("plan9", grub_cmd_plan9,
0, N_("Load Plan9 kernel.")); GRUB_COMMAND_OPTIONS_AT_START,
N_("KERNEL ARGS"), N_("Load Plan9 kernel."),
options);
my_mod = mod; my_mod = mod;
} }
GRUB_MOD_FINI(plan9) GRUB_MOD_FINI(plan9)
{ {
grub_unregister_command (cmd); grub_unregister_extcmd (cmd);
} }