[PATCH 2/4] handle arguments for ipv4 boot
Tony Breeds
tony at bakeyournoodle.com
Tue Feb 24 11:15:00 EST 2009
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 at 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 at 4000
net /vdevice/l-lan at 30000002
network /vdevice/l-lan at 30000002
scsi /vdevice/v-scsi at 30000032
nvram /vdevice/nvram at 4002
rtc /vdevice/rtc at 4001
screen /vdevice/vty at 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 at 4000
net /vdevice/l-lan at 30000002
network /vdevice/l-lan at 30000002
scsi /vdevice/v-scsi at 30000032
nvram /vdevice/nvram at 4002
rtc /vdevice/rtc at 4001
screen /vdevice/vty at 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 at 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 at 30000002
parse_device_path - imagepath = /vdevice/l-lan at 30000002; defdevice <NULL>; defpart -1, deffile
netdev_path_to_dev - path = /vdevice/l-lan at 30000002
yaboot_main - After parse_device_path: dev=/vdevice/l-lan at 30000002, part=-1, file=/vdevice/l-lan at 30000002
yaboot_main - After path kludgeup: dev=/vdevice/l-lan at 30000002, part=-1, file=/etc/yaboot.conf
Try to netboot
prom_get_netinfo - using /chosen/bootpreply-packet
open_file - dev_path = /vdevice/l-lan at 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 at 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 at 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 at 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 at 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 at 30000002:10.61.2.7,zImage.diego5,10.61.135.50,10.61.2.7
parse_device_path - imagepath = /vdevice/l-lan at 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 at 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 at 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 at 30000002:, part=-1, file=zImage.diego5
yaboot_main - After path kludgeup: dev=/vdevice/l-lan at 30000002:, part=-1, file=/etc/yaboot.conf
Try to netboot
prom_get_netinfo - using /chosen/bootpreply-packet
open_file - dev_path = /vdevice/l-lan at 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 at 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 at 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 at 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(-)
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);
--
1.6.0.6
-=-=-=-=-=-
Can you re-spin you patch series with something like this fix included?
Yours Tony
[1] http://ozlabs.org/pipermail/yaboot-devel/2007-October/000175.html [2]
[2] Also Manoel posted a patch in Oct 2008 that makes a check against
"ibm,fw-net-compatibility" for similar reasons, perhaps someone on the
firmware team can determine the best check?
More information about the Yaboot-devel
mailing list