[PATCH 1/2] support netbooting on JS21 GA3 and older firmwares

Doug Maxey dwm at enoyolf.org
Sat Oct 6 06:08:44 EST 2007


On Fri, 05 Oct 2007 11:07:10 EDT, Scott Moser wrote:
> 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.

This has never been true for IBM boxen, nothing new here.  Have you tested
any of this with the older apples that support yaboot?

> Newer versions will
>   effectively ignore the '<file>', from the open command and simply download
>   whatever file was listed in the bootp response.

This is still true.

>
>     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 a limitation of IBM OFW.

> 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.

That is incorrect.  You have always had the ability to specify the
tftp server from the OFW command line.

Also, if you let the system boot without specifying (boot uses bootp),
the next-server is still ignored.  Just had this conversation with SFW
folks recently.  The bootp server is the bootp server.  :p

>
>   At the moment we do not expect firmware to change in the future.

I strongly disagree with that statement.  Not only will it change, but
we (being linux) may have little or no say in how or when.  The best
we can hope for is that some documentation will be provided on a
timely basis.  The effort is still proceeding at a glacial pace to get
the documentation out on the new IBM OFW network stack that supports
iSCSI booting.  Thats going on 18 months now.

More comments inline.

>   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();

did it work?  for sure?

> +
>       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. */

You could set to zeros if on the same subnet.  That works from the
OFW CLI, so assume that it would work here.


> +	  strcat(buffer, prom_get_siaddr(packet));

strncat never hurts.  :)

>  	  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);

the binary to text transform could be factored out to a helper.

> +
> +     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);

ditto

> +
> +     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);

and again.

> +
> +     return conf_path;
> +}
> +
> +/*
>   * Local variables:
>   * c-file-style: "k&r"
>   * c-basic-offset: 5
>
> _______________________________________________
> Yaboot-devel mailing list
> Yaboot-devel at ozlabs.org
> https://ozlabs.org/mailman/listinfo/yaboot-devel
>







More information about the Yaboot-devel mailing list