rpms/yaboot/devel yaboot-1.3.14-better_netboot2.patch, NONE, 1.1 yaboot-1.3.14-move_kernel.patch, NONE, 1.1 yaboot.spec, 1.69, 1.70
Roman Rakus
rrakus at fedoraproject.org
Thu Oct 29 12:20:12 UTC 2009
Author: rrakus
Update of /cvs/extras/rpms/yaboot/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv5912
Modified Files:
yaboot.spec
Added Files:
yaboot-1.3.14-better_netboot2.patch
yaboot-1.3.14-move_kernel.patch
Log Message:
When netbooting "clobber" the LOAD_BUFFER and move the kernel into it to make room for RTAS (#530330)
Adding better netboot support more work on (#458438)
yaboot-1.3.14-better_netboot2.patch:
include/file.h | 1
include/prom.h | 2
second/cfg.c | 3 +
second/file.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
second/fs_of.c | 48 +++++++++++++--------
second/prom.c | 6 ++
second/yaboot.c | 4 +
7 files changed, 166 insertions(+), 25 deletions(-)
--- NEW FILE yaboot-1.3.14-better_netboot2.patch ---
diff -purN yaboot-1.3.14.orig/include/file.h yaboot-1.3.14/include/file.h
--- yaboot-1.3.14.orig/include/file.h 2009-10-15 11:39:01.112642471 +1100
+++ yaboot-1.3.14/include/file.h 2009-10-15 15:29:04.692654961 +1100
@@ -45,6 +45,7 @@ struct boot_fspec_t {
char* giaddr; /* Gateway address */
char* bootp_retries; /* Bootp retries */
char* tftp_retries; /* TFTP retries */
+ char* subnetmask; /* Subnet mask */
char* addl_params; /* copy all additional parameters */
/* Following fields are used only in ipv6 format */
diff -purN yaboot-1.3.14.orig/include/prom.h yaboot-1.3.14/include/prom.h
--- yaboot-1.3.14.orig/include/prom.h 2009-10-15 15:23:39.796944672 +1100
+++ yaboot-1.3.14/include/prom.h 2009-10-15 15:29:04.692654961 +1100
@@ -153,7 +153,7 @@ struct bootp_packet {
unsigned char chaddr[16];
unsigned char sname[64];
unsigned char file[128];
- /* vendor options go here if we need them */
+ unsigned char options[]; /* vendor options */
};
struct bootp_packet * prom_get_netinfo (void);
diff -purN yaboot-1.3.14.orig/second/cfg.c yaboot-1.3.14/second/cfg.c
--- yaboot-1.3.14.orig/second/cfg.c 2009-10-15 15:23:39.798647660 +1100
+++ yaboot-1.3.14/second/cfg.c 2009-10-15 15:29:04.693668247 +1100
@@ -597,6 +597,9 @@ int cfg_set_default_by_mac (char *mac_ad
char * label = NULL;
int haslabel = 0;
+ if (mac_addr == NULL)
+ return 0;
+
/* check if there is an image label equal to mac_addr */
for (tmp = images; tmp; tmp = tmp->next) {
label = cfg_get_strg_i (tmp->table, "label");
diff -purN yaboot-1.3.14.orig/second/file.c yaboot-1.3.14/second/file.c
--- yaboot-1.3.14.orig/second/file.c 2009-10-15 15:23:39.802647442 +1100
+++ yaboot-1.3.14/second/file.c 2009-10-15 15:29:04.694645423 +1100
@@ -51,6 +51,42 @@ ipv4_to_str(__u32 ip)
return buf;
}
+/* FIXME: COMMENT */
+static char * is_valid_ip_str(char *str)
+{
+ int i;
+ long tmp;
+ __u32 ip = 0;
+ char *ptr=str, *endptr;
+
+ if (str == NULL)
+ return NULL;
+
+ for (i=0; i<4; i++, ptr = ++endptr) {
+ tmp = strtol(ptr, &endptr, 10);
+ if ((tmp & 0xff) != tmp)
+ return NULL;
+
+ /* If we reach the end of the string but we're not in the 4th octet
+ * we have an invalid IP */
+ if (*endptr == '\x0' && i!=3)
+ return NULL;
+
+ /* If we have anything other than a NULL or '.' we have an invlaid
+ * IP */
+ if (*endptr != '\x0' && *endptr != '.')
+ return NULL;
+
+ ip += (tmp << (24-(i*8)));
+ }
+
+ if (ip == 0 || ip == ~0u)
+ return NULL;
+
+ return str;
+}
+
+
/*
* Copy the string from source to dest till newline or comma(,) is seen
* in the source.
@@ -130,12 +166,13 @@ extract_ipv4_args(char *imagepath, struc
* read the arguments in order: siaddr,filename,ciaddr,giaddr,
* bootp-retries,tftp-retries,addl_prameters
*/
- result->siaddr = scopy(&str, &args);
+ result->siaddr = is_valid_ip_str(scopy(&str, &args));
result->file = scopy(&str, &args);
- result->ciaddr = scopy(&str, &args);
- result->giaddr = scopy(&str, &args);
+ result->ciaddr = is_valid_ip_str(scopy(&str, &args));
+ result->giaddr = is_valid_ip_str(scopy(&str, &args));
result->bootp_retries = scopy(&str, &args);
result->tftp_retries = scopy(&str, &args);
+ result->subnetmask = scopy(&str, &args);
if (*args) {
result->addl_params = strdup(args);
if (!result->addl_params)
@@ -144,6 +181,82 @@ extract_ipv4_args(char *imagepath, struc
return 1;
}
+/* DHCP options */
+enum dhcp_options {
+ DHCP_PAD = 0,
+ DHCP_NETMASK = 1,
+ DHCP_ROUTERS = 3,
+ DHCP_DNS = 6,
+ DHCP_END = 255,
+};
+
+#define DHCP_COOKIE 0x63825363
+#define DHCP_COOKIE_SIZE 4
+
+/*
+ * FIXME: COMMENT
+ */
+static void
+extract_vendor_options(struct bootp_packet *packet, struct boot_fspec_t *result)
+{
+ int i = 0;
+ __u32 cookie;
+ __u8 *options = &packet->options[0];
+
+ memcpy(&cookie, &options[i], DHCP_COOKIE_SIZE);
+
+ if (cookie != DHCP_COOKIE) {
+ prom_printf("EEEK! cookie is fubar got %08x expected %08x\n",
+ cookie, DHCP_COOKIE);
+ return;
+ }
+
+ i += DHCP_COOKIE_SIZE;
+
+ /* FIXME: It may be possible to run off the end of a packet here /if/
+ * it's malformed. :( */
+ while (options[i] != DHCP_END) {
+ __u8 tag = options[i++], len;
+ __u32 value;
+
+ if (tag == DHCP_PAD)
+ continue;
+
+ len = options[i++];
+ memcpy(&value, &options[i], len);
+
+#if DEBUG
+{
+ DEBUG_F("tag=%2d, len=%2d, data=", tag, len);
+ int j;
+ for (j=0; j<len; j++)
+ prom_printf("%02x", options[i+j]);
+ prom_printf("\n");
+}
+#endif
+
+ switch (tag) {
+ case DHCP_NETMASK:
+ if ((result->subnetmask == NULL || *(result->subnetmask) == '\x0') && value != 0) {
+ result->subnetmask = ipv4_to_str(value);
+ DEBUG_F("Storing %s as subnetmask from options\n",
+ result->subnetmask);
+ }
+ /* FIXME: do we need to grok the subnet mask? */
+ break;
+ case DHCP_ROUTERS:
+ if ((result->giaddr == NULL || *(result->giaddr) == '\x0')
+ && value != 0) {
+ result->giaddr = ipv4_to_str(value);
+ DEBUG_F("Storing %s as gateway from options\n",
+ result->giaddr);
+ }
+ break;
+ }
+ i += len;
+ }
+}
+
/*
* Check netinfo for ipv4 parameters and add them to the fspec iff the
* fspec has no existing value.
@@ -170,16 +283,18 @@ extract_netinfo_args(struct boot_fspec_t
if (packet->ciaddr == 0 && packet->yiaddr != 0)
packet->ciaddr = packet->yiaddr;
- if ((result->siaddr == NULL || *(result->siaddr) == NULL)
+ if ((result->siaddr == NULL || *(result->siaddr) == '\x0')
&& packet->siaddr != 0)
result->siaddr = ipv4_to_str(packet->siaddr);
- if ((result->ciaddr == NULL || *(result->ciaddr) == NULL)
+ if ((result->ciaddr == NULL || *(result->ciaddr) == '\x0')
&& packet->ciaddr != 0)
result->ciaddr = ipv4_to_str(packet->ciaddr);
- if ((result->giaddr == NULL || *(result->giaddr) == NULL)
+ if ((result->giaddr == NULL || *(result->giaddr) == '\x0')
&& packet->giaddr != 0)
result->giaddr = ipv4_to_str(packet->giaddr);
+ extract_vendor_options(packet, result);
+
/* 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
diff -purN yaboot-1.3.14.orig/second/fs_of.c yaboot-1.3.14/second/fs_of.c
--- yaboot-1.3.14.orig/second/fs_of.c 2009-10-15 15:23:39.805647069 +1100
+++ yaboot-1.3.14/second/fs_of.c 2009-10-15 15:29:04.695645439 +1100
@@ -44,7 +44,7 @@
#include "errors.h"
#include "debug.h"
-#define LOAD_BUFFER_POS 0x1000000
+#define LOAD_BUFFER_POS 0x0000000
#define LOAD_BUFFER_SIZE 0x2000000
static int of_open(struct boot_file_t* file,
@@ -137,6 +137,7 @@ of_net_open(struct boot_file_t* file,
static char buffer[1024];
char *filename = NULL;
char *p;
+ int new_tftp;
DEBUG_ENTER;
DEBUG_OPEN;
@@ -148,34 +149,47 @@ of_net_open(struct boot_file_t* file,
*p = '\\';
}
- DEBUG_F("siaddr <%s>; filename <%s>; ciaddr <%s>; giaddr <%s>; ipv6 <%d>\n",
- fspec->siaddr, filename, fspec->ciaddr, fspec->giaddr, fspec->is_ipv6);
+ DEBUG_F("siaddr <%s>; filename <%s>; ciaddr <%s>; giaddr <%s>;"
+ " ipv6 <%d>\n",
+ fspec->siaddr, filename, fspec->ciaddr, fspec->giaddr,
+ fspec->is_ipv6);
+
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] != ':')
+ else if (fspec->dev[strlen(fspec->dev)-1] != ':')
strcat(buffer, ":");
- strcat(buffer, fspec->siaddr);
- strcat(buffer, ",");
- if (fspec->is_ipv6 && (strstr(filename, "filename=") == NULL))
- strcat(buffer, "filename=");
- strcat(buffer, filename);
- strcat(buffer, ",");
- strcat(buffer, fspec->ciaddr);
- strcat(buffer, ",");
- strcat(buffer, fspec->giaddr);
- /* If /packages/cas exists the we have a "new skool" tftp */
- if (prom_finddevice("/packages/cas") != PROM_INVALID_HANDLE) {
+ /* If /packages/cas exists the we have a "new skool" tftp.
+ * This means that siaddr is the tftp server and that we can add
+ * {tftp,bootp}_retrys, subnet mask and tftp block size to the load
+ * method */
+ new_tftp = (prom_finddevice("/packages/cas") != PROM_INVALID_HANDLE);
+ DEBUG_F("Using %s tftp style\n", (new_tftp? "new": "old"));
+
+ if (new_tftp) {
+ strcat(buffer, fspec->siaddr);
+ strcat(buffer, ",");
+
+ if (fspec->is_ipv6 && (strstr(filename, "filename=") == NULL))
+ strcat(buffer, "filename=");
+
+ 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->subnetmask);
+ strcat(buffer, ",");
strcat(buffer, fspec->addl_params);
} else {
- DEBUG_F("No \"/packages/cas\" using simple args\n")
+ strcat(buffer, ",");
+ strcat(buffer, filename);
}
DEBUG_F("Opening: \"%s\"\n", buffer);
diff -purN yaboot-1.3.14.orig/second/prom.c yaboot-1.3.14/second/prom.c
--- yaboot-1.3.14.orig/second/prom.c 2009-10-15 15:23:39.806647224 +1100
+++ yaboot-1.3.14/second/prom.c 2009-10-15 15:29:04.696645314 +1100
@@ -685,6 +685,10 @@ struct bootp_packet * prom_get_netinfo (
void *bootp_response = NULL;
char *propname;
struct bootp_packet *packet;
+ /* struct bootp_packet contains a VLA, so sizeof won't work.
+ the VLA /must/ be the last field in the structure so use it's
+ offset as a good estimate of the packet size */
+ size_t packet_size = offsetof(struct bootp_packet, options);
int i = 0, size, offset = 0;
prom_handle chosen;
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
@@ -709,7 +713,7 @@ struct bootp_packet * prom_get_netinfo (
if (size <= 0)
return NULL;
- if (sizeof(*packet) > size - offset) {
+ if (packet_size > size - offset) {
prom_printf("Malformed %s property?\n", propname);
return NULL;
}
diff -purN yaboot-1.3.14.orig/second/yaboot.c yaboot-1.3.14/second/yaboot.c
--- yaboot-1.3.14.orig/second/yaboot.c 2009-10-15 15:23:39.809646432 +1100
+++ yaboot-1.3.14/second/yaboot.c 2009-10-15 15:29:04.697642396 +1100
@@ -471,6 +471,10 @@ static int load_my_config_file(struct bo
int minlen;
packet = prom_get_netinfo();
+ if (packet == NULL) {
+ prom_printf("Failed to get netinfo data\n");
+ return 0;
+ }
/*
* First, try to match on mac address with the hardware type
yaboot-1.3.14-move_kernel.patch:
Makefile | 3 ++
include/file.h | 1
second/fs_of.c | 1
second/yaboot.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 65 insertions(+)
--- NEW FILE yaboot-1.3.14-move_kernel.patch ---
diff --git a/Makefile b/Makefile
index 8f2b1c4..3603c7d 100644
--- a/Makefile
+++ b/Makefile
@@ -121,6 +121,9 @@ mkofboot:
false; \
fi
+%.i: %.c
+ $(CC) $(YBCFLAGS) -E -o $@ $<
+
%.o: %.c
$(CC) $(YBCFLAGS) -c -o $@ $<
diff --git a/include/file.h b/include/file.h
index b2d9c63..9990f4b 100644
--- a/include/file.h
+++ b/include/file.h
@@ -68,6 +68,7 @@ struct boot_file_t {
ino_t inode;
__u64 pos;
unsigned char* buffer;
+ __u64 buffer_sz;
__u64 len;
// unsigned int dev_blk_size;
// unsigned int part_start;
diff --git a/second/fs_of.c b/second/fs_of.c
index 1f48f4f..d2e7434 100644
--- a/second/fs_of.c
+++ b/second/fs_of.c
@@ -214,6 +214,7 @@ of_net_open(struct boot_file_t* file,
DEBUG_LEAVE(FILE_IOERR);
return FILE_IOERR;
}
+ file->buffer_sz = LOAD_BUFFER_SIZE;
memset(file->buffer, 0, LOAD_BUFFER_SIZE);
DEBUG_F("TFP...\n");
diff --git a/second/yaboot.c b/second/yaboot.c
index 0ccfed5..1241eec 100644
--- a/second/yaboot.c
+++ b/second/yaboot.c
@@ -1052,6 +1052,7 @@ yaboot_text_ui(void)
static struct boot_param_t params;
void *initrd_base;
unsigned long initrd_size;
+ unsigned long initrd_end;
void *sysmap_base;
unsigned long sysmap_size;
kernel_entry_t kernel_entry;
@@ -1227,8 +1228,67 @@ yaboot_text_ui(void)
initrd_read = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_more);
DEBUG_F(" block at %p rc=%lu\n",initrd_more,initrd_read);
initrd_size += initrd_read;
+ initrd_end = initrd_more+INITRD_CHUNKSIZE;
}
}
+ /* If we netbooted and got this far, we may have filled the
+ * RMA. We're about the free the TFTP load buffer to we
+ * can "shuffle" things around so that the booted kernel
+ * has some memory to run with */
+ if (!is_elf64(&loadinfo)) {
+ DEBUG_F("Not running a 64-kernel\n");
+ /* Is this check enough? */
+ } else if (loadinfo.base == file.buffer + file.buffer_sz) {
+ DEBUG_F("file->buffer %lx -> %lx (%lx)\n",
+ (unsigned long)(file.buffer),
+ (unsigned long)(file.buffer+file.buffer_sz),
+ (unsigned long)(file.buffer_sz));
+ DEBUG_F("vmlinux %lx -> %lx (%lx)\n",
+ (unsigned long)(loadinfo.base),
+ (unsigned long)(loadinfo.base+loadinfo.memsize),
+ (unsigned long)(loadinfo.memsize));
+ DEBUG_F("initrd %lx -> %lx (%lx)\n",
+ (unsigned long)(initrd_base),
+ (unsigned long)(initrd_base+initrd_size),
+ (unsigned long)(initrd_size));
+
+ /* Check to see if we're near the top of the RMA */
+ /* Cheat and assume the RMA == 128Mb */
+ if (initrd_end > 0x7000000) {
+ unsigned long new_initrd_end, free_len;
+ unsigned long initrd_claim_len = initrd_end - (unsigned long)initrd_base;
+
+ memmove(file.buffer, loadinfo.base,
+ loadinfo.memsize+initrd_size);
+ loadinfo.base = file.buffer;
+ initrd_base = loadinfo.base+loadinfo.memsize;
+
+ new_initrd_end = (unsigned long)initrd_base+initrd_claim_len;
+ free_len = initrd_end - (unsigned long)new_initrd_end;
+ file.buffer = NULL;
+ file.buffer_sz = 0;
+ memset((void*)new_initrd_end, 0x0, free_len);
+ prom_release((void*)new_initrd_end, free_len);
+
+ DEBUG_F("Releaseing from 0x%08lx -> 0x%08lx\n",
+ new_initrd_end, free_len);
+
+ DEBUG_F("file->buffer %lx -> %lx (%lx)\n",
+ (unsigned long)(file.buffer),
+ (unsigned long)(file.buffer+file.buffer_sz),
+ (unsigned long)(file.buffer_sz));
+ DEBUG_F("vmlinux %lx -> %lx (%lx)\n",
+ (unsigned long)(loadinfo.base),
+ (unsigned long)(loadinfo.base+loadinfo.memsize),
+ (unsigned long)(loadinfo.memsize));
+ DEBUG_F("initrd %lx -> %lx (%lx)\n",
+ (unsigned long)(initrd_base),
+ (unsigned long)(initrd_base+initrd_size),
+ (unsigned long)(initrd_size));
+ } else {
+ DEBUG_F("Looks like we do not need to move the kernel\n");
+ }
+ }
file.fs->close(&file);
memset(&file, 0, sizeof(file));
}
Index: yaboot.spec
===================================================================
RCS file: /cvs/extras/rpms/yaboot/devel/yaboot.spec,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -p -r1.69 -r1.70
--- yaboot.spec 19 Oct 2009 12:44:27 -0000 1.69
+++ yaboot.spec 29 Oct 2009 12:20:12 -0000 1.70
@@ -1,7 +1,7 @@
Summary: Linux bootloader for Power Macintosh "New World" computers.
Name: yaboot
Version: 1.3.14
-Release: 20%{?dist}
+Release: 21%{?dist}
License: GPLv2+
Group: System Environment/Base
Source: http://yaboot.ozlabs.org/releases/yaboot-%{version}.tar.gz
@@ -37,6 +37,12 @@ Patch36: yaboot-1.3.14-ipv6.patch
# Do not open LINUX_NATIVE parttions with OF, as badness happens
Patch37: yaboot-1.3.14-dont_of_open_native_partitions.patch
+# Try #2 at better netboot now with DHCP parseing
+Patch38: yaboot-1.3.14-better_netboot2.patch
+
+# When netbooting, move the kernel onto the load buffer, sure it's a hack
+Patch39: yaboot-1.3.14-move_kernel.patch
+
URL: http://yaboot.ozlabs.org/
BuildRoot: %{_tmppath}/%{name}-root
Obsoletes: ybin
@@ -86,6 +92,8 @@ yaboot can also bootload IBM pSeries mac
%patch35 -p1 -b .returns
%patch36 -p1 -b .ipv6
%patch37 -p1 -b .partitions
+%patch38 -p1 -b .netboot2
+%patch39 -p1 -b .movekernel
%build
make VERSIONEXTRA='\ (Red Hat %version-%release)' DEBUG=1
@@ -126,6 +134,11 @@ rm -rf $RPM_BUILD_ROOT
%ghost %config(noreplace) %{_sysconfdir}/yaboot.conf
%changelog
+* Thu Oct 29 2009 Roman Rakus <rrakus at redhat.com> - 1.3.14-21
+- When netbooting "clobber" the LOAD_BUFFER and move the kernel into it to make
+ room for RTAS (#530330)
+- Adding better netboot support more work on (#458438)
+
* Mon Oct 19 2009 Roman Rakus <rrakus at redhat.com> - 1.3.13-20
- Only require hfsutils on fedora and rhel <= 5
- Explicitly build a DEBUG=1 version of yaboot to aid in debugging
More information about the fedora-extras-commits
mailing list