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

Re: Bug#366620: 2.6.16-1-powerpc fails to mount rootfs, 2.6.15-1-powerpc works



On Fri, Sep 15, 2006 at 11:21:33AM +0200, Christian Aichinger wrote:
> The kernel somehow loses the information where the initrd image is
> placed in memory. The correct data is there in
> arch/powerpc/kernel/prom_init.c:prom_check_initrd(), but in
> init/initramfs.c:populate_rootfs() it's wrong, initrd_{start,end}
> are both 0.

arch/powerpc/kernel/prom_init.c:prom_check_initrd() is broken. The
relevant part of the code is:

,------------------
|   unsigned long val;
|   ...
|   val = RELOC(prom_initrd_start);                                                                                                                                                                                                 
|   prom_setprop(_prom->chosen, "/chosen", "linux,initrd-start",                                                                                                                                                                    
|            &val, sizeof(val));                                                                                                                                                                                                    
|   val = RELOC(prom_initrd_end);                                                                                                                                                                                                   
|   prom_setprop(_prom->chosen, "/chosen", "linux,initrd-end",                                                                                                                                                                      
|            &val, sizeof(val));                                                                                                                                                                                                    
`------------------

As you can see it tries to store pointers to initrd start/end in the
/chosen node, however in reality it stores the address of val, a
local variable. Since that's long gone invalid when the values are
read out from /chosen again, the result is undefined.

The attached is a patch fixing the problem. It would be nice if the
bug submitters could test it to see if it fixes their problems too.

Cheers,
Christian Aichinger

PS: arch/powerpc/platforms/powermac/bootx_init.c does something
similar, though it looks saner, as it copies *val into it's own
permanent memory block AFAICS.
--- a/arch/powerpc/kernel/prom_init.c	2006-09-15 18:33:50.000000000 +0200
+++ b/arch/powerpc/kernel/prom_init.c	2006-09-15 18:33:44.000000000 +0200
@@ -2141,17 +2141,17 @@
        	struct prom_t *_prom = &RELOC(prom);
 
 	if (r3 && r4 && r4 != 0xdeadbeef) {
-		unsigned long val;
+		unsigned long *ptr;
 
 		RELOC(prom_initrd_start) = is_kernel_addr(r3) ? __pa(r3) : r3;
 		RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
 
-		val = RELOC(prom_initrd_start);
+		ptr = &RELOC(prom_initrd_start);
 		prom_setprop(_prom->chosen, "/chosen", "linux,initrd-start",
-			     &val, sizeof(val));
-		val = RELOC(prom_initrd_end);
+			     ptr, sizeof(prom_initrd_start));
+		ptr = &RELOC(prom_initrd_end);
 		prom_setprop(_prom->chosen, "/chosen", "linux,initrd-end",
-			     &val, sizeof(val));
+			     ptr, sizeof(prom_initrd_end));
 
 		reserve_mem(RELOC(prom_initrd_start),
 			    RELOC(prom_initrd_end) - RELOC(prom_initrd_start));

Attachment: signature.asc
Description: Digital signature


Reply to: