New patch, let me know how it works:
diff -urN quik-2.0e/first/first.S quik-2.0e-hacked/first/first.S
--- quik-2.0e/first/first.S 2003-10-15 22:03:56.056511120 +0200
+++ quik-2.0e-hacked/first/first.S 2003-10-15 21:49:39.000000000 +0200
@@ -56,7 +56,7 @@
sync
isync
-/* Use the BAT3 registers to map the 1st 8MB of RAM to 0. */
+/* Use the BAT2 & 3 registers to map the 1st 16MB of RAM to 0. */
mfpvr 9
rlwinm 9,9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
/* the 604 case now works on G3, and
should */
@@ -66,7 +66,7 @@
li 7,4 /* set up BAT registers for 601 */
li 8,0x7f
b 5f
-4: li 7,0xff /* set up BAT registers for 604 et al */
+4: li 7,0x1ff /* set up BAT registers for 604 et al */
li 8,2
mtdbatl 3,8
mtdbatu 3,7
@@ -75,6 +75,10 @@
b 6f
5: mtibatu 3,7
mtibatl 3,8
+ oris 7,7,0x80
+ oris 8,8,0x80
+ mtibatu 2,7
+ mtibatl 2,8
6: isync
/* Load up an initial stack pointer */
diff -urN quik-2.0e/include/layout.h quik-2.0e-hacked/include/layout.h
--- quik-2.0e/include/layout.h 2000-03-10 21:59:28.000000000 +0100
+++ quik-2.0e-hacked/include/layout.h 2003-10-15 22:05:03.011332440 +0200
@@ -22,7 +22,11 @@
/* 0x400000 - 0x500000 is one of OF's favourite places to be. */
-#define MALLOC_BASE 0x500000
+/* We malloc in low memory now and load kernel at 0x500000 instead, we
+ * also map 16Mb with BATs. This is all done to help loading larger
+ * kernels. --BenH.
+ */
+#define MALLOC_BASE 0x300000
#ifndef __ASSEMBLY__
struct first_info {
diff -urN quik-2.0e/second/main.c quik-2.0e-hacked/second/main.c
--- quik-2.0e/second/main.c 2003-10-15 22:03:56.045512792 +0200
+++ quik-2.0e-hacked/second/main.c 2003-10-17 11:44:53.700123056 +0200
@@ -38,6 +38,8 @@
#define TMP_BUF ((unsigned char *) 0x14000)
#define TMP_END ((unsigned char *) SECOND_BASE)
+#define IMAGE_BUF ((unsigned char *) 0x500000)
+#define IMAGE_END ((unsigned char *) 0x1000000)
#define ADDRMASK 0x0fffffff
char quik_conf[40];
@@ -428,22 +430,22 @@
continue;
fileok = load_file(device, part, kname,
- TMP_BUF, TMP_END, &image_len, 1, 0);
+ IMAGE_BUF, IMAGE_END, &image_len, 1, 0);
if (!fileok) {
printf ("\nImage not found.... try again\n");
continue;
}
- if (image_len > TMP_END - TMP_BUF) {
+ if (image_len > IMAGE_END - IMAGE_BUF) {
printf("\nImage is too large (%u > %u)\n", image_len,
- TMP_END - TMP_BUF);
+ IMAGE_END - IMAGE_BUF);
continue;
}
/* By this point the first sector is loaded (and the rest of */
/* the kernel) so we check if it is an executable elf binary. */
- e = (Elf32_Ehdr *) TMP_BUF;
+ e = (Elf32_Ehdr *) IMAGE_BUF;
if (!(e->e_ident[EI_MAG0] == ELFMAG0 &&
e->e_ident[EI_MAG1] == ELFMAG1 &&
e->e_ident[EI_MAG2] == ELFMAG2 &&
@@ -458,7 +460,7 @@
continue;
}
len = 0;
- p = (Elf32_Phdr *) (TMP_BUF + e->e_phoff);
+ p = (Elf32_Phdr *) (IMAGE_BUF + e->e_phoff);
for (i = 0; i < e->e_phnum; ++i, ++p) {
if (p->p_type != PT_LOAD || p->p_offset == 0)
continue;
@@ -478,12 +480,19 @@
len = image_len - off;
break;
}
-
+
+#if 0
/* chrp expects to start at 0x10000 */
if ( is_chrp )
load_loc = entry = 0x10000;
/* After this memmove, *p and *e may have been overwritten. */
memmove((void *)load_loc, TMP_BUF + off, len);
+#else
+ /* Execute in place, the kernel can relocate itself */
+ entry = (entry - load_loc) + off + (unsigned int)IMAGE_BUF;
+ load_loc = (unsigned int)IMAGE_BUF;
+ prom_map((unsigned int)load_loc, (unsigned int)load_loc, len + 0x200000);
+#endif
flush_cache(load_loc, len);
close();
diff -urN quik-2.0e/second/prom.c quik-2.0e-hacked/second/prom.c
--- quik-2.0e/second/prom.c 2000-03-10 21:59:28.000000000 +0100
+++ quik-2.0e-hacked/second/prom.c 2003-10-16 09:50:12.801693736 +0200
@@ -16,6 +16,7 @@
ihandle prom_stdout;
ihandle prom_chosen;
ihandle prom_options;
+ihandle prom_mmu;
struct prom_args {
char *service;
@@ -77,6 +78,41 @@
}
int
+prom_map(unsigned int phys, unsigned int virt, unsigned int size)
+{
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ char *method;
+ void *mmu_ihandle;
+ int misc;
+ unsigned int phys;
+ unsigned int virt;
+ unsigned int size;
+ int ret0;
+ int ret1;
+ } args;
+
+ if (prom_mmu == 0) {
+ printf("map() called, no MMU found\n");
+ return -1;
+ }
+ args.service = "call-method";
+ args.nargs = 6;
+ args.nret = 2;
+ args.method = "map";
+ args.mmu_ihandle = prom_mmu;
+ args.misc = -1;
+ args.phys = phys;
+ args.virt = virt;
+ args.size = size;
+ prom_entry(&args);
+
+ return (int)args.ret0;
+}
+
+int
putchar(int c)
{
char ch = c;
@@ -115,6 +151,7 @@
prom_exit();
getpromprop(prom_chosen, "stdout", &prom_stdout, sizeof(prom_stdout));
getpromprop(prom_chosen, "stdin", &prom_stdin, sizeof(prom_stdin));
+ getpromprop(prom_chosen, "mmu", &prom_mmu, sizeof(prom_mmu));
prom_options = call_prom("finddevice", 1, 1, "/options");
}
diff -urN quik-2.0e/second/prom.h quik-2.0e-hacked/second/prom.h
--- quik-2.0e/second/prom.h 2000-03-10 21:59:28.000000000 +0100
+++ quik-2.0e-hacked/second/prom.h 2003-10-15 21:54:53.000000000 +0200
@@ -22,6 +22,6 @@
int nbgetchar(void);
void prom_get_chosen(char *name, char *buf, int buflen);
void prom_get_options(char *name, char *buf, int buflen);
-void prom_map(unsigned char *addr, unsigned len);
+int prom_map(unsigned int phys, unsigned int virt, unsigned int size);
int get_ms(void);
void prom_pause(void);