Patchwork [2/4] handle arguments for ipv4 boot

login
register
mail settings
Submitter Tony Breeds
Date Feb. 24, 2009, 12:15 a.m.
Message ID <20090224001500.GL13714@ozlabs.org>
Download mbox | patch
Permalink /patch/23589/
State RFC
Headers show

Comments

Tony Breeds - Feb. 24, 2009, 12:15 a.m.
On Mon, Sep 15, 2008 at 05:23:39PM -0700, Chandra Seetharaman wrote:
> Currently, yaboot works properly when there is a tftp boot server serving 
> the broadcast requests sent in the network.
> 
> If the user specifies siaddr, ciaddr, and other arguments in the command
> line, it is not handled appropriately.
> 
> This patch changes that behavior and make yaboot work properly in both cases.
> 
> The semantics specified in section 4.1 of
> http://playground.sun.com/1275/practice/obp-tftp/tftp1_0.pdf is followed.
> ([bootp,]siaddr,filename,ciaddr,giaddr,bootp-retries,tftp-retries)
> 
> Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>

Hello Chandra,
	I've tested this out on some of the machines I have here.  The power5
machine fails to work.  Essentially theere are 2 problems.

A few bits about the machine:
-=-=-=-=-=-
     Memory      Keyboard     Network     SCSI     Speaker  ok
0 > devalias  
ibm,sp              /vdevice/IBM,sp@4000
net                 /vdevice/l-lan@30000002
network             /vdevice/l-lan@30000002
scsi                /vdevice/v-scsi@30000032
nvram               /vdevice/nvram@4002
rtc                 /vdevice/rtc@4001
screen              /vdevice/vty@30000000
0 > dev / .properties 
<snip>
name                    IBM,9124-720
model                   IBM,9124-720
compatible              IBM,9124-720
0 > dev /openprom .properties 
name                    openprom
ibm,fw-vernum_encoded   53463234 305f3335 3800
model                   IBM,SF240_358
relative-addressing     
-=-=-=-=-=-

Now to the problems ;P

1) My "bootpath" simply contains the raw device name without any IPv4 options.
   You can see this then the trace snippet below

-=-=-=-=-=-
     Memory      Keyboard     Network     SCSI     Speaker  ok
0 > devalias  
ibm,sp              /vdevice/IBM,sp@4000
net                 /vdevice/l-lan@30000002
network             /vdevice/l-lan@30000002
scsi                /vdevice/v-scsi@30000032
nvram               /vdevice/nvram@4002
rtc                 /vdevice/rtc@4001
screen              /vdevice/vty@30000000
 ok
0 > boot net 
BOOTP: chosen-network-type = ethernet,auto,none,auto
BOOTP: server   IP =        0.0.0.0
BOOTP: requested filename = 
BOOTP: client   IP =        0.0.0.0
BOOTP: client   HW addr =   da d2 30 0 50 2
BOOTP: gateway  IP =        0.0.0.0
BOOTP: device    /vdevice/l-lan@30000002
BOOTP: loc-code  U9124.720.650D08F-V5-C2-T1


BOOTP R = 1 BOOTP S = 2 
FILE: zImage.diego5
FINAL Packet Count = 874 
FINAL File Size = 447236 bytes.
load-base=0x4000 
real-base=0xc00000 

Elapsed time since release of system processors: 110738 mins 22 secs

Adding OF methods...
    prom_init - OF interface initialized.
    yaboot_start - Malloc buffer allocated at 00300000 (1048576 bytes)
    yaboot_start - reloc_offset :  0         (should be 0)
    yaboot_start - test_bss     :  0         (should be 0)
    yaboot_start - test_data    :  0         (should be 0)
    yaboot_start - &test_data   :  00233030
    yaboot_start - &test_bss    :  0023302c
    yaboot_start - linked at    :  0x00200000
    yaboot_start - Running on _machine = 4
    yaboot_main - /chosen/bootargs = 
    yaboot_main - /chosen/bootpath = /vdevice/l-lan@30000002
    parse_device_path - imagepath = /vdevice/l-lan@30000002; defdevice <NULL>; defpart -1, deffile 
    netdev_path_to_dev - path = /vdevice/l-lan@30000002
    yaboot_main - After parse_device_path: dev=/vdevice/l-lan@30000002, part=-1, file=/vdevice/l-lan@30000002
    yaboot_main - After path kludgeup: dev=/vdevice/l-lan@30000002, part=-1, file=/etc/yaboot.conf
Try to netboot
    prom_get_netinfo - using /chosen/bootpreply-packet
    open_file - dev_path = /vdevice/l-lan@30000002
file_name = /etc/01-da-d2-30-00-50-02
partition = -1
    open_file - device is a network device
--> of_net_open
    of_net_open - dev=/vdevice/l-lan@30000002, part=0x00000000 (-1), file_name=/etc/01-da-d2-30-00-50-02
    of_net_open - siaddr <<NULL>>; filename <\etc\01-da-d2-30-00-50-02>; ciaddr <<NULL>>; giaddr <<NULL>>; ipv6 <0>
    of_net_open - Opening: "/vdevice/l-lan@30000002,\etc\01-da-d2-30-00-50-02,,,,,"
    of_net_open - file->of_device = 01bd5900
    prom_claim_chunk - claimed 20971520 at 0x1c00000 (0x1000000)
    of_net_open - TFP...

BOOTP: chosen-network-type = ethernet,auto,none,auto
BOOTP: server   IP =        0.0.0.0
BOOTP: requested filename = 
BOOTP: client   IP =        0.0.0.0
BOOTP: client   HW addr =   da d2 30 0 50 2
BOOTP: gateway  IP =        0.0.0.0
BOOTP: device    /vdevice/l-lan@30000002
BOOTP: loc-code  U9124.720.650D08F-V5-C2-T1
-=-=-=-=-=-

   so while the open succeeded I got another copy of the yaboot ELF rather than a config file ;P

2) When supplying the IPv4 options to OF the prom_opn() fails.  It looks like
   this is because the firmware doesn't support all of the tftp options.
-=-=-=-=-=-
0 > boot net:10.61.2.7,zImage.diego5,10.61.135.50,10.61.2.7,5,5,512  ok
0 > boot net:10.61.2.7,zImage.diego5,10.61.135.50,10.61.2.7,,,  ok
0 > boot net:10.61.2.7,zImage.diego5,10.61.135.50,10.61.2.7 
BOOTP: chosen-network-type = ethernet,auto,none,auto
BOOTP: server   IP =        10.61.2.7
BOOTP: requested filename = zImage.diego5
BOOTP: client   IP =        10.61.135.50
BOOTP: client   HW addr =   da d2 30 0 50 2
BOOTP: gateway  IP =        10.61.2.7
BOOTP: device    /vdevice/l-lan@30000002
BOOTP: loc-code  U9124.720.650D08F-V5-C2-T1


BOOTP R = 1 BOOTP S = 2 
FILE: zImage.diego5
FINAL Packet Count = 874 
FINAL File Size = 447236 bytes.
load-base=0x4000 
real-base=0xc00000 

Elapsed time since release of system processors: 110773 mins 44 secs

Adding OF methods...
    prom_init - OF interface initialized.
    yaboot_start - Malloc buffer allocated at 00300000 (1048576 bytes)
    yaboot_start - reloc_offset :  0         (should be 0)
    yaboot_start - test_bss     :  0         (should be 0)
    yaboot_start - test_data    :  0         (should be 0)
    yaboot_start - &test_data   :  00233030
    yaboot_start - &test_bss    :  0023302c
    yaboot_start - linked at    :  0x00200000
    yaboot_start - Running on _machine = 4
    yaboot_main - /chosen/bootargs = 
    yaboot_main - /chosen/bootpath = /vdevice/l-lan@30000002:10.61.2.7,zImage.diego5,10.61.135.50,10.61.2.7
    parse_device_path - imagepath = /vdevice/l-lan@30000002:10.61.2.7,zImage.diego5,10.61.135.50,10.61.2.7; defdevice <NULL>; defpart -1, deffile 
    extract_args_from_netdev_path - imagepath = /vdevice/l-lan@30000002:10.61.2.7,zImage.diego5,10.61.135.50,10.61.2.7
    extract_args_from_netdev_path - ipv6 = <0>
    extract_args_from_netdev_path - siaddr = <10.61.2.7>
    extract_args_from_netdev_path - file = <zImage.diego5>
    extract_args_from_netdev_path - ciaddr = <10.61.135.50>
    extract_args_from_netdev_path - giaddr = <10.61.2.7>
    extract_args_from_netdev_path - bootp_retries = <<NULL>>
    extract_args_from_netdev_path - tftp_retries = <<NULL>>
    extract_args_from_netdev_path - addl_params = <<NULL>>
    extract_args_from_netdev_path - dhcpv6 = <<NULL>>
    extract_args_from_netdev_path - blksize = <<NULL>>
    netdev_path_to_dev - path = /vdevice/l-lan@30000002:10.61.2.7,zImage.diego5,10.61.135.50,10.61.2.7
    yaboot_main - After parse_device_path: dev=/vdevice/l-lan@30000002:, part=-1, file=zImage.diego5
    yaboot_main - After path kludgeup: dev=/vdevice/l-lan@30000002:, part=-1, file=/etc/yaboot.conf
Try to netboot
    prom_get_netinfo - using /chosen/bootpreply-packet
    open_file - dev_path = /vdevice/l-lan@30000002:
file_name = /etc/01-da-d2-30-00-50-02
partition = -1
    open_file - device is a network device
--> of_net_open
    of_net_open - dev=/vdevice/l-lan@30000002:, part=0x00000000 (-1), file_name=/etc/01-da-d2-30-00-50-02
    of_net_open - siaddr <10.61.2.7>; filename <\etc\01-da-d2-30-00-50-02>; ciaddr <10.61.135.50>; giaddr <10.61.2.7>; ipv6 <0>
    of_net_open - Opening: "/vdevice/l-lan@30000002:10.61.2.7,\etc\01-da-d2-30-00-50-02,10.61.135.50,10.61.2.7,,,"
    of_net_open - file->of_device = 00000000
<-- of_net_open - FILE_ERR_BAD_FSYS
/vdevice/l-lan@30000002::-1,/etc/01-da-d2-30-00-50-02: Unknown or corrupt filesystem
Can't open config file
Welcome to yaboot version 1.3.14
Enter "help" to get some basic usage information
boot: bye
Bye.
    yaboot_start - Malloc buffer released. Exiting with code 0
EXIT called ok
0 > 
-=-=-=-=-=-

   I hacked something up (based largely on a patch by Scott Moser [1]) which
   seems to work with the IPv4 changes.  Clearly its done at the wrong level.
   Still workign on a way to test the IPv6 netboot.

-=-=-=-=-=-
 second/fs_of.c |   63 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 57 insertions(+), 6 deletions(-)

Patch

diff --git a/second/fs_of.c b/second/fs_of.c
index 9c475d8..6227441 100644
--- a/second/fs_of.c
+++ b/second/fs_of.c
@@ -130,6 +130,18 @@  of_open(struct boot_file_t* file,
      return FILE_ERR_OK;
 }
 
+static char *ipv4_to_str(__u32 ip)
+{
+     char *buf = malloc(sizeof("000.000.000.000"));
+
+     sprintf(buf,"%u.%u.%u.%u",
+          (ip & 0xff000000) >> 24,
+          (ip & 0x00ff0000) >> 16,
+          (ip & 0x0000ff00) >> 8,
+          (ip & 0x000000ff));
+     return buf;
+}
+
 static int
 of_net_open(struct boot_file_t* file,
 	    struct partition_t* part, struct boot_fspec_t* fspec)
@@ -137,10 +149,42 @@  of_net_open(struct boot_file_t* file,
      static char	buffer[1024];
      char               *filename = NULL;
      char               *p;
+     struct bootp_packet *packet;
+     int real_tftp;
 
      DEBUG_ENTER;
      DEBUG_OPEN;
 
+     /* If /packages/cas exists the we have a "new skool" tftp */
+     real_tftp = (prom_finddevice("/packages/cas") != PROM_INVALID_HANDLE);
+     DEBUG_F("real_tftp == %x\n", real_tftp);
+
+     /* Check to see if we can get the [scyg]iaddr fields from netinfo */
+     packet = prom_get_netinfo();
+     if (packet != NULL) {
+          DEBUG_F("we have a boot packet\n");
+          DEBUG_F(" siaddr = <%x>\n", packet->siaddr);
+          DEBUG_F(" ciaddr = <%x>\n", packet->ciaddr);
+          DEBUG_F(" yiaddr = <%x>\n", packet->yiaddr);
+          DEBUG_F(" giaddr = <%x>\n", packet->giaddr);
+
+          if (fspec->siaddr == NULL && packet->siaddr != 0)
+               fspec->siaddr = ipv4_to_str(packet->siaddr);
+          if (fspec->ciaddr == NULL && packet->ciaddr != 0)
+               fspec->ciaddr = ipv4_to_str(packet->ciaddr);
+          if (fspec->giaddr == NULL && packet->giaddr != 0)
+               fspec->giaddr = ipv4_to_str(packet->giaddr);
+     }
+
+     /* FIXME: Yck! if we /still/ do not have a gateway then "cheat" and use
+      *        the server.  This will be okay if the client and server are on
+      *        the same IP network, if not then lets hope the server does ICMP
+      *        redirections */
+     if (fspec->giaddr == NULL) {
+          fspec->giaddr = ipv4_to_str(packet->siaddr);
+          DEBUG_F("Forcing giaddr to siaddr <%s>\n", fspec->giaddr);
+     }
+
      if (fspec->file && strlen(fspec->file)) {
 	  filename = strdup(fspec->file);
 	  for (p = filename; *p; p++)
@@ -153,6 +197,10 @@  of_net_open(struct boot_file_t* file,
      strncpy(buffer, fspec->dev, 768);
      if (fspec->is_ipv6)
 	  strcat(buffer, TOK_IPV6 ",");
+
+     /* If we didn't get a ':' include one */
+     if (fspec->dev[strlen(fspec->dev)-1] != ':')
+          strcat(buffer, ":");
      strcat(buffer, fspec->siaddr);
      strcat(buffer, ",");
      if (fspec->is_ipv6 && (strstr(filename, "filename=") == NULL))
@@ -162,12 +210,15 @@  of_net_open(struct boot_file_t* file,
      strcat(buffer, fspec->ciaddr);
      strcat(buffer, ",");
      strcat(buffer, fspec->giaddr);
-     strcat(buffer, ",");
-     strcat(buffer, fspec->bootp_retries);
-     strcat(buffer, ",");
-     strcat(buffer, fspec->tftp_retries);
-     strcat(buffer, ",");
-     strcat(buffer, fspec->addl_params);
+
+     if (real_tftp) {
+          strcat(buffer, ",");
+          strcat(buffer, fspec->bootp_retries);
+          strcat(buffer, ",");
+          strcat(buffer, fspec->tftp_retries);
+          strcat(buffer, ",");
+          strcat(buffer, fspec->addl_params);
+     }
 
      DEBUG_F("Opening: \"%s\"\n", buffer);