726 lines
27 KiB
Diff
726 lines
27 KiB
Diff
|
commit 37578220a9120f0a7770b0c6c6eae046ce72fc93
|
||
|
Author: David Woodhouse <dwmw2@infradead.org>
|
||
|
Date: Fri Mar 28 00:04:02 2008 +0000
|
||
|
|
||
|
Pegasos and partition numbering
|
||
|
|
||
|
The whole bplan partition numbering thing is a clusterfuck, but it
|
||
|
shouldn't be as crappy as it is.
|
||
|
|
||
|
We can _cope_ with the fact that firmware is broken and has an
|
||
|
off-by-one in its partition numbering. All we need to do in yaboot is
|
||
|
add 1 to the partition numbers we infer from in /chosen/boot-device, if
|
||
|
we detect that we're on an afflicted machine. That's all we need to do,
|
||
|
and all we ever _should_ have done. And is already in yaboot. Yaboot
|
||
|
does its own block device handling, including partitions, and doesn't
|
||
|
ever care about the firmware's problems (in that respect, at least).
|
||
|
|
||
|
It doesn't affect the installer at _all_, because the installer can't
|
||
|
set up the firmware's boot-device anyway and it has to be done by hand.
|
||
|
All it affects is the release notes telling the user how to make it
|
||
|
bootable.
|
||
|
|
||
|
Unfortunately, we didn't make it that simple when we first supported the
|
||
|
Pegasos. For reasons which aren't entirely clear to me, we ended up with
|
||
|
Amiga partition table support in yaboot with the _same_ off-by-one
|
||
|
error, to match the firmware. And thus we have hacks in the installer to
|
||
|
use amiga partitions for Pegasos, and to cope with the off-by-one crap.
|
||
|
|
||
|
It's only after avoiding all this crap purely by accident on Efika, by
|
||
|
using DOS partition tables, that I realise how stupid I was to blindly
|
||
|
copy the crap that other people were doing, and to believe that Pegasos
|
||
|
would only work with Amiga partition tables.
|
||
|
|
||
|
I'd like to get rid of the off-by-one bug in yaboot's Amiga partition
|
||
|
handling. At the moment, our simple 'if bplan, partition++' in
|
||
|
yaboot_main() is wrong when we have Amiga partitions, although it's fine
|
||
|
for other partition types.
|
||
|
|
||
|
Actually, I'd also like to make that same increment conditional on
|
||
|
!conf_given, so that if someone specifies 'conf=hd:1,/yaboot.conf' on
|
||
|
the command line, that partition number _isn't_ incremented.
|
||
|
|
||
|
So any time you see a proper path specified as 'dev:part,/path/name' you
|
||
|
know it's a real one with proper partition numbers. Remember, the bplan
|
||
|
firmware doesn't allow that form, and takes a space between the
|
||
|
'dev:part' bit and the filename:
|
||
|
boot hd:0 /yaboot/yaboot conf=hd:1,/yaboot/yaboot.conf
|
||
|
|
||
|
Fixing the off-by-one bug in the Amiga partition handling means that
|
||
|
upgrades might break. I suppose we could have a 'noamigaoffbyone'
|
||
|
configuration option which all newly-written yaboot.conf files would
|
||
|
have, which controls this behaviour. But to be honest I just don't think
|
||
|
it's worth it.
|
||
|
|
||
|
commit 0c0a18b7a1a6b44963da4469d21428e76f9c2b30
|
||
|
Author: Mike Wolf <mjw@linux.vnet.ibm.com>
|
||
|
Date: Tue Jan 15 14:33:51 2008 -0600
|
||
|
|
||
|
use public interface to detect CAS reboots (take 2)
|
||
|
|
||
|
This is the second pass of this patch. The fw variable name is changed
|
||
|
to use ibm,client-architecture-support-reboot field which is already present
|
||
|
in the firmware. Please disregard the previous patch.
|
||
|
|
||
|
The firmware field used to detect CAS reboots (ibm,fw-nbr-reboots) is
|
||
|
really a private field that could change without warning. A new field
|
||
|
ibm,#reconfig-reboots will be added as a public interface intended to
|
||
|
be used for this detection. The patch will first check for
|
||
|
ibm,client-architecture-support-reboot if that is not found it will see
|
||
|
if ibm,fw-nbr-reboots is present and will use that instead.
|
||
|
|
||
|
-------
|
||
|
|
||
|
commit 526b77920b050e1e37e842e8def4a5e7fb04cee6
|
||
|
Author: Paul Nasrat <pauln@truemesh.com>
|
||
|
Date: Fri Jan 4 13:00:19 2008 +0000
|
||
|
|
||
|
The CAS (Client-Architecture Support) call tells firmware what capabilities the
|
||
|
OS has. These capabilities result in different modes which the device-tree is
|
||
|
configured in, as well as what processor capabilities are presented. So, if
|
||
|
the capabilities are different from what was previously booted, firmware has to
|
||
|
reboot to reconfigure the device-tree. The second boot will have the updated
|
||
|
device-tree and we can boot as normal.
|
||
|
|
||
|
When this firmware initiated reboot occurs yaboot will now boot the same kernel
|
||
|
as the previous boot attempt with no action by the user needed. I have
|
||
|
successfully booted on POWER5 and POWER6 machines using various levels of the
|
||
|
kernel.
|
||
|
|
||
|
Patch from: Mike Wolf <mjw@linux.vnet.ibm.com>
|
||
|
|
||
|
commit f843e296a197cc94c0e0f80d49a67dc71c6785a2
|
||
|
Author: Paul Nasrat <pauln@truemesh.com>
|
||
|
Date: Thu Jan 3 19:21:44 2008 +0000
|
||
|
|
||
|
Revert "The attached patch adds support for writing the nvram using the nvram"
|
||
|
|
||
|
This reverts commit ac8fbd5ad52b43b820973f1828a29f85bed13a1d.
|
||
|
|
||
|
commit 50b58606fb2d11aa6548d1fec606275c33a930c7
|
||
|
Author: Paul Nasrat <pauln@truemesh.com>
|
||
|
Date: Thu Jan 3 19:21:22 2008 +0000
|
||
|
|
||
|
Revert "Fix shell syntax"
|
||
|
|
||
|
This reverts commit 24679e706305e0910f181a9640b8b88a30662d03.
|
||
|
|
||
|
commit 24679e706305e0910f181a9640b8b88a30662d03
|
||
|
Author: Paul Nasrat <pauln@truemesh.com>
|
||
|
Date: Thu Jan 3 19:07:50 2008 +0000
|
||
|
|
||
|
Fix shell syntax
|
||
|
|
||
|
commit ac8fbd5ad52b43b820973f1828a29f85bed13a1d
|
||
|
Author: Paul Nasrat <pauln@truemesh.com>
|
||
|
Date: Tue Dec 4 08:43:32 2007 +0000
|
||
|
|
||
|
The attached patch adds support for writing the nvram using the nvram
|
||
|
utility from the new powerpc-utils pkg from IBM; it also simplify a bit
|
||
|
the code.
|
||
|
|
||
|
Patch from: Emanuele Giaquinta (exg@gentoo.org)
|
||
|
|
||
|
commit 131e44d7e0bf592eaa8214e684fef38bf654410a
|
||
|
Author: Paul Nasrat <pauln@truemesh.com>
|
||
|
Date: Mon Dec 3 14:21:11 2007 +0000
|
||
|
|
||
|
Force build to be ppc32
|
||
|
|
||
|
commit ff0e80c9b39b18a907d1f1ffb8f836b13af4ebb1
|
||
|
Author: Paul Nasrat <pauln@truemesh.com>
|
||
|
Date: Mon Dec 3 14:14:42 2007 +0000
|
||
|
|
||
|
Fix typo
|
||
|
|
||
|
commit 66ffb9d32d2acb3613594ef492d341b5bacf02e5
|
||
|
Author: Paul Nasrat <pauln@truemesh.com>
|
||
|
Date: Mon Dec 3 14:13:54 2007 +0000
|
||
|
|
||
|
Fix typo in patch porting
|
||
|
|
||
|
commit 082b8310e3f92ea8da0b7011549bd86c9fd4ce95
|
||
|
Author: Paul Nasrat <pauln@truemesh.com>
|
||
|
Date: Mon Dec 3 14:05:48 2007 +0000
|
||
|
|
||
|
Fix partition numbering handling with bplan firmware
|
||
|
Patch based on Fedora patch by dwmw2@infradead.org
|
||
|
|
||
|
commit afaf577190536fe8e15fb5b2ed8372dbda82e7b1
|
||
|
Author: Paul Nasrat <pauln@truemesh.com>
|
||
|
Date: Mon Dec 3 13:17:33 2007 +0000
|
||
|
|
||
|
Try harder to allocate malloc region
|
||
|
Patch from dwmw2@infradead.org
|
||
|
|
||
|
commit 752525a7feb16e02b759ca7811fc9a0276712c3d
|
||
|
Author: Paul Nasrat <pauln@truemesh.com>
|
||
|
Date: Mon Dec 3 13:13:23 2007 +0000
|
||
|
|
||
|
Print version-release of yaboot
|
||
|
Patch from dwmw2@infradead.org
|
||
|
|
||
|
commit c8b04c614770870d75825c19bcd4729cc779b84a
|
||
|
Author: Paul Nasrat <pauln@enki.eridu>
|
||
|
Date: Mon Dec 3 13:04:19 2007 +0000
|
||
|
|
||
|
Let prom_claim_chunk do the work for tftp images to support larger images.
|
||
|
|
||
|
Patch from: Leonardo Rangel <lrangel@linux.vnet.ibm.com>
|
||
|
|
||
|
commit b6b70ff54df42432d58801ac69ba24e7d95e0426
|
||
|
Author: Paul Nasrat <pauln@enki.eridu>
|
||
|
Date: Mon Dec 3 12:41:42 2007 +0000
|
||
|
|
||
|
These patch provides the function of load a alternative initrd file
|
||
|
specified by the user via Yaboot prompt. To load the new file, just use
|
||
|
the "initrd=<name_of_file>" command. The <name_of_file> could include
|
||
|
all the directory path to the file.
|
||
|
|
||
|
Using only the "initrd" command, Yaboot will load the default kernel
|
||
|
specified in the configuration file and the initrd file specified by the
|
||
|
user. The user can, also, specify an initrd file to any other label of
|
||
|
the configuration file, just adding the "initrd" command before the
|
||
|
label's name.
|
||
|
|
||
|
Signed-off-by: Paulo Ricardo Paz Vital <vital@br.ibm.com>
|
||
|
|
||
|
commit 4ba173298fa8630628c9014028fccc22e511d48a
|
||
|
Author: Paul Nasrat <pauln@enki.eridu>
|
||
|
Date: Mon Dec 3 12:39:06 2007 +0000
|
||
|
|
||
|
move the tftp load space and use prom_claim_chunk to claim the memory.
|
||
|
Growing kernels mean that the 6MB that was allotted is not enough.
|
||
|
|
||
|
Patch from Scott Moser
|
||
|
|
||
|
commit f3d8af0e0ac4642499d5430c202ac57d1d4c5ceb
|
||
|
Author: Paul Nasrat <pauln@enki.eridu>
|
||
|
Date: Mon Dec 3 12:37:10 2007 +0000
|
||
|
|
||
|
The patch from Scott Moser moves the "search-for-prom_claim'able" routine that
|
||
|
was present in load_elf64 and load_elf32 to a function named
|
||
|
prom_claim_chunk. This reduces the code-snippit duplication and makes
|
||
|
the function available for of_net_open.
|
||
|
|
||
|
Scott Moser ssmoser@us.ibm.com
|
||
|
--------------------------------------------------------------------------------
|
||
|
diff --git a/Makefile b/Makefile
|
||
|
index ce0dc06..fe2f2fd 100644
|
||
|
--- a/Makefile
|
||
|
+++ b/Makefile
|
||
|
@@ -21,7 +21,7 @@ TEXTADDR = 0x200000
|
||
|
MALLOCADDR = 0x300000
|
||
|
MALLOCSIZE = 0x100000
|
||
|
# Load kernel and ramdisk at real-base. If there is overlap, will retry until find open space
|
||
|
-KERNELADDR = 0x00C00000
|
||
|
+KERNELADDR = 0x00000000
|
||
|
|
||
|
# Set this to the prefix of your cross-compiler, if you have one.
|
||
|
# Else leave it empty.
|
||
|
@@ -35,8 +35,8 @@ OBJCOPY := $(CROSS)objcopy
|
||
|
|
||
|
# The flags for the yaboot binary.
|
||
|
#
|
||
|
-YBCFLAGS = -Os $(CFLAGS) -nostdinc -Wall -isystem `$(CC) -print-file-name=include` -fsigned-char
|
||
|
-YBCFLAGS += -DVERSION=\"${VERSION}\" #"
|
||
|
+YBCFLAGS = -Os $(CFLAGS) -nostdinc -Wall -isystem `$(CC) -m32 -print-file-name=include` -fsigned-char
|
||
|
+YBCFLAGS += -DVERSION="\"${VERSION}${VERSIONEXTRA}\"" #"
|
||
|
YBCFLAGS += -DTEXTADDR=$(TEXTADDR) -DDEBUG=$(DEBUG)
|
||
|
YBCFLAGS += -DMALLOCADDR=$(MALLOCADDR) -DMALLOCSIZE=$(MALLOCSIZE)
|
||
|
YBCFLAGS += -DKERNELADDR=$(KERNELADDR)
|
||
|
@@ -64,7 +64,7 @@ endif
|
||
|
|
||
|
# Link flags
|
||
|
#
|
||
|
-LFLAGS = -Ttext $(TEXTADDR) -Bstatic
|
||
|
+LFLAGS = -Ttext $(TEXTADDR) -Bstatic -melf32ppclinux
|
||
|
|
||
|
# Libraries
|
||
|
#
|
||
|
@@ -99,7 +99,7 @@ OBJS += second/fs_reiserfs.o
|
||
|
endif
|
||
|
|
||
|
# compilation
|
||
|
-lgcc = `$(CC) -print-libgcc-file-name`
|
||
|
+lgcc = `$(CC) -m32 -print-libgcc-file-name`
|
||
|
|
||
|
all: yaboot addnote mkofboot
|
||
|
|
||
|
diff --git a/include/bootinfo.h b/include/bootinfo.h
|
||
|
index f61409a..7602e48 100644
|
||
|
--- a/include/bootinfo.h
|
||
|
+++ b/include/bootinfo.h
|
||
|
@@ -34,6 +34,7 @@
|
||
|
#define _MACH_classic 0x00000400 /* RPCG RPX-Classic 8xx board */
|
||
|
#define _MACH_oak 0x00000800 /* IBM "Oak" 403 eval. board */
|
||
|
#define _MACH_walnut 0x00001000 /* IBM "Walnut" 405GP eval. board */
|
||
|
+#define _MACH_bplan 0x00002000 /* Pegasos/Efika, broken partition #s */
|
||
|
|
||
|
struct bi_record {
|
||
|
unsigned long tag; /* tag ID */
|
||
|
@@ -51,6 +52,8 @@ struct bi_record {
|
||
|
|
||
|
#endif /* _PPC_BOOTINFO_H */
|
||
|
|
||
|
+extern int _machine;
|
||
|
+
|
||
|
/*
|
||
|
* Local variables:
|
||
|
* c-file-style: "k&r"
|
||
|
diff --git a/include/prom.h b/include/prom.h
|
||
|
index f5ee88f..eacee77 100644
|
||
|
--- a/include/prom.h
|
||
|
+++ b/include/prom.h
|
||
|
@@ -37,6 +37,9 @@ typedef void *phandle;
|
||
|
#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 @@ int prom_set_color(prom_handle device, int color, int r, int g, int b);
|
||
|
|
||
|
/* 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);
|
||
|
diff --git a/second/fs_ext2.c b/second/fs_ext2.c
|
||
|
index 3240ce2..67571f2 100644
|
||
|
--- a/second/fs_ext2.c
|
||
|
+++ b/second/fs_ext2.c
|
||
|
@@ -35,6 +35,7 @@
|
||
|
#include "fs.h"
|
||
|
#include "errors.h"
|
||
|
#include "debug.h"
|
||
|
+#include "bootinfo.h"
|
||
|
|
||
|
#define FAST_VERSION
|
||
|
#define MAX_READ_RANGE 256
|
||
|
@@ -170,7 +171,8 @@ ext2_open( struct boot_file_t* file,
|
||
|
|
||
|
/* Open the OF device for the entire disk */
|
||
|
strncpy(buffer, dev_name, 1020);
|
||
|
- strcat(buffer, ":0");
|
||
|
+ if (_machine != _MACH_bplan)
|
||
|
+ strcat(buffer, ":0");
|
||
|
|
||
|
DEBUG_F("<%s>\n", buffer);
|
||
|
|
||
|
diff --git a/second/fs_of.c b/second/fs_of.c
|
||
|
index 76474ee..0d554c5 100644
|
||
|
--- a/second/fs_of.c
|
||
|
+++ b/second/fs_of.c
|
||
|
@@ -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 0x00000000
|
||
|
+#define LOAD_BUFFER_SIZE 0x01000000
|
||
|
|
||
|
static int of_open(struct boot_file_t* file, const char* dev_name,
|
||
|
struct partition_t* part, const char* file_name);
|
||
|
@@ -166,7 +165,9 @@ of_net_open(struct boot_file_t* file, const char* dev_name,
|
||
|
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 --git a/second/fs_reiserfs.c b/second/fs_reiserfs.c
|
||
|
index 4ad1c2e..238f523 100644
|
||
|
--- a/second/fs_reiserfs.c
|
||
|
+++ b/second/fs_reiserfs.c
|
||
|
@@ -29,6 +29,7 @@
|
||
|
#include "fs.h"
|
||
|
#include "errors.h"
|
||
|
#include "debug.h"
|
||
|
+#include "bootinfo.h"
|
||
|
#include "reiserfs/reiserfs.h"
|
||
|
|
||
|
/* Exported in struct fs_t */
|
||
|
@@ -84,7 +85,10 @@ reiserfs_open( struct boot_file_t *file, const char *dev_name,
|
||
|
else
|
||
|
INFO->partition_offset = 0;
|
||
|
|
||
|
- sprintf( buffer, "%s:%d", dev_name, 0 ); /* 0 is full disk in OF */
|
||
|
+ strncpy(buffer, dev_name, 1020);
|
||
|
+ if (_machine != _MACH_bplan)
|
||
|
+ strcat(buffer, ":0"); /* 0 is full disk in (non-buggy) OF */
|
||
|
+
|
||
|
file->of_device = prom_open( buffer );
|
||
|
DEBUG_F( "Trying to open dev_name=%s; filename=%s; partition offset=%Lu\n",
|
||
|
buffer, file_name, INFO->partition_offset );
|
||
|
diff --git a/second/fs_xfs.c b/second/fs_xfs.c
|
||
|
index 9a2aaa6..04d6cf3 100644
|
||
|
--- a/second/fs_xfs.c
|
||
|
+++ b/second/fs_xfs.c
|
||
|
@@ -30,6 +30,7 @@
|
||
|
#include "xfs/xfs.h"
|
||
|
#include "errors.h"
|
||
|
#include "debug.h"
|
||
|
+#include "bootinfo.h"
|
||
|
|
||
|
#define SECTOR_BITS 9
|
||
|
|
||
|
@@ -77,7 +78,9 @@ xfs_open(struct boot_file_t *file, const char *dev_name,
|
||
|
else
|
||
|
partition_offset = 0;
|
||
|
|
||
|
- sprintf(buffer, "%s:%d", dev_name, 0); /* 0 is full disk in OF */
|
||
|
+ strncpy(buffer, dev_name, 1020);
|
||
|
+ if (_machine != _MACH_bplan)
|
||
|
+ strcat(buffer, ":0"); /* 0 is full disk in (non-buggy) OF */
|
||
|
DEBUG_F("Trying to open dev_name=%s; filename=%s; partition offset=%Lu\n",
|
||
|
buffer, file_name, partition_offset);
|
||
|
file->of_device = prom_open(buffer);
|
||
|
diff --git a/second/partition.c b/second/partition.c
|
||
|
index 0cb8ae8..d20a0ed 100644
|
||
|
--- a/second/partition.c
|
||
|
+++ b/second/partition.c
|
||
|
@@ -40,6 +40,7 @@
|
||
|
#include "linux/iso_fs.h"
|
||
|
#include "debug.h"
|
||
|
#include "errors.h"
|
||
|
+#include "bootinfo.h"
|
||
|
#include "byteorder.h"
|
||
|
|
||
|
/* We currently don't check the partition type, some users
|
||
|
@@ -286,7 +287,7 @@ partition_amiga_lookup( const char *dev_name, prom_handle disk,
|
||
|
for (i=0; i < possible; i++) used[i] = 0;
|
||
|
|
||
|
|
||
|
- for (part = amiga_block[AMIGA_PARTITIONS], partition = 0;
|
||
|
+ for (part = amiga_block[AMIGA_PARTITIONS], partition = 1;
|
||
|
part != AMIGA_END;
|
||
|
part = amiga_block[AMIGA_PART_NEXT], partition++)
|
||
|
{
|
||
|
@@ -337,7 +338,8 @@ partitions_lookup(const char *device)
|
||
|
unsigned int prom_blksize, iso_root_block;
|
||
|
|
||
|
strncpy(block_buffer, device, 2040);
|
||
|
- strcat(block_buffer, ":0");
|
||
|
+ if (_machine != _MACH_bplan)
|
||
|
+ strcat(block_buffer, ":0");
|
||
|
|
||
|
/* Open device */
|
||
|
disk = prom_open(block_buffer);
|
||
|
diff --git a/second/prom.c b/second/prom.c
|
||
|
index e9c5843..4ad7277 100644
|
||
|
--- a/second/prom.c
|
||
|
+++ b/second/prom.c
|
||
|
@@ -568,6 +568,25 @@ prom_sleep (int seconds)
|
||
|
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)
|
||
|
{
|
||
|
diff --git a/second/yaboot.c b/second/yaboot.c
|
||
|
index 0232d33..d6e8017 100644
|
||
|
--- a/second/yaboot.c
|
||
|
+++ b/second/yaboot.c
|
||
|
@@ -114,6 +114,9 @@ int useconf = 0;
|
||
|
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;
|
||
|
@@ -178,6 +181,7 @@ yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5)
|
||
|
{
|
||
|
int result;
|
||
|
void* malloc_base = NULL;
|
||
|
+ unsigned long addr;
|
||
|
prom_handle root;
|
||
|
|
||
|
/* OF seems to do it, but I'm not very confident */
|
||
|
@@ -196,7 +200,10 @@ yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5)
|
||
|
prom_init ((prom_entry) r5);
|
||
|
|
||
|
/* Allocate some memory for malloc'ator */
|
||
|
- malloc_base = prom_claim((void *)MALLOCADDR, MALLOCSIZE, 0);
|
||
|
+ for (addr = MALLOCADDR; addr <= MALLOCADDR * 16 ;addr+=0x100000) {
|
||
|
+ malloc_base = prom_claim((void *)addr, MALLOCSIZE, 0);
|
||
|
+ if (malloc_base != (void *)-1) break;
|
||
|
+ }
|
||
|
if (malloc_base == (void *)-1) {
|
||
|
prom_printf("Can't claim malloc buffer (%d bytes at 0x%08x)\n",
|
||
|
MALLOCSIZE, MALLOCADDR);
|
||
|
@@ -219,7 +226,10 @@ yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5)
|
||
|
root = prom_finddevice("/");
|
||
|
if (root != 0) {
|
||
|
static char model[256];
|
||
|
- if (prom_getprop(root, "device_type", model, 256 ) > 0 &&
|
||
|
+ if (prom_getprop(root, "CODEGEN,vendor", model, 256) > 0 &&
|
||
|
+ !strncmp("bplan", model, 5))
|
||
|
+ _machine = _MACH_bplan;
|
||
|
+ else if (prom_getprop(root, "device_type", model, 256 ) > 0 &&
|
||
|
!strncmp("chrp", model, 4))
|
||
|
_machine = _MACH_chrp;
|
||
|
else {
|
||
|
@@ -455,7 +465,7 @@ static int load_my_config_file(struct boot_fspec_t *orig_fspec)
|
||
|
struct bootp_packet *packet;
|
||
|
int rc = 0;
|
||
|
struct boot_fspec_t fspec = *orig_fspec;
|
||
|
- char *cfgpath = (_machine == _MACH_chrp) ? "/etc/" : "";
|
||
|
+ char *cfgpath = (_machine == _MACH_chrp || _machine == _MACH_bplan) ? "/etc/" : "";
|
||
|
int flen;
|
||
|
int minlen;
|
||
|
|
||
|
@@ -654,6 +664,8 @@ int get_params(struct boot_param_t* params)
|
||
|
static char imagepath[1024];
|
||
|
static char initrdpath[1024];
|
||
|
static char sysmappath[1024];
|
||
|
+ static char manualinitrd[1024];
|
||
|
+ static int definitrd = 1, hasarg = 0;
|
||
|
|
||
|
pause_after = 0;
|
||
|
memset(params, 0, sizeof(*params));
|
||
|
@@ -665,7 +677,7 @@ int get_params(struct boot_param_t* params)
|
||
|
|
||
|
cmdinit();
|
||
|
|
||
|
- if (first) {
|
||
|
+ if (first && !fw_reboot_cnt) {
|
||
|
first = 0;
|
||
|
imagename = bootargs;
|
||
|
word_split(&imagename, ¶ms->args);
|
||
|
@@ -680,6 +692,13 @@ int get_params(struct boot_param_t* params)
|
||
|
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 +735,9 @@ int get_params(struct boot_param_t* params)
|
||
|
if (!imagename) {
|
||
|
if (bootoncelabel[0] != 0)
|
||
|
imagename = bootoncelabel;
|
||
|
- else
|
||
|
+ else if (bootlastlabel[0] != 0)
|
||
|
+ imagename = bootlastlabel;
|
||
|
+ else
|
||
|
imagename = cfg_get_default();
|
||
|
}
|
||
|
if (imagename)
|
||
|
@@ -733,10 +754,53 @@ int get_params(struct boot_param_t* params)
|
||
|
word_split(&imagename, ¶ms->args);
|
||
|
}
|
||
|
|
||
|
+ /* initrd setup via cmd console */
|
||
|
+ /* first, check if the user uses it with some label */
|
||
|
+ if (!strncmp(params->args, "initrd=", 7)) {
|
||
|
+ DEBUG_F("params->args: %s\n", params->args);
|
||
|
+ definitrd = 0;
|
||
|
+ }
|
||
|
+ /* after, check if there is the 'initrd=' in the imagename string */
|
||
|
+ if (!strncmp(imagename, "initrd=", 7) || !definitrd) {
|
||
|
+
|
||
|
+ /* return the value of definitrd to 1 */
|
||
|
+ if (!definitrd)
|
||
|
+ definitrd = 1;
|
||
|
+
|
||
|
+ /* args = "initrd=blah" */
|
||
|
+ char *args = NULL;
|
||
|
+
|
||
|
+ if (params->args) {
|
||
|
+ args = params->args;
|
||
|
+ params->args = NULL;
|
||
|
+ hasarg = 1;
|
||
|
+ } else
|
||
|
+ args = imagename;
|
||
|
+
|
||
|
+ if (strlen(args)){
|
||
|
+ /* copy the string after the '=' to manualinitrd */
|
||
|
+ strcpy(manualinitrd, args+7);
|
||
|
+ definitrd = 0;
|
||
|
+ prom_printf("New initrd file specified: %s\n", manualinitrd);
|
||
|
+ } else {
|
||
|
+ prom_printf("ERROR: no initrd specified!\n");
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* set imagename with the default values of the config file */
|
||
|
+ if ((prom_get_devtype(boot.dev) == FILE_DEVICE_NET) && !hasarg)
|
||
|
+ imagename = cfg_get_default();
|
||
|
+ else
|
||
|
+ imagename = cfg_get_default();
|
||
|
+ }
|
||
|
+
|
||
|
/* chrp gets this wrong, force it -- Cort */
|
||
|
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;
|
||
|
|
||
|
@@ -794,6 +858,12 @@ int get_params(struct boot_param_t* params)
|
||
|
"resides on, and \"partno\" is the partition number the image resides on.\n"
|
||
|
"Note that the comma (,) is only required if you specify an OpenFirmware\n"
|
||
|
"device, if you only specify a filename you should not start it with a \",\"\n\n"
|
||
|
+ "To boot a alternative initrd file rather than specified in the yaboot\n"
|
||
|
+ "configuration file, use the \"initrd\" command on Yaboot's prompt: \n"
|
||
|
+ "\"initrd=[name.img]\". This will load the \"name.img\" file after the default\n"
|
||
|
+ "kernel image. You can, also, specify a different initrd file to any other\n"
|
||
|
+ "label of the yaboot configuration file. Just type \"label initrd=[name.img]\"\n"
|
||
|
+ "and the specified initrd file will be loaded.\n\n"
|
||
|
"To load an alternative config file rather than /etc/yaboot.conf, enter\n"
|
||
|
"its device, partno and path, on Open Firmware Prompt:\n"
|
||
|
"boot conf=device:partno,/path/to/configfile\n."
|
||
|
@@ -923,14 +993,22 @@ int get_params(struct boot_param_t* params)
|
||
|
prom_printf("%s: Unable to parse\n", imagepath);
|
||
|
return 0;
|
||
|
}
|
||
|
- DEBUG_F("after parse_device_path: dev=%s part=%d file=%s\n", params->kernel.dev,
|
||
|
- params->kernel.part, params->kernel.file);
|
||
|
-
|
||
|
+ DEBUG_F("after parse_device_path: dev=%s part=%d file=%s\n", params->kernel.dev, params->kernel.part, params->kernel.file);
|
||
|
if (useconf) {
|
||
|
p = cfg_get_strg(label, "initrd");
|
||
|
if (p && *p) {
|
||
|
- DEBUG_F("Parsing initrd path <%s>\n", p);
|
||
|
- strncpy(initrdpath, p, 1024);
|
||
|
+
|
||
|
+ /* check if user seted to use a initrd file from boot console */
|
||
|
+ if (!definitrd && p != manualinitrd) {
|
||
|
+ if (manualinitrd[0] != "/" && (prom_get_devtype(defdevice_bak) != FILE_DEVICE_NET)) {
|
||
|
+ strcpy(initrdpath, "/");
|
||
|
+ strcat(initrdpath, manualinitrd);
|
||
|
+ } else
|
||
|
+ strncpy(initrdpath, manualinitrd, 1024);
|
||
|
+ } else
|
||
|
+ strncpy(initrdpath, p, 1024);
|
||
|
+
|
||
|
+ DEBUG_F("Parsing initrd path <%s>\n", initrdpath);
|
||
|
if (!parse_device_path(initrdpath, defdevice, defpart,
|
||
|
"/root.bin", ¶ms->rd)) {
|
||
|
prom_printf("%s: Unable to parse\n", imagepath);
|
||
|
@@ -1233,7 +1311,7 @@ load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo)
|
||
|
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 +1399,7 @@ load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo)
|
||
|
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 +1449,7 @@ load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo)
|
||
|
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 +1537,7 @@ load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo)
|
||
|
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,6 +1691,7 @@ int
|
||
|
yaboot_main(void)
|
||
|
{
|
||
|
char *ptype;
|
||
|
+ char *endp;
|
||
|
int conf_given = 0;
|
||
|
char conf_path[1024];
|
||
|
|
||
|
@@ -1635,6 +1702,11 @@ yaboot_main(void)
|
||
|
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,client-architecture-support-reboot",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
|
||
|
@@ -1678,11 +1750,13 @@ yaboot_main(void)
|
||
|
prom_printf("%s: Unable to parse\n", bootdevice);
|
||
|
return -1;
|
||
|
}
|
||
|
+ if (_machine == _MACH_bplan && !conf_given)
|
||
|
+ boot.part++;
|
||
|
DEBUG_F("After parse_device_path: dev=%s, part=%d, file=%s\n",
|
||
|
boot.dev, boot.part, boot.file);
|
||
|
|
||
|
if (!conf_given) {
|
||
|
- if (_machine == _MACH_chrp)
|
||
|
+ if (_machine == _MACH_chrp || _machine == _MACH_bplan)
|
||
|
boot.file = "/etc/";
|
||
|
else if (strlen(boot.file)) {
|
||
|
if (!strncmp(boot.file, "\\\\", 2))
|