[PATCH 1/2] support netbooting on JS21 GA3 and older firmwares
Scott Moser
ssmoser at us.ibm.com
Sat Oct 6 01:07:10 EST 2007
The patch below was originally submitted by Andrew Wray under subject
"Patch to allow netbooting with IBM JS21 GA3 firmware" [1].
I'm re-submitting it with the following description.
modify of_net_open to add support for recent power openfirmware
implementations. This includes JS21 ("GA3" level), JS22, and power6
hardware. Newer firmware differs on how the following "load" command is
handled
<device>:,<file>
Previous versions would do a bootp request to get the TCP/IP information
and then tftp the my_file from the returned siaddr. Newer versions will
effectively ignore the '<file>', from the open command and simply download
whatever file was listed in the bootp response.
These changes break yaboot's of_net_open on networks where the bootp
server is not the same system as the tftp server. This is implemented
by dhcpd's 'next-server' keyword. This is because the older firmwares were
really not capable of doing a tftp load. Ie, the 'boot' command line:
<device>:<siaddr>,<file>,<ciaddr>
requires that <siaddr> to be running a bootp server, not simply a tftp
server. The above syntax works correctly with new firmwares.
At the moment we do not expect firmware to change in the future. In
order to make network booting work on these systems these changes (or
similar) will be needed.
--
[1] http://ozlabs.org/pipermail/yaboot-devel/2007-August/000156.html
diff --git a/include/prom.h b/include/prom.h
index f5ee88f..b48e230 100644
--- a/include/prom.h
+++ b/include/prom.h
@@ -154,5 +154,8 @@ struct bootp_packet {
struct bootp_packet * prom_get_netinfo (void);
char * prom_get_mac (struct bootp_packet * packet);
char * prom_get_ip (struct bootp_packet * packet);
+char * prom_get_yiaddr (struct bootp_packet * packet);
+char * prom_get_siaddr (struct bootp_packet * packet);
+char * prom_get_giaddr (struct bootp_packet * packet);
#endif
diff --git a/second/fs_of.c b/second/fs_of.c
index 76474ee..a9404f6 100644
--- a/second/fs_of.c
+++ b/second/fs_of.c
@@ -138,18 +138,29 @@ of_net_open(struct boot_file_t* file, const char* dev_name,
static char buffer[1024];
char *filename;
char *p;
+ struct bootp_packet *packet;
DEBUG_ENTER;
DEBUG_OPEN;
+ packet = prom_get_netinfo();
+
strncpy(buffer, dev_name, 768);
if (file_name && strlen(file_name)) {
+ strcat(buffer, prom_get_siaddr(packet));
strcat(buffer, ",");
filename = strdup(file_name);
for (p = filename; *p; p++)
if (*p == '/')
*p = '\\';
strcat(buffer, filename);
+ strcat(buffer, ",");
+ strcat(buffer, prom_get_yiaddr(packet));
+ strcat(buffer, ",");
+ /* Hack required since giaddr not returned on some systems
+ and required to boot on those systems. This should work
+ for the client and server on the same subnet. */
+ strcat(buffer, prom_get_siaddr(packet));
free(filename);
}
diff --git a/second/prom.c b/second/prom.c
index e9c5843..bd2451e 100644
--- a/second/prom.c
+++ b/second/prom.c
@@ -752,6 +752,78 @@ char * prom_get_ip (struct bootp_packet * packet)
}
/*
+ * prom_get_yiaddr()
+ * returns the ip addr of the client in dotted decimal format
+ */
+char * prom_get_yiaddr (struct bootp_packet * packet)
+{
+ char * conf_path;
+
+ if (!packet)
+ return NULL;
+
+ /* 15 chars in yiaddr + \0 */
+ conf_path = malloc(16);
+ if (!conf_path)
+ return NULL;
+ sprintf(conf_path, "%d.%d.%d.%d",
+ packet->yiaddr >> 24,
+ (packet->yiaddr << 8) >> 24,
+ (packet->yiaddr << 16) >> 24,
+ (packet->yiaddr << 24) >> 24);
+
+ return conf_path;
+}
+
+/*
+ * prom_get_siaddr()
+ * returns the ip addr of the server in dotted decimal format
+ */
+char * prom_get_siaddr (struct bootp_packet * packet)
+{
+ char * conf_path;
+
+ if (!packet)
+ return NULL;
+
+ /* 15 chars in siaddr + \0 */
+ conf_path = malloc(16);
+ if (!conf_path)
+ return NULL;
+ sprintf(conf_path, "%d.%d.%d.%d",
+ packet->siaddr >> 24,
+ (packet->siaddr << 8) >> 24,
+ (packet->siaddr << 16) >> 24,
+ (packet->siaddr << 24) >> 24);
+
+ return conf_path;
+}
+
+/*
+ * prom_get_giaddr()
+ * returns the ip addr of the gateway in dotted decimal format
+ */
+char * prom_get_giaddr (struct bootp_packet * packet)
+{
+ char * conf_path;
+
+ if (!packet)
+ return NULL;
+
+ /* 15 chars in giaddr + \0 */
+ conf_path = malloc(16);
+ if (!conf_path)
+ return NULL;
+ sprintf(conf_path, "%d.%d.%d.%d",
+ packet->giaddr >> 24,
+ (packet->giaddr << 8) >> 24,
+ (packet->giaddr << 16) >> 24,
+ (packet->giaddr << 24) >> 24);
+
+ return conf_path;
+}
+
+/*
* Local variables:
* c-file-style: "k&r"
* c-basic-offset: 5
More information about the Yaboot-devel
mailing list