diff options
author | Zheng Da <zhengda1936@gmail.com> | 2010-09-20 21:39:02 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2010-09-20 21:39:02 +0200 |
commit | 22bc9da3dd61c6b12f8d03946ef75ec9cfb88a22 (patch) | |
tree | 74d5a3fe9843307c99543ff4b91bb65b8e20d00d | |
parent | e58f5b6e2ef7ec859b799ba3d58914443ae47efe (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.
-rw-r--r-- | boot/boot.c | 56 |
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); } |