[PATCH 1/15] boot: find initrd location from device-tree

Milton Miller miltonm at bga.com
Mon Sep 24 18:02:36 EST 2007


On Sep 23, 2007, at 9:58 PM, David Gibson wrote:

> On Fri, Sep 21, 2007 at 06:03:24PM -0500, Milton Miller wrote:
>> Some platforms have a boot agent that can create or modify properties 
>> in
>> the device-tree and load images into memory.  Provide a helper to set
>> loader_info used by prep_initrd().
>>
>> Signed-off-by: Milton Miller <miltonm at bga.com>
>> Acked-by: David Gibson <david at gibson.dropbear.id.au>
>
> Hrm, despite my earlier ack, I'm going to whinge about a few nits
> here.
>
>> ---
>> re 12168
>> rediffed types.h, offset in ops.h
>>
>> Index: kernel/arch/powerpc/boot/ops.h
>> ===================================================================
>> --- kernel.orig/arch/powerpc/boot/ops.h	2007-09-17 22:12:47.000000000 
>> -0500
>> +++ kernel/arch/powerpc/boot/ops.h	2007-09-17 22:12:51.000000000 -0500
>> @@ -163,6 +163,7 @@ void dt_fixup_clock(const char *path, u3
>>  void __dt_fixup_mac_addresses(u32 startindex, ...);
>>  #define dt_fixup_mac_addresses(...) \
>>  	__dt_fixup_mac_addresses(0, __VA_ARGS__, NULL)
>> +void dt_find_initrd(void);
>>
>>
>>  static inline void *find_node_by_linuxphandle(const u32 linuxphandle)
>> Index: kernel/arch/powerpc/boot/types.h
>> ===================================================================
>> --- kernel.orig/arch/powerpc/boot/types.h	2007-09-17 
>> 22:12:47.000000000 -0500
>> +++ kernel/arch/powerpc/boot/types.h	2007-09-17 22:12:51.000000000 
>> -0500
>> @@ -12,6 +12,8 @@ typedef short			s16;
>>  typedef int			s32;
>>  typedef long long		s64;
>>
>> +#define UINT_MAX	0xFFFFFFFF
>
> I actually don't like this constant - at the point you compare you
> care, explicitly, about the value not being over 32-bits, rather than
> whether it fits a uint, so the named constant is more misleading than
> helpful.

Arguable, I don't like counting F's or zeros in C code.

It is used as the max address that the wrapper deals with, both here 
and memranges, which happens to be 32 bits.

Actually it cares about overflowing the unsigned long in loader_info, 
not that the address fits in 32 bits.

So it should be ULONG_MAX now (malloc and all the address code was 
changed to use unsigned long instead of unsigned int since the patch 
was written).

And dt_xlate needs the same information.  Its is using a hardcoded 64 
bit constant to provide the a simiar check.


>> +
>>  #define min(x,y) ({ \
>>  	typeof(x) _x = (x);	\
>>  	typeof(y) _y = (y);	\
>> Index: kernel/arch/powerpc/boot/devtree.c
>> ===================================================================
>> --- kernel.orig/arch/powerpc/boot/devtree.c	2007-09-17 
>> 22:12:47.000000000 -0500
>> +++ kernel/arch/powerpc/boot/devtree.c	2007-09-17 22:12:51.000000000 
>> -0500
>> @@ -1,6 +1,7 @@
>>  /*
>>   * devtree.c - convenience functions for device tree manipulation
>>   * Copyright 2007 David Gibson, IBM Corporation.
>> + * Copyright 2007 Milton Miller, IBM Corporation.
>>   * Copyright (c) 2007 Freescale Semiconductor, Inc.
>>   *
>>   * Authors: David Gibson <david at gibson.dropbear.id.au>
>> @@ -333,3 +334,68 @@ int dt_is_compatible(void *node, const c
>>
>>  	return 0;
>>  }
>> +
>> +/**
>> + * dt_find_initrd - set loader initrd location based on existing 
>> properties
>> + *
>> + * finds the linux,initrd-start and linux,initrd-end properties in
>> + * the /chosen node and sets the loader initrd fields accordingly.
>> + *
>> + * Use this if your loader sets the properties to allow other code to
>> + * relocate the tree and/or cause r3 and r4 to be set on true OF
>> + * platforms.
>
> I am unable to make sense of the paragraph above.

The phrase "relocate the tree" should be "relocate the initrd", which 
the wrapper will do if it located below vmlinux.size.  Also, r3 and r4 
need to be set when booting the kernel from a client interface with an 
initrd so it can take it into consideration when choosing the location 
to build the flat tree.

How about:

Filling in the loader info allows main.c to be aware of the initrd, 
meaning prep_initrd will move the initrd if it will be overwritten when 
the kernel is copied to its runtime location.  In addition, if you are 
booting the kernel from a client interface instead of a flat device 
tree, this also causes r3 and r4 to be set so the kernel can avoid 
overwriting the initrd when creating the flat tree.

>
>> + */
>> +void dt_find_initrd(void)
>> +{
>> +	int rc;
>> +	unsigned long long initrd_start, initrd_end;
>> +	void *devp;
>> +	static const char start_prop[] = "linux,initrd-start";
>> +	static const char end_prop[] = "linux,initrd-end";
>
> I think these constants are more obscuring than useful.

They are useful to the extent they reduce the number of source 
characters causing about 8 less line wraps.  Since they are used 
multiple places, the compiler only needs to emit one copy of this byte 
sequence.  Admitedly you made this point in a prior review.

>
>> +
>> +	devp = finddevice("/chosen");
>> +	if (! devp) {
>> +		return;
>> +	}
>
> CodingStyle would not put { } here.

Yea, nit.  not sure why I have the braces there, I usually follow that 
one.  And what's that space doing after !?

>
>> +
>> +	rc = getprop(devp, start_prop, &initrd_start, sizeof(initrd_start));
>> +	if (rc < 0)
>> +		return;				/* not found */
>> +	/* The properties had to be 8 bytes until 2.6.22 */
>> +	if (rc == sizeof(unsigned long)) {
>> +		unsigned long tmp;
>> +		memcpy(&tmp, &initrd_start, rc);
>> +		initrd_start = tmp;
>> +	} else if (rc != sizeof(initrd_start)) {	/* now they
>> can be 4 */
>
> Right.  8 bytes and 4 bytes, so you should be using explicit length
> types instead of long and long long.

Ok, I guess we ahve u32 and u64 in types.h now.  But there is other 
code in the wrapper that assumes its compiled 32 bit ILP.

>
>> +		printf("unexpected length of %s in /chosen!\n\r", start_prop);
>> +		return;
>
> All these printf() / return stanzas add a lot of verbosity to this
> function.  Any way they can be consolidated a bit, maybe a single
> error path that just prints the property values, so the user can
> figure out what was wrong with them.

On a prior review I got asked to split the reasons for ingoring the 
values below (the > 32 bit address from end < start cases).  Admitedly 
without all the detailed errors the justification for the string 
varables is reduced.

>
>> +	}
>> +
>> +	rc = getprop(devp, end_prop, &initrd_end, sizeof(initrd_end));
>> +	if (rc < 0) {
>> +		printf("chosen has %s but no %s!\n\r", start_prop, end_prop);
>> +		return;
>> +	}
>> +	if (rc == sizeof(unsigned long)) {
>> +		unsigned long tmp;
>> +		memcpy(&tmp, &initrd_end, rc);
>> +		initrd_end = tmp;
>> +	} else if (rc != sizeof(initrd_end)) {
>> +		printf("unexpected length of %s in /chosen!\n\r", end_prop);
>> +		return;
>> +	}
>> +
>> +	/* Check for presence, ignore if (partially) loaded above 32 bits */
>> +	if (initrd_start == initrd_end) {
>> +		printf("ignoring empty device-tree supplied initrd\n");
>> +	} else if (initrd_start > initrd_end) {
>> +		printf("ignoring device-tree supplied initrd: start 0x%llx"
>> +				" > end 0x%llx \n", initrd_start, initrd_end);
>> +	} else if (initrd_end > UINT_MAX) {
>> +		printf("ignoring device-tree supplied initrd:"
>> +				" end 0x%llx > 32 bits\n", initrd_end);
>> +	} else {
>> +		loader_info.initrd_addr = initrd_start;
>> +		loader_info.initrd_size  = initrd_end - initrd_start;
>> +	}
>> +}
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev at ozlabs.org
>> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>>
>
> -- 
> David Gibson			| I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ 
> _other_
> 				| _way_ _around_!
> http://www.ozlabs.org/~dgibson
>




More information about the Linuxppc-dev mailing list