Index: yaboot.git_head/include/file.h
===================================================================
--- yaboot.git_head.orig/include/file.h
+++ yaboot.git_head/include/file.h
@@ -39,7 +39,13 @@ struct boot_file_t;
 struct boot_fspec_t {
 	char*	dev;		/* OF device path */
 	int	part;		/* Partition number or -1 */
+	char*	siaddr;		/* Server address */
 	char*	file;		/* File path */
+	char*	ciaddr;		/* Client address */
+	char*	giaddr;		/* Gateway address */
+	char*	bootp_retries;	/* Bootp retries */
+	char*	tftp_retries;	/* TFTP retries */
+	char*	addl_params;	/* copy all additional parameters */
 };
 
 struct boot_file_t {
Index: yaboot.git_head/second/file.c
===================================================================
--- yaboot.git_head.orig/second/file.c
+++ yaboot.git_head/second/file.c
@@ -38,19 +38,48 @@
 
 extern char bootdevice[];
 
-static char *netdev_path_to_filename(const char *path)
+/*
+ * Copy the string from source to dest till newline or comma(,) is seen
+ * in the source.
+ * Move source and dest pointers respectively.
+ * Returns pointer to the start of the string that has just been copied.
+ */
+static char *
+scopy(char **dest, char **source)
 {
-     char *tmp, *args, *filename;
-     size_t len;
-
-     DEBUG_F("path = %s\n", path);
+     char *ret = *dest;
 
-     if (!path)
+     if (!**source)
 	  return NULL;
 
-     args = strrchr(path, ':');
+     while (**source != ',' && **source != '\0')
+	  *(*dest)++ = *(*source)++;
+     if (**source != '\0')
+	  *(*source)++;
+     **dest = '\0';
+     *(*dest)++;
+     return ret;
+}
+
+/*
+ * Extract all the arguments provided in the imagepath and fill it in result.
+ * Returns 1 on success, 0 on failure.
+ */
+static int
+extract_args_from_netdev_path(char *imagepath, struct boot_fspec_t *result)
+{
+     char *tmp, *args, *str, *start;
+
+     DEBUG_F("imagepath = %s\n", imagepath);
+
+     if (!imagepath)
+	  return 1;
+
+     args = strrchr(imagepath, ':');
      if (!args)
-	  return NULL;
+	  return 1;
+
+     start = args; /* used to see if we read any optional parameters */
 
      /* The obp-tftp device arguments should be at the end of
       * the argument list.  Skip over any extra arguments (promiscuous,
@@ -77,46 +106,42 @@ static char *netdev_path_to_filename(con
      if (tmp && tmp > args)
 	  args = tmp + strlen("rarp");
 
-     args = strchr(args, ',');
-     if (!args)
-	  return NULL;
-
-     tmp = args;
-     tmp--;
-     /* If the preceding character is ':' then there were no
-      * non-obp-tftp arguments and we know we're right up to the
-      * filename.  Otherwise, we must advance args once more.
-      */
-     args++;
-     if (*tmp != ':') {
+     if (args != start) /* we read some parameters, so go past the next comma(,) */
 	  args = strchr(args, ',');
-	  if (!args)
-	       return NULL;
-	  args++;
-     }
-
-     /* filename may be empty; e.g. enet:192.168.1.1,,192.168.1.2 */
-     if (*args == ',') {
-	  DEBUG_F("null filename\n");
-	  return NULL;
-     }
+     if (!args)
+	  return 1;
 
-     /* Now see whether there are more args following the filename. */
-     tmp = strchr(args, ',');
-     if (!tmp)
-	  len = strlen(args) + 1;
-     else
-	  len = tmp - args + 1;
+     str = malloc(strlen(args) + 1); /*long enough to hold all strings */
+     if (!str)
+	  return 0;
 
-     filename = malloc(len);
-     if (!filename)
-	  return NULL;
+     if (args[-1] != ':')
+	  args++; /* If comma(,) is not immediately followed by ':' then go past the , */
 
-     strncpy(filename, args, len);
-     filename[len - 1] = '\0';
+     /*
+      * read the arguments in order: siaddr,filename,ciaddr,giaddr,
+      * bootp-retries,tftp-retries,addl_prameters
+      */
+     result->siaddr = scopy(&str, &args);
+     result->file = scopy(&str, &args);
+     result->ciaddr = scopy(&str, &args);
+     result->giaddr = scopy(&str, &args);
+     result->bootp_retries = scopy(&str, &args);
+     result->tftp_retries = scopy(&str, &args);
+     if (*args) {
+	  result->addl_params = strdup(args);
+	  if (!result->addl_params)
+		return 0;
+     }
 
-     DEBUG_F("filename = %s\n", filename);
-     return filename;
+     DEBUG_F("siaddr = <%s>\n", result->siaddr);
+     DEBUG_F("file = <%s>\n", result->file);
+     DEBUG_F("ciaddr = <%s>\n", result->ciaddr);
+     DEBUG_F("giaddr = <%s>\n", result->giaddr);
+     DEBUG_F("bootp_retries = <%s>\n", result->bootp_retries);
+     DEBUG_F("tftp_retries = <%s>\n", result->tftp_retries);
+     DEBUG_F("addl_params = <%s>\n", result->addl_params);
+     return 1;
 }
 
 static char *netdev_path_to_dev(const char *path)
@@ -163,6 +188,10 @@ static char *netdev_path_to_dev(const ch
     - enet:,/tftpboot/vmlinux
     - enet:bootp
     - enet:0
+    - arguments for obp-tftp open as specified in section 4.1 of
+      http://playground.sun.com/1275/practice/obp-tftp/tftp1_0.pdf
+      [bootp,]siaddr,filename,ciaddr,giaddr,bootp-retries,tftp-retries
+      ex: enet:bootp,10.0.0.11,bootme,10.0.0.12,10.0.0.1,5,5
    Supported only if defdevice == NULL
     - disc
     - any other device path lacking a :
@@ -179,6 +208,9 @@ parse_device_path(char *imagepath, char 
      char *defdev = NULL;
      int device_kind = -1;
 
+     DEBUG_F("imagepath = %s; defdevice %s; defpart %d, deffile %s\n",
+		imagepath, defdevice, defpart, deffile);
+
      result->dev = NULL;
      result->part = -1;
      result->file = NULL;
@@ -247,9 +279,10 @@ parse_device_path(char *imagepath, char 
      }
 
      if (device_kind == FILE_DEVICE_NET) {
-	  if (strchr(ipath, ':'))
-	       result->file = netdev_path_to_filename(ipath);
-	  else
+	  if (strchr(ipath, ':')) {
+	       if (extract_args_from_netdev_path(ipath, result) == 0)
+		   return 0;
+	  } else
 	       result->file = strdup(ipath);
 
 	  if (!defdev)
Index: yaboot.git_head/second/fs_of.c
===================================================================
--- yaboot.git_head.orig/second/fs_of.c
+++ yaboot.git_head/second/fs_of.c
@@ -135,23 +135,36 @@ of_net_open(struct boot_file_t* file,
 	    struct partition_t* part, struct boot_fspec_t* fspec)
 {
      static char	buffer[1024];
-     char               *filename;
+     char               *filename = NULL;
      char               *p;
 
      DEBUG_ENTER;
      DEBUG_OPEN;
 
-     strncpy(buffer, fspec->dev, 768);
      if (fspec->file && strlen(fspec->file)) {
-	  strcat(buffer, ",");
 	  filename = strdup(fspec->file);
 	  for (p = filename; *p; p++)
 	       if (*p == '/')
 		    *p = '\\';
-	  strcat(buffer, filename);
-	  free(filename);
      }
 
+     DEBUG_F("siaddr <%s>; filename <%s>; ciaddr <%s>; giaddr <%s>;\n",
+		fspec->siaddr, filename, fspec->ciaddr, fspec->giaddr);
+     strncpy(buffer, fspec->dev, 768);
+     strcat(buffer, fspec->siaddr);
+     strcat(buffer, ",");
+     strcat(buffer, filename);
+     strcat(buffer, ",");
+     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);
+
      DEBUG_F("Opening: \"%s\"\n", buffer);
 
      file->of_device = prom_open(buffer);
Index: yaboot.git_head/second/yaboot.c
===================================================================
--- yaboot.git_head.orig/second/yaboot.c
+++ yaboot.git_head/second/yaboot.c
@@ -300,6 +300,7 @@ void print_message_file(char *filename)
 	  }
 
      strncpy(msgpath, filename, sizeof(msgpath));
+     msgfile = boot; /* Copy all the original paramters */
      if (!parse_device_path(msgpath, defdev, defpart, "/etc/yaboot.msg", &msgfile)) {
 	  prom_printf("%s: Unable to parse\n", msgpath);
 	  goto done;
@@ -990,6 +991,7 @@ int get_params(struct boot_param_t* para
      if (!label && password)
 	  check_password ("To boot a custom image you must enter the password.");
 
+     params->kernel = boot; /* Copy all the original paramters */
      if (!parse_device_path(imagepath, defdevice, defpart,
 			    "/vmlinux", &params->kernel)) {
 	  prom_printf("%s: Unable to parse\n", imagepath);
@@ -1011,6 +1013,7 @@ int get_params(struct boot_param_t* para
                strncpy(initrdpath, p, 1024);
 
 	       DEBUG_F("Parsing initrd path <%s>\n", initrdpath);
+	       params->rd = boot; /* Copy all the original paramters */
 	       if (!parse_device_path(initrdpath, defdevice, defpart,
 				      "/root.bin", &params->rd)) {
 		    prom_printf("%s: Unable to parse\n", imagepath);
@@ -1021,6 +1024,7 @@ int get_params(struct boot_param_t* para
 	  if (p && *p) {
 	       DEBUG_F("Parsing sysmap path <%s>\n", p);
 	       strncpy(sysmappath, p, 1024);
+	       params->sysmap = boot; /* Copy all the original paramters */
 	       if (!parse_device_path(sysmappath, defdevice, defpart,
 				      "/boot/System.map", &params->sysmap)) {
 		    prom_printf("%s: Unable to parse\n", imagepath);
