2007-09-30 Robert Millan * kern/powerpc/ieee1275/init.c: Rename HEAP_LIMIT to HEAP_MAX_ADDR, and make it easier to figure out. Add HEAP_MIN_SIZE and HEAP_MAX_ADDR definitions. (grub_claim_heap): Use HEAP_MAX_ADDR rather than taking a parameter. Do not avoid claiming a region above HEAP_MAX_ADDR if that would leave us with less than HEAP_MIN_SIZE total heap. Avoid our total amount of heap to surpass HEAP_MAX_SIZE. diff -ur grub2/kern/powerpc/ieee1275/init.c grub2.efika/kern/powerpc/ieee1275/init.c --- grub2/kern/powerpc/ieee1275/init.c 2007-07-22 01:32:27.000000000 +0200 +++ grub2.efika/kern/powerpc/ieee1275/init.c 2007-09-30 21:54:19.000000000 +0200 @@ -33,7 +33,15 @@ #include #include -#define HEAP_LIMIT (4<<20) /* 4 MiB */ +/* The minimal heap size we can live with. */ +#define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024) + +/* The maximum heap size we're going to claim */ +#define HEAP_MAX_SIZE (unsigned long) (4 * 1024 * 1024) + +/* If possible, we will avoid claiming heap above this address, because it + seems to cause relocation problems with OSes that link at 4 MiB */ +#define HEAP_MAX_ADDR (unsigned long) (4 * 1024 * 1024) extern char _start[]; extern char _end[]; @@ -113,16 +121,24 @@ } /* Claim some available memory in the first /memory node. */ -static void grub_claim_heap (unsigned long heaplimit) +static void grub_claim_heap () { + unsigned long total = 0; + auto int heap_init (grub_uint64_t addr, grub_uint64_t len); int heap_init (grub_uint64_t addr, grub_uint64_t len) { len -= 1; /* Required for some firmware. */ - /* Don't claim anything above `heaplimit'. */ - if (addr + len > heaplimit) - len = heaplimit - addr; + /* Never exceed HEAP_MAX_SIZE */ + if (total + len > HEAP_MAX_SIZE) + len = HEAP_MAX_SIZE - total; + + /* Avoid claiming anything above HEAP_MAX_ADDR, if possible. */ + if ((addr < HEAP_MAX_ADDR) && /* if it's too late, don't bother */ + (addr + len > HEAP_MAX_ADDR) && /* if it wasn't available anyway, don't bother */ + (total + (HEAP_MAX_ADDR - addr) > HEAP_MIN_SIZE)) /* only limit ourselves when we can afford to */ + len = HEAP_MAX_ADDR - addr; if (len) { @@ -134,6 +150,10 @@ grub_mm_init_region ((void *) (grub_addr_t) addr, len); } + total += len; + if (total >= HEAP_MAX_SIZE) + return 1; + return 0; } @@ -147,7 +167,7 @@ int actual; grub_console_init (); - grub_claim_heap (HEAP_LIMIT); + grub_claim_heap (); grub_ofdisk_init (); /* Process commandline. */