|
@@ -24,6 +24,7 @@
|
24
|
24
|
#include <gpxe/settings.h>
|
25
|
25
|
#include <gpxe/image.h>
|
26
|
26
|
#include <gpxe/embedded.h>
|
|
27
|
+#include <gpxe/uri.h>
|
27
|
28
|
#include <usr/ifmgmt.h>
|
28
|
29
|
#include <usr/route.h>
|
29
|
30
|
#include <usr/dhcpmgmt.h>
|
|
@@ -78,15 +79,39 @@ static int boot_embedded_image ( void ) {
|
78
|
79
|
}
|
79
|
80
|
|
80
|
81
|
/**
|
81
|
|
- * Boot using filename
|
|
82
|
+ * Boot using next-server and filename
|
82
|
83
|
*
|
83
|
84
|
* @v filename Boot filename
|
84
|
85
|
* @ret rc Return status code
|
85
|
86
|
*/
|
86
|
|
-static int boot_filename ( const char *filename ) {
|
|
87
|
+static int boot_next_server_and_filename ( struct in_addr next_server,
|
|
88
|
+ const char *filename ) {
|
|
89
|
+ struct uri *uri;
|
87
|
90
|
struct image *image;
|
|
91
|
+ char buf[ 23 /* tftp://xxx.xxx.xxx.xxx/ */ + strlen(filename) + 1 ];
|
|
92
|
+ int filename_is_absolute;
|
88
|
93
|
int rc;
|
89
|
94
|
|
|
95
|
+ /* Construct URI */
|
|
96
|
+ uri = parse_uri ( filename );
|
|
97
|
+ if ( ! uri ) {
|
|
98
|
+ printf ( "Out of memory\n" );
|
|
99
|
+ return -ENOMEM;
|
|
100
|
+ }
|
|
101
|
+ filename_is_absolute = uri_is_absolute ( uri );
|
|
102
|
+ uri_put ( uri );
|
|
103
|
+ if ( ! filename_is_absolute ) {
|
|
104
|
+ /* Construct a tftp:// URI for the filename. We can't
|
|
105
|
+ * just rely on the current working URI, because the
|
|
106
|
+ * relative URI resolution will remove the distinction
|
|
107
|
+ * between filenames with and without initial slashes,
|
|
108
|
+ * which is significant for TFTP.
|
|
109
|
+ */
|
|
110
|
+ snprintf ( buf, sizeof ( buf ), "tftp://%s/%s",
|
|
111
|
+ inet_ntoa ( next_server ), filename );
|
|
112
|
+ filename = buf;
|
|
113
|
+ }
|
|
114
|
+
|
90
|
115
|
image = alloc_image();
|
91
|
116
|
if ( ! image ) {
|
92
|
117
|
printf ( "Out of memory\n" );
|
|
@@ -135,6 +160,7 @@ int boot_root_path ( const char *root_path ) {
|
135
|
160
|
*/
|
136
|
161
|
static int netboot ( struct net_device *netdev ) {
|
137
|
162
|
char buf[256];
|
|
163
|
+ struct in_addr next_server;
|
138
|
164
|
int rc;
|
139
|
165
|
|
140
|
166
|
/* Open device and display device status */
|
|
@@ -161,10 +187,11 @@ static int netboot ( struct net_device *netdev ) {
|
161
|
187
|
return rc;
|
162
|
188
|
|
163
|
189
|
/* Try to download and boot whatever we are given as a filename */
|
|
190
|
+ fetch_ipv4_setting ( NULL, &next_server_setting, &next_server );
|
164
|
191
|
fetch_string_setting ( NULL, &filename_setting, buf, sizeof ( buf ) );
|
165
|
192
|
if ( buf[0] ) {
|
166
|
193
|
printf ( "Booting from filename \"%s\"\n", buf );
|
167
|
|
- return boot_filename ( buf );
|
|
194
|
+ return boot_next_server_and_filename ( next_server, buf );
|
168
|
195
|
}
|
169
|
196
|
|
170
|
197
|
/* No filename; try the root path */
|