Subject: howto pass ramdisk loaddress to kernel

From: Guido Guenther <[email-masked]>
Date: Tue, 7 May 2002 12:32:49 +0200

Hi,
in order to get rid of some ip22 specific hacks in setup.c as well as
addinitrd/elf2ecoff I've written a small tool that links kernel+initrd
as type "binary" into the data segment of the bootloader. This file can
then be fetched by the prom via tftp(or from a CD or whatever). The
bootloader copies the kernel to its loaddress and puts the initrd just
after the kernel.
My question is now: how do i properly pass the initrd's memory address
to the kernel? Choices are:
1) on the commandline: rd_start=0x...
2) a bootparameter block like on i386 or sparc in head.S
3) rely on the kernel to identify if a radisk has
  been loaded by a magic number

I'd prefer (1) but it seems none of the other arches does this. Is there
a reason for that? If not could we just introduce a new kernel
commandline parameter rd_start which has a memory address as a
parameter. Ralf, would you let this into the kernel?
 -- Guido

---

From: Florian Lohoff <[email-masked]>
Date: Tue, 7 May 2002 12:45:38 +0200

> parameter. Ralf, would you let this into the kernel?

I would do 1+3 - Give the address on the command line and let the ramdisk
have a magic + length in the first 2 __u32.

Flo
-- 
Florian Lohoff                  [email-masked]             +49-5201-669912
                        Heisenberg may have been here.

---

From: Guido Guenther <[email-masked]>
Date: Fri, 10 May 2002 20:37:37 +0200

Hi,
> have a magic + length in the first 2 __u32.
I implemented (1) only since the kernel checks for a proper fs/gzip
magic anyway. I added this to the kernels at:
 http://honk.physik.uni-konstanz.de/linux-mips/kernels/
Patch is at:
 http://honk.physik.uni-konstanz.de/linux-mips/kernel-patches/ramdisk-cmdline-2002-05-09.diff
Regards,
 -- Guido

---

From: Florian Lohoff <[email-masked]>
Date: Sat, 11 May 2002 20:38:08 +0200

> magic anyway. I added this to the kernels at:

Ok ...

>  http://honk.physik.uni-konstanz.de/linux-mips/kernel-patches/ramdisk-cmdline-2002-05-09.diff

I looked at the patch and it seems it does support all sub-archs - Is that
correct ?

BTW: When we boot with tip we might also compress the kernel as gzip.

Flo

---

From: Guido Guenther <[email-masked]>
Date: Sun, 12 May 2002 23:31:52 +0200

> I looked at the patch and it seems it does support all sub-archs - Is that
It doesn't refer to any subarchitecture specific details so it can be
used by any subarch, yes.
> BTW: When we boot with tip we might also compress the kernel as gzip.
That's also on my todo list for arcboot/tip22 but I'd like to get
bootfloppies fixed first.
 -- Guido

---

From: Guido Guenther <[email-masked]>
Date: Thu, 16 May 2002 16:34:10 +0200

>   been loaded by a magic number
Attached is a patch that implements (1). Arguments used are rd_start &
rd_size. Ralf, please apply if suitable.
 -- Guido
Index: arch/mips/kernel/setup.c
===================================================================
RCS file: /cvs/linux/arch/mips/kernel/setup.c,v
retrieving revision 1.96.2.12
diff -u -u -r1.96.2.12 setup.c
--- arch/mips/kernel/setup.c	2002/02/15 21:05:48	1.96.2.12
+++ arch/mips/kernel/setup.c	2002/05/10 18:32:09
@@ -650,6 +650,38 @@
 	}
 }
 
+static inline void parse_rd_cmdline(unsigned long* rd_start, unsigned long* rd_end)
+{
+	char c = ' ', *to = command_line, *from = saved_command_line;
+	int len = 0;
+	unsigned long rd_size = 0;
+
+	for (;;) {
+		/*
+		 * "rd_start=0xNNNNNNNN" defines the memory address of an initrd
+		 * "rd_size=0xNN" it's size
+		 */
+		if (c == ' ' && !memcmp(from, "rd_start=", 9)) {
+			if (to != command_line)
+				to--;
+			(*rd_start) = memparse(from + 9, &from);
+		}
+		if (c == ' ' && !memcmp(from, "rd_size=", 8)) {
+			if (to != command_line)
+				to--;
+			rd_size = memparse(from + 8, &from);
+		}
+		c = *(from++);
+		if (!c)
+			break;
+		if (CL_SIZE <= ++len)
+			break;
+		*(to++) = c;
+	}
+	*to = '\0';
+	(*rd_end) = (*rd_start) + rd_size;
+}
+
 void __init setup_arch(char **cmdline_p)
 {
 	void atlas_setup(void);
@@ -674,10 +706,7 @@
 
 	unsigned long bootmap_size;
 	unsigned long start_pfn, max_pfn, max_low_pfn, first_usable_pfn;
-#ifdef CONFIG_BLK_DEV_INITRD
-	unsigned long tmp;
-	unsigned long* initrd_header;
-#endif
+	unsigned long end = &_end;
 
 	int i;
 
@@ -828,22 +857,18 @@
 #define MAXMEM_PFN	PFN_DOWN(MAXMEM)
 
 #ifdef CONFIG_BLK_DEV_INITRD
-	tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; 
-	if (tmp < (unsigned long)&_end) 
-		tmp += PAGE_SIZE;
-	initrd_header = (unsigned long *)tmp;
-	if (initrd_header[0] == 0x494E5244) {
-		initrd_start = (unsigned long)&initrd_header[2];
-		initrd_end = initrd_start + initrd_header[1];
+	parse_rd_cmdline(&initrd_start, &initrd_end);
+	if(initrd_start && initrd_end)
+		end = initrd_end;
+	else {
+		initrd_start = initrd_end = 0;
 	}
-	start_pfn = PFN_UP(__pa((&_end)+(initrd_end - initrd_start) + PAGE_SIZE));
-#else
+#endif /* CONFIG_BLK_DEV_INITRD */
 	/*
 	 * Partially used pages are not usable - thus
 	 * we are rounding upwards.
 	 */
-	start_pfn = PFN_UP(__pa(&_end));
-#endif	/* CONFIG_BLK_DEV_INITRD */
+	start_pfn = PFN_UP(__pa(end));
 
 	/* Find the highest page frame number we have available.  */
 	max_pfn = 0;