patch-2.4.21 linux-2.4.21/arch/ppc/boot/prep/misc.c

Next file: linux-2.4.21/arch/ppc/boot/prep/of1275.c
Previous file: linux-2.4.21/arch/ppc/boot/prep/kbd.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.20/arch/ppc/boot/prep/misc.c linux-2.4.21/arch/ppc/boot/prep/misc.c
@@ -1,6 +1,4 @@
 /*
- * BK Id: SCCS/s.misc.c 1.25 01/26/02 12:27:41 trini
- *
  * arch/ppc/boot/prep/misc.c
  *
  * Adapted for PowerPC by Gary Thomas
@@ -23,6 +21,16 @@
 #include "nonstdio.h"
 #include "zlib.h"
 
+#ifdef CONFIG_CMDLINE
+#define CMDLINE CONFIG_CMDLINE
+#else
+#define CMDLINE ""
+#endif
+
+#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_VGA_CONSOLE)
+#define INTERACTIVE_CONSOLE	1
+#endif
+
 /*
  * Please send me load/board info and such data for hardware not
  * listed here so I can keep track since things are getting tricky
@@ -38,11 +46,6 @@
 extern char __ramdisk_begin, __ramdisk_end;
 extern char _end[];
 
-#ifdef CONFIG_CMDLINE
-#define CMDLINE CONFIG_CMDLINE
-#else
-#define CMDLINE ""
-#endif
 char cmd_preset[] = CMDLINE;
 char cmd_buf[256];
 char *cmd_line = cmd_buf;
@@ -56,9 +59,7 @@
 char *zimage_start;
 int zimage_size;
 
-#if defined(CONFIG_SERIAL_CONSOLE)
 unsigned long com_port;
-#endif /* CONFIG_SERIAL_CONSOLE */
 #ifdef CONFIG_VGA_CONSOLE
 char *vidmem = (char *)0xC00B8000;
 int lines = 25, cols = 80;
@@ -122,10 +123,14 @@
 decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
 		  RESIDUAL *residual, void *OFW_interface)
 {
+#ifdef INTERACTIVE_CONSOLE
 	int timer = 0;
+	char ch;
+#endif
 	extern unsigned long start;
-	char *cp, ch;
-	unsigned long TotalMemory;
+	char *cp;
+	/* Default to 32MiB memory. */
+	unsigned long TotalMemory = 0x02000000;
 	int dev_handle;
 	int mem_info[2];
 	int res, size;
@@ -135,9 +140,7 @@
 	unsigned int pci_viddid, pci_did, tulip_pci_base, tulip_base;
 
 	serial_fixups();
-#if defined(CONFIG_SERIAL_CONSOLE)
 	com_port = serial_init(0, NULL);
-#endif /* CONFIG_SERIAL_CONSOLE */
 #if defined(CONFIG_VGA_CONSOLE)
 	vga_init((unsigned char *)0xC0000000);
 #endif /* CONFIG_VGA_CONSOLE */
@@ -215,13 +218,14 @@
 				start_multi = 1;
 		}
 		memcpy(hold_residual,residual,sizeof(RESIDUAL));
+
+		/* Copy the memory info. */
+		if (residual->TotalMemory)
+			TotalMemory = residual->TotalMemory;
 	} else {
 		/* Tell the user we didn't find anything. */
 		puts("No residual data found.\n");
 
-		/* Assume 32M in the absence of more info... */
-		TotalMemory = 0x02000000;
-
 		/*
 		 * This is a 'best guess' check.  We want to make sure
 		 * we don't try this on a PReP box without OF
@@ -254,9 +258,6 @@
 			break;
 		}
 
-		hold_residual->TotalMemory = TotalMemory;
-		residual = hold_residual;
-
 		/* Enforce a sane MSR for booting. */
 		_put_MSR(MSR_IP);
         }
@@ -304,6 +305,11 @@
 	memcpy (cmd_line, cmd_preset, sizeof(cmd_preset));
 	while ( *cp )
 		putc(*cp++);
+#ifdef INTERACTIVE_CONSOLE
+	/*
+	 * If they have a console, allow them to edit the command line.
+	 * Otherwise, don't bother wasting the five seconds.
+	 */
 	while (timer++ < 5*1000) {
 		if (tstc()) {
 			while ((ch = getc()) != '\n' && ch != '\r') {
@@ -328,6 +334,7 @@
 		}
 		udelay(1000);  /* 1 msec */
 	}
+#endif
 	*cp = 0;
 	puts("\nUncompressing Linux...");
 
@@ -343,14 +350,41 @@
 
 	{
 		struct bi_record *rec;
-		
-		rec = (struct bi_record *)_ALIGN((unsigned long)(zimage_size) +
+		unsigned long initrd_loc;
+		unsigned long rec_loc = _ALIGN((unsigned long)(zimage_size) +
 				(1 << 20) - 1, (1 << 20));
+		
+		rec = (struct bi_record *)rec_loc;
+
+		/* We need to make sure that the initrd and bi_recs do not
+		 * overlap. */
+		if ( initrd_size ) {
+			initrd_loc = (unsigned long)(&__ramdisk_begin);
+			/* If the bi_recs are in the middle of the current
+			 * initrd, move the initrd to the next MB
+			 * boundary. */
+			if ((rec_loc > initrd_loc) &&
+					((initrd_loc + initrd_size)
+					 > rec_loc)) {
+				initrd_loc = _ALIGN((unsigned long)(zimage_size)
+						+ (2 << 20) - 1, (2 << 20));
+			 	memmove((void *)initrd_loc, &__ramdisk_begin,
+					 initrd_size);
+		         	puts("initrd moved:  "); puthex(initrd_loc);
+			 	puts(" "); puthex(initrd_loc + initrd_size);
+			 	puts("\n");
+			}
+		}
 
 		rec->tag = BI_FIRST;
 		rec->size = sizeof(struct bi_record);
 		rec = (struct bi_record *)((unsigned long)rec + rec->size);
 
+		rec->tag = BI_MEMSIZE;
+		rec->data[0] = TotalMemory;
+		rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+		rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
 		rec->tag = BI_BOOTLOADER_ID;
 		memcpy( (void *)rec->data, "prepboot", 9);
 		rec->size = sizeof(struct bi_record) + 8 + 1;
@@ -370,7 +404,7 @@
 
 		if ( initrd_size ) {
 			rec->tag = BI_INITRD;
-			rec->data[0] = (unsigned long)(&__ramdisk_begin);
+			rec->data[0] = initrd_loc;
 			rec->data[1] = initrd_size;
 			rec->size = sizeof(struct bi_record) + 2 *
 				sizeof(unsigned long);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)