summaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
authorZheng Da <zhengda1936@gmail.com>2010-09-20 21:39:02 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2010-09-20 21:39:02 +0200
commit22bc9da3dd61c6b12f8d03946ef75ec9cfb88a22 (patch)
tree74d5a3fe9843307c99543ff4b91bb65b8e20d00d /boot
parente58f5b6e2ef7ec859b799ba3d58914443ae47efe (diff)
Add device virtualisation support to boot
* boot/boot.c: Add '-f' option. (dev_map): New structure. (dev_map_head): New variable. (add_dev_map): New function. (lookup_dev): New function. (parse_opt): Handle the '-f' option: call 'add_dev_map'. (ds_device_open): Try to call 'lookup_dev', and open the device from the device file if it succeeds.
Diffstat (limited to 'boot')
-rw-r--r--boot/boot.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/boot/boot.c b/boot/boot.c
index 33e1930e..1a4e1b12 100644
--- a/boot/boot.c
+++ b/boot/boot.c
@@ -432,14 +432,53 @@ static struct argp_option options[] =
"Pause for user confirmation at various times during booting" },
{ "isig", 'I', 0, 0,
"Do not disable terminal signals, so you can suspend and interrupt boot."},
+ { "device", 'f', "device_name=device_file", 0,
+ "Specify a device file used by subhurd and its virtual name."},
{ 0 }
};
static char args_doc[] = "BOOT-SCRIPT";
static char doc[] = "Boot a second hurd";
+struct dev_map
+{
+ char *name;
+ mach_port_t port;
+ struct dev_map *next;
+};
+
+static struct dev_map *dev_map_head;
+
+static struct dev_map *add_dev_map (char *dev_name, char *dev_file)
+{
+ struct dev_map *map = malloc (sizeof (*map));
+
+ assert (map);
+ map->name = dev_name;
+ map->port = file_name_lookup (dev_file, 0, 0);
+ if (map->port == MACH_PORT_NULL)
+ error (1, errno, "file_name_lookup: %s", dev_file);
+ map->next = dev_map_head;
+ dev_map_head = map;
+ return map;
+}
+
+static struct dev_map *lookup_dev (char *dev_name)
+{
+ struct dev_map *map;
+
+ for (map = dev_map_head; map; map = map->next)
+ {
+ if (strcmp (map->name, dev_name) == 0)
+ return map;
+ }
+ return NULL;
+}
+
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
+ char *dev_file;
+
switch (key)
{
size_t len;
@@ -458,6 +497,14 @@ parse_opt (int key, char *arg, struct argp_state *state)
bootstrap_args[len] = '\0';
break;
+ case 'f':
+ dev_file = strchr (arg, '=');
+ if (dev_file == NULL)
+ return ARGP_ERR_UNKNOWN;
+ *dev_file = 0;
+ add_dev_map (arg, dev_file+1);
+ break;
+
case ARGP_KEY_ARG:
if (state->arg_num == 0)
bootscript = arg;
@@ -942,6 +989,8 @@ ds_device_open (mach_port_t master_port,
mach_port_t *device,
mach_msg_type_name_t *devicetype)
{
+ struct dev_map *map;
+
if (master_port != pseudo_master_device_port)
return D_INVALID_OPERATION;
@@ -965,6 +1014,13 @@ ds_device_open (mach_port_t master_port,
return 0;
}
+ map = lookup_dev (name);
+ if (map)
+ {
+ *devicetype = MACH_MSG_TYPE_MOVE_SEND;
+ return device_open (map->port, mode, "", device);
+ }
+
*devicetype = MACH_MSG_TYPE_MOVE_SEND;
return device_open (master_device_port, mode, name, device);
}