mirror of
https://github.com/xcat2/xcat-dep.git
synced 2024-11-21 17:11:45 +00:00
371 lines
11 KiB
Diff
371 lines
11 KiB
Diff
diff -urN yaboot-1.3.14/include/prom.h yaboot-1.3.14-fixes/include/prom.h
|
|
--- yaboot-1.3.14/include/prom.h 2007-08-17 10:29:26.000000000 -0400
|
|
+++ yaboot-1.3.14-fixes/include/prom.h 2008-04-22 10:40:59.000000000 -0400
|
|
@@ -37,6 +37,9 @@
|
|
#define PROM_INVALID_HANDLE ((prom_handle)-1UL)
|
|
#define BOOTDEVSZ (2048) /* iscsi args can be in excess of 1040 bytes */
|
|
#define TOK_ISCSI "iscsi"
|
|
+#define PROM_CLAIM_MAX_ADDR 0x8000000
|
|
+#define BOOTLASTSZ 1024
|
|
+#define FW_NBR_REBOOTSZ 4
|
|
|
|
struct prom_args;
|
|
typedef int (*prom_entry)(struct prom_args *);
|
|
@@ -85,6 +88,7 @@
|
|
|
|
/* memory */
|
|
|
|
+void *prom_claim_chunk(void *virt, unsigned int size, unsigned int align);
|
|
void *prom_claim (void *virt, unsigned int size, unsigned int align);
|
|
void prom_release(void *virt, unsigned int size);
|
|
void prom_map (void *phys, void *virt, int size);
|
|
@@ -154,5 +158,8 @@
|
|
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 -urN yaboot-1.3.14/second/fs_of.c yaboot-1.3.14-fixes/second/fs_of.c
|
|
--- yaboot-1.3.14/second/fs_of.c 2007-08-17 10:29:26.000000000 -0400
|
|
+++ yaboot-1.3.14-fixes/second/fs_of.c 2008-04-22 10:43:43.000000000 -0400
|
|
@@ -44,9 +44,8 @@
|
|
#include "errors.h"
|
|
#include "debug.h"
|
|
|
|
-#define LOAD_BUFFER_POS 0x600000
|
|
-/* this cannot be safely increased any further */
|
|
-#define LOAD_BUFFER_SIZE 0x600000
|
|
+#define LOAD_BUFFER_POS 0x1000000
|
|
+#define LOAD_BUFFER_SIZE 0x1000000
|
|
|
|
static int of_open(struct boot_file_t* file, const char* dev_name,
|
|
struct partition_t* part, const char* file_name);
|
|
@@ -60,6 +59,8 @@
|
|
static int of_net_read(struct boot_file_t* file, unsigned int size, void* buffer);
|
|
static int of_net_seek(struct boot_file_t* file, unsigned int newpos);
|
|
|
|
+static int of_supports_real_tftp(void);
|
|
+static int of_net_use_tftp = -1;
|
|
|
|
struct fs_t of_filesystem =
|
|
{
|
|
@@ -131,6 +132,34 @@
|
|
return FILE_ERR_OK;
|
|
}
|
|
|
|
+/*
|
|
+ * 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 with new firmwares.
|
|
+ *
|
|
+ * This function should return 1 if the running firmware fully supports
|
|
+ * tftp and 0 if not.
|
|
+ */
|
|
+static int of_supports_real_tftp() {
|
|
+ of_net_use_tftp=1;
|
|
+ return(of_net_use_tftp);
|
|
+/*
|
|
+ prom_handle h;
|
|
+ if(of_net_use_tftp>=0) return(of_net_use_tftp);
|
|
+
|
|
+ h=prom_open("/packages/cas");
|
|
+ if(h) {
|
|
+ prom_close(h);
|
|
+ of_net_use_tftp=1;
|
|
+ } else {
|
|
+ of_net_use_tftp=0;
|
|
+ }
|
|
+ return(of_net_use_tftp);
|
|
+*/
|
|
+}
|
|
+
|
|
+
|
|
static int
|
|
of_net_open(struct boot_file_t* file, const char* dev_name,
|
|
struct partition_t* part, const char* file_name)
|
|
@@ -138,18 +167,33 @@
|
|
static char buffer[1024];
|
|
char *filename;
|
|
char *p;
|
|
+ struct bootp_packet *packet;
|
|
|
|
DEBUG_ENTER;
|
|
DEBUG_OPEN;
|
|
|
|
+
|
|
strncpy(buffer, dev_name, 768);
|
|
if (file_name && strlen(file_name)) {
|
|
+ if(of_supports_real_tftp()){
|
|
+ packet = prom_get_netinfo();
|
|
+ strcat(buffer, prom_get_siaddr(packet));
|
|
+ }
|
|
strcat(buffer, ",");
|
|
filename = strdup(file_name);
|
|
for (p = filename; *p; p++)
|
|
if (*p == '/')
|
|
*p = '\\';
|
|
strcat(buffer, filename);
|
|
+ if(of_supports_real_tftp()) {
|
|
+ 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. */
|
|
+ strcat(buffer, prom_get_siaddr(packet));
|
|
+ }
|
|
free(filename);
|
|
}
|
|
|
|
@@ -166,7 +210,9 @@
|
|
return FILE_ERR_BAD_FSYS;
|
|
}
|
|
|
|
- file->buffer = prom_claim((void *)LOAD_BUFFER_POS, LOAD_BUFFER_SIZE, 0);
|
|
+
|
|
+ file->buffer = prom_claim_chunk((void *)LOAD_BUFFER_POS,
|
|
+ LOAD_BUFFER_SIZE, 0);
|
|
if (file->buffer == (void *)-1) {
|
|
prom_printf("Can't claim memory for TFTP download\n");
|
|
prom_close(file->of_device);
|
|
diff -urN yaboot-1.3.14/second/prom.c yaboot-1.3.14-fixes/second/prom.c
|
|
--- yaboot-1.3.14/second/prom.c 2007-08-17 10:29:26.000000000 -0400
|
|
+++ yaboot-1.3.14-fixes/second/prom.c 2008-04-22 10:40:59.000000000 -0400
|
|
@@ -568,6 +568,25 @@
|
|
while (prom_getms() <= end);
|
|
}
|
|
|
|
+/* if address given is claimed look for other addresses to get the needed
|
|
+ * space before giving up
|
|
+ */
|
|
+void *
|
|
+prom_claim_chunk(void *virt, unsigned int size, unsigned int align)
|
|
+{
|
|
+ void *found, *addr;
|
|
+ for(addr=virt; addr <= (void*)PROM_CLAIM_MAX_ADDR;
|
|
+ addr+=(0x100000/sizeof(addr))) {
|
|
+ found = prom_claim(addr, size, 0);
|
|
+ if (found != (void *)-1) {
|
|
+ DEBUG_F("claimed %i at 0x%x (0x%x)\n",size,(int)found,(int)virt);
|
|
+ return(found);
|
|
+ }
|
|
+ }
|
|
+ prom_printf("Claim error, can't allocate %x at 0x%x\n",size,(int)virt);
|
|
+ return((void*)-1);
|
|
+}
|
|
+
|
|
void *
|
|
prom_claim (void *virt, unsigned int size, unsigned int align)
|
|
{
|
|
@@ -752,6 +771,78 @@
|
|
}
|
|
|
|
/*
|
|
+ * 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);
|
|
+
|
|
+ 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);
|
|
+
|
|
+ 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);
|
|
+
|
|
+ return conf_path;
|
|
+}
|
|
+
|
|
+/*
|
|
* Local variables:
|
|
* c-file-style: "k&r"
|
|
* c-basic-offset: 5
|
|
diff -urN yaboot-1.3.14/second/yaboot.c yaboot-1.3.14-fixes/second/yaboot.c
|
|
--- yaboot-1.3.14/second/yaboot.c 2007-08-17 10:29:26.000000000 -0400
|
|
+++ yaboot-1.3.14-fixes/second/yaboot.c 2008-04-22 10:40:59.000000000 -0400
|
|
@@ -114,6 +114,9 @@
|
|
char bootdevice[BOOTDEVSZ];
|
|
char bootoncelabel[1024];
|
|
char bootargs[1024];
|
|
+char bootlastlabel[BOOTLASTSZ] = {0};
|
|
+char fw_nbr_reboots[FW_NBR_REBOOTSZ] = {0};
|
|
+long fw_reboot_cnt = 0;
|
|
char *password = NULL;
|
|
struct boot_fspec_t boot;
|
|
int _machine = _MACH_Pmac;
|
|
@@ -665,7 +668,7 @@
|
|
|
|
cmdinit();
|
|
|
|
- if (first) {
|
|
+ if (first && !fw_reboot_cnt) {
|
|
first = 0;
|
|
imagename = bootargs;
|
|
word_split(&imagename, ¶ms->args);
|
|
@@ -680,6 +683,13 @@
|
|
timeout = simple_strtol(q, NULL, 0);
|
|
}
|
|
|
|
+ /* If this is a reboot due to FW detecting CAS changes then
|
|
+ * set timeout to 1. The last kernel booted will be booted
|
|
+ * again automatically. It should seem seamless to the user
|
|
+ */
|
|
+ if (fw_reboot_cnt)
|
|
+ timeout = 1;
|
|
+
|
|
prom_printf("boot: ");
|
|
c = -1;
|
|
if (timeout != -1) {
|
|
@@ -716,7 +726,9 @@
|
|
if (!imagename) {
|
|
if (bootoncelabel[0] != 0)
|
|
imagename = bootoncelabel;
|
|
- else
|
|
+ else if (bootlastlabel[0] != 0)
|
|
+ imagename = bootlastlabel;
|
|
+ else
|
|
imagename = cfg_get_default();
|
|
}
|
|
if (imagename)
|
|
@@ -737,6 +749,9 @@
|
|
if ( useconf && (!imagename || imagename[0] == 0 ))
|
|
imagename = cfg_get_default();
|
|
|
|
+ /* write the imagename out so it can be reused on reboot if necessary */
|
|
+ prom_set_options("boot-last-label", imagename, strlen(imagename));
|
|
+
|
|
label = 0;
|
|
defdevice = boot.dev;
|
|
|
|
@@ -1233,7 +1248,7 @@
|
|
Elf32_Ehdr *e = &(loadinfo->elf.elf32hdr);
|
|
Elf32_Phdr *p, *ph;
|
|
int size = sizeof(Elf32_Ehdr) - sizeof(Elf_Ident);
|
|
- unsigned long addr, loadaddr;
|
|
+ unsigned long loadaddr;
|
|
|
|
/* Read the rest of the Elf header... */
|
|
if ((*(file->fs->read))(file, size, &e->e_version) < size) {
|
|
@@ -1321,13 +1336,7 @@
|
|
loadaddr = loadinfo->load_loc;
|
|
}
|
|
|
|
- /* On some systems, loadaddr may already be claimed, so try some
|
|
- * other nearby addresses before giving up.
|
|
- */
|
|
- for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) {
|
|
- loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0);
|
|
- if (loadinfo->base != (void *)-1) break;
|
|
- }
|
|
+ loadinfo->base = prom_claim_chunk((void *)loadaddr, loadinfo->memsize, 0);
|
|
if (loadinfo->base == (void *)-1) {
|
|
prom_printf("Claim error, can't allocate kernel memory\n");
|
|
goto bail;
|
|
@@ -1377,7 +1386,7 @@
|
|
Elf64_Ehdr *e = &(loadinfo->elf.elf64hdr);
|
|
Elf64_Phdr *p, *ph;
|
|
int size = sizeof(Elf64_Ehdr) - sizeof(Elf_Ident);
|
|
- unsigned long addr, loadaddr;
|
|
+ unsigned long loadaddr;
|
|
|
|
/* Read the rest of the Elf header... */
|
|
if ((*(file->fs->read))(file, size, &e->e_version) < size) {
|
|
@@ -1465,13 +1474,7 @@
|
|
loadaddr = e->e_entry;
|
|
}
|
|
|
|
- /* On some systems, loadaddr may already be claimed, so try some
|
|
- * other nearby addresses before giving up.
|
|
- */
|
|
- for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) {
|
|
- loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0);
|
|
- if (loadinfo->base != (void *)-1) break;
|
|
- }
|
|
+ loadinfo->base = prom_claim_chunk((void *)loadaddr, loadinfo->memsize, 0);
|
|
if (loadinfo->base == (void *)-1) {
|
|
prom_printf("Claim error, can't allocate kernel memory\n");
|
|
goto bail;
|
|
@@ -1625,8 +1628,10 @@
|
|
yaboot_main(void)
|
|
{
|
|
char *ptype;
|
|
+ char *endp;
|
|
int conf_given = 0;
|
|
char conf_path[1024];
|
|
+ int ret;
|
|
|
|
if (_machine == _MACH_Pmac)
|
|
setup_display();
|
|
@@ -1635,6 +1640,11 @@
|
|
DEBUG_F("/chosen/bootargs = %s\n", bootargs);
|
|
prom_get_chosen("bootpath", bootdevice, BOOTDEVSZ);
|
|
DEBUG_F("/chosen/bootpath = %s\n", bootdevice);
|
|
+ if (prom_get_options("ibm,#reconfig-reboots",fw_nbr_reboots, FW_NBR_REBOOTSZ) == -1 )
|
|
+ prom_get_options("ibm,fw-nbr-reboots",fw_nbr_reboots, FW_NBR_REBOOTSZ);
|
|
+ fw_reboot_cnt = simple_strtol(fw_nbr_reboots,&endp,10);
|
|
+ if (fw_reboot_cnt > 0L)
|
|
+ prom_get_options("boot-last-label", bootlastlabel, BOOTLASTSZ);
|
|
|
|
/* If conf= specified on command line, it overrides
|
|
Usage: conf=device:partition,/path/to/conffile
|