[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: quik kernel size limit



> OK, but what are the options for 2.6 kernels? Is it possible to compile
> kernels small enough?

Maybe... :)

> > 
> >  - Update the BAT mapping code to map 16Mb instead of just 8
> >  - Use an OF map() call to create a 1:1 mapping in the OF own
> >    tables (not that the MAP may be useless thanks to that mapping,
> >    but we keep it for efficiency on oldworld). Without this map()
> >    call, you'll end up with the OF "translate" call failing in the
> >    kernel entry.

Totally untested hack:

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-15 22:03:05.000000000 +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,18 @@
 	    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
+    load_loc = (unsigned int)IMAGE_BUF;
+    entry += (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-15 21:53:37.000000000 +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) {
+    	printk("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);




Reply to: