yaboot/yaboot-1.3.14-memory_manage...

193 lines
6.6 KiB
Diff

diff -ur yaboot-1.3.14.orig/include/fs.h yaboot-1.3.14/include/fs.h
--- yaboot-1.3.14.orig/include/fs.h 2010-08-03 15:28:29.886806113 -0500
+++ yaboot-1.3.14/include/fs.h 2010-08-03 15:47:40.274304966 -0500
@@ -44,6 +44,8 @@
unsigned int newpos);
int (*close)( struct boot_file_t* file);
+
+ unsigned int (*ino_size)(struct boot_file_t *file);
};
extern const struct fs_t *fs_of;
diff -ur yaboot-1.3.14.orig/include/prom.h yaboot-1.3.14/include/prom.h
--- yaboot-1.3.14.orig/include/prom.h 2010-08-03 15:28:29.916805885 -0500
+++ yaboot-1.3.14/include/prom.h 2010-08-03 15:47:40.274304966 -0500
@@ -37,7 +37,7 @@
#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 PROM_CLAIM_MAX_ADDR 0x10000000
#define BOOTLASTSZ 1024
#define FW_NBR_REBOOTSZ 4
#define TOK_IPV6 "ipv6"
@@ -89,6 +89,7 @@
/* memory */
void *prom_claim_chunk(void *virt, unsigned int size, unsigned int align);
+void *prom_claim_chunk_top(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 -ur yaboot-1.3.14.orig/second/fs_ext2.c yaboot-1.3.14/second/fs_ext2.c
--- yaboot-1.3.14.orig/second/fs_ext2.c 2010-08-03 15:28:29.916805885 -0500
+++ yaboot-1.3.14/second/fs_ext2.c 2010-08-03 15:47:40.274304966 -0500
@@ -54,6 +54,7 @@
static int ext2_seek( struct boot_file_t* file,
unsigned int newpos);
static int ext2_close( struct boot_file_t* file);
+static unsigned int ext2_ino_size(struct boot_file_t *file);
struct fs_t ext2_filesystem =
{
@@ -61,7 +62,8 @@
ext2_open,
ext2_read,
ext2_seek,
- ext2_close
+ ext2_close,
+ ext2_ino_size,
};
/* IO manager structure for the ext2 library */
@@ -565,6 +567,16 @@
return 0;
}
+static unsigned int ext2_ino_size(struct boot_file_t *file)
+{
+ struct ext2_inode ei;
+
+ if (ext2fs_read_inode(fs, file->inode, &ei))
+ return 0;
+
+ return ei.i_size;
+}
+
static errcode_t linux_open (const char *name, int flags, io_channel * channel)
{
io_channel io;
diff -ur 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 2010-08-03 15:28:29.896804336 -0500
+++ yaboot-1.3.14/second/fs_of.c 2010-08-03 15:47:40.274304966 -0500
@@ -44,7 +44,6 @@
#include "errors.h"
#include "debug.h"
-#define LOAD_BUFFER_POS 0x00000000
#define LOAD_BUFFER_SIZE 0x02000000
static int of_open(struct boot_file_t* file,
@@ -58,6 +57,7 @@
struct partition_t* part, struct boot_fspec_t* fspec);
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 unsigned int of_net_ino_size(struct boot_file_t* file);
struct fs_t of_filesystem =
@@ -75,7 +75,8 @@
of_net_open,
of_net_read,
of_net_seek,
- of_close
+ of_close,
+ of_net_ino_size,
};
static int
@@ -206,8 +207,7 @@
}
- file->buffer = prom_claim_chunk((void *)LOAD_BUFFER_POS,
- LOAD_BUFFER_SIZE, 0);
+ file->buffer = prom_claim_chunk_top(LOAD_BUFFER_SIZE, 0);
if (file->buffer == (void *)-1) {
prom_printf("Can't claim memory for TFTP download\n");
prom_close(file->of_device);
@@ -284,6 +284,12 @@
return 0;
}
+static unsigned int
+of_net_ino_size(struct boot_file_t* file)
+{
+ return file->len;
+}
+
/*
* Local variables:
* c-file-style: "k&r"
diff -ur yaboot-1.3.14.orig/second/prom.c yaboot-1.3.14/second/prom.c
--- yaboot-1.3.14.orig/second/prom.c 2010-08-03 15:28:29.916805885 -0500
+++ yaboot-1.3.14/second/prom.c 2010-08-03 15:48:08.934304926 -0500
@@ -548,6 +548,23 @@
return((void*)-1);
}
+/* Start from top of memory and work down to get the needed space */
+void *
+prom_claim_chunk_top(unsigned int size, unsigned int align)
+{
+ void *found, *addr;
+ for(addr=(void*)PROM_CLAIM_MAX_ADDR; addr >= (void *)size;
+ addr-=(0x100000/sizeof(addr))) {
+ found = call_prom("claim", 3, 1, addr, size, 0);
+ if (found != (void *)-1) {
+ prom_printf("claim of 0x%x at 0x%x returned 0x%x\n", size, (int)addr, (int)found);
+ return(found);
+ }
+ }
+ prom_printf("ERROR: claim of 0x%x in range 0x0-0x%x failed\n", size, PROM_CLAIM_MAX_ADDR);
+ return((void*)-1);
+}
+
void *
prom_claim (void *virt, unsigned int size, unsigned int align)
{
diff -ur yaboot-1.3.14.orig/second/yaboot.c yaboot-1.3.14/second/yaboot.c
--- yaboot-1.3.14.orig/second/yaboot.c 2010-08-03 15:28:29.906805706 -0500
+++ yaboot-1.3.14/second/yaboot.c 2010-08-03 15:47:40.274304966 -0500
@@ -1211,25 +1211,33 @@
}
else {
#define INITRD_CHUNKSIZE 0x100000
- initrd_base = prom_claim(loadinfo.base+loadinfo.memsize, INITRD_CHUNKSIZE, 0);
+ unsigned int len = INITRD_CHUNKSIZE;
+
+ /* We add a bit to the actual size so the loop below doesn't think
+ * there is more to load.
+ */
+ if (file.fs->ino_size && file.fs->ino_size(&file) > 0)
+ len = file.fs->ino_size(&file) + 0x1000;
+
+ initrd_base = prom_claim_chunk(loadinfo.base+loadinfo.memsize, len, 0);
if (initrd_base == (void *)-1) {
prom_printf("Claim failed for initrd memory\n");
initrd_base = 0;
} else {
- initrd_size = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_base);
+ initrd_size = file.fs->read(&file, len, initrd_base);
if (initrd_size == 0)
initrd_base = 0;
initrd_read = initrd_size;
initrd_more = initrd_base;
- while (initrd_read == INITRD_CHUNKSIZE ) { /* need to read more? */
- initrd_want = (void *)((unsigned long)initrd_more+INITRD_CHUNKSIZE);
- initrd_more = prom_claim(initrd_want, INITRD_CHUNKSIZE, 0);
+ while (initrd_read == len ) { /* need to read more? */
+ initrd_want = (void *)((unsigned long)initrd_more+len);
+ initrd_more = prom_claim(initrd_want, len, 0);
if (initrd_more != initrd_want) {
prom_printf("Claim failed for initrd memory at %p rc=%p\n",initrd_want,initrd_more);
prom_pause();
break;
}
- initrd_read = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_more);
+ initrd_read = file.fs->read(&file, len, initrd_more);
DEBUG_F(" block at %p rc=%lu\n",initrd_more,initrd_read);
initrd_size += initrd_read;
initrd_end = initrd_more+INITRD_CHUNKSIZE;