Browse Source

[linux] Add command line arguments

Support qemu-like arguments for network setup:
--net driver_name[,setting=value]*

and global settings:
--settings setting=value[,setting=value]*

Signed-off-by: Piotr Jaroszyński <p.jaroszynski@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Piotr Jaroszyński 14 years ago
parent
commit
ddef2e1bc1

+ 3
- 0
src/arch/i386/prefix/linuxprefix.S View File

@@ -16,6 +16,9 @@ _start:
16 16
 	pushl	%edi // argv -> C arg2
17 17
 	pushl	%esi // argc -> C arg1
18 18
 
19
+	call	save_args
20
+
21
+	/* Our main doesn't use any arguments */
19 22
 	call	main
20 23
 
21 24
 	movl	%eax, %ebx // rc -> syscall arg1

+ 3
- 0
src/arch/x86_64/prefix/linuxprefix.S View File

@@ -13,6 +13,9 @@ _start:
13 13
 
14 14
 	andq	$~15, %rsp // 16-byte align the stack
15 15
 
16
+	call	save_args
17
+
18
+	/* Our main doesn't use any arguments */
16 19
 	call	main
17 20
 
18 21
 	movq	%rax, %rdi // rc -> syscall arg1

+ 190
- 0
src/hci/linux_args.c View File

@@ -0,0 +1,190 @@
1
+/*
2
+ * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17
+ */
18
+
19
+FILE_LICENCE(GPL2_OR_LATER);
20
+
21
+#include <hci/linux_args.h>
22
+#include <getopt.h>
23
+#include <string.h>
24
+#include <stdio.h>
25
+#include <ipxe/settings.h>
26
+#include <ipxe/linux.h>
27
+#include <ipxe/malloc.h>
28
+#include <ipxe/init.h>
29
+
30
+/** Saved argc */
31
+static int saved_argc = 0;
32
+/** Saved argv */
33
+static char ** saved_argv;
34
+
35
+/**
36
+ * Save argc and argv for later access.
37
+ *
38
+ * To be called by linuxprefix
39
+ */
40
+__asmcall void save_args(int argc, char **argv)
41
+{
42
+	saved_argc = argc;
43
+	saved_argv = argv;
44
+}
45
+
46
+/** Supported command-line options */
47
+static struct option options[] = {
48
+	{"net", 1, 0, 'n'},
49
+	{"settings", 1, 0, 's'},
50
+	{0, 0, 0, 0}
51
+};
52
+
53
+/**
54
+ * Parse k1=v1[,k2=v2]* into linux_settings
55
+ */
56
+static int parse_kv(char *kv, struct list_head *list)
57
+{
58
+	char *token;
59
+	char *name;
60
+	char *value;
61
+	struct linux_setting *setting;
62
+
63
+	while ((token = strsep(&kv, ",")) != NULL) {
64
+		name = strsep(&token, "=");
65
+		if (name == NULL)
66
+			continue;
67
+		value = token;
68
+		if (value == NULL) {
69
+			DBG("Bad parameter: '%s'\n", name);
70
+			continue;
71
+		}
72
+
73
+		setting = malloc(sizeof(*setting));
74
+
75
+		if (! setting)
76
+			return -1;
77
+
78
+		setting->name = name;
79
+		setting->value = value;
80
+		setting->applied = 0;
81
+		list_add(&setting->list, list);
82
+	}
83
+
84
+	return 0;
85
+}
86
+
87
+/**
88
+ * Parse --net arguments
89
+ *
90
+ * Format is --net driver_name[,name=value]*
91
+ */
92
+static int parse_net_args(char *args)
93
+{
94
+	char *driver;
95
+	struct linux_device_request *dev_request;
96
+	int rc;
97
+
98
+	driver = strsep(&args, ",");
99
+
100
+	if (strlen(driver) == 0) {
101
+		printf("Missing driver name");
102
+		return -1;
103
+	}
104
+
105
+	dev_request = malloc(sizeof(*dev_request));
106
+
107
+	dev_request->driver = driver;
108
+	INIT_LIST_HEAD(&dev_request->settings);
109
+	list_add_tail(&dev_request->list, &linux_device_requests);
110
+
111
+	/* Parse rest of the settings */
112
+	rc = parse_kv(args, &dev_request->settings);
113
+
114
+	if (rc)
115
+		printf("Parsing net settings failed");
116
+
117
+	return rc;
118
+}
119
+
120
+/**
121
+ * Parse --settings arguments
122
+ *
123
+ * Format is --settings name=value[,name=value]*
124
+ */
125
+static int parse_settings_args(char *args)
126
+{
127
+	return parse_kv(args, &linux_global_settings);
128
+}
129
+
130
+
131
+/** Parse passed command-line arguments */
132
+void linux_args_parse()
133
+{
134
+	int c;
135
+	int rc;
136
+
137
+	reset_getopt();
138
+	while (1) {
139
+		int option_index = 0;
140
+
141
+		c = getopt_long(saved_argc, saved_argv, "", options, &option_index);
142
+		if (c == -1)
143
+			break;
144
+
145
+		switch (c) {
146
+		case 'n':
147
+			if ((rc = parse_net_args(optarg)) != 0)
148
+				return;
149
+			break;
150
+		case 's':
151
+			if ((rc = parse_settings_args(optarg)) != 0)
152
+				return;
153
+			break;
154
+		default:
155
+			return;
156
+		}
157
+	}
158
+
159
+	return;
160
+}
161
+
162
+/** Clean up requests and settings */
163
+void linux_args_cleanup(int flags __unused)
164
+{
165
+	struct linux_device_request *request;
166
+	struct linux_device_request *rtmp;
167
+	struct linux_setting *setting;
168
+	struct linux_setting *stmp;
169
+
170
+	/* Clean up requests and their settings */
171
+	list_for_each_entry_safe(request, rtmp, &linux_device_requests, list) {
172
+		list_for_each_entry_safe(setting, stmp, &request->settings, list) {
173
+			list_del(&setting->list);
174
+			free(setting);
175
+		}
176
+		list_del(&request->list);
177
+		free(request);
178
+	}
179
+
180
+	/* Clean up global settings */
181
+	list_for_each_entry_safe(setting, stmp, &linux_global_settings, list) {
182
+		list_del(&setting->list);
183
+		free(setting);
184
+	}
185
+}
186
+
187
+struct startup_fn startup_linux_args __startup_fn(STARTUP_EARLY) = {
188
+	.startup = linux_args_parse,
189
+	.shutdown = linux_args_cleanup,
190
+};

+ 31
- 0
src/include/hci/linux_args.h View File

@@ -0,0 +1,31 @@
1
+/*
2
+ * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17
+ */
18
+
19
+#ifndef _HCI_LINUX_ARGS_H
20
+#define _HCI_LINUX_ARGS_H
21
+
22
+FILE_LICENCE(GPL2_OR_LATER);
23
+
24
+/**
25
+ * Save argc and argv for later access.
26
+ *
27
+ * To be called by linuxprefix
28
+ */
29
+extern __asmcall void save_args(int argc, char **argv);
30
+
31
+#endif /* _HCI_LINUX_ARGS_H */

Loading…
Cancel
Save