* [PATCH 1/15] boot: find initrd location from device-tree
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
@ 2007-09-21 23:03 ` Milton Miller
2007-09-24 2:58 ` David Gibson
2007-09-21 23:03 ` [PATCH 2/15] boot: record header bytes in gunzip_start Milton Miller
` (15 subsequent siblings)
16 siblings, 1 reply; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:03 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
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@bga.com>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
---
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
+
#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@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.
+ */
+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";
+
+ devp = finddevice("/chosen");
+ if (! devp) {
+ return;
+ }
+
+ 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 */
+ printf("unexpected length of %s in /chosen!\n\r", start_prop);
+ return;
+ }
+
+ 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;
+ }
+}
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/15] boot: find initrd location from device-tree
2007-09-21 23:03 ` [PATCH 1/15] boot: find initrd location from device-tree Milton Miller
@ 2007-09-24 2:58 ` David Gibson
2007-09-24 5:50 ` Rob Landley
2007-09-24 8:02 ` Milton Miller
0 siblings, 2 replies; 55+ messages in thread
From: David Gibson @ 2007-09-24 2:58 UTC (permalink / raw)
To: Milton Miller; +Cc: linuxppc-dev, Paul Mackerras, Rob Landley
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@bga.com>
> Acked-by: David Gibson <david@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.
> +
> #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@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.
> + */
> +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.
> +
> + devp = finddevice("/chosen");
> + if (! devp) {
> + return;
> + }
CodingStyle would not put { } here.
> +
> + 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.
> + 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.
> + }
> +
> + 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@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
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/15] boot: find initrd location from device-tree
2007-09-24 2:58 ` David Gibson
@ 2007-09-24 5:50 ` Rob Landley
2007-09-24 8:02 ` Milton Miller
1 sibling, 0 replies; 55+ messages in thread
From: Rob Landley @ 2007-09-24 5:50 UTC (permalink / raw)
To: David Gibson; +Cc: linuxppc-dev, Paul Mackerras, Milton Miller
On Sunday 23 September 2007 9:58:24 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@bga.com>
> > Acked-by: David Gibson <david@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.
Except int and uint are 32 bits on all targets, due to unix standardizing on
LP64:
http://www.unix.org/whitepapers/64bit.html
http://www.unix.org/version2/whatsnew/lp64_wp.html
> > +/**
> > + * 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.
I think this means it finds the initrd location from the device tree (supplied
by your firmware or bootloader) rather than from the kernel command line the
way all the other platforms do.
Rob
--
"One of my most productive days was throwing away 1000 lines of code."
- Ken Thompson.
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/15] boot: find initrd location from device-tree
2007-09-24 2:58 ` David Gibson
2007-09-24 5:50 ` Rob Landley
@ 2007-09-24 8:02 ` Milton Miller
2007-09-25 3:27 ` David Gibson
1 sibling, 1 reply; 55+ messages in thread
From: Milton Miller @ 2007-09-24 8:02 UTC (permalink / raw)
To: David Gibson; +Cc: ppcdev, Paul Mackerras
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@bga.com>
>> Acked-by: David Gibson <david@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@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@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
>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/15] boot: find initrd location from device-tree
2007-09-24 8:02 ` Milton Miller
@ 2007-09-25 3:27 ` David Gibson
2007-09-26 5:49 ` Milton Miller
0 siblings, 1 reply; 55+ messages in thread
From: David Gibson @ 2007-09-25 3:27 UTC (permalink / raw)
To: Milton Miller; +Cc: ppcdev, Paul Mackerras
On Mon, Sep 24, 2007 at 03:02:36AM -0500, Milton Miller wrote:
>
> 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@bga.com>
> >> Acked-by: David Gibson <david@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.
So check if (addr >> 32) is non-zero.
> It is used as the max address that the wrapper deals with, both here
> and memranges, which happens to be 32 bits.
Right and the reasons for that being the value it is are not because
it also hapeens to be the max uint *or* ulong.
> 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@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.
Clearer, but I still don't see that it says anything useful - "finds
the initrd from the devtree and does all the things that are supposed
to be done with an initrd" - which is implied in the previous
paragraph.
>
> >
> >> + */
> >> +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.
The compiler is perfectly capable of folding identical string
constants.
> >> +
> >> + 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.
Yes, but that's no reason to propagate the sin.
> >> + 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.
Hrm. Well, I can't say I'm entirely convinced either way on this
one. I guess I'll think about it again once the rest is cleaned up.
--
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
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/15] boot: find initrd location from device-tree
2007-09-25 3:27 ` David Gibson
@ 2007-09-26 5:49 ` Milton Miller
0 siblings, 0 replies; 55+ messages in thread
From: Milton Miller @ 2007-09-26 5:49 UTC (permalink / raw)
To: David Gibson; +Cc: ppcdev, Paul Mackerras
On Sep 24, 2007, at 10:27 PM, David Gibson wrote:
> On Mon, Sep 24, 2007 at 03:02:36AM -0500, Milton Miller wrote:
>>
>> 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@bga.com>
>>>> Acked-by: David Gibson <david@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.
>
> So check if (addr >> 32) is non-zero.
>
>> It is used as the max address that the wrapper deals with, both here
>> and memranges, which happens to be 32 bits.
>
> Right and the reasons for that being the value it is are not because
> it also hapeens to be the max uint *or* ulong.
Huh? the code is checking that the value will fit in the ulongs that
are the type that stores this value in the struct. Are you aruging for
max_ptr_type? If the code were compiled LP64 then it would not need
to check that the address was 32 bits. Here you say "check for 32
bits", while below ...
>
>> 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@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.
>
> Clearer, but I still don't see that it says anything useful - "finds
> the initrd from the devtree and does all the things that are supposed
> to be done with an initrd" - which is implied in the previous
> paragraph.
I was tring to point out there is additional processing that is done
when the bootwrapper is aware of the initrd, as opposed to the kernel
finding it after it processes the flattened the tree. suggestions?
>>>> + */
>>>> +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.
>
> The compiler is perfectly capable of folding identical string
> constants.
Yes it is, but are you going to leave the constant strings as %s in the
printf strings?
Maybe i shold create a function that takes the property and returns the
int if its either 32 or 64 bits, calling it twice?
>>>> +
>>>> + 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.
>
> Yes, but that's no reason to propagate the sin.
HAH! so abvoe you are tring to get me to hard code in 32 bits, and now
you argue that long == 32 bits is "sinful"?
>
>>>> + 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.
>
> Hrm. Well, I can't say I'm entirely convinced either way on this
> one. I guess I'll think about it again once the rest is cleaned up.
I'll make some of these changes when I get back to work (been at the
power.org conference), but I still think ulong_max is the correct
check.
milton
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 2/15] boot: record header bytes in gunzip_start
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
2007-09-21 23:03 ` [PATCH 1/15] boot: find initrd location from device-tree Milton Miller
@ 2007-09-21 23:03 ` Milton Miller
2007-09-24 2:59 ` David Gibson
2007-09-21 23:03 ` [PATCH 3/15] boot: simplfy gunzip_finish Milton Miller
` (14 subsequent siblings)
16 siblings, 1 reply; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:03 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
Record the number of header bytes skipped in the total bytes read field.
This is needed for the initramfs parsing code to find the end of the zip file.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
Identical to 12169
Index: kernel/arch/powerpc/boot/gunzip_util.c
===================================================================
--- kernel.orig/arch/powerpc/boot/gunzip_util.c 2007-07-10 03:33:34.000000000 -0500
+++ kernel/arch/powerpc/boot/gunzip_util.c 2007-07-10 03:40:59.000000000 -0500
@@ -78,6 +78,7 @@ void gunzip_start(struct gunzip_state *s
fatal("inflateInit2 returned %d\n\r", r);
}
+ state->s.total_in = hdrlen;
state->s.next_in = src + hdrlen;
state->s.avail_in = srclen - hdrlen;
}
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 3/15] boot: simplfy gunzip_finish
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
2007-09-21 23:03 ` [PATCH 1/15] boot: find initrd location from device-tree Milton Miller
2007-09-21 23:03 ` [PATCH 2/15] boot: record header bytes in gunzip_start Milton Miller
@ 2007-09-21 23:03 ` Milton Miller
2007-09-21 23:03 ` [PATCH 4/15] bootwrapper: smp support code Milton Miller
` (13 subsequent siblings)
16 siblings, 0 replies; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:03 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
Call gunzip_partial to calculate the remaining length and copy the
data to the user buffer. This makes it shorter and reduces
duplication.
Signed-off-by: Milton Miller <miltonm@bga.com>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
---
identical content to 12170, removed extra space in change log
Index: kernel/arch/powerpc/boot/gunzip_util.c
===================================================================
--- kernel.orig/arch/powerpc/boot/gunzip_util.c 2007-07-10 03:39:07.000000000 -0500
+++ kernel/arch/powerpc/boot/gunzip_util.c 2007-07-10 03:39:07.000000000 -0500
@@ -194,13 +194,10 @@ int gunzip_finish(struct gunzip_state *s
{
int len;
+ len = gunzip_partial(state, dst, dstlen);
+
if (state->s.workspace) {
- len = gunzip_partial(state, dst, dstlen);
zlib_inflateEnd(&state->s);
- } else {
- /* uncompressed image */
- len = min(state->s.avail_in, (unsigned)dstlen);
- memcpy(dst, state->s.next_in, len);
}
return len;
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 4/15] bootwrapper: smp support code
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
` (2 preceding siblings ...)
2007-09-21 23:03 ` [PATCH 3/15] boot: simplfy gunzip_finish Milton Miller
@ 2007-09-21 23:03 ` Milton Miller
2007-09-21 23:04 ` [PATCH 5/15] bootwrapper: occuppied memory ranges Milton Miller
` (12 subsequent siblings)
16 siblings, 0 replies; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:03 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
Support code to move cpus around, both a spin loop and c code to
move the cpus before uncompressing and copying the kernel to 0.
The low level code is designed to be included in a crt0 or other
assembly file because it may need to be at a fixed location or there
may be other entry point requirements.
Note: this code works with kernel head_64.S. head_6xx.S needs the
0x60 entry point (it currently mentions something at address 0xC0; but
the similar code is at 0xC4); the other heads don't appear to support
SMP.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
vs 12171
get barrier from io.h instead of adding to reg.h
rediff ops.h, Makefile
Index: kernel/arch/powerpc/boot/marshal_low.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/boot/marshal_low.S 2007-09-17 22:13:14.000000000 -0500
@@ -0,0 +1,103 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2007 IBM Corporation.
+ *
+ * Authors: Milton Miller <miltonm@bga.com>
+ *
+ */
+
+#include "ppc_asm.h"
+
+ .text
+ /*
+ * This code is designed to be a kexec entry point block.
+ * That is, it has both code for the master cpu that begins
+ * at offset 0 as linked into the image, and a sequence of
+ * 0x100 bytes that, when copied to address 0, forms the
+ * wait loop for slave cpus. Each slave should have its
+ * unique hardware cpu identifier in r3 before entering
+ * this code.
+ */
+ .globl master
+master: b _zimage_start_plat
+
+ .global slave_wait
+slave_wait:
+ /* r3 cpu id, r4 slaves_wait, r5 cpu bit, r6 cpu mask word offset */
+
+ /* set our bit in the slaves mask */
+98: lwarx r7,r4,r6
+ or r8,r7,r5
+ stwcx. r8,r4,r6
+ bne 98b
+
+ and. r8,r7,r5
+ bnel- err_slave
+
+99: lwz r7,gohere-slave_wait(r4)
+ cmpwi 0,r7,0
+ beq 99b
+ mtctr r7
+ mr r4,r7
+ bctr
+
+
+ .global gohere
+gohere: .long 0 /* when set the slave moves */
+
+
+err_slave:
+ stw r5,slave_error-slave_wait(4) /* no locking */
+ blr
+
+ .globl slave_error /* set when slave detects error */
+slave_error:
+ .long 0
+
+ /*
+ * The slaves may be in 32 or 64 bit mode, we don't care
+ * r3 is the slave cpu number, matching the device tree.
+ */
+ .org master+0x60
+ .globl slave
+slave: bl 1f
+1: mflr r4
+ addi r4,r4,slave_wait-1b /* code assumes r4=slave_wait */
+ li r5,1
+ rlwnm r5,r5,r3,0,31 /* bit within word */
+ rlwinm r6,r3,32-5+2,4,29 /* word in array */
+ addi r6,r6,slaves-slave_wait /* relative to r4, slave_wait */
+ b slave_wait
+
+ .org master+0x80 /* put locked bitmask data in another line */
+ .global slaves
+slaves:
+
+ .globl slaves_end;
+slaves_end = 0f
+
+#if 0
+ /* today, the 32 bit kernel starts slaves at 0xc0
+ * but this limits us to cpu to 512 vs 1024
+ */
+ .org master+0xc0
+0: b slave
+#endif
+
+
+ .org master+0x100 /* we must fit in 0x100 bytes */
+0:
+
Index: kernel/arch/powerpc/boot/marshal.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/boot/marshal.c 2007-09-17 22:13:14.000000000 -0500
@@ -0,0 +1,276 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright (C) 2007 IBM Corporation.
+ *
+ * Authors: Milton Miller <miltonm@bga.com>
+ */
+
+#include "ops.h"
+#include "stdio.h"
+#include "reg.h"
+#include "io.h"
+
+extern unsigned int gohere[], master[], slave_wait[], slaves[], slaves_end[];
+extern unsigned int slave_error[1];
+
+static unsigned int slaves_run_here[SMP_SLAVE_SIZE / sizeof(unsigned int)];
+static unsigned int *slaves_were_here = master;
+static unsigned int *slaves_goto_here = master;
+
+/**
+ * check_slave_errors - check if the slaves have set the error flag.
+ * @slaves_here ... the location that the slaves should be spinning.
+ */
+static void check_slave_errors(unsigned int *slaves_here)
+{
+ unsigned int *error = slave_error - master + slaves_here;
+
+ if (*error) {
+ printf("WARNING: error detected by one or more slave cpus!!\n\r"
+ "WARNING: This probably means you have duplicate cpu ids\n\r");
+ /* exit() */
+ }
+}
+
+/**
+ * wait_slaves_moved - wait for the slaves to catch up
+ *
+ * Wait until all slaves that checked in the previous location have
+ * checked into the current location. Seperate so we can do other
+ * work while we wait for them to catch up.
+ */
+void wait_slaves_moved(void)
+{
+ int offset = slaves - master;
+ int len = sizeof(slaves_end[0]) * (slaves_end - slaves);
+ int printed = 0;
+ unsigned int *to = slaves_goto_here;
+ unsigned int *from = slaves_were_here;
+
+ from += offset;
+ to += offset;
+
+ if (from == to)
+ return;
+
+ while (memcmp(from, to, len)) {
+ if (!printed) {
+ printf("waiting for slave cpus to move...");
+ printed = 1;
+ HMT_LOW;
+ barrier();
+ }
+ /* check from is superset of to */
+ }
+ if (printed) {
+ HMT_MEDIUM;
+ printf("done.\n\r");
+ }
+
+ slaves_were_here = slaves_goto_here;
+}
+
+/**
+ * move_slaves_here - move slaves to a specified address.
+ * @addr: location of %SMP_SLAVE_SIZE buffer to place code and spin
+ *
+ * Tell slaves to go from their current location to a buffer @addr
+ * of %SMP_SLAVE_SIZE bytes somewhere in memory.
+ */
+void move_slaves_here(void *addr)
+{
+ unsigned int *move_slaves_here = addr;
+ unsigned int *tell_them = gohere - master + slaves_goto_here;
+ unsigned int *goto_here = slave_wait - master + move_slaves_here;
+ unsigned int *wait_here = gohere - master + move_slaves_here;
+
+ if (move_slaves_here == slaves_goto_here)
+ return; /* already there */
+
+ wait_slaves_moved(); /* one move at a time */
+
+ printf("moving slave cpus from %p to %p\n\r", slaves_goto_here,
+ move_slaves_here);
+
+ memcpy(move_slaves_here, master, SMP_SLAVE_SIZE);
+ memset(move_slaves_here + (slaves - master), 0,
+ (slaves_end - slaves) * sizeof(slaves_end[0]));
+ *wait_here = 0;
+
+ flush_cache(move_slaves_here, SMP_SLAVE_SIZE);
+
+ check_slave_errors(slaves_were_here);
+
+ *tell_them = (unsigned int)goto_here;
+ slaves_goto_here = move_slaves_here;
+}
+
+/**
+ * move_slaves_up - move slaves from somewhere low to our bss.
+ * Call before decompressing the kernel to address 0.
+ */
+void move_slaves_up(void)
+{
+ move_slaves_here(slaves_run_here);
+}
+
+/**
+ * slaves_are_low - Assert that the slaves are spinning at 0, and move them
+ * Assert that the slaves are running in a copy of the marshall code
+ * that was copied to address 0. Ask them to go up to our bss, as we
+ * know we have to move them away from 0.
+ */
+void slaves_are_low(void)
+{
+ slaves_goto_here = slaves_were_here = (void *)0;
+ move_slaves_up();
+}
+
+/**
+ * wait_slave_checkout - wait for slaves to execute checkout store.
+ * @checkout - slave checkout flag array
+ *
+ * Wait for every slave who checked in at slaves_were_here to
+ * perform the stb to @checkout before the branch to self spin loop.
+ */
+static void wait_slave_checkout(char *checkout)
+{
+ unsigned int *end = slaves_end - master + slaves_were_here;
+ unsigned int *from = slaves - master + slaves_were_here;;
+ unsigned int bit;
+ int i, ncpus = 0;
+ char *waiting = "waiting on slaves to go to kernel...";
+
+ for (i=0; from < end; from++)
+ for (bit = 1; bit; i++, bit <<= 1)
+ if (*from & bit) {
+ ncpus++;
+ while (!checkout[i]) {
+ if (waiting) {
+ printf(waiting);
+ waiting = NULL;
+ }
+ HMT_LOW;
+ barrier();
+ }
+ }
+
+ if (waiting == NULL)
+ printf("done.\n\r");
+
+ printf("moved %d slaves to the kernel.\n\r", ncpus);
+}
+
+/* The slave checkin code ... used by checkout_slaves_to_kernel below */
+extern unsigned int slave_checkout_begin[], slave_checkout_spin[];
+asm ("\
+ .globl slave_checkout_begin ;\
+ .globl slave_checkout_spin ;\
+slave_checkout_begin: ;\
+ lwz 7,0(0) ;\
+ li 8,1 ;\
+ stbx 8,7,3 ;\
+slave_checkout_spin: ;\
+ b $ ;\
+");
+
+
+/**
+ * checkout_slaves_to_kernel - send SMP slaves to the kernel
+ * @tell_them - the expected marshalling buffer for the slaves
+ *
+ * Actively move slaves spinning on @tell_them to 0x60. Since we
+ * don't know what code is there, replace it with our one code that
+ * ends with a byte store and branch to self, with the branch at 0x60.
+ * After the stores complete, we can restore the rest of the line,
+ * flush, then restore the remaining line.
+ */
+static void checkout_slaves_to_kernel(unsigned int *tell_them)
+{
+ int to, spin;
+ unsigned int *from, *low, save[SMP_SLAVE_SIZE/sizeof(unsigned int)];
+ char *checkout;
+
+ checkout = malloc(1024);
+ if (checkout == NULL)
+ fatal("can't malloc slave checkout buffer");
+ memset(checkout, 0, 1024);
+
+ low = (unsigned int *)0;
+ memcpy(save, low, SMP_SLAVE_SIZE);
+
+ to = spin = 0x60 / sizeof(int);
+
+ to++;
+ from = slave_checkout_spin;
+ while (from >= slave_checkout_begin)
+ low[--to] = *from--;
+
+ low[0] = (unsigned int)checkout;
+ flush_cache(low, SMP_SLAVE_SIZE);
+
+ *tell_them = (unsigned int)(low + to);
+
+ wait_slave_checkout(checkout);
+
+ /* at this point, all have completed the store at %0x5c and are at
+ * the branch to self at %0x60. Restore the rest of the vector,
+ * flush cache, then do the final store replacing the spin and
+ * flush again.
+ */
+ low[0] = save[0];
+ for (;to < spin; to++)
+ low[to] = save[to];
+ flush_cache(low, SMP_SLAVE_SIZE);
+ low[to] = save[to];
+ flush_cache(low, SMP_SLAVE_SIZE);
+
+}
+
+/**
+ * send_slaves_to_kernel - send SMP slaves to the kernel
+ * @vmlinux_addr: address vmlinux was decompressed to (where to get slave loop)
+ *
+ * Send slaves currently running in the marshalling system to the slave code
+ * in the next kernel which has been uncompressed at address @vmlinux_addr.
+ * Copies the first %SMP_SLAVE_SIZE bytes of the image to address %0 and
+ * then tells the slaves to go to %0x60.
+ */
+void send_slaves_to_kernel(void *vmlinux_addr)
+{
+ unsigned int *tell_them = gohere - master + slaves_goto_here;
+
+ if ((unsigned long)slaves_goto_here < SMP_SLAVE_SIZE) {
+ if ((unsigned long)vmlinux_addr < SMP_SLAVE_SIZE)
+ fatal("ERROR: slaves were not marshaled before "
+ "decompressing the kernel to 0!\n");
+ move_slaves_up();
+ send_slaves_to_kernel(vmlinux_addr);
+ return;
+ }
+
+ wait_slaves_moved();
+
+ if (vmlinux_addr) {
+ memcpy((void *)0, vmlinux_addr, SMP_SLAVE_SIZE);
+ flush_cache((void *)0, SMP_SLAVE_SIZE);
+ } else {
+ printf("kernel was decompressed to 0\n\r");
+ }
+ check_slave_errors(slaves_goto_here);
+
+ checkout_slaves_to_kernel(tell_them);
+}
Index: kernel/arch/powerpc/boot/Makefile
===================================================================
--- kernel.orig/arch/powerpc/boot/Makefile 2007-09-17 22:12:41.000000000 -0500
+++ kernel/arch/powerpc/boot/Makefile 2007-09-17 22:13:14.000000000 -0500
@@ -42,6 +42,7 @@ $(addprefix $(obj)/,$(zlib) gunzip_util.
$(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
+ marshal.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
Index: kernel/arch/powerpc/boot/reg.h
===================================================================
--- kernel.orig/arch/powerpc/boot/reg.h 2007-09-17 22:12:41.000000000 -0500
+++ kernel/arch/powerpc/boot/reg.h 2007-09-17 22:13:14.000000000 -0500
@@ -19,4 +19,8 @@ static inline u32 mfpvr(void)
register void *__stack_pointer asm("r1");
#define get_sp() (__stack_pointer)
+#define HMT_MEDIUM asm volatile("or 2,2,2")
+#define HMT_LOW asm volatile("or 1,1,1")
+
+
#endif /* _PPC_BOOT_REG_H */
Index: kernel/arch/powerpc/boot/ops.h
===================================================================
--- kernel.orig/arch/powerpc/boot/ops.h 2007-09-17 22:12:51.000000000 -0500
+++ kernel/arch/powerpc/boot/ops.h 2007-09-17 22:13:14.000000000 -0500
@@ -18,6 +18,7 @@
#define COMMAND_LINE_SIZE 512
#define MAX_PATH_LEN 256
#define MAX_PROP_LEN 256 /* What should this be? */
+#define SMP_SLAVE_SIZE 256 /* Size of SMP slave block, kexec/kernel */
typedef void (*kernel_entry_t)(unsigned long r3, unsigned long r4, void *r5);
@@ -86,7 +87,13 @@ int mpsc_console_init(void *devp, struct
int cpm_console_init(void *devp, struct serial_console_data *scdp);
void *simple_alloc_init(char *base, unsigned long heap_size,
unsigned long granularity, unsigned long max_allocs);
-extern void flush_cache(void *, unsigned long);
+void flush_cache(void *, unsigned long);
+void move_slaves_up(void);
+void move_slaves_here(void *where);
+void send_slaves_to_kernel(void *vmlinux_addr);
+void slaves_are_low(void);
+void wait_slaves_moved(void);
+
int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size);
int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr);
int dt_is_compatible(void *node, const char *compat);
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 5/15] bootwrapper: occuppied memory ranges
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
` (3 preceding siblings ...)
2007-09-21 23:03 ` [PATCH 4/15] bootwrapper: smp support code Milton Miller
@ 2007-09-21 23:04 ` Milton Miller
2007-09-24 3:09 ` David Gibson
2007-09-21 23:04 ` [PATCH 6/15] bootwrapper: help for 64 bit cpus Milton Miller
` (11 subsequent siblings)
16 siblings, 1 reply; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:04 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
Add a set of library routines to manage gross memory allocations.
This code uses an array in bss to store upto 32 entrys with merging
representing a range of memory below rma_end (aka end of real mode
memory at 0).
To use this code, a platform would set rma_end (find_rma_end), mark
memory ranges occupied (add_known_ranges et al), initialize malloc in
the spaces between (ranges_init_malloc), and optionally use the supplied
vmlinux_alloc may be used.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
vs 12172
rename rmo_end to rma_end (real mode area, as used in papr)
removed section labels (now in ops.h)
rediff ops.h, Makefile
moved find_rma_end here (from kexec.c in a later patch)
find_rma_end searches by node type for "memory", checks that
the parent is the root node, then looks for a reg property
with the first address/size pair starting at 0.
Index: kernel/arch/powerpc/boot/memranges.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/boot/memranges.c 2007-09-20 17:51:42.000000000 -0500
@@ -0,0 +1,299 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright IBM Corporation 2007
+ *
+ * Authors: Milton Miller <miltonm@bga.com>
+ */
+
+#include "ops.h"
+#include "stdio.h"
+#include "flatdevtree.h"
+#include "page.h"
+#include "types.h"
+
+void *rma_end;
+
+static struct {
+ void *start, *end;
+} ranges[32];
+static int num_ranges;
+
+/**
+ * find_rma_end - find end of Real Mode Area
+ * Query the device tree to find the node of type memory that contains a
+ * reg starting with address 0, and update rma_end to point to the end
+ * of that region. On PAPR systems, only this RMA region is accessable
+ * in real mode.
+ */
+void find_rma_end(void)
+{
+ unsigned int na, ns, reg[4], *rp; char path[MAX_PATH_LEN];
+ void *devp, *root; int rc;
+
+ path[0] = '\0';
+ root = finddevice("/");
+ if (!root)
+ fatal("Ack, can't get device-tree root");
+ rc = getprop(root, "#address-cells", &na, sizeof(na));
+ if (rc != sizeof(na))
+ fatal("Ack, no #address-cells in root");
+ rc = getprop(root, "#size-cells", &ns, sizeof(ns));
+ if (rc != sizeof(ns))
+ fatal("Ack, no #size-cells in root");
+ if (!na || !ns || na < 1 || na > 2 || ns < 1 || ns > 2)
+ fatal("find_rma_end: / #addr-cells or #size-cells unsupported");
+
+ devp = NULL;
+ while ((devp = find_node_by_devtype(devp, "memory"))) {
+ if (root != get_parent(devp)) {
+ printf("Ignoring memory node %s"
+ " --- not a child of root\n\r",
+ get_path(devp, path, sizeof(path)));
+ continue;
+ }
+ rc = getprop(devp, "reg", reg, sizeof(reg));
+ if (rc < (na + ns) * sizeof(int)) {
+ printf("No valid reg property in memory node %s\n\r",
+ get_path(devp, path, sizeof(path)));
+ continue;
+ }
+ /* find the node where the first reg entry starts at 0 */
+ rp = ®[0];
+ if (*rp++)
+ continue;
+ if (na > 1 && *rp++)
+ continue;
+
+ /* if >4G, limit it */
+ if (ns > 1 && *rp++) {
+ rma_end = (void *)0xFFFFFFFF;
+ return;
+ }
+
+ /* other wise use its size */
+ rma_end = (void *)*rp;
+ return;
+ }
+ fatal("find_rma_end: didn't find memory at 0\n\r");
+}
+
+/**
+ * add_occupied_range - mark a range as occupied
+ * @start: start of range pointer
+ * @end: end of range pointer
+ *
+ * Mark the range from @start to @end as occupied.
+ * Ignore anything above rma_end.
+ */
+void add_occupied_range(void *start, void *end)
+{
+ int i, j;
+
+ if (start == end)
+ return;
+ if (start > rma_end)
+ return;
+ if (end > rma_end)
+ end = rma_end;
+ if (start > end)
+ fatal("%s: BUG: start %p > end %p\n\r", __FUNCTION__,
+ start, end);
+
+ printf("add %p %p: ", start, end);
+
+ for (i=0; i < num_ranges; i++)
+ if (start <= ranges[i].end)
+ break;
+
+ /* extend and merge any overlapping ranges */
+ if (i < num_ranges && end >= ranges[i].start) {
+ ranges[i].start = min(start, ranges[i].start);
+ for (j=i; j < num_ranges; j++)
+ if (end >= ranges[j].start)
+ end = max(end, ranges[j].end);
+ else
+ break;
+ ranges[i].end = end;
+
+ if (j == i + 1) {
+ printf("extending range %d to %p %p\n\r", i,
+ ranges[i].start, ranges[i].end);
+ } else {
+ printf("merged ranges %d to %d now %p %p\n\r", i, j,
+ ranges[i].start, ranges[i].end);
+
+ ++i;
+ memmove(&ranges[i], &ranges[j],
+ (num_ranges - j) * sizeof(ranges[0]));
+ num_ranges -= j-i;
+ }
+ } else {
+ /* insert a new range */
+ if (num_ranges >= ARRAY_SIZE(ranges) - 1)
+ fatal("Too many memory ranges to track\n");
+
+ printf("inserting range %d between %p and %p\n\r",
+ i, i ? ranges[i-1].end : 0,
+ i == num_ranges ? rma_end : ranges[i].start);
+
+ memmove(&ranges[i+1], &ranges[i],
+ (num_ranges - i) * sizeof(ranges[0]));
+ num_ranges++;
+
+ ranges[i].start = start;
+ ranges[i].end = end;
+ }
+}
+
+/**
+ * add_occupied_range_ulong - mark a range as occupied
+ * @start: start of block to occupy
+ * @end: start of block to occupy
+ *
+ * Call add_occupied_range() after casting to ulong @start and @end to
+ * void * pointers.
+ */
+void add_occupied_range_ulong(unsigned long start, unsigned long end)
+{
+ add_occupied_range((void *)start, (void *)end);
+}
+
+/**
+ * add_known_ranges - occupy some known regions
+ * @dt_blob: a flattend device tree to occupy, or NULL to skip
+ *
+ * call add_occupied_range() for the wrapper, loader supplied initrd,
+ * and, if not %NULL, the device tree blob @dt_blob and any reserved
+ * memory ranges therein.
+ */
+void add_known_ranges(struct boot_param_header *dt_blob)
+{
+ unsigned long long rstart, rlen, rend, *rsrv;
+
+ add_occupied_range(_start, _end);
+
+ add_occupied_range_ulong(loader_info.initrd_addr,
+ loader_info.initrd_addr + loader_info.initrd_size);
+
+ if (dt_blob == NULL)
+ return;
+
+ add_occupied_range(dt_blob, (void *)dt_blob + dt_blob->totalsize);
+
+ /* only support 8-byte reserve map. Only care about < 4G */
+ rsrv = (void *)dt_blob + dt_blob->off_mem_rsvmap;
+ do {
+ rstart = *rsrv++;
+ rlen = *rsrv++;
+ rend = rstart + rlen;
+
+ if (rlen && rstart < UINT_MAX) {
+ if (rend < UINT_MAX)
+ add_occupied_range_ulong(rstart, rend);
+ else
+ add_occupied_range_ulong(rstart, UINT_MAX);
+ }
+ } while (rlen);
+}
+
+/**
+ * ranges_init_malloc - initialize malloc heap in a free memory range.
+ *
+ * Call simple_alloc_init using the largest gap between occupied ranges.
+ * Does not consider before the first or after the last range.
+ */
+void ranges_init_malloc(void)
+{
+ int i;
+ unsigned long size = 0;
+ void *heap_start, *heap_end;
+
+ /*
+ * Allow the beginning for the kernel and the end for
+ * other things the platform might want to have reserved.
+ */
+
+ heap_start = NULL; /* avoid gcc warning */
+ for (i=1; i < num_ranges; i++) {
+ unsigned long newsize;
+
+ newsize = ranges[i].start - ranges[i-1].end;
+ if (newsize > size) {
+ size = newsize;
+ heap_start = ranges[i-1].end;
+ }
+ }
+
+ if (size < 4 * 1024 * 1024)
+ fatal("Can't find a sutiable gap (largest 0x%lx)", size);
+
+ printf("putting heap between %p and %p size 0x%lx\n\r", heap_start,
+ heap_start + size, size);
+ heap_end = simple_alloc_init(heap_start, size * 7 / 8,
+ PAGE_SIZE, /* max num alloc */ 4096);
+ if (heap_end > (heap_start + size))
+ fatal("heap alloc overflowed gap (%p)\n\r", heap_end);
+
+ add_occupied_range(heap_start, heap_end);
+}
+
+/**
+ * ranges_vmlinux_alloc - an optonal kernel allocator.
+ * @size: the image size of the kernel
+ *
+ * Searches for a location to put the kernel, then reserve that range
+ * and the area to which the kernel will relocate itself. First try
+ * address %0. If that is blocked by a previos call to add_occupied_range(),
+ * try malloc(). If that also fails search for free space between the
+ * occupied ranges or between the last range and rma_end.
+ */
+void *ranges_vmlinux_alloc(unsigned long size)
+{
+ void *addr;
+ int i;
+
+ /* Assume _start to _end is occupied */
+ addr = (void *)0;
+ if (addr + size < ranges[0].start)
+ goto occupy;
+
+ addr = malloc(size);
+ if (addr)
+ goto out;
+
+ for (i=1; i < num_ranges; i++) {
+ if (size < ranges[i].start - ranges[i-1].end)
+ goto occupy_range;
+ }
+ if (size < rma_end - ranges[i-1].end)
+ goto occupy_range;
+
+ fatal("Unable to find a 0x%lx byte gap for the kernel\n", size);
+
+occupy_range:
+ addr = ranges[i-1].end;
+occupy:
+ add_occupied_range(addr, addr + size);
+out:
+ /*
+ * Assume the kernel will decompress to 0, but don't implicity
+ * create a new gap below the current first range.
+ */
+ if ((unsigned long)ranges[0].end < size)
+ add_occupied_range_ulong(0, size);
+
+ return addr;
+}
Index: kernel/arch/powerpc/boot/ops.h
===================================================================
--- kernel.orig/arch/powerpc/boot/ops.h 2007-09-17 22:13:14.000000000 -0500
+++ kernel/arch/powerpc/boot/ops.h 2007-09-20 17:51:18.000000000 -0500
@@ -22,6 +22,8 @@
typedef void (*kernel_entry_t)(unsigned long r3, unsigned long r4, void *r5);
+struct boot_param_header;
+
/* Platform specific operations */
struct platform_ops {
void (*fixups)(void);
@@ -99,6 +101,15 @@ int dt_xlate_addr(void *node, u32 *buf,
int dt_is_compatible(void *node, const char *compat);
void dt_get_reg_format(void *node, u32 *naddr, u32 *nsize);
+/* memory ranges */
+extern void *rma_end;
+void add_occupied_range(void *start, void *end);
+void add_occupied_range_ulong(unsigned long start, unsigned long end);
+void add_known_ranges(struct boot_param_header *dt_blob);
+void find_rma_end(void);
+void ranges_init_malloc(void);
+void *ranges_vmlinux_alloc(unsigned long size);
+
static inline void *finddevice(const char *name)
{
return (dt_ops.finddevice) ? dt_ops.finddevice(name) : NULL;
Index: kernel/arch/powerpc/boot/Makefile
===================================================================
--- kernel.orig/arch/powerpc/boot/Makefile 2007-09-17 22:13:14.000000000 -0500
+++ kernel/arch/powerpc/boot/Makefile 2007-09-20 17:51:18.000000000 -0500
@@ -42,7 +42,7 @@ $(addprefix $(obj)/,$(zlib) gunzip_util.
$(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
- marshal.c \
+ marshal.c memranges.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 5/15] bootwrapper: occuppied memory ranges
2007-09-21 23:04 ` [PATCH 5/15] bootwrapper: occuppied memory ranges Milton Miller
@ 2007-09-24 3:09 ` David Gibson
2007-09-24 9:33 ` Milton Miller
0 siblings, 1 reply; 55+ messages in thread
From: David Gibson @ 2007-09-24 3:09 UTC (permalink / raw)
To: Milton Miller; +Cc: linuxppc-dev, Paul Mackerras, Rob Landley
On Fri, Sep 21, 2007 at 06:04:18PM -0500, Milton Miller wrote:
> Add a set of library routines to manage gross memory allocations.
>
> This code uses an array in bss to store upto 32 entrys with merging
> representing a range of memory below rma_end (aka end of real mode
> memory at 0).
>
> To use this code, a platform would set rma_end (find_rma_end), mark
> memory ranges occupied (add_known_ranges et al), initialize malloc in
> the spaces between (ranges_init_malloc), and optionally use the supplied
> vmlinux_alloc may be used.
>
> Signed-off-by: Milton Miller <miltonm@bga.com>
> ---
> vs 12172
> rename rmo_end to rma_end (real mode area, as used in papr)
> removed section labels (now in ops.h)
> rediff ops.h, Makefile
> moved find_rma_end here (from kexec.c in a later patch)
> find_rma_end searches by node type for "memory", checks that
> the parent is the root node, then looks for a reg property
> with the first address/size pair starting at 0.
Urg. It's an awful lot of code for the bootwrapper. Am I right in
understanding that the only reason to use the ranges code is for the
ranges based malloc() and vmlinux_alloc() you get out of it?
--
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
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 5/15] bootwrapper: occuppied memory ranges
2007-09-24 3:09 ` David Gibson
@ 2007-09-24 9:33 ` Milton Miller
0 siblings, 0 replies; 55+ messages in thread
From: Milton Miller @ 2007-09-24 9:33 UTC (permalink / raw)
To: David Gibson; +Cc: ppcdev, Paul Mackerras
On Sep 23, 2007, at 10:09 PM, David Gibson wrote:
> On Fri, Sep 21, 2007 at 06:04:18PM -0500, Milton Miller wrote:
>> Add a set of library routines to manage gross memory allocations.
>>
>> This code uses an array in bss to store upto 32 entrys with merging
>> representing a range of memory below rma_end (aka end of real mode
>> memory at 0).
>>
>> To use this code, a platform would set rma_end (find_rma_end), mark
>> memory ranges occupied (add_known_ranges et al), initialize malloc in
>> the spaces between (ranges_init_malloc), and optionally use the
>> supplied
>> vmlinux_alloc may be used.
>
> Urg. It's an awful lot of code for the bootwrapper. Am I right in
> understanding that the only reason to use the ranges code is for the
> ranges based malloc() and vmlinux_alloc() you get out of it?
Yes.
The ranges based malloc is simple_alloc after finding a sutable chunk
to operate in.
When doing a kexec, there are several chunks of memory to avoid. There
are at least the wrapper, the initrd, the input device tree, and
possibly rtas and tce tables. The last two are avoided by parsing the
memory resrve list in the flat tree blob.
In practice, on 64 bit powerpc kexec-tools loads the kernel (in this
case zImage) immediately following the old kernel _end (becauset the
kernel doesnt' allow otherwise, like 32 bit and most other platforms
do). If the kernel being execd is larger than the kernel invoking
kexec, then the vmlinux will not fit below the wrapper, but when they
are the same it will fit. So in the malloc region we need space for
random temps, the final device tree, the kernel, and possibly the
initrd -- especially if its attached to the zImage instead of supplied
by kexec-tools.
While I titled this platform kexec, in reality, it is a generic chain
looading platform for flat device trees in that it is invoked with the
same calling conveintions as it calls the kernel. With the current
policy of run-where-loadeed, the wrapper has to be able to find out
what memory is available. It may be above or below itself, and the
bulk of available memory may be after any of the above mentioned
ranges. The only information is the the flat device tree and its
knowledge of itself. Most of this code deals with building the sorted
list of what memory is used.
Actually, there is a hole in that malloc may be initialzed below the
vmlinux.size and the initrd and deviece tree could end up overwritten.
This can't be eliminated without doing something like prpmc2800 where
the kernel decompression is started and the elf header is read before
initializing malloc. In practice has not triggered because the
vmlinux will be malloced before the device tree without an initrd, and
with it the kernel is likely smaller than the wrapper (since the memory
chunk at 0 is avoided, it requires the end of some other chunk to be
low in memory).
At one point you had mentioned considering changes to run out of bss
and handling the initrd and kernel with calls to memmove; any such
movement would requrie similar information to what is being built into
the storted structure in this code to support externally loaded initrds
and device-trees, which could not be allocated into the bss wihout
arbitrarilly limiting their size.
I've made several changes to the split btween memranges.c and kexec.c
over time. Perhaps there are more left. There is a bit of policy in
the ranges malloc initialilzation; that could probably be eliminated by
query functions for the largest chunk. The vmlinux alloc could try just
0 and malloc(). And the area from the last occupied range to roa_end
should be available for malloc as well as the kernel.
milton
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 6/15] bootwrapper: help for 64 bit cpus
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
` (4 preceding siblings ...)
2007-09-21 23:04 ` [PATCH 5/15] bootwrapper: occuppied memory ranges Milton Miller
@ 2007-09-21 23:04 ` Milton Miller
2007-09-24 3:14 ` David Gibson
2007-09-21 23:04 ` [PATCH 7/15] bootwrapper: Add kexec callable zImage wrapper Milton Miller
` (10 subsequent siblings)
16 siblings, 1 reply; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:04 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
Add code to check if the processor is in 64 or 32 bit mode using
only instructions from the 32 bit subset. If the processor is in
64 bit mode, switch to 32 bit mode by clearing MSR[SF].
Also add a 64 bit procedure descriptor to use as a elf64 entry
point.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
vs 12173
correct comment (equal vs not-equal)
Index: kernel/arch/powerpc/boot/crt0.S
===================================================================
--- kernel.orig/arch/powerpc/boot/crt0.S 2007-07-10 03:33:36.000000000 -0500
+++ kernel/arch/powerpc/boot/crt0.S 2007-07-10 03:39:08.000000000 -0500
@@ -17,11 +17,47 @@
_zimage_start_opd:
.long _zimage_start, 0, 0, 0
+ /* a procedure descriptor used when pretending to be elf64_powerpc */
+ .balign 8
+ .globl _zimage_start_64
+_zimage_start_64:
+ .long 0, _zimage_start /* big endian, supported reloc ppc32 */
+ .long 0, 0, 0, 0, 0, 0
+
+
.weak _zimage_start
.globl _zimage_start
_zimage_start:
.globl _zimage_start_lib
_zimage_start_lib:
+ /* Check if the processor is running in 32 bit mode, using
+ * only 32 bit instructions which should be safe on 32 and
+ * 64 bit processors.
+ *
+ * Subtract bottom 32 bits of MSR from full value recording
+ * the result. Since MSR[SF] is in the high word, we will
+ * be equal iff in 32 bit mode (either the processor is
+ * a 32 bit processor or MSR[SF] = 0).
+ */
+ mfmsr r0 /* grab whole msr */
+ rlwinm r8,r0,0,0,31 /* extract bottom word */
+ subf. r8,r8,r0 /* subtract, same? */
+ beq 0f /* yes: we are 32 bit mode */
+
+ /* We are in 64-bit mode. This program must run in 32 bit
+ * mode. Assume we are actually running somewhere in the
+ * low 32 bits of the address space, so we can just turn
+ * off MSR[SF] which is bit 0.
+ */
+ .machine push
+ .machine "ppc64"
+ rldicl r0,r0,0,1
+ sync
+ mtmsrd r0
+ isync
+ .machine pop
+0: /* We are now in 32-bit mode */
+
/* Work out the offset between the address we were linked at
and the address where we're running. */
bl 1f
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 6/15] bootwrapper: help for 64 bit cpus
2007-09-21 23:04 ` [PATCH 6/15] bootwrapper: help for 64 bit cpus Milton Miller
@ 2007-09-24 3:14 ` David Gibson
0 siblings, 0 replies; 55+ messages in thread
From: David Gibson @ 2007-09-24 3:14 UTC (permalink / raw)
To: Milton Miller; +Cc: linuxppc-dev, Paul Mackerras, Rob Landley
On Fri, Sep 21, 2007 at 06:04:37PM -0500, Milton Miller wrote:
> Add code to check if the processor is in 64 or 32 bit mode using
> only instructions from the 32 bit subset. If the processor is in
> 64 bit mode, switch to 32 bit mode by clearing MSR[SF].
>
> Also add a 64 bit procedure descriptor to use as a elf64 entry
> point.
>
> Signed-off-by: Milton Miller <miltonm@bga.com>
> ---
> vs 12173
> correct comment (equal vs not-equal)
>
> Index: kernel/arch/powerpc/boot/crt0.S
> ===================================================================
> --- kernel.orig/arch/powerpc/boot/crt0.S 2007-07-10 03:33:36.000000000 -0500
> +++ kernel/arch/powerpc/boot/crt0.S 2007-07-10 03:39:08.000000000 -0500
> @@ -17,11 +17,47 @@
> _zimage_start_opd:
> .long _zimage_start, 0, 0, 0
>
> + /* a procedure descriptor used when pretending to be elf64_powerpc */
> + .balign 8
> + .globl _zimage_start_64
> +_zimage_start_64:
Hrm, I'd prefer _zimage_start_opd64 in analogy with the COFF opd entry
above.
> + .long 0, _zimage_start /* big endian, supported reloc ppc32 */
> + .long 0, 0, 0, 0, 0, 0
> +
> +
> .weak _zimage_start
> .globl _zimage_start
> _zimage_start:
> .globl _zimage_start_lib
> _zimage_start_lib:
> + /* Check if the processor is running in 32 bit mode, using
> + * only 32 bit instructions which should be safe on 32 and
> + * 64 bit processors.
> + *
> + * Subtract bottom 32 bits of MSR from full value recording
> + * the result. Since MSR[SF] is in the high word, we will
> + * be equal iff in 32 bit mode (either the processor is
> + * a 32 bit processor or MSR[SF] = 0).
> + */
> + mfmsr r0 /* grab whole msr */
> + rlwinm r8,r0,0,0,31 /* extract bottom word */
> + subf. r8,r8,r0 /* subtract, same? */
> + beq 0f /* yes: we are 32 bit mode */
> +
> + /* We are in 64-bit mode. This program must run in 32 bit
> + * mode. Assume we are actually running somewhere in the
> + * low 32 bits of the address space, so we can just turn
> + * off MSR[SF] which is bit 0.
> + */
> + .machine push
> + .machine "ppc64"
> + rldicl r0,r0,0,1
> + sync
> + mtmsrd r0
> + isync
> + .machine pop
> +0: /* We are now in 32-bit mode */
> +
> /* Work out the offset between the address we were linked at
> and the address where we're running. */
> bl 1f
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@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
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 7/15] bootwrapper: Add kexec callable zImage wrapper
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
` (5 preceding siblings ...)
2007-09-21 23:04 ` [PATCH 6/15] bootwrapper: help for 64 bit cpus Milton Miller
@ 2007-09-21 23:04 ` Milton Miller
2007-09-24 3:23 ` David Gibson
2007-09-21 23:05 ` [PATCH 8/15] bootwrapper: convert flatdevtree to version 16 Milton Miller
` (9 subsequent siblings)
16 siblings, 1 reply; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:04 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
This code creates a 32 bit zImage wrapper for a 32 or 64 bit PowerPC
Linux kernel. This allows you to kexec a zImage with its compressed
vmlinux instead of the uncompressed vmlinux elf. The code is also
packaged as a 64 bit elf for use by kexec-tools on 64 bit kernels.
Limitations:
Note: the device-tree generated by kexec-tools is currently version 2,
not the version 16 supported by the boot code base.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
find_rmo_end moved to memranges as find_rma_end.
early_scan_flat_tree replaced with calls to its pieces in
kexec_platform_init
rediff wrapper, Makefile, ops.h
Index: kernel/arch/powerpc/boot/kexec.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/boot/kexec.c 2007-09-21 04:52:46.000000000 -0500
@@ -0,0 +1,122 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright IBM Corporation 2007
+ *
+ * Authors: Milton Miller <miltonm@bga.com>
+ */
+
+#include "ops.h"
+#include "stdio.h"
+#include "flatdevtree.h"
+#include "page.h"
+#include "types.h"
+
+extern char _start[];
+extern char _end[];
+
+BSS_STACK(16*1024);
+
+static void find_console_from_tree(void)
+{
+ int rc = -1;
+
+ if (rc) {
+ /* no console, oh well */
+ }
+}
+
+/**
+ * setup_initial_heap - setup a small heap in the bss
+ * Using a preallocated heap, setup for scanning the device tree.
+ * Intended for the initial read while the tree will remain read-only so
+ * a minimal malloc and search limit can be used. This way we don't have
+ * lots of data or bss to clear.
+ */
+static void setup_initial_heap(void)
+{
+ static char initial_heap[8*1024];
+ void *heap_end;
+
+ heap_end = simple_alloc_init(initial_heap,
+ sizeof(initial_heap) * 7 / 8,
+ sizeof(long), 64);
+
+ if (heap_end - sizeof(initial_heap) > (void *)&initial_heap[0])
+ fatal("Initial heap too big\n\r");
+}
+
+static void init_flat_tree(struct boot_param_header *dt_blob)
+{
+ int rc;
+
+ rc = ft_init(dt_blob, dt_blob->totalsize, /* max_finddevice */ 1024);
+ if (rc)
+ fatal("Unable to initialize device_tree library!\n\r");
+}
+
+static void *saved_vmlinux_addr;
+
+static void *kexec_vmlinux_alloc(unsigned long size)
+{
+ void *addr;
+
+ addr = ranges_vmlinux_alloc(size);
+
+ saved_vmlinux_addr = addr;
+ return addr;
+}
+
+static void kexec_fixups(void)
+{
+ wait_slaves_moved();
+}
+
+static unsigned long (*finalize_chain)(void);
+
+static unsigned long kexec_finalize(void)
+{
+ send_slaves_to_kernel(saved_vmlinux_addr);
+
+ return finalize_chain();
+}
+
+void kexec_platform_init(struct boot_param_header *dt_blob)
+{
+ slaves_are_low();
+ move_slaves_up();
+
+ setup_initial_heap();
+ init_flat_tree(dt_blob);
+ /*
+ * drivers can malloc and read the tree, but not realloc later
+ * or modify the tree now.
+ */
+ if (!console_ops.write)
+ find_console_from_tree();
+
+ find_rma_end();
+ dt_find_initrd();
+ add_known_ranges(dt_blob);
+ ranges_init_malloc();
+
+ /* now that we have a malloc region, start over from the flat tree */
+ init_flat_tree(dt_blob);
+
+ platform_ops.vmlinux_alloc = kexec_vmlinux_alloc;
+ platform_ops.fixups = kexec_fixups;
+ finalize_chain = dt_ops.finalize;
+ dt_ops.finalize = kexec_finalize;
+}
Index: kernel/arch/powerpc/boot/crt0_kexec.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/boot/crt0_kexec.S 2007-09-21 04:52:46.000000000 -0500
@@ -0,0 +1,45 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2007 IBM Corporation.
+ *
+ * Authors: Milton Miller <miltonm@bga.com>
+ *
+ */
+ /*
+ * The kernel calls out to the first image with
+ * r3 = boot cpu, r4 = entrypoint, r5 = 0
+ *
+ * kexec-tools purgatory calls this as it would a linux kernel:
+ * r3 = boot block, r4 = entrypoint, r5 = 0
+ *
+ * The boot block boot_cpu field has been filled in.
+ *
+ * kexec-tools and its purgatory are suppposed to copy SMP_SLAVE_SIZE
+ * bytes from the from entry point, but aparently instead it copies
+ * from the image start.
+ */
+ .globl _zimage_start
+_zimage_start:
+
+#include "marshal_low.S"
+
+ .globl _zimage_start_plat
+_zimage_start_plat:
+ b _zimage_start_lib
+
+ .globl platform_init
+platform_init:
+ b kexec_platform_init
Index: kernel/arch/powerpc/boot/wrapper
===================================================================
--- kernel.orig/arch/powerpc/boot/wrapper 2007-09-21 04:51:31.000000000 -0500
+++ kernel/arch/powerpc/boot/wrapper 2007-09-21 04:52:46.000000000 -0500
@@ -133,6 +133,12 @@ coff)
platformo=$object/of.o
lds=$object/zImage.coff.lds
;;
+kexec)
+ platformo=$object/crt0_kexec.o
+ ;;
+kexec64)
+ platformo="-e _zimage_start_64 $object/crt0_kexec.o"
+ ;;
miboot|uboot)
# miboot and U-boot want just the bare bits, not an ELF binary
ext=bin
@@ -190,6 +196,9 @@ uboot)
fi
exit 0
;;
+kexec64)
+ ${CROSS}objcopy -O elf64-powerpc $ofile
+ ;;
esac
addsec() {
Index: kernel/arch/powerpc/boot/Makefile
===================================================================
--- kernel.orig/arch/powerpc/boot/Makefile 2007-09-21 04:52:44.000000000 -0500
+++ kernel/arch/powerpc/boot/Makefile 2007-09-21 04:52:46.000000000 -0500
@@ -42,12 +42,12 @@ $(addprefix $(obj)/,$(zlib) gunzip_util.
$(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
- marshal.c memranges.c \
+ marshal.c memranges.c kexec.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
cpm-serial.c stdlib.c
-src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \
+src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c crt0_kexec.S \
cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c cuboot-bamboo.c
@@ -128,6 +128,9 @@ quiet_cmd_wrap = WRAP $@
cmd_wrap =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \
$(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) vmlinux
+kexec-$(CONFIG_PPC32) += zImage.kexec
+kexec-$(CONFIG_PPC64) += zImage.kexec64
+
image-$(CONFIG_PPC_PSERIES) += zImage.pseries
image-$(CONFIG_PPC_MAPLE) += zImage.pseries
image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries
@@ -140,6 +143,7 @@ image-$(CONFIG_PPC_HOLLY) += zImage.hol
image-$(CONFIG_PPC_PRPMC2800) += zImage.prpmc2800
image-$(CONFIG_PPC_ISERIES) += zImage.iseries
image-$(CONFIG_DEFAULT_UIMAGE) += uImage
+image-$(CONFIG_KEXEC) += $(kexec-y)
ifneq ($(CONFIG_DEVICE_TREE),"")
image-$(CONFIG_PPC_8xx) += cuImage.8xx
@@ -158,7 +162,7 @@ ifeq ($(CONFIG_PPC32),y)
image-$(CONFIG_PPC_PMAC) += zImage.coff zImage.miboot
endif
-initrd- := $(patsubst zImage%, zImage.initrd%, $(image-n) $(image-))
+initrd- := $(patsubst zImage%, zImage.initrd%, $(image-n) $(image-) $(kexec-))
initrd-y := $(patsubst zImage%, zImage.initrd%, \
$(patsubst treeImage%, treeImage.initrd%, $(image-y)))
initrd-y := $(filter-out $(image-y), $(initrd-y))
@@ -227,7 +231,7 @@ install: $(CONFIGURE) $(addprefix $(obj)
# anything not in $(targets)
clean-files += $(image-) $(initrd-) zImage zImage.initrd cuImage.* treeImage.* \
- otheros.bld
+ otheros.bld $(kexec-)
# clean up files cached by wrapper
clean-kernel := vmlinux.strip vmlinux.bin
Index: kernel/arch/powerpc/boot/ops.h
===================================================================
--- kernel.orig/arch/powerpc/boot/ops.h 2007-09-21 04:52:44.000000000 -0500
+++ kernel/arch/powerpc/boot/ops.h 2007-09-21 04:52:46.000000000 -0500
@@ -95,6 +95,7 @@ void move_slaves_here(void *where);
void send_slaves_to_kernel(void *vmlinux_addr);
void slaves_are_low(void);
void wait_slaves_moved(void);
+void kexec_platform_init(struct boot_param_header *dt_blob);
int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size);
int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr);
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 7/15] bootwrapper: Add kexec callable zImage wrapper
2007-09-21 23:04 ` [PATCH 7/15] bootwrapper: Add kexec callable zImage wrapper Milton Miller
@ 2007-09-24 3:23 ` David Gibson
0 siblings, 0 replies; 55+ messages in thread
From: David Gibson @ 2007-09-24 3:23 UTC (permalink / raw)
To: Milton Miller; +Cc: linuxppc-dev, Paul Mackerras, Rob Landley
On Fri, Sep 21, 2007 at 06:04:58PM -0500, Milton Miller wrote:
>
> This code creates a 32 bit zImage wrapper for a 32 or 64 bit PowerPC
> Linux kernel. This allows you to kexec a zImage with its compressed
> vmlinux instead of the uncompressed vmlinux elf. The code is also
> packaged as a 64 bit elf for use by kexec-tools on 64 bit kernels.
>
> Limitations:
> Note: the device-tree generated by kexec-tools is currently version 2,
> not the version 16 supported by the boot code base.
>
> Signed-off-by: Milton Miller <miltonm@bga.com>
> ---
> find_rmo_end moved to memranges as find_rma_end.
> early_scan_flat_tree replaced with calls to its pieces in
> kexec_platform_init
> rediff wrapper, Makefile, ops.h
>
> Index: kernel/arch/powerpc/boot/kexec.c
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ kernel/arch/powerpc/boot/kexec.c 2007-09-21 04:52:46.000000000 -0500
> @@ -0,0 +1,122 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> + *
> + * Copyright IBM Corporation 2007
> + *
> + * Authors: Milton Miller <miltonm@bga.com>
> + */
> +
> +#include "ops.h"
> +#include "stdio.h"
> +#include "flatdevtree.h"
> +#include "page.h"
> +#include "types.h"
> +
> +extern char _start[];
> +extern char _end[];
Don't need these externs any more, they're in the headers.
> +
> +BSS_STACK(16*1024);
> +
> +static void find_console_from_tree(void)
> +{
> + int rc = -1;
> +
> + if (rc) {
> + /* no console, oh well */
> + }
Um... pointless function...?
> +}
> +
> +/**
> + * setup_initial_heap - setup a small heap in the bss
> + * Using a preallocated heap, setup for scanning the device tree.
> + * Intended for the initial read while the tree will remain read-only so
> + * a minimal malloc and search limit can be used. This way we don't have
> + * lots of data or bss to clear.
> + */
> +static void setup_initial_heap(void)
> +{
> + static char initial_heap[8*1024];
> + void *heap_end;
> +
> + heap_end = simple_alloc_init(initial_heap,
> + sizeof(initial_heap) * 7 / 8,
> + sizeof(long), 64);
> +
> + if (heap_end - sizeof(initial_heap) > (void *)&initial_heap[0])
> + fatal("Initial heap too big\n\r");
> +}
> +
> +static void init_flat_tree(struct boot_param_header *dt_blob)
> +{
> + int rc;
> +
> + rc = ft_init(dt_blob, dt_blob->totalsize, /* max_finddevice */ 1024);
> + if (rc)
> + fatal("Unable to initialize device_tree library!\n\r");
> +}
> +
> +static void *saved_vmlinux_addr;
> +
> +static void *kexec_vmlinux_alloc(unsigned long size)
> +{
> + void *addr;
> +
> + addr = ranges_vmlinux_alloc(size);
> +
> + saved_vmlinux_addr = addr;
> + return addr;
> +}
> +
> +static void kexec_fixups(void)
> +{
> + wait_slaves_moved();
> +}
> +
> +static unsigned long (*finalize_chain)(void);
> +
> +static unsigned long kexec_finalize(void)
> +{
> + send_slaves_to_kernel(saved_vmlinux_addr);
Ow, yuck, no. The finalize callback is for finalizing the device
tree, don't abuse it for SMP entry. It's a new thing that needs to be
done, so create a new callback for it.
> +
> + return finalize_chain();
> +}
> +
> +void kexec_platform_init(struct boot_param_header *dt_blob)
> +{
> + slaves_are_low();
> + move_slaves_up();
> +
> + setup_initial_heap();
> + init_flat_tree(dt_blob);
> + /*
> + * drivers can malloc and read the tree, but not realloc later
> + * or modify the tree now.
> + */
> + if (!console_ops.write)
> + find_console_from_tree();
> +
> + find_rma_end();
> + dt_find_initrd();
> + add_known_ranges(dt_blob);
> + ranges_init_malloc();
> +
> + /* now that we have a malloc region, start over from the flat tree */
> + init_flat_tree(dt_blob);
> +
> + platform_ops.vmlinux_alloc = kexec_vmlinux_alloc;
> + platform_ops.fixups = kexec_fixups;
> + finalize_chain = dt_ops.finalize;
> + dt_ops.finalize = kexec_finalize;
> +}
> Index: kernel/arch/powerpc/boot/crt0_kexec.S
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ kernel/arch/powerpc/boot/crt0_kexec.S 2007-09-21 04:52:46.000000000 -0500
> @@ -0,0 +1,45 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> + *
> + * Copyright 2007 IBM Corporation.
> + *
> + * Authors: Milton Miller <miltonm@bga.com>
> + *
> + */
> + /*
> + * The kernel calls out to the first image with
> + * r3 = boot cpu, r4 = entrypoint, r5 = 0
> + *
> + * kexec-tools purgatory calls this as it would a linux kernel:
> + * r3 = boot block, r4 = entrypoint, r5 = 0
> + *
> + * The boot block boot_cpu field has been filled in.
> + *
> + * kexec-tools and its purgatory are suppposed to copy SMP_SLAVE_SIZE
> + * bytes from the from entry point, but aparently instead it copies
> + * from the image start.
> + */
> + .globl _zimage_start
> +_zimage_start:
> +
> +#include "marshal_low.S"
> +
> + .globl _zimage_start_plat
> +_zimage_start_plat:
> + b _zimage_start_lib
> +
> + .globl platform_init
> +platform_init:
> + b kexec_platform_init
> Index: kernel/arch/powerpc/boot/wrapper
> ===================================================================
> --- kernel.orig/arch/powerpc/boot/wrapper 2007-09-21 04:51:31.000000000 -0500
> +++ kernel/arch/powerpc/boot/wrapper 2007-09-21 04:52:46.000000000 -0500
> @@ -133,6 +133,12 @@ coff)
> platformo=$object/of.o
> lds=$object/zImage.coff.lds
> ;;
> +kexec)
> + platformo=$object/crt0_kexec.o
> + ;;
> +kexec64)
> + platformo="-e _zimage_start_64 $object/crt0_kexec.o"
Arg. Again, just because it happens to fit is not a good reason to
abuse platformo - which, obviously enough, s meant to contain the .o
file for the platform - to also contain flags.
> + ;;
> miboot|uboot)
> # miboot and U-boot want just the bare bits, not an ELF binary
> ext=bin
> @@ -190,6 +196,9 @@ uboot)
> fi
> exit 0
> ;;
> +kexec64)
> + ${CROSS}objcopy -O elf64-powerpc $ofile
> + ;;
> esac
>
> addsec() {
> Index: kernel/arch/powerpc/boot/Makefile
> ===================================================================
> --- kernel.orig/arch/powerpc/boot/Makefile 2007-09-21 04:52:44.000000000 -0500
> +++ kernel/arch/powerpc/boot/Makefile 2007-09-21 04:52:46.000000000 -0500
> @@ -42,12 +42,12 @@ $(addprefix $(obj)/,$(zlib) gunzip_util.
> $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
>
> src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
> - marshal.c memranges.c \
> + marshal.c memranges.c kexec.c \
> ns16550.c serial.c simple_alloc.c div64.S util.S \
> gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
> 4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
> cpm-serial.c stdlib.c
> -src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \
> +src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c crt0_kexec.S \
> cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
> ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
> cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c cuboot-bamboo.c
> @@ -128,6 +128,9 @@ quiet_cmd_wrap = WRAP $@
> cmd_wrap =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \
> $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) vmlinux
>
> +kexec-$(CONFIG_PPC32) += zImage.kexec
> +kexec-$(CONFIG_PPC64) += zImage.kexec64
> +
> image-$(CONFIG_PPC_PSERIES) += zImage.pseries
> image-$(CONFIG_PPC_MAPLE) += zImage.pseries
> image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries
> @@ -140,6 +143,7 @@ image-$(CONFIG_PPC_HOLLY) += zImage.hol
> image-$(CONFIG_PPC_PRPMC2800) += zImage.prpmc2800
> image-$(CONFIG_PPC_ISERIES) += zImage.iseries
> image-$(CONFIG_DEFAULT_UIMAGE) += uImage
> +image-$(CONFIG_KEXEC) += $(kexec-y)
>
> ifneq ($(CONFIG_DEVICE_TREE),"")
> image-$(CONFIG_PPC_8xx) += cuImage.8xx
> @@ -158,7 +162,7 @@ ifeq ($(CONFIG_PPC32),y)
> image-$(CONFIG_PPC_PMAC) += zImage.coff zImage.miboot
> endif
>
> -initrd- := $(patsubst zImage%, zImage.initrd%, $(image-n) $(image-))
> +initrd- := $(patsubst zImage%, zImage.initrd%, $(image-n) $(image-) $(kexec-))
> initrd-y := $(patsubst zImage%, zImage.initrd%, \
> $(patsubst treeImage%, treeImage.initrd%, $(image-y)))
> initrd-y := $(filter-out $(image-y), $(initrd-y))
> @@ -227,7 +231,7 @@ install: $(CONFIGURE) $(addprefix $(obj)
>
> # anything not in $(targets)
> clean-files += $(image-) $(initrd-) zImage zImage.initrd cuImage.* treeImage.* \
> - otheros.bld
> + otheros.bld $(kexec-)
>
> # clean up files cached by wrapper
> clean-kernel := vmlinux.strip vmlinux.bin
> Index: kernel/arch/powerpc/boot/ops.h
> ===================================================================
> --- kernel.orig/arch/powerpc/boot/ops.h 2007-09-21 04:52:44.000000000 -0500
> +++ kernel/arch/powerpc/boot/ops.h 2007-09-21 04:52:46.000000000 -0500
> @@ -95,6 +95,7 @@ void move_slaves_here(void *where);
> void send_slaves_to_kernel(void *vmlinux_addr);
> void slaves_are_low(void);
> void wait_slaves_moved(void);
> +void kexec_platform_init(struct boot_param_header *dt_blob);
This platform specific function should not poluute ops.h.
>
> int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size);
> int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr);
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@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
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 8/15] bootwrapper: convert flatdevtree to version 16
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
` (6 preceding siblings ...)
2007-09-21 23:04 ` [PATCH 7/15] bootwrapper: Add kexec callable zImage wrapper Milton Miller
@ 2007-09-21 23:05 ` Milton Miller
2007-09-24 3:36 ` David Gibson
2007-09-21 23:05 ` [PATCH 9/15] bootwrapper: rtas support Milton Miller
` (8 subsequent siblings)
16 siblings, 1 reply; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:05 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
kexec-tools still produces a version 2 device tree, while the
libraries in the wrapper only support version 16 and later.
Add a routine to convert a v2 flat device tree to a v16 one inplace
by inserting OF_DT_NOP and chomping full path. Make space for new
headers by moving and then chomping the OF_DT_NOPs.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
vs 12175
Rediffed Makefile, ops, kexec.c
Index: kernel/arch/powerpc/boot/flatdevtree_conv.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/boot/flatdevtree_conv.c 2007-09-20 17:49:04.000000000 -0500
@@ -0,0 +1,280 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright IBM Corporation 2007
+ *
+ * Authors: Milton Miller <miltonm@bga.com>
+ */
+#include "flatdevtree.h"
+#include "stdio.h"
+#include "ops.h"
+
+#define MIN_VERSION 2
+#define OUT_VERSION 16
+#define OUT_COMPAT 16
+
+#ifdef NO_CHECK
+static int check_v123_tree(u32 *start, u32 *limit)
+{
+ return 0;
+}
+#else
+/**
+ * check_v123_tree - check integrety of a version 1, 2, or 3 tree
+ * @start: the start of the device tree struct
+ * @limit: the end of the region for the struct
+ * structural checks on device_tree
+ */
+static int check_v123_tree(u32 *start, u32 *limit)
+{
+ u32 len;
+ int depth = 0;
+ u32 *dtp = start;
+
+ while (dtp < limit)
+ switch (*dtp) {
+ case OF_DT_END:
+ if (depth)
+ return -1;
+ return ++dtp - start;
+ case OF_DT_NOP:
+ dtp++;
+ break;
+ case OF_DT_END_NODE:
+ dtp++;
+ depth--;
+ break;
+ case OF_DT_BEGIN_NODE:
+ len = strlen((char *)(++dtp));
+ /* check path is suffix to previous? */
+ dtp += 1 + (len / 4);
+ depth++;
+ break;
+ case OF_DT_PROP:
+ len = dtp[1];
+ dtp += 3;
+ if ((len >= 8) && ((long)dtp & 4))
+ dtp++;
+ dtp += (len + 3) / 4;
+ break;
+ default:
+ return -1;
+ }
+ return -1; /* no OF_DT_END */
+}
+#endif
+
+/**
+ * nop_to_v16 - add %OF_DT_NOP to hide alignment differences
+ * @dtp: pointer to the beginning of the struct area to modify
+ * insert %OF_DT_NOP into the dt_struct @dtp to make it v16 from v1, 2, or 3.
+ */
+static int nop_to_v16(u32 *dtp)
+{
+ int nops = 0;
+ char *p, *s;
+ int len;
+ u32 *next;
+
+ while (*dtp != OF_DT_END)
+ switch (*dtp) {
+ case OF_DT_BEGIN_NODE:
+ /* v2 & v3 names are full path, v16+ is relative */
+ p = (char *)(++dtp);
+ len = strlen(p);
+ next = dtp + 1 + len / 4;
+
+ for (s = p + len; *s != '/'; s--)
+ if (s == p)
+ fatal("name %s has no '/'", p);
+
+ len -= s++ - p; /* not the slash but the nul */
+ memmove(p, s, len);
+ while (len % 4)
+ p[len++] = '\0';
+ dtp += len / 4;
+ while (dtp != next) {
+ *dtp++ = OF_DT_NOP;
+ nops++;
+ }
+ break;
+ case OF_DT_PROP:
+ /* convert from align_8 to align_4 via prefixing nop */
+ len = dtp[1];
+ if ((len >= 8) && !((long)dtp & 4)) {
+ memmove(dtp+1, dtp, 12);
+ *dtp++ = OF_DT_NOP;
+ nops++;
+ }
+ dtp += 3 + (len + 3)/4;
+ break;
+ default:
+ fatal("%s: unrecognised tag %d at %p\n", __FUNCTION__,
+ *dtp, dtp);
+ case OF_DT_NOP:
+ nops ++;
+ /* fall through */
+ case OF_DT_END_NODE:
+ dtp ++;
+ break;
+ }
+ return nops;
+}
+
+#if MIN_VERSION < 3 || OUT_VERSION > 16
+/**
+ * move_nops_fwd - move nops in a v16 dt_struct to the beginning
+ * @start - device tree starting address
+ * @count - number of %OF_DT_NOP cells to move
+ */
+static void move_nops_fwd(u32 *start, int count)
+{
+ u32 *dtp = start;
+ int len;
+ while (count)
+ switch (*dtp) {
+ case OF_DT_NOP:
+ memmove(start+1,start,(dtp-start) * 4);
+ *start++ = OF_DT_NOP;
+ dtp++;
+ count--;
+ break;
+ case OF_DT_END_NODE:
+ dtp++;
+ break;
+ case OF_DT_BEGIN_NODE:
+ len = strlen((char *)(++dtp));
+ dtp += 1 + len / 4;
+ break;
+ case OF_DT_PROP:
+ len = dtp[1];
+ dtp += 3 + (len + 3) / 4;
+ break;
+ case OF_DT_END:
+ fatal("Not enough nops -- need %d more\n", count);
+ return;
+ default:
+ fatal("%s: unknown tag %d at %p", __FUNCTION__, *dtp, dtp)
+ }
+}
+#endif
+
+/**
+ * conv_flattree_inplace upgrade the version of a boot_param_header
+ * @tree: pointer to the device tree header to convert
+ *
+ * Converts a v1, 2, 3 device tree (of at least MIN_VERSION)
+ * in place to OUT_VERSION (16) format, usable by flatdevtree.c
+ */
+void conv_flattree_inplace(struct boot_param_header *tree)
+{
+ u32 *dtp;
+ u32 need = 0, nops;
+ int slen;
+
+ if (tree->magic != OF_DT_HEADER)
+ fatal("%s: no magic", __FUNCTION__);
+
+ if (tree->last_comp_version > 3)
+ return; /* don't know what to do */
+
+ if (tree->version < MIN_VERSION) {
+ printf("%s: Warning: can't handle version %d tree\n",
+ __FUNCTION__, tree->version);
+ return;
+ }
+
+ if (tree->version < 2)
+ need++; /* boot_cpu_id */
+
+ if (tree->version < 3)
+ need++; /* dt_string_size */
+
+ if (OUT_VERSION > 16)
+ need++; /* dt_struct_size */
+
+ dtp = (void *)tree + tree->off_dt_struct;
+
+ slen = check_v123_tree(dtp, (void *)tree + tree->totalsize);
+ if (slen < 0)
+ fatal("device tree check failed\n");
+
+ nops = nop_to_v16(dtp);
+
+ if (need & 1) /* keep 8 byte alignment of mem reserve */
+ need++;
+
+ if (need > nops)
+ fatal("Didn't find enough space to add new header fields\n\r"
+ "(needed %d found %d tree %p)", need, nops, tree);
+
+ /* ok now compress the dtb struct */
+ move_nops_fwd(dtp, need);
+ dtp += need;
+
+ /*
+ * move mem_rsvmap and dt_strings if they are before dt_struct
+ * onto our nops . Adjust start addresses for the 3 sections.
+ */
+ if ((tree->off_mem_rsvmap < tree->off_dt_struct) ||
+ (tree->off_dt_strings < tree->off_dt_struct)) {
+ int start, end;
+ void *ptr;
+
+ if (tree->off_mem_rsvmap < tree->off_dt_strings)
+ start = tree->off_mem_rsvmap;
+ else
+ start = tree->off_dt_strings;
+
+ end = tree->off_dt_struct;
+ ptr = (void *)tree + start;
+
+ memmove(ptr + 4 * need, ptr, end - start);
+
+ if (tree->off_mem_rsvmap < tree->off_dt_struct)
+ tree->off_mem_rsvmap += 4 * need;
+ if (tree->off_dt_strings < tree->off_dt_struct)
+ tree->off_dt_strings += 4 * need;
+ }
+ tree->off_dt_struct += 4 * need;
+
+ /* ok now we have space to extend the header. */
+ if (tree->version < 2 && MIN_VERSION < 2) {
+ tree->boot_cpuid_phys = 0; /* default, caller can fix */
+ }
+
+ /* calculate size of dt_strings_size */
+ if (tree->version < 3 && MIN_VERSION < 3) {
+ int end = tree->totalsize;
+
+ if (tree->off_dt_strings < tree->off_mem_rsvmap)
+ end = tree->off_mem_rsvmap;
+
+ if ((tree->off_dt_strings < tree->off_dt_struct) &&
+ (end > tree->off_dt_struct))
+ end = tree->off_dt_struct;
+
+ tree->dt_strings_size = end - tree->off_dt_strings;
+ }
+
+#if OUT_VERSION > 16
+ tree->dt_struct_size = 4 * slen;
+#endif
+
+ tree->version = OUT_VERSION;
+ tree->last_comp_version = OUT_COMPAT;
+
+ return;
+}
Index: kernel/arch/powerpc/boot/Makefile
===================================================================
--- kernel.orig/arch/powerpc/boot/Makefile 2007-09-20 17:42:24.000000000 -0500
+++ kernel/arch/powerpc/boot/Makefile 2007-09-20 17:49:04.000000000 -0500
@@ -42,7 +42,7 @@ $(addprefix $(obj)/,$(zlib) gunzip_util.
$(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
- marshal.c memranges.c kexec.c \
+ flatdevtree_conv.c marshal.c memranges.c kexec.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
Index: kernel/arch/powerpc/boot/ops.h
===================================================================
--- kernel.orig/arch/powerpc/boot/ops.h 2007-09-20 17:42:24.000000000 -0500
+++ kernel/arch/powerpc/boot/ops.h 2007-09-20 17:49:04.000000000 -0500
@@ -81,7 +81,10 @@ struct loader_info {
};
extern struct loader_info loader_info;
+struct boot_param_header;
+
void start(void);
+void conv_flattree_inplace(struct boot_param_header *tree);
int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device);
int serial_console_init(void);
int ns16550_console_init(void *devp, struct serial_console_data *scdp);
Index: kernel/arch/powerpc/boot/kexec.c
===================================================================
--- kernel.orig/arch/powerpc/boot/kexec.c 2007-09-20 17:42:24.000000000 -0500
+++ kernel/arch/powerpc/boot/kexec.c 2007-09-20 17:49:04.000000000 -0500
@@ -99,6 +99,7 @@ void kexec_platform_init(struct boot_par
move_slaves_up();
setup_initial_heap();
+ conv_flattree_inplace(dt_blob);
init_flat_tree(dt_blob);
/*
* drivers can malloc and read the tree, but not realloc later
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 8/15] bootwrapper: convert flatdevtree to version 16
2007-09-21 23:05 ` [PATCH 8/15] bootwrapper: convert flatdevtree to version 16 Milton Miller
@ 2007-09-24 3:36 ` David Gibson
2007-09-24 6:54 ` Milton Miller
0 siblings, 1 reply; 55+ messages in thread
From: David Gibson @ 2007-09-24 3:36 UTC (permalink / raw)
To: Milton Miller; +Cc: linuxppc-dev, Paul Mackerras, Rob Landley
On Fri, Sep 21, 2007 at 06:05:06PM -0500, Milton Miller wrote:
> kexec-tools still produces a version 2 device tree, while the
> libraries in the wrapper only support version 16 and later.
>
> Add a routine to convert a v2 flat device tree to a v16 one inplace
> by inserting OF_DT_NOP and chomping full path. Make space for new
> headers by moving and then chomping the OF_DT_NOPs.
>
> Signed-off-by: Milton Miller <miltonm@bga.com>
> ---
> vs 12175
> Rediffed Makefile, ops, kexec.c
>
> Index: kernel/arch/powerpc/boot/flatdevtree_conv.c
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ kernel/arch/powerpc/boot/flatdevtree_conv.c 2007-09-20 17:49:04.000000000 -0500
> @@ -0,0 +1,280 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> + *
> + * Copyright IBM Corporation 2007
> + *
> + * Authors: Milton Miller <miltonm@bga.com>
> + */
> +#include "flatdevtree.h"
> +#include "stdio.h"
> +#include "ops.h"
> +
> +#define MIN_VERSION 2
> +#define OUT_VERSION 16
Should output version 17. In any case, don't try to be so general -
just convert v123 (all basically the same) to latest (i.e. v17)
without all the #if nonsense.
> +#define OUT_COMPAT 16
> +
> +#ifdef NO_CHECK
> +static int check_v123_tree(u32 *start, u32 *limit)
> +{
> + return 0;
> +}
> +#else
> +/**
> + * check_v123_tree - check integrety of a version 1, 2, or 3 tree
> + * @start: the start of the device tree struct
> + * @limit: the end of the region for the struct
> + * structural checks on device_tree
> + */
> +static int check_v123_tree(u32 *start, u32 *limit)
What is the point of this check? If the device tree is corrupt, we're
stuffed anyway, so why bother?
> +{
> + u32 len;
> + int depth = 0;
> + u32 *dtp = start;
> +
> + while (dtp < limit)
> + switch (*dtp) {
> + case OF_DT_END:
> + if (depth)
> + return -1;
> + return ++dtp - start;
> + case OF_DT_NOP:
> + dtp++;
> + break;
> + case OF_DT_END_NODE:
> + dtp++;
> + depth--;
> + break;
> + case OF_DT_BEGIN_NODE:
> + len = strlen((char *)(++dtp));
> + /* check path is suffix to previous? */
> + dtp += 1 + (len / 4);
> + depth++;
> + break;
> + case OF_DT_PROP:
> + len = dtp[1];
> + dtp += 3;
> + if ((len >= 8) && ((long)dtp & 4))
> + dtp++;
> + dtp += (len + 3) / 4;
> + break;
> + default:
> + return -1;
> + }
> + return -1; /* no OF_DT_END */
> +}
> +#endif
> +
> +/**
> + * nop_to_v16 - add %OF_DT_NOP to hide alignment differences
> + * @dtp: pointer to the beginning of the struct area to modify
> + * insert %OF_DT_NOP into the dt_struct @dtp to make it v16 from v1, 2, or 3.
> + */
> +static int nop_to_v16(u32 *dtp)
> +{
> + int nops = 0;
> + char *p, *s;
> + int len;
> + u32 *next;
> +
> + while (*dtp != OF_DT_END)
> + switch (*dtp) {
> + case OF_DT_BEGIN_NODE:
> + /* v2 & v3 names are full path, v16+ is relative */
> + p = (char *)(++dtp);
> + len = strlen(p);
> + next = dtp + 1 + len / 4;
> +
> + for (s = p + len; *s != '/'; s--)
> + if (s == p)
> + fatal("name %s has no '/'", p);
> +
> + len -= s++ - p; /* not the slash but the nul */
> + memmove(p, s, len);
> + while (len % 4)
> + p[len++] = '\0';
> + dtp += len / 4;
> + while (dtp != next) {
> + *dtp++ = OF_DT_NOP;
> + nops++;
> + }
> + break;
> + case OF_DT_PROP:
> + /* convert from align_8 to align_4 via prefixing nop */
> + len = dtp[1];
> + if ((len >= 8) && !((long)dtp & 4)) {
> + memmove(dtp+1, dtp, 12);
> + *dtp++ = OF_DT_NOP;
> + nops++;
> + }
> + dtp += 3 + (len + 3)/4;
> + break;
> + default:
> + fatal("%s: unrecognised tag %d at %p\n", __FUNCTION__,
> + *dtp, dtp);
> + case OF_DT_NOP:
> + nops ++;
> + /* fall through */
> + case OF_DT_END_NODE:
> + dtp ++;
> + break;
> + }
> + return nops;
> +}
> +
> +#if MIN_VERSION < 3 || OUT_VERSION > 16
> +/**
> + * move_nops_fwd - move nops in a v16 dt_struct to the beginning
> + * @start - device tree starting address
> + * @count - number of %OF_DT_NOP cells to move
> + */
> +static void move_nops_fwd(u32 *start, int count)
What on earth is the point of this. The NOPs are perfectly valid
scattered within the tree, why go to all this trouble to shuffle them
about.
> +{
> + u32 *dtp = start;
> + int len;
> + while (count)
> + switch (*dtp) {
> + case OF_DT_NOP:
> + memmove(start+1,start,(dtp-start) * 4);
> + *start++ = OF_DT_NOP;
> + dtp++;
> + count--;
> + break;
> + case OF_DT_END_NODE:
> + dtp++;
> + break;
> + case OF_DT_BEGIN_NODE:
> + len = strlen((char *)(++dtp));
> + dtp += 1 + len / 4;
> + break;
> + case OF_DT_PROP:
> + len = dtp[1];
> + dtp += 3 + (len + 3) / 4;
> + break;
> + case OF_DT_END:
> + fatal("Not enough nops -- need %d more\n", count);
> + return;
> + default:
> + fatal("%s: unknown tag %d at %p", __FUNCTION__, *dtp, dtp)
> + }
> +}
> +#endif
> +
> +/**
> + * conv_flattree_inplace upgrade the version of a boot_param_header
> + * @tree: pointer to the device tree header to convert
> + *
> + * Converts a v1, 2, 3 device tree (of at least MIN_VERSION)
> + * in place to OUT_VERSION (16) format, usable by flatdevtree.c
> + */
> +void conv_flattree_inplace(struct boot_param_header *tree)
> +{
> + u32 *dtp;
> + u32 need = 0, nops;
> + int slen;
> +
> + if (tree->magic != OF_DT_HEADER)
> + fatal("%s: no magic", __FUNCTION__);
More pointless tests...
> + if (tree->last_comp_version > 3)
> + return; /* don't know what to do */
Rather, don't need to do anything.
> +
> + if (tree->version < MIN_VERSION) {
> + printf("%s: Warning: can't handle version %d tree\n",
> + __FUNCTION__, tree->version);
> + return;
> + }
> +
> + if (tree->version < 2)
> + need++; /* boot_cpu_id */
> +
> + if (tree->version < 3)
> + need++; /* dt_string_size */
> +
> + if (OUT_VERSION > 16)
> + need++; /* dt_struct_size */
> +
> + dtp = (void *)tree + tree->off_dt_struct;
> +
> + slen = check_v123_tree(dtp, (void *)tree + tree->totalsize);
> + if (slen < 0)
> + fatal("device tree check failed\n");
> +
> + nops = nop_to_v16(dtp);
> +
> + if (need & 1) /* keep 8 byte alignment of mem reserve */
> + need++;
> +
> + if (need > nops)
> + fatal("Didn't find enough space to add new header fields\n\r"
> + "(needed %d found %d tree %p)", need, nops, tree);
> +
> + /* ok now compress the dtb struct */
> + move_nops_fwd(dtp, need);
> + dtp += need;
> +
> + /*
> + * move mem_rsvmap and dt_strings if they are before dt_struct
> + * onto our nops . Adjust start addresses for the 3 sections.
> + */
Hrm. Do we really need to worry about this case. You may be
producing v2 trees in kexec-tools, but do they actually have the
blocks out of order? dtc certainly never produced them that way.
> + if ((tree->off_mem_rsvmap < tree->off_dt_struct) ||
> + (tree->off_dt_strings < tree->off_dt_struct)) {
> + int start, end;
> + void *ptr;
> +
> + if (tree->off_mem_rsvmap < tree->off_dt_strings)
> + start = tree->off_mem_rsvmap;
> + else
> + start = tree->off_dt_strings;
> +
> + end = tree->off_dt_struct;
> + ptr = (void *)tree + start;
> +
> + memmove(ptr + 4 * need, ptr, end - start);
> +
> + if (tree->off_mem_rsvmap < tree->off_dt_struct)
> + tree->off_mem_rsvmap += 4 * need;
> + if (tree->off_dt_strings < tree->off_dt_struct)
> + tree->off_dt_strings += 4 * need;
> + }
> + tree->off_dt_struct += 4 * need;
> +
> + /* ok now we have space to extend the header. */
> + if (tree->version < 2 && MIN_VERSION < 2) {
> + tree->boot_cpuid_phys = 0; /* default, caller can fix */
> + }
> +
> + /* calculate size of dt_strings_size */
> + if (tree->version < 3 && MIN_VERSION < 3) {
> + int end = tree->totalsize;
> +
> + if (tree->off_dt_strings < tree->off_mem_rsvmap)
> + end = tree->off_mem_rsvmap;
> +
> + if ((tree->off_dt_strings < tree->off_dt_struct) &&
> + (end > tree->off_dt_struct))
> + end = tree->off_dt_struct;
> +
> + tree->dt_strings_size = end - tree->off_dt_strings;
> + }
> +
> +#if OUT_VERSION > 16
> + tree->dt_struct_size = 4 * slen;
> +#endif
> +
> + tree->version = OUT_VERSION;
> + tree->last_comp_version = OUT_COMPAT;
> +
> + return;
> +}
> Index: kernel/arch/powerpc/boot/Makefile
> ===================================================================
> --- kernel.orig/arch/powerpc/boot/Makefile 2007-09-20 17:42:24.000000000 -0500
> +++ kernel/arch/powerpc/boot/Makefile 2007-09-20 17:49:04.000000000 -0500
> @@ -42,7 +42,7 @@ $(addprefix $(obj)/,$(zlib) gunzip_util.
> $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
>
> src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
> - marshal.c memranges.c kexec.c \
> + flatdevtree_conv.c marshal.c memranges.c kexec.c \
> ns16550.c serial.c simple_alloc.c div64.S util.S \
> gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
> 4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
> Index: kernel/arch/powerpc/boot/ops.h
> ===================================================================
> --- kernel.orig/arch/powerpc/boot/ops.h 2007-09-20 17:42:24.000000000 -0500
> +++ kernel/arch/powerpc/boot/ops.h 2007-09-20 17:49:04.000000000 -0500
> @@ -81,7 +81,10 @@ struct loader_info {
> };
> extern struct loader_info loader_info;
>
> +struct boot_param_header;
> +
> void start(void);
> +void conv_flattree_inplace(struct boot_param_header *tree);
> int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device);
> int serial_console_init(void);
> int ns16550_console_init(void *devp, struct serial_console_data *scdp);
> Index: kernel/arch/powerpc/boot/kexec.c
> ===================================================================
> --- kernel.orig/arch/powerpc/boot/kexec.c 2007-09-20 17:42:24.000000000 -0500
> +++ kernel/arch/powerpc/boot/kexec.c 2007-09-20 17:49:04.000000000 -0500
> @@ -99,6 +99,7 @@ void kexec_platform_init(struct boot_par
> move_slaves_up();
>
> setup_initial_heap();
> + conv_flattree_inplace(dt_blob);
> init_flat_tree(dt_blob);
> /*
> * drivers can malloc and read the tree, but not realloc later
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@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
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 8/15] bootwrapper: convert flatdevtree to version 16
2007-09-24 3:36 ` David Gibson
@ 2007-09-24 6:54 ` Milton Miller
2007-09-25 3:46 ` David Gibson
0 siblings, 1 reply; 55+ messages in thread
From: Milton Miller @ 2007-09-24 6:54 UTC (permalink / raw)
To: David Gibson; +Cc: ppcdev, Paul Mackerras
On Sep 23, 2007, at 10:36 PM, David Gibson wrote:
> On Fri, Sep 21, 2007 at 06:05:06PM -0500, Milton Miller wrote:
>> kexec-tools still produces a version 2 device tree, while the
>> libraries in the wrapper only support version 16 and later.
>>
>> Add a routine to convert a v2 flat device tree to a v16 one inplace
>> by inserting OF_DT_NOP and chomping full path. Make space for new
>> headers by moving and then chomping the OF_DT_NOPs.
>>
>> Signed-off-by: Milton Miller <miltonm@bga.com>
>> ---
>> vs 12175
>> Rediffed Makefile, ops, kexec.c
>>
>> Index: kernel/arch/powerpc/boot/flatdevtree_conv.c
>> ===================================================================
>> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
>> +++ kernel/arch/powerpc/boot/flatdevtree_conv.c 2007-09-20
>> 17:49:04.000000000 -0500
>> @@ -0,0 +1,280 @@
>> +/*
>> + * This program is free software; you can redistribute it and/or
>> modify
>> + * it under the terms of the GNU General Public License as published
>> by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
>> 02110-1301, USA.
>> + *
>> + * Copyright IBM Corporation 2007
>> + *
>> + * Authors: Milton Miller <miltonm@bga.com>
>> + */
>> +#include "flatdevtree.h"
>> +#include "stdio.h"
>> +#include "ops.h"
>> +
>> +#define MIN_VERSION 2
>> +#define OUT_VERSION 16
>
> Should output version 17. In any case, don't try to be so general -
> just convert v123 (all basically the same) to latest (i.e. v17)
> without all the #if nonsense.
Outputing v17 instead of 16 requires more words to be added to the
header, and the library does fine with v16. Actually the v1 trees has
some other differences such as initrd addresses were kernel linear not
real, cpus were assigned logical numbers ... so while the structure
didn't change except for the header field, the contents did. Actually,
when converting v3 to v16 some of the code issn't needed, the ifs allow
the code size to be reduced.
>
>> +#define OUT_COMPAT 16
>> +
>> +#ifdef NO_CHECK
>> +static int check_v123_tree(u32 *start, u32 *limit)
>> +{
>> + return 0;
>> +}
>> +#else
>> +/**
>> + * check_v123_tree - check integrety of a version 1, 2, or 3 tree
>> + * @start: the start of the device tree struct
>> + * @limit: the end of the region for the struct
>> + * structural checks on device_tree
>> + */
>> +static int check_v123_tree(u32 *start, u32 *limit)
>
> What is the point of this check? If the device tree is corrupt, we're
> stuffed anyway, so why bother?
Hence the ifdef NO_CHECK. When developing, sometimes its nice to know
if its your input or your program. These functions are destructive to
an improperlly formed tree, and in non-obvious ways. When debugging,
it's not hard to hardcode console write or read the printf string
buffer with a hardware debugger to see error messages. That said, it
could be removed.
>
>> +{
>> + u32 len;
>> + int depth = 0;
>> + u32 *dtp = start;
>> +
>> + while (dtp < limit)
>> + switch (*dtp) {
>> + case OF_DT_END:
>> + if (depth)
>> + return -1;
>> + return ++dtp - start;
>> + case OF_DT_NOP:
>> + dtp++;
>> + break;
>> + case OF_DT_END_NODE:
>> + dtp++;
>> + depth--;
>> + break;
>> + case OF_DT_BEGIN_NODE:
>> + len = strlen((char *)(++dtp));
>> + /* check path is suffix to previous? */
>> + dtp += 1 + (len / 4);
>> + depth++;
>> + break;
>> + case OF_DT_PROP:
>> + len = dtp[1];
>> + dtp += 3;
>> + if ((len >= 8) && ((long)dtp & 4))
>> + dtp++;
>> + dtp += (len + 3) / 4;
>> + break;
>> + default:
>> + return -1;
>> + }
>> + return -1; /* no OF_DT_END */
>> +}
>> +#endif
>> +
>> +/**
>> + * nop_to_v16 - add %OF_DT_NOP to hide alignment differences
>> + * @dtp: pointer to the beginning of the struct area to modify
>> + * insert %OF_DT_NOP into the dt_struct @dtp to make it v16 from v1,
>> 2, or 3.
>> + */
>> +static int nop_to_v16(u32 *dtp)
>> +{
>> + int nops = 0;
>> + char *p, *s;
>> + int len;
>> + u32 *next;
>> +
>> + while (*dtp != OF_DT_END)
>> + switch (*dtp) {
>> + case OF_DT_BEGIN_NODE:
>> + /* v2 & v3 names are full path, v16+ is relative */
>> + p = (char *)(++dtp);
>> + len = strlen(p);
>> + next = dtp + 1 + len / 4;
>> +
>> + for (s = p + len; *s != '/'; s--)
>> + if (s == p)
>> + fatal("name %s has no '/'", p);
>> +
>> + len -= s++ - p; /* not the slash but the nul */
>> + memmove(p, s, len);
>> + while (len % 4)
>> + p[len++] = '\0';
>> + dtp += len / 4;
>> + while (dtp != next) {
>> + *dtp++ = OF_DT_NOP;
>> + nops++;
>> + }
>> + break;
>> + case OF_DT_PROP:
>> + /* convert from align_8 to align_4 via prefixing nop */
>> + len = dtp[1];
>> + if ((len >= 8) && !((long)dtp & 4)) {
>> + memmove(dtp+1, dtp, 12);
>> + *dtp++ = OF_DT_NOP;
>> + nops++;
>> + }
>> + dtp += 3 + (len + 3)/4;
>> + break;
>> + default:
>> + fatal("%s: unrecognised tag %d at %p\n", __FUNCTION__,
>> + *dtp, dtp);
>> + case OF_DT_NOP:
>> + nops ++;
>> + /* fall through */
>> + case OF_DT_END_NODE:
>> + dtp ++;
>> + break;
>> + }
>> + return nops;
>> +}
>> +
>> +#if MIN_VERSION < 3 || OUT_VERSION > 16
>> +/**
>> + * move_nops_fwd - move nops in a v16 dt_struct to the beginning
>> + * @start - device tree starting address
>> + * @count - number of %OF_DT_NOP cells to move
>> + */
>> +static void move_nops_fwd(u32 *start, int count)
>
> What on earth is the point of this. The NOPs are perfectly valid
> scattered within the tree, why go to all this trouble to shuffle them
> about.
And if you notice, there is a "how many to move" argument. The point
of moving them to the front of the tree is the v17 device tree header
takes more space than the v3 one, and the v2 header is smaller than
both v17 and v16 header. Since I am converting the tree in place, the
space has to come from somewhere. Since we are pretty much guaranteed
to get several nops, this function moves them forward so they can be
overwritten. In practice we move 1-3 NOPS from the early properties >
8 bytes and early grandchild nodes (eg /cpus/PowerPC,xxx).
>
>> +{
>> + u32 *dtp = start;
>> + int len;
>> + while (count)
>> + switch (*dtp) {
>> + case OF_DT_NOP:
>> + memmove(start+1,start,(dtp-start) * 4);
>> + *start++ = OF_DT_NOP;
>> + dtp++;
>> + count--;
>> + break;
>> + case OF_DT_END_NODE:
>> + dtp++;
>> + break;
>> + case OF_DT_BEGIN_NODE:
>> + len = strlen((char *)(++dtp));
>> + dtp += 1 + len / 4;
>> + break;
>> + case OF_DT_PROP:
>> + len = dtp[1];
>> + dtp += 3 + (len + 3) / 4;
>> + break;
>> + case OF_DT_END:
>> + fatal("Not enough nops -- need %d more\n", count);
>> + return;
>> + default:
>> + fatal("%s: unknown tag %d at %p", __FUNCTION__, *dtp, dtp)
>> + }
>> +}
>> +#endif
>> +
>> +/**
>> + * conv_flattree_inplace upgrade the version of a boot_param_header
>> + * @tree: pointer to the device tree header to convert
>> + *
>> + * Converts a v1, 2, 3 device tree (of at least MIN_VERSION)
>> + * in place to OUT_VERSION (16) format, usable by flatdevtree.c
>> + */
>> +void conv_flattree_inplace(struct boot_param_header *tree)
>> +{
>> + u32 *dtp;
>> + u32 need = 0, nops;
>> + int slen;
>> +
>> + if (tree->magic != OF_DT_HEADER)
>> + fatal("%s: no magic", __FUNCTION__);
>
> More pointless tests...
It says you didn't pass a tree ... yea, its dumb, but I prefer an
explicit error to figuring out where a machine check came from.
>
>> + if (tree->last_comp_version > 3)
>> + return; /* don't know what to do */
>
> Rather, don't need to do anything.
If the tree is >= 16 then we don't presently need to do anything. If
there is a theoritical v4 tree we don't know what to do. And if output
version is 17 but input is 16 we don't know what to do either, because
there likely aren't nops in the tree to consume. I suppose we could
preceed it with a check for version == OUTPUT_VERSION, but then I'm
sure I'd get pointless differentation :-).
>
>> +
>> + if (tree->version < MIN_VERSION) {
>> + printf("%s: Warning: can't handle version %d tree\n",
>> + __FUNCTION__, tree->version);
>> + return;
>> + }
>> +
>> + if (tree->version < 2)
>> + need++; /* boot_cpu_id */
>> +
>> + if (tree->version < 3)
>> + need++; /* dt_string_size */
>> +
>> + if (OUT_VERSION > 16)
>> + need++; /* dt_struct_size */
>> +
>> + dtp = (void *)tree + tree->off_dt_struct;
>> +
>> + slen = check_v123_tree(dtp, (void *)tree + tree->totalsize);
>> + if (slen < 0)
>> + fatal("device tree check failed\n");
>> +
>> + nops = nop_to_v16(dtp);
>> +
>> + if (need & 1) /* keep 8 byte alignment of mem reserve */
>> + need++;
>> +
>> + if (need > nops)
>> + fatal("Didn't find enough space to add new header fields\n\r"
>> + "(needed %d found %d tree %p)", need, nops, tree);
>> +
>> + /* ok now compress the dtb struct */
>> + move_nops_fwd(dtp, need);
>> + dtp += need;
>> +
>> + /*
>> + * move mem_rsvmap and dt_strings if they are before dt_struct
>> + * onto our nops . Adjust start addresses for the 3 sections.
>> + */
>
> Hrm. Do we really need to worry about this case. You may be
> producing v2 trees in kexec-tools, but do they actually have the
> blocks out of order? dtc certainly never produced them that way.
Out of order? There has never been a spec as to the order of the
blocks, only the implicit assumption that they follow the device tree
header in a reasonably packed sequence. booting-without-of says it
must be in ram,; the offsets are unsigned 32 bit quantities.
As to the order, used, the first implemntation was the kernel which
writes memreserve, strings, then struct (both the openfirmware client
in prom_init and the iSeries procedural library in dt.c). The second
implentation written is a procedural based library (similar to iseries,
never published, but still used internally) that starts with a
pre-built header and string table, builds the dt_struct as the
functions are called, and when finished copies the memreserve table and
fills in the dt_size, total size, and memreserve offset.
fs2dt writes memreserve, struct, then strings. Aparently the same as
dtc. But yes, the strings can be before the struct, and the mem
reserve may or may not be when the strings are before the struct.
>
>> + if ((tree->off_mem_rsvmap < tree->off_dt_struct) ||
>> + (tree->off_dt_strings < tree->off_dt_struct)) {
>> + int start, end;
>> + void *ptr;
>> +
>> + if (tree->off_mem_rsvmap < tree->off_dt_strings)
>> + start = tree->off_mem_rsvmap;
>> + else
>> + start = tree->off_dt_strings;
>> +
>> + end = tree->off_dt_struct;
>> + ptr = (void *)tree + start;
>> +
>> + memmove(ptr + 4 * need, ptr, end - start);
>> +
>> + if (tree->off_mem_rsvmap < tree->off_dt_struct)
>> + tree->off_mem_rsvmap += 4 * need;
>> + if (tree->off_dt_strings < tree->off_dt_struct)
>> + tree->off_dt_strings += 4 * need;
>> + }
>> + tree->off_dt_struct += 4 * need;
>> +
>> + /* ok now we have space to extend the header. */
>> + if (tree->version < 2 && MIN_VERSION < 2) {
>> + tree->boot_cpuid_phys = 0; /* default, caller can fix */
>> + }
>> +
>> + /* calculate size of dt_strings_size */
>> + if (tree->version < 3 && MIN_VERSION < 3) {
>> + int end = tree->totalsize;
>> +
>> + if (tree->off_dt_strings < tree->off_mem_rsvmap)
>> + end = tree->off_mem_rsvmap;
>> +
>> + if ((tree->off_dt_strings < tree->off_dt_struct) &&
>> + (end > tree->off_dt_struct))
>> + end = tree->off_dt_struct;
>> +
>> + tree->dt_strings_size = end - tree->off_dt_strings;
>> + }
>> +
>> +#if OUT_VERSION > 16
>> + tree->dt_struct_size = 4 * slen;
>> +#endif
>> +
>> + tree->version = OUT_VERSION;
>> + tree->last_comp_version = OUT_COMPAT;
>> +
>> + return;
>> +}
>> Index: kernel/arch/powerpc/boot/Makefile
>> ===================================================================
>> --- kernel.orig/arch/powerpc/boot/Makefile 2007-09-20
>> 17:42:24.000000000 -0500
>> +++ kernel/arch/powerpc/boot/Makefile 2007-09-20 17:49:04.000000000
>> -0500
>> @@ -42,7 +42,7 @@ $(addprefix $(obj)/,$(zlib) gunzip_util.
>> $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix
>> $(obj)/,$(zlibheader))
>>
>> src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c
>> flatdevtree_misc.c \
>> - marshal.c memranges.c kexec.c \
>> + flatdevtree_conv.c marshal.c memranges.c kexec.c \
>> ns16550.c serial.c simple_alloc.c div64.S util.S \
>> gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
>> 4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
>> Index: kernel/arch/powerpc/boot/ops.h
>> ===================================================================
>> --- kernel.orig/arch/powerpc/boot/ops.h 2007-09-20 17:42:24.000000000
>> -0500
>> +++ kernel/arch/powerpc/boot/ops.h 2007-09-20 17:49:04.000000000 -0500
>> @@ -81,7 +81,10 @@ struct loader_info {
>> };
>> extern struct loader_info loader_info;
>>
>> +struct boot_param_header;
>> +
>> void start(void);
>> +void conv_flattree_inplace(struct boot_param_header *tree);
>> int ft_init(void *dt_blob, unsigned int max_size, unsigned int
>> max_find_device);
>> int serial_console_init(void);
>> int ns16550_console_init(void *devp, struct serial_console_data
>> *scdp);
>> Index: kernel/arch/powerpc/boot/kexec.c
>> ===================================================================
>> --- kernel.orig/arch/powerpc/boot/kexec.c 2007-09-20
>> 17:42:24.000000000 -0500
>> +++ kernel/arch/powerpc/boot/kexec.c 2007-09-20 17:49:04.000000000
>> -0500
>> @@ -99,6 +99,7 @@ void kexec_platform_init(struct boot_par
>> move_slaves_up();
>>
>> setup_initial_heap();
>> + conv_flattree_inplace(dt_blob);
>> init_flat_tree(dt_blob);
>> /*
>> * drivers can malloc and read the tree, but not realloc later
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@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
>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 8/15] bootwrapper: convert flatdevtree to version 16
2007-09-24 6:54 ` Milton Miller
@ 2007-09-25 3:46 ` David Gibson
2007-09-26 16:19 ` Milton Miller
0 siblings, 1 reply; 55+ messages in thread
From: David Gibson @ 2007-09-25 3:46 UTC (permalink / raw)
To: Milton Miller; +Cc: ppcdev, Paul Mackerras
On Mon, Sep 24, 2007 at 01:54:32AM -0500, Milton Miller wrote:
>
> On Sep 23, 2007, at 10:36 PM, David Gibson wrote:
>
> > On Fri, Sep 21, 2007 at 06:05:06PM -0500, Milton Miller wrote:
[snip]
> >> +#define MIN_VERSION 2
> >> +#define OUT_VERSION 16
> >
> > Should output version 17. In any case, don't try to be so general -
> > just convert v123 (all basically the same) to latest (i.e. v17)
> > without all the #if nonsense.
>
> Outputing v17 instead of 16 requires more words to be added to the
> header, and the library does fine with v16.
For now. libfdt will want v17. Although it will (eventually) have
it's own v16->v17 conversion code.
> Actually the v1 trees has
> some other differences such as initrd addresses were kernel linear not
> real, cpus were assigned logical numbers ... so while the structure
> didn't change except for the header field, the contents did.
!? what's your source for this. v2 and v3 were absolutely supposed to
be backwards compatible with v1 which would not be the case with
silent semantic changes such as this.
> Actually,
> when converting v3 to v16 some of the code issn't needed, the ifs allow
> the code size to be reduced.
Yes, but it never will be, because the only reason we'd include this
file is for converting old kexec-tools device trees which are v2 not
v3.
> >> +#define OUT_COMPAT 16
> >> +
> >> +#ifdef NO_CHECK
> >> +static int check_v123_tree(u32 *start, u32 *limit)
> >> +{
> >> + return 0;
> >> +}
> >> +#else
> >> +/**
> >> + * check_v123_tree - check integrety of a version 1, 2, or 3 tree
> >> + * @start: the start of the device tree struct
> >> + * @limit: the end of the region for the struct
> >> + * structural checks on device_tree
> >> + */
> >> +static int check_v123_tree(u32 *start, u32 *limit)
> >
> > What is the point of this check? If the device tree is corrupt, we're
> > stuffed anyway, so why bother?
>
> Hence the ifdef NO_CHECK. When developing, sometimes its nice to know
> if its your input or your program. These functions are destructive to
> an improperlly formed tree, and in non-obvious ways. When debugging,
> it's not hard to hardcode console write or read the printf string
> buffer with a hardware debugger to see error messages. That said, it
> could be removed.
Right. Debugging code shouldn't pollute final patches.
[snip]
> >> +#if MIN_VERSION < 3 || OUT_VERSION > 16
> >> +/**
> >> + * move_nops_fwd - move nops in a v16 dt_struct to the beginning
> >> + * @start - device tree starting address
> >> + * @count - number of %OF_DT_NOP cells to move
> >> + */
> >> +static void move_nops_fwd(u32 *start, int count)
> >
> > What on earth is the point of this. The NOPs are perfectly valid
> > scattered within the tree, why go to all this trouble to shuffle them
> > about.
>
> And if you notice, there is a "how many to move" argument. The point
> of moving them to the front of the tree is the v17 device tree header
> takes more space than the v3 one, and the v2 header is smaller than
> both v17 and v16 header. Since I am converting the tree in place, the
> space has to come from somewhere. Since we are pretty much guaranteed
> to get several nops, this function moves them forward so they can be
> overwritten. In practice we move 1-3 NOPS from the early properties >
> 8 bytes and early grandchild nodes (eg /cpus/PowerPC,xxx).
This is a hell of a lot of bother to go to for a few bytes.
Allocating a big-enough buffer for any reasonable devtree in BSS and
memmove()ing into there would be far simpler.
Remember this is a hack for horrid old device trees produced by
kexec-tools. It simply doesn't justify large amounts of code to work
around.
[snip]
> >> + if (tree->last_comp_version > 3)
> >> + return; /* don't know what to do */
> >
> > Rather, don't need to do anything.
>
> If the tree is >= 16 then we don't presently need to do anything. If
> there is a theoritical v4 tree we don't know what to do. And if output
> version is 17 but input is 16 we don't know what to do either, because
> there likely aren't nops in the tree to consume. I suppose we could
> preceed it with a check for version == OUTPUT_VERSION, but then I'm
> sure I'd get pointless differentation :-).
There will never be a v4. Or anything between v3 and v16.
Again this is far too general. It's a hack to deal with kexec-tools
old trees. Therefore it doesn't need to deal with any general old
tree, just the minimum to deal with trees as produced by old
kexec-tools.
[snip]
> >> + /*
> >> + * move mem_rsvmap and dt_strings if they are before dt_struct
> >> + * onto our nops . Adjust start addresses for the 3 sections.
> >> + */
> >
> > Hrm. Do we really need to worry about this case. You may be
> > producing v2 trees in kexec-tools, but do they actually have the
> > blocks out of order? dtc certainly never produced them that way.
>
> Out of order? There has never been a spec as to the order of the
> blocks, only the implicit assumption that they follow the device tree
> header in a reasonably packed sequence. booting-without-of says it
> must be in ram,; the offsets are unsigned 32 bit quantities.
> As to the order, used, the first implemntation was the kernel which
> writes memreserve, strings, then struct (both the openfirmware client
> in prom_init and the iSeries procedural library in dt.c). The second
> implentation written is a procedural based library (similar to iseries,
> never published, but still used internally) that starts with a
> pre-built header and string table, builds the dt_struct as the
> functions are called, and when finished copies the memreserve table and
> fills in the dt_size, total size, and memreserve offset.
Hrm. Yes, well, the iSeries tree is weird in a bunch of ways.
> fs2dt writes memreserve, struct, then strings. Aparently the same as
> dtc. But yes, the strings can be before the struct, and the mem
> reserve may or may not be when the strings are before the struct.
Again. We don't need to deal with the general case here - just the
real case of trees produced by old kexec-tools.
[snip]
--
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
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 8/15] bootwrapper: convert flatdevtree to version 16
2007-09-25 3:46 ` David Gibson
@ 2007-09-26 16:19 ` Milton Miller
2007-09-27 2:45 ` David Gibson
0 siblings, 1 reply; 55+ messages in thread
From: Milton Miller @ 2007-09-26 16:19 UTC (permalink / raw)
To: David Gibson; +Cc: ppcdev, Paul Mackerras
On Sep 24, 2007, at 10:46 PM, David Gibson wrote:
> On Mon, Sep 24, 2007 at 01:54:32AM -0500, Milton Miller wrote:
>> On Sep 23, 2007, at 10:36 PM, David Gibson wrote:
>>> On Fri, Sep 21, 2007 at 06:05:06PM -0500, Milton Miller wrote:
> [snip]
>>>> +#define MIN_VERSION 2
>>>> +#define OUT_VERSION 16
>>>
>>> Should output version 17. In any case, don't try to be so general -
>>> just convert v123 (all basically the same) to latest (i.e. v17)
>>> without all the #if nonsense.
>>
>> Outputing v17 instead of 16 requires more words to be added to the
>> header, and the library does fine with v16.
>
> For now. libfdt will want v17. Although it will (eventually) have
> it's own v16->v17 conversion code.
If libfdt gets merged without supporting v16 input, then that will be a
regression. This code isn't pretending to address that. The current
flat tree code works with v16.
>> Actually the v1 trees has
>> some other differences such as initrd addresses were kernel linear not
>> real, cpus were assigned logical numbers ... so while the structure
>> didn't change except for the header field, the contents did.
>
> !? what's your source for this. v2 and v3 were absolutely supposed to
> be backwards compatible with v1 which would not be the case with
> silent semantic changes such as this.
What's your souce for saying the were supposed to be backwards
compatable? That dtc fills out the struct header so?
My source is my involvment when v2 was defined (they were discovered
while writing my device tree generation code):
The actual binary structure is compatable, just not the contents of the
properties nor how any slave cpus wait (for some trees it doesn't
matter).
http://git.kernel.org/?p=linux/kernel/git/horms/kexec-tools-
testing.git;a=blob;f=kexec/arch/ppc64/fs2dt.c;
hb=b84b87747a16f0afbef6f6802bb794a94f4961d9
And some more changes just before that:
http://git.kernel.org/?p=linux/kernel/git/torvalds/old-2.6-bkcvs.git;
a=history;f=arch/ppc64/kernel/prom_init.c;
h=e570799a84cc5328e9f0fd44592cb0b828d8c13a;
hb=4ae24c4e8a8f68950a7774ca1cdfe69bfe4e2ffc
So its mostly when the kernel generated and required v1 trees, it was
ppc64 only and had these other content and handoff semantics. If it
were to get a v1 tree, it only copes for the boot cpu determination
I'm not aware of any code other than the kernel that would actually
generate a v1 tree (other than dtc, which always supporteed v2, and
doesn't care about these differences).
>> Actually,
>> when converting v3 to v16 some of the code issn't needed, the ifs
>> allow
>> the code size to be reduced.
>
> Yes, but it never will be, because the only reason we'd include this
> file is for converting old kexec-tools device trees which are v2 not
> v3.
>
>>>> +#define OUT_COMPAT 16
>>>> +
>>>> +#ifdef NO_CHECK
>>>> +static int check_v123_tree(u32 *start, u32 *limit)
>>>> +{
>>>> + return 0;
>>>> +}
>>>> +#else
>>>> +/**
>>>> + * check_v123_tree - check integrety of a version 1, 2, or 3 tree
>>>> + * @start: the start of the device tree struct
>>>> + * @limit: the end of the region for the struct
>>>> + * structural checks on device_tree
>>>> + */
>>>> +static int check_v123_tree(u32 *start, u32 *limit)
>>>
>>> What is the point of this check? If the device tree is corrupt,
>>> we're
>>> stuffed anyway, so why bother?
>>
>> Hence the ifdef NO_CHECK. When developing, sometimes its nice to
>> know
>> if its your input or your program. These functions are destructive to
>> an improperlly formed tree, and in non-obvious ways. When debugging,
>> it's not hard to hardcode console write or read the printf string
>> buffer with a hardware debugger to see error messages. That said, it
>> could be removed.
>
> Right. Debugging code shouldn't pollute final patches.
There debug code, and validation code. I call this the later. It
validates that the information that should be redundant is in fact
redundant before its removed. The response of the kernel to the tree
may be different if this check fails..
> [snip]
>>>> +#if MIN_VERSION < 3 || OUT_VERSION > 16
>>>> +/**
>>>> + * move_nops_fwd - move nops in a v16 dt_struct to the beginning
>>>> + * @start - device tree starting address
>>>> + * @count - number of %OF_DT_NOP cells to move
>>>> + */
>>>> +static void move_nops_fwd(u32 *start, int count)
>>>
>>> What on earth is the point of this. The NOPs are perfectly valid
>>> scattered within the tree, why go to all this trouble to shuffle them
>>> about.
>>
>> And if you notice, there is a "how many to move" argument. The point
>> of moving them to the front of the tree is the v17 device tree header
>> takes more space than the v3 one, and the v2 header is smaller than
>> both v17 and v16 header. Since I am converting the tree in place, the
>> space has to come from somewhere. Since we are pretty much guaranteed
>> to get several nops, this function moves them forward so they can be
>> overwritten. In practice we move 1-3 NOPS from the early properties >
>> 8 bytes and early grandchild nodes (eg /cpus/PowerPC,xxx).
>
> This is a hell of a lot of bother to go to for a few bytes.
> Allocating a big-enough buffer for any reasonable devtree in BSS and
> memmove()ing into there would be far simpler.
How big is enough? Who is going to do the research for the various
firmware levels of the big machines to find out how big the tree is?
Sure there are other ways to get the tree to version 16, one way is to
change what is generated. We could update kexec-tools fs2dt to
geneerate a v16 tree to support zImages.
A question for the list: does anyone else have firmware/environment
that supplies a tree < v16?
> [snip]
>>>> + if (tree->last_comp_version > 3)
>>>> + return; /* don't know what to do */
>>>
>>> Rather, don't need to do anything.
>>
>> If the tree is >= 16 then we don't presently need to do anything. If
>> there is a theoritical v4 tree we don't know what to do. And if
>> output
>> version is 17 but input is 16 we don't know what to do either, because
>> there likely aren't nops in the tree to consume. I suppose we could
>> preceed it with a check for version == OUTPUT_VERSION, but then I'm
>> sure I'd get pointless differentation :-).
>
> There will never be a v4. Or anything between v3 and v16.
I could see a v4 defined as v3 + the extra header in v17, not that I am
proposing that. Someone decided to skip to v16 for a reason. If we
knew there would never be v4-v15, why did we skip them?
[too general]
> [snip]
>>>> + /*
>>>> + * move mem_rsvmap and dt_strings if they are before dt_struct
>>>> + * onto our nops . Adjust start addresses for the 3 sections.
>>>> + */
>>>
>>> Hrm. Do we really need to worry about this case. You may be
>>> producing v2 trees in kexec-tools, but do they actually have the
>>> blocks out of order? dtc certainly never produced them that way.
>>
>> Out of order? There has never been a spec as to the order of the
>> blocks, only the implicit assumption that they follow the device tree
>> header in a reasonably packed sequence. booting-without-of says it
>> must be in ram,; the offsets are unsigned 32 bit quantities.
>
>> As to the order, used, the first implemntation was the kernel which
>> writes memreserve, strings, then struct (both the openfirmware client
>> in prom_init and the iSeries procedural library in dt.c). The second
>> implentation written is a procedural based library (similar to
>> iseries,
>> never published, but still used internally) that starts with a
>> pre-built header and string table, builds the dt_struct as the
>> functions are called, and when finished copies the memreserve table
>> and
>> fills in the dt_size, total size, and memreserve offset.
>
> Hrm. Yes, well, the iSeries tree is weird in a bunch of ways.
My point is its the same as the client interface code, and proves the
point the order is not specified nor need it be. And since the order
is the same in platforms/iseries/dt.c and kernel/prom_init.c, I fail to
see your point of calling the iseries code wierd. It's building a
device tree via the structured programming methods of calling
functions, each of which creates a node and the properties for that
node. Doesn't sound that much different than how a ieee bytecode
program would create the device tree and fill out properties, and I
would expect any firmware who created the device tree from scratch (as
oposed to editing a paritially built tree like the fixup hooks
presently in the wrapper) would be structured similarly. Since it
doesn't ahve a dynamic insertion library, it must fill in all the
properties of a node completely before its children, and must travel
some depth first order when creating the tree. I don't see any reason
to call it wierd.
>
>> fs2dt writes memreserve, struct, then strings. Aparently the same as
>> dtc. But yes, the strings can be before the struct, and the mem
>> reserve may or may not be when the strings are before the struct.
>
> Again. We don't need to deal with the general case here - just the
> real case of trees produced by old kexec-tools.
This function isn't conver_kexec_tree_inplacee. While my justification
for merging this code is it can be used as the target for kexec with
kexec-tools, its not my only use. I also have my internal library that
generates a v3 tree with the pieces ordered differently. If the code
is changed from its general support to support only the tree generated
by kexec-tools, then merging has little benifit to me and in fact it is
harder (I have to maintain a diff to a changing target vs adding a file
to the makefile).
I'll write a later reply that talks about what subsets of this series
make sense to merge.
milton
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 8/15] bootwrapper: convert flatdevtree to version 16
2007-09-26 16:19 ` Milton Miller
@ 2007-09-27 2:45 ` David Gibson
2007-09-27 15:44 ` Milton Miller
0 siblings, 1 reply; 55+ messages in thread
From: David Gibson @ 2007-09-27 2:45 UTC (permalink / raw)
To: Milton Miller; +Cc: ppcdev, Paul Mackerras
On Wed, Sep 26, 2007 at 11:19:47AM -0500, Milton Miller wrote:
> On Sep 24, 2007, at 10:46 PM, David Gibson wrote:
> > On Mon, Sep 24, 2007 at 01:54:32AM -0500, Milton Miller wrote:
> >> On Sep 23, 2007, at 10:36 PM, David Gibson wrote:
> >>> On Fri, Sep 21, 2007 at 06:05:06PM -0500, Milton Miller wrote:
> > [snip]
> >>>> +#define MIN_VERSION 2
> >>>> +#define OUT_VERSION 16
> >>>
> >>> Should output version 17. In any case, don't try to be so general -
> >>> just convert v123 (all basically the same) to latest (i.e. v17)
> >>> without all the #if nonsense.
> >>
> >> Outputing v17 instead of 16 requires more words to be added to the
> >> header, and the library does fine with v16.
> >
> > For now. libfdt will want v17. Although it will (eventually) have
> > it's own v16->v17 conversion code.
>
> If libfdt gets merged without supporting v16 input, then that will be a
> regression. This code isn't pretending to address that. The current
> flat tree code works with v16.
Hrm, true. Since I'm working on merging libfdt right now, I guess
that moves up my schedule for getting the v16->v17 conversion code
working.
>
> >> Actually the v1 trees has
> >> some other differences such as initrd addresses were kernel linear not
> >> real, cpus were assigned logical numbers ... so while the structure
> >> didn't change except for the header field, the contents did.
> >
> > !? what's your source for this. v2 and v3 were absolutely supposed to
> > be backwards compatible with v1 which would not be the case with
> > silent semantic changes such as this.
>
> What's your souce for saying the were supposed to be backwards
> compatable? That dtc fills out the struct header so?
Sitting next to BenH and knowing he always intended them to be so.
> My source is my involvment when v2 was defined (they were discovered
> while writing my device tree generation code):
>
> The actual binary structure is compatable, just not the contents of the
> properties nor how any slave cpus wait (for some trees it doesn't
> matter).
>
> http://git.kernel.org/?p=linux/kernel/git/horms/kexec-tools-
> testing.git;a=blob;f=kexec/arch/ppc64/fs2dt.c;
> hb=b84b87747a16f0afbef6f6802bb794a94f4961d9
An old version of fs2dt is hardly definitive. It could just be Plain
Wrong, nothing to do with the dt version.
> And some more changes just before that:
>
> http://git.kernel.org/?p=linux/kernel/git/torvalds/old-2.6-bkcvs.git;
> a=history;f=arch/ppc64/kernel/prom_init.c;
> h=e570799a84cc5328e9f0fd44592cb0b828d8c13a;
> hb=4ae24c4e8a8f68950a7774ca1cdfe69bfe4e2ffc
I don't know what bit you're referring to in that batch of commits.
> So its mostly when the kernel generated and required v1 trees, it was
> ppc64 only and had these other content and handoff semantics. If it
> were to get a v1 tree, it only copes for the boot cpu determination
> I'm not aware of any code other than the kernel that would actually
> generate a v1 tree (other than dtc, which always supporteed v2, and
> doesn't care about these differences).
--
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
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 8/15] bootwrapper: convert flatdevtree to version 16
2007-09-27 2:45 ` David Gibson
@ 2007-09-27 15:44 ` Milton Miller
2007-09-28 2:40 ` David Gibson
0 siblings, 1 reply; 55+ messages in thread
From: Milton Miller @ 2007-09-27 15:44 UTC (permalink / raw)
To: David Gibson; +Cc: ppcdev
On Sep 26, 2007, at 9:45 PM, David Gibson wrote:
> On Wed, Sep 26, 2007 at 11:19:47AM -0500, Milton Miller wrote:
>> On Sep 24, 2007, at 10:46 PM, David Gibson wrote:
>>> On Mon, Sep 24, 2007 at 01:54:32AM -0500, Milton Miller wrote:
>>>> On Sep 23, 2007, at 10:36 PM, David Gibson wrote:
>>>>> On Fri, Sep 21, 2007 at 06:05:06PM -0500, Milton Miller wrote:
>>> [snip]
>>>>>> +#define MIN_VERSION 2
>>>>>> +#define OUT_VERSION 16z
>>>> Actually the v1 trees has
>>>> some other differences such as initrd addresses were kernel linear
>>>> not
>>>> real, cpus were assigned logical numbers ... so while the structure
>>>> didn't change except for the header field, the contents did.
>>>
>>> !? what's your source for this. v2 and v3 were absolutely supposed
>>> to
>>> be backwards compatible with v1 which would not be the case with
>>> silent semantic changes such as this.
>>
>> What's your souce for saying the were supposed to be backwards
>> compatable? That dtc fills out the struct header so?
>
> Sitting next to BenH and knowing he always intended them to be so.
>
>> My source is my involvment when v2 was defined (they were discovered
>> while writing my device tree generation code):
>>
>> The actual binary structure is compatable, just not the contents of
>> the
>> properties nor how any slave cpus wait (for some trees it doesn't
>> matter).
>>
>> http://git.kernel.org/?p=linux/kernel/git/horms/kexec-tools-
>> testing.git;a=blob;f=kexec/arch/ppc64/fs2dt.c;
>> hb=b84b87747a16f0afbef6f6802bb794a94f4961d9
>
> An old version of fs2dt is hardly definitive. It could just be Plain
> Wrong, nothing to do with the dt version.
Sorry, copy and paste error. I was tring to point out this changelog
in 2.6.10:
http://git.kernel.org/?p=linux/kernel/git/torvalds/old-2.6-bkcvs.git;
a=commitdiff;h=e1b47549d1588ccea1fa5726eb430aae4e80f8ed
>
>> And some more changes just before that:
>>
>> http://git.kernel.org/?p=linux/kernel/git/torvalds/old-2.6-bkcvs.git;
>> a=history;f=arch/ppc64/kernel/prom_init.c;
>> h=e570799a84cc5328e9f0fd44592cb0b828d8c13a;
>> hb=4ae24c4e8a8f68950a7774ca1cdfe69bfe4e2ffc
>
> I don't know what bit you're referring to in that batch of commits.
The following properties changed semantics and no heuristics are
employed to check for the old vs new:
(1) tces changed from virtual to real
(2) cpus spin on physical (hw id) not logical (0-n)
Other changes in that series
(3) 0->klimit is not a memreserve in the tree (we now allow overlapping
reserves, but not at the time)
(4) rtas properties are in a different location (but both could exist)
>
>> So its mostly when the kernel generated and required v1 trees, it was
>> ppc64 only and had these other content and handoff semantics. If it
>> were to get a v1 tree, it only copes for the boot cpu determination
>> I'm not aware of any code other than the kernel that would actually
>> generate a v1 tree (other than dtc, which always supporteed v2, and
>> doesn't care about these differences).
So trying to boot 2.6.9 (2004-10-18 cutoff) kernel from a tree for
2.6.10 would fail, and vice versa. But a 2.6.10 kernel can boot a v1
tree with properties, memreserves, and cpu ids that it expects, getting
the boot-cpuid from the extra property in the tree.
Is that compatible? If you only are talking about parsing the tree it
is.
milton
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 8/15] bootwrapper: convert flatdevtree to version 16
2007-09-27 15:44 ` Milton Miller
@ 2007-09-28 2:40 ` David Gibson
2007-09-28 15:16 ` Milton Miller
0 siblings, 1 reply; 55+ messages in thread
From: David Gibson @ 2007-09-28 2:40 UTC (permalink / raw)
To: Milton Miller; +Cc: ppcdev
On Thu, Sep 27, 2007 at 10:44:27AM -0500, Milton Miller wrote:
>
> On Sep 26, 2007, at 9:45 PM, David Gibson wrote:
[snip]
> >> What's your souce for saying the were supposed to be backwards
> >> compatable? That dtc fills out the struct header so?
> >
> > Sitting next to BenH and knowing he always intended them to be so.
> >
> >> My source is my involvment when v2 was defined (they were discovered
> >> while writing my device tree generation code):
> >>
> >> The actual binary structure is compatable, just not the contents of
> >> the
> >> properties nor how any slave cpus wait (for some trees it doesn't
> >> matter).
> >>
> >> http://git.kernel.org/?p=linux/kernel/git/horms/kexec-tools-
> >> testing.git;a=blob;f=kexec/arch/ppc64/fs2dt.c;
> >> hb=b84b87747a16f0afbef6f6802bb794a94f4961d9
> >
> > An old version of fs2dt is hardly definitive. It could just be Plain
> > Wrong, nothing to do with the dt version.
>
> Sorry, copy and paste error. I was tring to point out this changelog
> in 2.6.10:
>
> http://git.kernel.org/?p=linux/kernel/git/torvalds/old-2.6-bkcvs.git;
> a=commitdiff;h=e1b47549d1588ccea1fa5726eb430aae4e80f8ed
Hrm, I see, yes that seems conclusive enough. Yuck.
In which case, I think we should try to forget that v1 ever existed.
I don't think anyone ever generated v1 trees other than kernels which
also consumed them, and I doubt current kernels will correctly deal
with v1 trees in this form.
In any case, this is all rather beside the point. My basic point is
that this bootwrapper stuff should not attempt to be a general
backwards compatibility layer for every broken early dt format that
ever existed. In general we should try to make sure nothing ever uses
<v16 trees. We want, here, to do the minimum we can get away with to
support the specific v2 trees produced by kexec-tools, as an interim
measure while kexec-tools itself is fixed to produce v17 trees (say,
by replacing fs2dt with dtc plus a libfdt based post-processing
program).
--
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
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 8/15] bootwrapper: convert flatdevtree to version 16
2007-09-28 2:40 ` David Gibson
@ 2007-09-28 15:16 ` Milton Miller
2007-10-03 5:29 ` David Gibson
0 siblings, 1 reply; 55+ messages in thread
From: Milton Miller @ 2007-09-28 15:16 UTC (permalink / raw)
To: David Gibson; +Cc: ppcdev
On Sep 27, 2007, at 9:40 PM, David Gibson wrote:
> On Thu, Sep 27, 2007 at 10:44:27AM -0500, Milton Miller wrote:
>> On Sep 26, 2007, at 9:45 PM, David Gibson wrote:
>>>> The actual binary structure is compatable, just not the contents of
>>>> the
>>>> properties nor how any slave cpus wait (for some trees it doesn't
>>>> matter).
>>
>> Sorry, copy and paste error. I was tring to point out this changelog
>> in 2.6.10:
>>
>> http://git.kernel.org/?p=linux/kernel/git/torvalds/old-2.6-bkcvs.git;
>> a=commitdiff;h=e1b47549d1588ccea1fa5726eb430aae4e80f8ed
>
> Hrm, I see, yes that seems conclusive enough. Yuck.
>
> In which case, I think we should try to forget that v1 ever existed.
> I don't think anyone ever generated v1 trees other than kernels which
> also consumed them,
I believe this to be true, unless you count telling dtc to do so.
> and I doubt current kernels will correctly deal
> with v1 trees in this form.
I'm quite certain of that.
> In any case, this is all rather beside the point. My basic point is
> that this bootwrapper stuff should not attempt to be a general
> backwards compatibility layer for every broken early dt format that
> ever existed.
The only broken format was v1; I was submitting v2 :-). Version 16 was
"... to support a more compact representation, for use by embedded
systems mostly"
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;
a=commitdiff;h=34153fa3af45d84f3221d9b67ba2ab7e8a220d28
> In general we should try to make sure nothing ever uses
> <v16 trees. We want, here, to do the minimum we can get away with to
> support the specific v2 trees produced by kexec-tools, as an interim
> measure
As I stated, that by itself isn't sufficient for my usage, as I have
other v2 trees I need to deal with, at least until that generator gets
updated.
> while kexec-tools itself is fixed to produce v17 trees (say,
> by replacing fs2dt with dtc plus a libfdt based post-processing
> program).
If you thought there were complaints trying to require an external
utility to build zImage, just wait until you try to make kexec-tools
not be self-contained. Currently kexec doesn't even use a data
directory, instead it builds the purgatory and other trampoline
binaries into the kexec program. Incorporating the post-processing and
generation using libfdt (with a copy of the library in the source)
could fly, if people don't care about kexec into kernels from 2.6.10 to
2.6.14 when v16 was merged (about 1 year).
Actually, there is another approach: put this converter in kexec's
purgatory or even the kexec program. It can then run conditionally
under command line flags to keep compatibility with the old kernels.
If and when its is decided to only support >=v16 in kexec-tools it can
be removed and we don't have this interim support code in the kernel
forever (I'll handle my other usage out of tree).
milton
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 8/15] bootwrapper: convert flatdevtree to version 16
2007-09-28 15:16 ` Milton Miller
@ 2007-10-03 5:29 ` David Gibson
0 siblings, 0 replies; 55+ messages in thread
From: David Gibson @ 2007-10-03 5:29 UTC (permalink / raw)
To: Milton Miller; +Cc: ppcdev
On Fri, Sep 28, 2007 at 10:16:51AM -0500, Milton Miller wrote:
[snip]
> Actually, there is another approach: put this converter in kexec's
> purgatory or even the kexec program. It can then run conditionally
> under command line flags to keep compatibility with the old kernels.
> If and when its is decided to only support >=v16 in kexec-tools it can
> be removed and we don't have this interim support code in the kernel
> forever (I'll handle my other usage out of tree).
Hurrah! Well, please do that then.
--
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
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 9/15] bootwrapper: rtas support
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
` (7 preceding siblings ...)
2007-09-21 23:05 ` [PATCH 8/15] bootwrapper: convert flatdevtree to version 16 Milton Miller
@ 2007-09-21 23:05 ` Milton Miller
2007-09-24 3:46 ` David Gibson
2007-09-21 23:05 ` [PATCH 10/15] bootwrapper: add cpio file extraction library Milton Miller
` (7 subsequent siblings)
16 siblings, 1 reply; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:05 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
This code provides a console write that calls put-term-char.
To avoid PIC relocation of the absolute rtas addresses, hide the
actual call to rtas in assembly and declare all variables as int.
An instantiated rtas will be protected by a reserved range in the
device tree, so no explicit call to add_occupied_range is needed
here.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
vs 12176
rtas_put_term_write now takes const char *buf
rediff ops.h, Makefile
Index: kernel/arch/powerpc/boot/rtas.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/boot/rtas.c 2007-09-21 01:43:08.000000000 -0500
@@ -0,0 +1,146 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2007 IBM Corporation.
+ *
+ * Authors: Milton Miller <miltonm@bga.com>
+ *
+ */
+
+#include "ops.h"
+#include "stdio.h"
+#include "flatdevtree.h"
+
+static int rtas_entry;
+static int rtas_base;
+static int rtas_size;
+
+static void find_rtas(void)
+{
+ int rc;
+ void *devp;
+ char *str;
+
+ devp = finddevice("/rtas");
+ if (! devp)
+ return;
+
+ str = "linux,rtas-entry";
+ rc = getprop(devp, str, &rtas_entry, sizeof(rtas_entry));
+ if (rc < 0)
+ return;
+ if (rc != sizeof(rtas_entry))
+ goto fail;
+
+ str = "rtas-size";
+ rc = getprop(devp, str, &rtas_size, sizeof(rtas_size));
+ if (rc < 0)
+ return;
+ if (rc != sizeof(rtas_size))
+ goto fail;
+
+ str = "linux,rtas-base";
+ rc = getprop(devp, str, &rtas_base, sizeof(rtas_base));
+ if (rc < 0) {
+ printf("rtas-size but no linux,rtas-base in /rtas. "
+ "disabling wrapper rtas interface\n\r");
+ rtas_entry = 0;
+ return;
+ }
+
+ if (rc != sizeof(rtas_base))
+ goto fail;
+
+ return;
+
+
+fail:
+ printf("Unexpected length %d of %s property in /rtas.\n\r"
+ "disabling wrapper rtas interface\n\r", rc, str);
+ rtas_entry = 0;
+ return;
+}
+
+/*
+ * PIC relocation of function pointers happens at call time.
+ * We have an absolute out-of-image address. So tell C they
+ * are just integers, and hide the call as an out-of-file
+ * function.
+ */
+__asm__ (
+ " .globl call_rtas\n"
+ " call_rtas: mtctr 5\n"
+ " bctr\n"
+ );
+
+void call_rtas(int args[], int base, int entry);
+
+
+static int put_term_char;
+
+static void rtas_put_term_write(const char *buf, int len)
+{
+ int i, args[5];
+
+ args[0] = put_term_char;
+ args[1] = 1; /* num inputs */
+ args[2] = 1; /* num outputs */
+
+ for (i=0; i < len; ) {
+ args[3] = buf[i];
+ args[4] = 0;
+
+ call_rtas(args, rtas_base, rtas_entry);
+ if (args[4] == 0) /* SUCCESS */
+ i++;
+ else if (args[4] == -1) /* HARDWARE_ERROR */
+ break;
+ /* else retry */
+ }
+}
+
+int rtas_console_init(void)
+{
+ void *devp;
+ int rc;
+
+
+ devp = finddevice("/rtas");
+ if (!devp)
+ return -1;
+
+ if (!rtas_entry)
+ find_rtas();
+ if (!rtas_entry)
+ return -1;
+
+ rc = getprop(devp, "put-term-char", &put_term_char,
+ sizeof(put_term_char));
+ if (rc == sizeof(put_term_char))
+ console_ops.write = rtas_put_term_write;
+ else
+ put_term_char = -1;
+
+ return put_term_char == -1 ? -1 : 0;
+}
+
+/* for debug, hard code */
+void use_rtas_console(int entry, int base, int tc)
+{
+ rtas_entry = entry;
+ rtas_base = base;
+ put_term_char = tc;
+ console_ops.write = rtas_put_term_write;
+}
Index: kernel/arch/powerpc/boot/ops.h
===================================================================
--- kernel.orig/arch/powerpc/boot/ops.h 2007-09-21 01:43:02.000000000 -0500
+++ kernel/arch/powerpc/boot/ops.h 2007-09-21 01:43:08.000000000 -0500
@@ -99,6 +99,8 @@ void send_slaves_to_kernel(void *vmlinux
void slaves_are_low(void);
void wait_slaves_moved(void);
void kexec_platform_init(struct boot_param_header *dt_blob);
+int rtas_console_init(void);
+void use_rtas_console(int entry, int base, int tc);
int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size);
int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr);
Index: kernel/arch/powerpc/boot/kexec.c
===================================================================
--- kernel.orig/arch/powerpc/boot/kexec.c 2007-09-21 01:43:02.000000000 -0500
+++ kernel/arch/powerpc/boot/kexec.c 2007-09-21 01:43:08.000000000 -0500
@@ -33,6 +33,9 @@ static void find_console_from_tree(void)
{
int rc = -1;
+ rc = rtas_console_init();
+ if (!rc)
+ return;
if (rc) {
/* no console, oh well */
}
Index: kernel/arch/powerpc/boot/Makefile
===================================================================
--- kernel.orig/arch/powerpc/boot/Makefile 2007-09-21 01:43:02.000000000 -0500
+++ kernel/arch/powerpc/boot/Makefile 2007-09-21 01:43:08.000000000 -0500
@@ -42,7 +42,7 @@ $(addprefix $(obj)/,$(zlib) gunzip_util.
$(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
- flatdevtree_conv.c marshal.c memranges.c kexec.c \
+ flatdevtree_conv.c marshal.c memranges.c kexec.c rtas.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 9/15] bootwrapper: rtas support
2007-09-21 23:05 ` [PATCH 9/15] bootwrapper: rtas support Milton Miller
@ 2007-09-24 3:46 ` David Gibson
0 siblings, 0 replies; 55+ messages in thread
From: David Gibson @ 2007-09-24 3:46 UTC (permalink / raw)
To: Milton Miller; +Cc: linuxppc-dev, Paul Mackerras, Rob Landley
On Fri, Sep 21, 2007 at 06:05:30PM -0500, Milton Miller wrote:
> This code provides a console write that calls put-term-char.
>
> To avoid PIC relocation of the absolute rtas addresses, hide the
> actual call to rtas in assembly and declare all variables as int.
>
> An instantiated rtas will be protected by a reserved range in the
> device tree, so no explicit call to add_occupied_range is needed
> here.
>
> Signed-off-by: Milton Miller <miltonm@bga.com>
> ---
> vs 12176
> rtas_put_term_write now takes const char *buf
> rediff ops.h, Makefile
>
> Index: kernel/arch/powerpc/boot/rtas.c
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ kernel/arch/powerpc/boot/rtas.c 2007-09-21 01:43:08.000000000 -0500
> @@ -0,0 +1,146 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> + *
> + * Copyright 2007 IBM Corporation.
> + *
> + * Authors: Milton Miller <miltonm@bga.com>
> + *
> + */
> +
> +#include "ops.h"
> +#include "stdio.h"
> +#include "flatdevtree.h"
> +
> +static int rtas_entry;
> +static int rtas_base;
> +static int rtas_size;
> +
> +static void find_rtas(void)
> +{
> + int rc;
> + void *devp;
> + char *str;
> +
> + devp = finddevice("/rtas");
> + if (! devp)
> + return;
> +
> + str = "linux,rtas-entry";
wtf? Just use the literals in the getprop() calls, this is pure
obfuscation.
> + rc = getprop(devp, str, &rtas_entry, sizeof(rtas_entry));
> + if (rc < 0)
> + return;
> + if (rc != sizeof(rtas_entry))
> + goto fail;
> +
> + str = "rtas-size";
> + rc = getprop(devp, str, &rtas_size, sizeof(rtas_size));
> + if (rc < 0)
> + return;
> + if (rc != sizeof(rtas_size))
> + goto fail;
> +
> + str = "linux,rtas-base";
> + rc = getprop(devp, str, &rtas_base, sizeof(rtas_base));
> + if (rc < 0) {
> + printf("rtas-size but no linux,rtas-base in /rtas. "
> + "disabling wrapper rtas interface\n\r");
> + rtas_entry = 0;
> + return;
> + }
> +
> + if (rc != sizeof(rtas_base))
> + goto fail;
> +
> + return;
> +
> +
> +fail:
> + printf("Unexpected length %d of %s property in /rtas.\n\r"
> + "disabling wrapper rtas interface\n\r", rc, str);
> + rtas_entry = 0;
> + return;
> +}
> +
> +/*
> + * PIC relocation of function pointers happens at call time.
> + * We have an absolute out-of-image address. So tell C they
> + * are just integers, and hide the call as an out-of-file
> + * function.
> + */
I don't get this. If we can call into the kernel using a function
pointer, you should be able to call into rtas without this weirdness.
> +__asm__ (
> + " .globl call_rtas\n"
> + " call_rtas: mtctr 5\n"
> + " bctr\n"
> + );
> +
> +void call_rtas(int args[], int base, int entry);
> +
> +
> +static int put_term_char;
> +
> +static void rtas_put_term_write(const char *buf, int len)
> +{
> + int i, args[5];
> +
> + args[0] = put_term_char;
> + args[1] = 1; /* num inputs */
> + args[2] = 1; /* num outputs */
> +
> + for (i=0; i < len; ) {
> + args[3] = buf[i];
> + args[4] = 0;
> +
> + call_rtas(args, rtas_base, rtas_entry);
> + if (args[4] == 0) /* SUCCESS */
> + i++;
> + else if (args[4] == -1) /* HARDWARE_ERROR */
> + break;
> + /* else retry */
> + }
> +}
> +
> +int rtas_console_init(void)
> +{
> + void *devp;
> + int rc;
> +
> +
> + devp = finddevice("/rtas");
> + if (!devp)
> + return -1;
> +
> + if (!rtas_entry)
> + find_rtas();
> + if (!rtas_entry)
> + return -1;
> +
> + rc = getprop(devp, "put-term-char", &put_term_char,
> + sizeof(put_term_char));
> + if (rc == sizeof(put_term_char))
> + console_ops.write = rtas_put_term_write;
> + else
> + put_term_char = -1;
> +
> + return put_term_char == -1 ? -1 : 0;
> +}
> +
> +/* for debug, hard code */
> +void use_rtas_console(int entry, int base, int tc)
> +{
> + rtas_entry = entry;
> + rtas_base = base;
> + put_term_char = tc;
> + console_ops.write = rtas_put_term_write;
> +}
> Index: kernel/arch/powerpc/boot/ops.h
> ===================================================================
> --- kernel.orig/arch/powerpc/boot/ops.h 2007-09-21 01:43:02.000000000 -0500
> +++ kernel/arch/powerpc/boot/ops.h 2007-09-21 01:43:08.000000000 -0500
> @@ -99,6 +99,8 @@ void send_slaves_to_kernel(void *vmlinux
> void slaves_are_low(void);
> void wait_slaves_moved(void);
> void kexec_platform_init(struct boot_param_header *dt_blob);
> +int rtas_console_init(void);
> +void use_rtas_console(int entry, int base, int tc);
>
> int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size);
> int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr);
> Index: kernel/arch/powerpc/boot/kexec.c
> ===================================================================
> --- kernel.orig/arch/powerpc/boot/kexec.c 2007-09-21 01:43:02.000000000 -0500
> +++ kernel/arch/powerpc/boot/kexec.c 2007-09-21 01:43:08.000000000 -0500
> @@ -33,6 +33,9 @@ static void find_console_from_tree(void)
> {
> int rc = -1;
>
> + rc = rtas_console_init();
> + if (!rc)
> + return;
> if (rc) {
> /* no console, oh well */
> }
> Index: kernel/arch/powerpc/boot/Makefile
> ===================================================================
> --- kernel.orig/arch/powerpc/boot/Makefile 2007-09-21 01:43:02.000000000 -0500
> +++ kernel/arch/powerpc/boot/Makefile 2007-09-21 01:43:08.000000000 -0500
> @@ -42,7 +42,7 @@ $(addprefix $(obj)/,$(zlib) gunzip_util.
> $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
>
> src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
> - flatdevtree_conv.c marshal.c memranges.c kexec.c \
> + flatdevtree_conv.c marshal.c memranges.c kexec.c rtas.c \
> ns16550.c serial.c simple_alloc.c div64.S util.S \
> gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
> 4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@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
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 10/15] bootwrapper: add cpio file extraction library.
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
` (8 preceding siblings ...)
2007-09-21 23:05 ` [PATCH 9/15] bootwrapper: rtas support Milton Miller
@ 2007-09-21 23:05 ` Milton Miller
2007-09-21 23:06 ` [PATCH 11/15] bootwrapper: allow vmlinuz to be an external payload Milton Miller
` (6 subsequent siblings)
16 siblings, 0 replies; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:05 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
Add a library to search through a cpio or initramfs buffer for a
specified path name. No canocalization of the path is performed.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
vs 12177
rediff Makefile
cpio.c should be reusable by a stand alone user space applicaton.
Index: kernel/arch/powerpc/boot/cpio.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/boot/cpio.c 2007-08-22 20:51:29.000000000 -0500
@@ -0,0 +1,306 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2007 IBM Corporation.
+ *
+ * Authors: Milton Miller <miltonm@bga.com>
+ *
+ */
+
+#include "cpio.h"
+#include "string.h"
+
+struct cpio_header {
+ char ino[8];
+ char mode[8];
+ char uid[8];
+ char gid[8];
+ char nlink[8];
+ char mtime[8];
+ char filesize[8];
+ char maj[8];
+ char min[8];
+ char rmaj[8];
+ char rmin[8];
+ char namesize[8];
+ char chksum[8];
+} cpio_header_buf;
+
+static int check_magic(char magic[6])
+{
+ return !memcmp(magic,"070701",6) || !memcmp(magic,"070702",6);
+}
+
+static int read_magic(struct gunzip_state *stream)
+{
+ int len;
+ char magic[6];
+
+ len = gunzip_partial(stream, magic, sizeof(magic));
+ if (len == 0)
+ return 0;
+
+ if (len == sizeof(magic) && check_magic(magic))
+ return len;
+
+
+ /* Not the right magic or short read. We might have stumbled
+ * onto a compressed archive immediately following an
+ * uncompressed one, or just some NUL bytes at the end of the
+ * archive. Inform the higher layers by the negative length.
+ */
+ return -len;
+}
+
+static int get_cpio_header(struct gunzip_state *stream)
+{
+ int len;
+
+ len = read_magic(stream);
+ if (len <= 0)
+ return len;
+
+ gunzip_exactly(stream, &cpio_header_buf, sizeof(cpio_header_buf));
+ len += sizeof(cpio_header_buf);
+
+ return len;
+}
+
+static unsigned int cpio_str_to_num(char hexascii[8])
+{
+ unsigned int num = 0;
+ char c;
+ int d;
+
+ for (d=0; d < 8; d++) {
+ c = hexascii[d];
+ num <<= 4;
+ if (c >= '0' && c <= '9') {
+ num += c - '0';
+ } else if (c >= 'A' && c <= 'F') {
+ num += c - 'A' + 10;
+ } else if (c >= 'a' && c <= 'f') {
+ num += c - 'a' + 10;
+ } else {
+ cpio_error("bad cpio archive header: "
+ "invalid a hex digit");
+ }
+ }
+
+ return num;
+}
+
+static char name_buf[MAX_PATH+1];
+static const char cpio_end[] = "TRAILER!!!";
+#define CPIO_END_LEN sizeof(cpio_end)
+
+/* check_next_file
+ * Look for @path in @stream. Set @consumed to the number of bytes
+ * succesfully read and processed. return 1 on match, 0 for discarding
+ * an unmatched file, -1 on end of archive (either detected trailer or
+ * EOF on stream), or -(1 + bytes read) for a short read or bad magic
+ * number. (For the short or bad read, the consumed is not changed).
+ */
+static int check_next_file(char *path, int pathlen,
+ struct gunzip_state *stream, int *consumed)
+{
+ int len, total, match;
+
+ if (pathlen > MAX_PATH) {
+ cpio_error("path too long to search\n");
+ }
+ total = get_cpio_header(stream);
+ if (total <= 0)
+ return total - 1;
+
+ len = cpio_str_to_num(cpio_header_buf.namesize);
+
+ if (len == pathlen || len == CPIO_END_LEN) {
+ gunzip_exactly(stream, name_buf, len);
+ total += len;
+ match = !strcmp(name_buf, path);
+ if (!match && !cpio_str_to_num(cpio_header_buf.filesize))
+ match = -!strcmp(name_buf, cpio_end);
+ } else {
+ gunzip_discard(stream, len);
+ total += len;
+ name_buf[0] = '\0';
+ match = 0;
+ }
+
+ len = total % 4;
+ if (len) {
+ gunzip_discard(stream, 4 - len);
+ total += 4 - len;
+ }
+
+ if (!match) {
+ len = cpio_str_to_num(cpio_header_buf.filesize);
+ gunzip_discard(stream, len);
+ total += len;
+
+ len = total % 4;
+ if (len) {
+ gunzip_discard(stream, 4 - len);
+ total += 4 - len;
+ }
+ }
+
+ *consumed += total;
+ return match;
+}
+
+static char *this_buf;
+static int this_archive;
+
+/* find_in_cpio.
+ * find a pathname @path in a single cpio archive described by @stream.
+ * Return is the same as check_next_file.
+ */
+int find_in_cpio(char *path, struct gunzip_state *stream)
+{
+ int found;
+ int pathlen = strlen(path) + 1;
+
+ this_archive = 0;
+ do {
+ found = check_next_file(path, pathlen, stream, &this_archive);
+ } while (found == 0);
+
+ return found;
+}
+
+/* find_in_initramfs
+ * Search a initramfs buffer for a given path name. Returns 0 on
+ * not found, or 1 with @state ready to read the file.
+ *
+ * Note: this returns the first match, not the last. The kernel
+ * decompressor effectivly uses the last match. This code also
+ * doesn't worry about the directories in the path existing.
+ */
+int find_in_initramfs(char *path, char *buf, int len,
+ struct gunzip_state *stream)
+{
+ int found, total = 0;
+ int pathlen = strlen(path) + 1;
+ int *ibuf;
+
+ do {
+ /* get to word boundary, but stop if not NUL */
+ for (; total % 4 && total < len - 4; total++)
+ if (buf[total])
+ break;
+
+ if ((total % 4) == 0) {
+ /* fast forward over NUL words. */
+ for (ibuf = (int *)&buf[total];
+ total < len - sizeof(*ibuf) && !*ibuf;
+ ibuf++)
+ total += sizeof(*ibuf);
+ }
+
+ /* check remainder of a short archive -- it must all be
+ * zero as both gzip header and cpio header are bigger
+ * than this.
+ */
+ if (total >= len - 4) {
+ for (;total < len; total++) {
+ if (buf[len]) {
+ cpio_error("Junk at end of buffer");
+ }
+ }
+ break;
+ } else if (total % 4) {
+ /*
+ * If we are unalinged and not at the end of the buffer
+ * we must be following a compressed archive. Only
+ * NUL and gzip headers are allowed. We skipped NUL.
+ */
+ if (!(buf[total] == 0x1b && buf[total + 1] == 0x8b))
+ cpio_error("unalinged junk in buffer");
+ }
+
+ this_buf = buf + total;
+ this_archive = 0;
+
+ gunzip_start(stream, this_buf, len - total);
+
+ do {
+ found = check_next_file(path, pathlen, stream,
+ &this_archive);
+ } while (!found);
+
+ if (found > 0)
+ return found;
+
+ if (stream->s.workspace) {
+ int discard;
+
+ if (found < -1) {
+ cpio_error("Junk in compressed archive");
+ }
+
+ /* we either found EOF or TRAILER!!!. In the later
+ * case we need to discard to the end of the gzip
+ * contents.
+ */
+ do {
+ discard = gunzip_partial(stream, name_buf,
+ MAX_PATH);
+ this_archive += discard;
+ } while (discard);
+
+ /*
+ * Peek at how many input bytes were consumed.
+ * reset our consumed input.
+ */
+ total += stream->s.total_in + 8;
+
+ /* clean up zlib */
+ discard = gunzip_finish(stream, name_buf, 0);
+ } else {
+ if (this_archive % 4) {
+ cpio_error("Archive not multiple of 4?");
+ }
+ total += this_archive;
+
+ if (!this_archive) {
+ cpio_error("junk between archives");
+ }
+ /* don't check the < -1 of found, it might be an
+ * archive. This will be caught by the !this_archive
+ * check on the next loop.
+ */
+ }
+ } while (total < len);
+
+ return 0;
+}
+
+void get_cpio_info(void **archive_start, int *consumed)
+{
+ *archive_start = this_buf;
+ *consumed = this_archive;
+}
+
+int get_cpio_file_mode(void)
+{
+ return cpio_str_to_num(cpio_header_buf.mode);
+}
+
+int get_cpio_file_size(void)
+{
+ return cpio_str_to_num(cpio_header_buf.filesize);
+}
Index: kernel/arch/powerpc/boot/cpio.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/boot/cpio.h 2007-08-22 20:51:29.000000000 -0500
@@ -0,0 +1,12 @@
+#include "gunzip_util.h"
+
+extern int find_in_cpio(char *path, struct gunzip_state *stream);
+extern int find_in_initramfs(char *path, char *buf, int len,
+ struct gunzip_state *state);
+extern void get_cpio_info(void **archive_start, int *consumed);
+extern int get_cpio_file_size(void);
+extern int get_cpio_file_mode(void);
+
+#define MAX_PATH 256
+
+extern void cpio_error(char *msg);
Index: kernel/arch/powerpc/boot/Makefile
===================================================================
--- kernel.orig/arch/powerpc/boot/Makefile 2007-08-22 20:51:06.000000000 -0500
+++ kernel/arch/powerpc/boot/Makefile 2007-08-22 20:52:46.000000000 -0500
@@ -36,13 +36,13 @@ $(obj)/ebony.o: BOOTCFLAGS += -mcpu=440
zlib := inffast.c inflate.c inftrees.c
zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h
-zliblinuxheader := zlib.h zconf.h zutil.h
+zliblinuxheader := zlib.h zconf.h zutil.h stat.h
$(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \
$(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
- flatdevtree_conv.c marshal.c memranges.c kexec.c rtas.c \
+ flatdevtree_conv.c marshal.c memranges.c kexec.c rtas.c cpio.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 11/15] bootwrapper: allow vmlinuz to be an external payload
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
` (9 preceding siblings ...)
2007-09-21 23:05 ` [PATCH 10/15] bootwrapper: add cpio file extraction library Milton Miller
@ 2007-09-21 23:06 ` Milton Miller
2007-09-21 23:06 ` [PATCH 12/15] bootwrapper: kexec extract vmlinux from initramfs Milton Miller
` (5 subsequent siblings)
16 siblings, 0 replies; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:06 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
Allow the boot wrapper to obtain the vmlinux elf from an external
platform supplied location instead of embedding it at link time.
When used with the cpio library, the kernel can be stored as a file in
the initramfs, allowing the same (compressed) copy of the vmlinux elf
to be used for both the kernel to execute and any user space tools such
as kexec (for reboot), crash dump, or oprofile.
Another use would be to uncompress directly from a memory mapped
region such as a flash partition.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
vs 12178, just fuzz.
The source and source len variables are passed to the routine
only to allow them to be printed later.
The gunzip_state is passed to allow a platform to find the
elf stream in an arbitrary container (cpio, ar, etc) without
decompressing leading data twice.
I also used this hook for qemu, where the "rom" contains the
wrapper code and device tree blob, but the kernel is loaded
into ram via the -kernel flag (allowing a raw vmlinux elf).
Index: kernel/arch/powerpc/boot/main.c
===================================================================
--- kernel.orig/arch/powerpc/boot/main.c 2007-09-20 17:00:15.000000000 -0500
+++ kernel/arch/powerpc/boot/main.c 2007-09-20 17:49:10.000000000 -0500
@@ -37,10 +37,19 @@ static struct addr_range prep_kernel(voi
struct elf_info ei;
int len;
- /* gunzip the ELF header of the kernel */
- gunzip_start(&gzstate, vmlinuz_addr, vmlinuz_size);
- gunzip_exactly(&gzstate, elfheader, sizeof(elfheader));
+ /* Initialze zlib. Any attached kernel overrides find_vmlinuz */
+ if (vmlinuz_size)
+ gunzip_start(&gzstate, vmlinuz_addr, vmlinuz_size);
+ else
+ if (platform_ops.find_vmlinuz)
+ platform_ops.find_vmlinuz(&gzstate, &vmlinuz_addr,
+ &vmlinuz_size);
+ else
+ fatal("Can't find a kernel to boot: no attached "
+ "vmlinuz and no find_vmlinuz method\n\r");
+ /* gunzip and parse the ELF header of the kernel */
+ gunzip_exactly(&gzstate, elfheader, sizeof(elfheader));
if (!parse_elf64(elfheader, &ei) && !parse_elf32(elfheader, &ei))
fatal("Error: not a valid PPC32 or PPC64 ELF file!\n\r");
Index: kernel/arch/powerpc/boot/ops.h
===================================================================
--- kernel.orig/arch/powerpc/boot/ops.h 2007-09-20 17:49:08.000000000 -0500
+++ kernel/arch/powerpc/boot/ops.h 2007-09-20 17:49:10.000000000 -0500
@@ -24,6 +24,8 @@ typedef void (*kernel_entry_t)(unsigned
struct boot_param_header;
+struct gunzip_state;
+
/* Platform specific operations */
struct platform_ops {
void (*fixups)(void);
@@ -33,6 +35,8 @@ struct platform_ops {
void * (*realloc)(void *ptr, unsigned long size);
void (*exit)(void);
void * (*vmlinux_alloc)(unsigned long size);
+ void (*find_vmlinuz)(struct gunzip_state *, void **srcp,
+ unsigned long *lenp);
};
extern struct platform_ops platform_ops;
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 12/15] bootwrapper: kexec extract vmlinux from initramfs
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
` (10 preceding siblings ...)
2007-09-21 23:06 ` [PATCH 11/15] bootwrapper: allow vmlinuz to be an external payload Milton Miller
@ 2007-09-21 23:06 ` Milton Miller
2007-09-21 23:06 ` [PATCH 13/15] bootwrapper: attach an empty vmlinux Milton Miller
` (4 subsequent siblings)
16 siblings, 0 replies; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:06 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
Teach the kexec platform to find the vmlinux from the initramfs.
The implementation searches the initramfs for a path specified
by the property linux,kernel-path in chosen.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
vs 12179
change property from boot-file to linux,kernel-path
context diffs
Index: kernel/arch/powerpc/boot/kexec.c
===================================================================
--- kernel.orig/arch/powerpc/boot/kexec.c 2007-09-20 17:49:08.000000000 -0500
+++ kernel/arch/powerpc/boot/kexec.c 2007-09-20 17:49:13.000000000 -0500
@@ -23,6 +23,8 @@
#include "flatdevtree.h"
#include "page.h"
#include "types.h"
+#include "cpio.h"
+#include "stat.h"
extern char _start[];
extern char _end[];
@@ -41,6 +43,51 @@ static void find_console_from_tree(void)
}
}
+void find_vmlinux_in_initramfs(struct gunzip_state *state,
+ void **srcp, unsigned long *lenp)
+{
+ void *devp;
+ int rc;
+ char path[MAX_PATH];
+
+ if (!loader_info.initrd_size)
+ dt_find_initrd();
+ if (!loader_info.initrd_size)
+ fatal("find_vmlinux: no initramfs");
+ devp = finddevice("/chosen");
+ if (!devp)
+ fatal("find_vmlinux: no /chosen to find vmlinux");
+ rc = getprop(devp, "linux,kernel-path", path, sizeof(path));
+ if (rc < 0)
+ fatal("find_vmlinux: no linux,kernel-path property in /chosen")
+ else if (rc == 0 || rc > MAX_PATH)
+ fatal("linux,kernel-path too long in /chosen")
+
+ rc = find_in_initramfs(path, (void *)loader_info.initrd_addr,
+ loader_info.initrd_size, state);
+ if (!rc)
+ fatal("find_vmlinux: couldn't find linux,kernel-path %s"
+ " in initramfs", path);
+
+ rc = get_cpio_file_mode();
+ if (!S_ISREG(rc))
+ fatal("find_vmlinux: linux,kernel-path %s is not"
+ " a regular file", path)
+
+ get_cpio_info(srcp, &rc);
+ *lenp = get_cpio_file_size();
+}
+
+void cpio_error(char *msg)
+{
+ void *srcp;
+ int read;
+
+ get_cpio_info(&srcp, &read);
+
+ fatal("cpio_error at %p + 0x%x(%d): %s", srcp, read, read, msg);
+}
+
/**
* setup_initial_heap - setup a small heap in the bss
* Using a preallocated heap, setup for scanning the device tree.
@@ -119,6 +166,7 @@ void kexec_platform_init(struct boot_par
/* now that we have a malloc region, start over from the flat tree */
init_flat_tree(dt_blob);
+ platform_ops.find_vmlinuz = find_vmlinux_in_initramfs;
platform_ops.vmlinux_alloc = kexec_vmlinux_alloc;
platform_ops.fixups = kexec_fixups;
finalize_chain = dt_ops.finalize;
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 13/15] bootwrapper: attach an empty vmlinux
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
` (11 preceding siblings ...)
2007-09-21 23:06 ` [PATCH 12/15] bootwrapper: kexec extract vmlinux from initramfs Milton Miller
@ 2007-09-21 23:06 ` Milton Miller
2007-09-24 4:03 ` David Gibson
2007-09-21 23:08 ` [PATCH 14/15] boot: add a hook to start cpus Milton Miller
` (3 subsequent siblings)
16 siblings, 1 reply; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:06 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
Allow the boot wrapper code to be linked without an attached vmlinux.
Rather than invent a new syntax to invoke the wrapper, attach the
stripped version of empty.o, which produces the same result.
This new intermediary is called zBoot.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
vs 12180
context diffs, identical content
Iniital attempts to remove the dependency on vmlinux in the arch Makefile
have lead to multiple make commands competeing in the boot directory and
destroying each other. Until the make rules are fixed, the full kenrel
must be built.
There are parallel make conflicts when specifying a dts file to be
compiled into the binary unaffected by this patch, except one may
choose more targets showing the problems..
Index: kernel/arch/powerpc/boot/Makefile
===================================================================
--- kernel.orig/arch/powerpc/boot/Makefile 2007-09-17 22:11:51.000000000 -0500
+++ kernel/arch/powerpc/boot/Makefile 2007-09-17 22:12:05.000000000 -0500
@@ -126,7 +126,8 @@ endif
# args (to if_changed): 1 = (this rule), 2 = platform, 3 = dts 4=dtb 5=initrd
quiet_cmd_wrap = WRAP $@
cmd_wrap =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \
- $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) vmlinux
+ $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) \
+ $(if $6,$6,vmlinux)
kexec-$(CONFIG_PPC32) += zImage.kexec
kexec-$(CONFIG_PPC64) += zImage.kexec64
@@ -144,6 +145,7 @@ image-$(CONFIG_PPC_PRPMC2800) += zImage
image-$(CONFIG_PPC_ISERIES) += zImage.iseries
image-$(CONFIG_DEFAULT_UIMAGE) += uImage
image-$(CONFIG_KEXEC) += $(kexec-y)
+image-$(CONFIG_KEXEC) += $(patsubst zImage%,zBoot%,$(kexec-y))
ifneq ($(CONFIG_DEVICE_TREE),"")
image-$(CONFIG_PPC_8xx) += cuImage.8xx
@@ -197,6 +199,9 @@ $(obj)/vmlinux.strip: vmlinux
$(obj)/zImage.iseries: vmlinux
$(STRIP) -s -R .comment $< -o $@
+$(obj)/zBoot.%: $(wrapperbits) $(dts)
+ $(call if_changed,wrap,$*,$(dts),,,$(obj)/empty.o)
+
$(obj)/zImage.ps3: vmlinux $(wrapper) $(wrapperbits) $(srctree)/$(src)/dts/ps3.dts
$(STRIP) -s -R .comment $< -o vmlinux.strip
$(call cmd,wrap,ps3,$(srctree)/$(src)/dts/ps3.dts,,)
@@ -234,7 +239,7 @@ clean-files += $(image-) $(initrd-) zIma
otheros.bld $(kexec-)
# clean up files cached by wrapper
-clean-kernel := vmlinux.strip vmlinux.bin
+clean-kernel := vmlinux.strip vmlinux.bin empty.o.bin
clean-kernel += $(addsuffix .gz,$(clean-kernel))
# If not absolute clean-files are relative to $(obj).
clean-files += $(addprefix $(objtree)/, $(clean-kernel))
Index: kernel/arch/powerpc/boot/wrapper
===================================================================
--- kernel.orig/arch/powerpc/boot/wrapper 2007-09-17 22:11:51.000000000 -0500
+++ kernel/arch/powerpc/boot/wrapper 2007-09-17 22:12:05.000000000 -0500
@@ -161,6 +161,13 @@ ps3)
;;
esac
+if [ "$kernel" = $object/empty.o ] ; then
+ ext=bin
+ objflags="-O binary"
+ gzip=
+fi
+
+
vmz="$tmpdir/`basename \"$kernel\"`.$ext"
if [ -z "$cacheit" -o ! -f "$vmz$gzip" -o "$vmz$gzip" -ot "$kernel" ]; then
${CROSS}objcopy $objflags "$kernel" "$vmz.$$"
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 13/15] bootwrapper: attach an empty vmlinux
2007-09-21 23:06 ` [PATCH 13/15] bootwrapper: attach an empty vmlinux Milton Miller
@ 2007-09-24 4:03 ` David Gibson
0 siblings, 0 replies; 55+ messages in thread
From: David Gibson @ 2007-09-24 4:03 UTC (permalink / raw)
To: Milton Miller; +Cc: linuxppc-dev, Paul Mackerras, Rob Landley
On Fri, Sep 21, 2007 at 06:06:38PM -0500, Milton Miller wrote:
> Allow the boot wrapper code to be linked without an attached vmlinux.
>
> Rather than invent a new syntax to invoke the wrapper, attach the
> stripped version of empty.o, which produces the same result.
Aiee. Please don't do that. Add a new wrapper option so the vmlinux
is optional instead.
Particularly since...
> Index: kernel/arch/powerpc/boot/wrapper
> ===================================================================
> --- kernel.orig/arch/powerpc/boot/wrapper 2007-09-17 22:11:51.000000000 -0500
> +++ kernel/arch/powerpc/boot/wrapper 2007-09-17 22:12:05.000000000 -0500
> @@ -161,6 +161,13 @@ ps3)
> ;;
> esac
>
> +if [ "$kernel" = $object/empty.o ] ; then
> + ext=bin
> + objflags="-O binary"
> + gzip=
> +fi
Making the vmlinux empty.o *isn't* just a matter of doing that but
also has other side effects as above.
--
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
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 14/15] boot: add a hook to start cpus
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
` (12 preceding siblings ...)
2007-09-21 23:06 ` [PATCH 13/15] bootwrapper: attach an empty vmlinux Milton Miller
@ 2007-09-21 23:08 ` Milton Miller
2007-09-21 23:08 ` [PATCH 15/15] bootwrapper: recheck for command line after fixups Milton Miller
` (2 subsequent siblings)
16 siblings, 0 replies; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:08 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
The kexec code is doing strange contortions with dtops.finalize and
platform_ops.vmlinux_alloc to manage the slave cpus. Add a hook
with the needed information.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
vs 12181
rediff fuzz.
Index: kernel/arch/powerpc/boot/kexec.c
===================================================================
--- kernel.orig/arch/powerpc/boot/kexec.c 2007-09-20 17:49:13.000000000 -0500
+++ kernel/arch/powerpc/boot/kexec.c 2007-09-20 17:49:19.000000000 -0500
@@ -117,32 +117,11 @@ static void init_flat_tree(struct boot_p
fatal("Unable to initialize device_tree library!\n\r");
}
-static void *saved_vmlinux_addr;
-
-static void *kexec_vmlinux_alloc(unsigned long size)
-{
- void *addr;
-
- addr = ranges_vmlinux_alloc(size);
-
- saved_vmlinux_addr = addr;
- return addr;
-}
-
static void kexec_fixups(void)
{
wait_slaves_moved();
}
-static unsigned long (*finalize_chain)(void);
-
-static unsigned long kexec_finalize(void)
-{
- send_slaves_to_kernel(saved_vmlinux_addr);
-
- return finalize_chain();
-}
-
void kexec_platform_init(struct boot_param_header *dt_blob)
{
slaves_are_low();
@@ -167,8 +146,7 @@ void kexec_platform_init(struct boot_par
init_flat_tree(dt_blob);
platform_ops.find_vmlinuz = find_vmlinux_in_initramfs;
- platform_ops.vmlinux_alloc = kexec_vmlinux_alloc;
+ platform_ops.vmlinux_alloc = ranges_vmlinux_alloc;
platform_ops.fixups = kexec_fixups;
- finalize_chain = dt_ops.finalize;
- dt_ops.finalize = kexec_finalize;
+ platform_ops.start_smp = send_slaves_to_kernel;
}
Index: kernel/arch/powerpc/boot/main.c
===================================================================
--- kernel.orig/arch/powerpc/boot/main.c 2007-09-20 17:49:10.000000000 -0500
+++ kernel/arch/powerpc/boot/main.c 2007-09-20 17:49:19.000000000 -0500
@@ -202,6 +202,9 @@ void start(void)
else
printf(" using OF tree (promptr=%p)\n\r", loader_info.promptr);
+ if (platform_ops.start_smp)
+ platform_ops.start_smp(vmlinux.addr);
+
if (console_ops.close)
console_ops.close();
Index: kernel/arch/powerpc/boot/ops.h
===================================================================
--- kernel.orig/arch/powerpc/boot/ops.h 2007-09-20 17:49:10.000000000 -0500
+++ kernel/arch/powerpc/boot/ops.h 2007-09-20 17:49:19.000000000 -0500
@@ -35,6 +35,7 @@ struct platform_ops {
void * (*realloc)(void *ptr, unsigned long size);
void (*exit)(void);
void * (*vmlinux_alloc)(unsigned long size);
+ void (*start_smp)(void *vmlinux);
void (*find_vmlinuz)(struct gunzip_state *, void **srcp,
unsigned long *lenp);
};
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 15/15] bootwrapper: recheck for command line after fixups
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
` (13 preceding siblings ...)
2007-09-21 23:08 ` [PATCH 14/15] boot: add a hook to start cpus Milton Miller
@ 2007-09-21 23:08 ` Milton Miller
2007-09-21 23:08 ` [PATCH 1/2] qemu platform, v2 Milton Miller
2007-09-21 23:08 ` [PATCH 2/2] qemu platform rom, v2 Milton Miller
16 siblings, 0 replies; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:08 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
After the fixups hook has run, if we still have not set a command line,
check to see if fixups pointed us to one.
Running as a part of fixup allows device tree interaction and error
messages to be displayed.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
The code in main presently checks for the platform providing commandline
information before calling the console open or platform fixups "in case
the command line data is not safe from overwrite by malloc".
If malloc can overwrite the command line then how do we know flat tree
initialization or console search has not already overwritten it? And why
would the same argument not apply to the initrd?
If a platform can't adjust malloc to keep the loader supplied command line
safe, then it could copy the loader command line to a buffer in bss.
Regardless, this is safe as we will stop once the command line contains
any information. My current qemu patch relies on this.
Index: kernel/arch/powerpc/boot/main.c
===================================================================
--- kernel.orig/arch/powerpc/boot/main.c 2007-09-19 02:21:18.000000000 -0500
+++ kernel/arch/powerpc/boot/main.c 2007-09-19 02:21:18.000000000 -0500
@@ -181,6 +181,11 @@ void start(void)
if (platform_ops.fixups)
platform_ops.fixups();
+ /* check again, in case fixups told us about it */
+ if ((loader_info.cmdline_len > 0) && (cmdline[0] == '\0'))
+ memmove(cmdline, loader_info.cmdline,
+ min(loader_info.cmdline_len, COMMAND_LINE_SIZE-1));
+
printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r",
_start, get_sp());
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 1/2] qemu platform, v2
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
` (14 preceding siblings ...)
2007-09-21 23:08 ` [PATCH 15/15] bootwrapper: recheck for command line after fixups Milton Miller
@ 2007-09-21 23:08 ` Milton Miller
2007-09-22 9:55 ` Christoph Hellwig
2007-09-21 23:08 ` [PATCH 2/2] qemu platform rom, v2 Milton Miller
16 siblings, 1 reply; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:08 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
Here is the second rev of patches to boot a arch powerpc kernel on
qemu with the prep architecture.
The goal is to provide an environment for use with the existing qemu
hardware suppplied hardware, as oposed to changing the qemu
machine description.
This patch contains only the kernel portion. While the diff was
generated against for-2.6.24, this first patch applies cleanly
to 2.6.23-rc7. With the rom image created in the next patch,
a kernel built by this patch should boot when using qemu -kernel.
I debated putting this in the embedded6xx tree, especially when I
discovered that the bridge is suposedly a '105, but saw no advantage
in the end.
pci config space is now working, however cirrusfb causes crashes
and ohci times out, so at least pci memory is likely still broken.
ide and serial work, floppy and parallel are untested.
I added a defconfig based on chrp32; hardware options still need
tweaking (eg isa ne2k).
Index: kernel/arch/powerpc/platforms/Kconfig
===================================================================
--- kernel.orig/arch/powerpc/platforms/Kconfig 2007-09-19 02:32:54.000000000 -0500
+++ kernel/arch/powerpc/platforms/Kconfig 2007-09-19 02:41:00.000000000 -0500
@@ -47,6 +47,7 @@ source "arch/powerpc/platforms/chrp/Kcon
source "arch/powerpc/platforms/52xx/Kconfig"
source "arch/powerpc/platforms/powermac/Kconfig"
source "arch/powerpc/platforms/prep/Kconfig"
+source "arch/powerpc/platforms/qemu/Kconfig"
source "arch/powerpc/platforms/maple/Kconfig"
source "arch/powerpc/platforms/pasemi/Kconfig"
source "arch/powerpc/platforms/celleb/Kconfig"
Index: kernel/arch/powerpc/platforms/qemu/Kconfig
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/platforms/qemu/Kconfig 2007-09-20 14:12:57.000000000 -0500
@@ -0,0 +1,10 @@
+config PPC_QEMU
+ bool "QEMU emulated PowerPC Reference Platform (PReP) system"
+ depends on PPC_MULTIPLATFORM && PPC32
+ select PPC_I8259
+ select PPC_INDIRECT_PCI
+ select PPC_UDBG_16550
+ select PPC_NATIVE
+ select WANT_DEVICE_TREE
+ default n
+
Index: kernel/arch/powerpc/platforms/qemu/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/platforms/qemu/Makefile 2007-09-19 02:41:00.000000000 -0500
@@ -0,0 +1,2 @@
+obj-y += setup.o
+obj-$(CONFIG_PCI) += pci.o
Index: kernel/arch/powerpc/platforms/qemu/pci.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/platforms/qemu/pci.c 2007-09-19 02:56:36.000000000 -0500
@@ -0,0 +1,133 @@
+/*
+ * prep Port to arch/powerpc:
+ * Copyright 2007 David Gibson, IBM Corporation.
+ *
+ * prep Port to qemu:
+ * Copyright 2007 Milton Miller, IBM Corporation.
+ *
+ * Based on OpenHackware 0.4
+ * Copyright (c) 2004-2005 Jocelyn Mayer
+ *
+ * pci config based on arch/powerpc/platforms/chrp/pci.c GoldenGate code
+ *
+ */
+
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/udbg.h>
+
+static volatile void __iomem *qemu_config_addr(struct pci_bus *bus,
+ unsigned int devfn, int off)
+{
+ int dev, fn;
+ struct pci_controller *hose = bus->sysdata;
+
+ if (!hose->cfg_data)
+ return NULL;
+
+ if (bus->number != 0)
+ return NULL;
+
+ dev = devfn >> 3;
+ fn = devfn & 7;
+
+ if (dev < 11 || dev > 21)
+ return NULL;
+
+ return hose->cfg_data + ((1 << dev) | (fn << 8) | off);
+}
+
+int qemu_read_config(struct pci_bus *bus, unsigned int devfn, int off,
+ int len, u32 *val)
+{
+ volatile void __iomem *cfg_data = qemu_config_addr(bus, devfn, off);
+
+ if (cfg_data == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ /*
+ * Note: the caller has already checked that off is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ switch (len) {
+ case 1:
+ *val = in_8(cfg_data);
+ break;
+ case 2:
+ *val = in_le16(cfg_data);
+ break;
+ default:
+ *val = in_le32(cfg_data);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int qemu_write_config(struct pci_bus *bus, unsigned int devfn, int off,
+ int len, u32 val)
+{
+ volatile void __iomem *cfg_data = qemu_config_addr(bus, devfn, off);
+
+ if (cfg_data == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ /*
+ * Note: the caller has already checked that off is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ switch (len) {
+ case 1:
+ out_8(cfg_data, val);
+ break;
+ case 2:
+ out_le16(cfg_data, val);
+ break;
+ default:
+ out_le32(cfg_data, val);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops qemu_pci_ops =
+{
+ qemu_read_config,
+ qemu_write_config
+};
+
+void __init qemu_find_bridges(void)
+{
+ struct device_node *phb;
+ struct pci_controller *hose;
+
+ phb = of_find_node_by_type(NULL, "pci");
+ if (!phb) {
+ printk(KERN_ERR "PReP: Cannot find PCI bridge OF node\n");
+ return;
+ }
+
+ hose = pcibios_alloc_controller(phb);
+ if (!hose)
+ return;
+
+ pci_process_bridge_OF_ranges(hose, phb, 1);
+
+#define PREP_PCI_DRAM_OFFSET 0x80000000
+
+ pci_dram_offset = PREP_PCI_DRAM_OFFSET;
+ ISA_DMA_THRESHOLD = 0x00ffffff;
+ DMA_MODE_READ = 0x44;
+ DMA_MODE_WRITE = 0x48;
+
+ hose->cfg_data = ioremap(0x80800000, 1 << 22);
+
+ hose->ops = &qemu_pci_ops;
+
+ udbg_init_uart(hose->io_base_virt + 0x3f8, 0, 0);
+ register_early_udbg_console();
+ printk(KERN_INFO "qemu_find_bridges: config at %p\n", hose->cfg_data);
+}
+
Index: kernel/arch/powerpc/platforms/qemu/setup.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/platforms/qemu/setup.c 2007-09-19 02:41:00.000000000 -0500
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 1995 Linus Torvalds
+ * Adapted from 'alpha' version by Gary Thomas
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
+ *
+ * Support for PReP (Motorola MTX/MVME)
+ * by Troy Benjegerdes (hozer@drgw.net)
+ *
+ * Port to arch/powerpc:
+ * Copyright 2007 David Gibson, IBM Corporation.
+ *
+ * Port to qemu:
+ * Copyright 2007 Milton Miller, IBM Corporation.
+ *
+ * Some information based on OpenHackware 0.4
+ * Copyright (c) 2004-2005 Jocelyn Mayer
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/seq_file.h>
+#include <linux/initrd.h>
+#include <linux/ide.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+/* #include <asm/mpic.h> */
+#include <asm/i8259.h>
+#include <asm/time.h>
+#include <asm/udbg.h>
+
+static const char *qemu_model = "(unknown)";
+
+extern void qemu_find_bridges(void);
+
+/* cpuinfo code common to all IBM PReP */
+static void qemu_ibm_cpuinfo(struct seq_file *m)
+{
+ seq_printf(m, "machine\t\t: PReP %s\n", qemu_model);
+}
+
+#define NVRAM_AS0 0x74
+#define NVRAM_AS1 0x75
+#define NVRAM_DAT 0x77
+
+static unsigned char qemu_nvram_read_val(int addr)
+{
+ outb(NVRAM_AS0, addr & 0xff);
+ outb(NVRAM_AS1, (addr >> 8) & 0xff);
+ return inb(NVRAM_DAT);
+}
+
+
+static void qemu_nvram_write_val(int addr, unsigned char val)
+{
+ outb(NVRAM_AS0, addr & 0xff);
+ outb(NVRAM_AS1, (addr >> 8) & 0xff);
+ outb(NVRAM_DAT, val);
+}
+
+
+static void __init qemu_setup_arch(void)
+{
+ struct device_node *root;
+ const char *model;
+
+ root = of_find_node_by_path("/");
+ model = of_get_property(root, "model", NULL);
+ of_node_put(root);
+ if (model)
+ qemu_model = model;
+
+ /* Lookup PCI host bridges */
+ qemu_find_bridges();
+
+ /* Read in NVRAM data */
+/* init_qemu_nvram(); */
+}
+
+static void __init qemu_init_IRQ(void)
+{
+ struct device_node *pic = NULL;
+ unsigned long int_ack = 0;
+
+ pic = of_find_node_by_type(NULL, "i8259");
+ if (!pic) {
+ printk(KERN_ERR "No interrupt controller found!\n");
+ return;
+ }
+
+ /* polling */
+ i8259_init(pic, int_ack);
+ ppc_md.get_irq = i8259_irq;
+
+ /* set default host */
+ irq_set_default_host(i8259_get_host());
+}
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+/*
+ * IDE stuff.
+ */
+static int qemu_ide_default_irq(unsigned long base)
+{
+ switch (base) {
+ case 0x1f0: return 13;
+ case 0x170: return 13;
+ case 0x1e8: return 11;
+ case 0x168: return 10;
+ case 0xfff0: return 14; /* MCP(N)750 ide0 */
+ case 0xffe0: return 15; /* MCP(N)750 ide1 */
+ default: return 0;
+ }
+}
+
+static unsigned long qemu_ide_default_io_base(int index)
+{
+ switch (index) {
+ case 0: return 0x1f0;
+ case 1: return 0x170;
+ case 2: return 0x1e8;
+ case 3: return 0x168;
+ default:
+ return 0;
+ }
+}
+#endif
+
+#if 0
+static int __init prep_request_io(void)
+{
+#ifdef CONFIG_NVRAM
+ request_region(PREP_NVRAM_AS0, 0x8, "nvram");
+#endif
+ request_region(0x00,0x20,"dma1");
+ request_region(0x40,0x20,"timer");
+ request_region(0x80,0x10,"dma page reg");
+ request_region(0xc0,0x20,"dma2");
+
+ return 0;
+}
+device_initcall(prep_request_io);
+#endif
+
+
+static int __init qemu_probe(void)
+{
+ if (!of_flat_dt_is_compatible(of_get_flat_dt_root(), "qemu-prep"))
+ return 0;
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+ ppc_ide_md.default_irq = qemu_ide_default_irq;
+ ppc_ide_md.default_io_base = qemu_ide_default_io_base;
+#endif
+
+ return 1;
+}
+
+define_machine(qemu) {
+ .name = "QEMU",
+ .probe = qemu_probe,
+ .setup_arch = qemu_setup_arch,
+ .progress = udbg_progress,
+ .show_cpuinfo = qemu_ibm_cpuinfo,
+ .init_IRQ = qemu_init_IRQ,
+/* .pcibios_fixup = qemu_pcibios_fixup, */
+/* .restart = qemu_restart, */
+/* .power_off = qemu_halt, */
+/* .halt = qemu_halt, */
+/* .time_init = todc_time_init, */
+/* .set_rtc_time = todc_set_rtc_time, */
+/* .get_rtc_time = todc_get_rtc_time, */
+ .calibrate_decr = generic_calibrate_decr,
+ .nvram_read_val = qemu_nvram_read_val,
+ .nvram_write_val = qemu_nvram_write_val,
+ .phys_mem_access_prot = pci_phys_mem_access_prot,
+};
Index: kernel/arch/powerpc/platforms/Makefile
===================================================================
--- kernel.orig/arch/powerpc/platforms/Makefile 2007-09-19 02:32:54.000000000 -0500
+++ kernel/arch/powerpc/platforms/Makefile 2007-09-19 02:41:00.000000000 -0500
@@ -17,6 +17,7 @@ obj-$(CONFIG_PPC_82xx) += 82xx/
obj-$(CONFIG_PPC_83xx) += 83xx/
obj-$(CONFIG_PPC_85xx) += 85xx/
obj-$(CONFIG_PPC_86xx) += 86xx/
+obj-$(CONFIG_PPC_QEMU) += qemu/
obj-$(CONFIG_PPC_PSERIES) += pseries/
obj-$(CONFIG_PPC_ISERIES) += iseries/
obj-$(CONFIG_PPC_MAPLE) += maple/
Index: kernel/arch/powerpc/configs/qemu_defconfig
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/configs/qemu_defconfig 2007-09-19 02:41:00.000000000 -0500
@@ -0,0 +1,1217 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.23-rc6
+# Tue Sep 18 15:18:32 2007
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_PPC_FPU=y
+# CONFIG_ALTIVEC is not set
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# Platform support
+#
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_EMBEDDED6xx is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_EFIKA is not set
+# CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_PMAC is not set
+CONFIG_PPC_QEMU=y
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+CONFIG_PPC_NATIVE=y
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+CONFIG_PPC_I8259=y
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+# CONFIG_CPM2 is not set
+# CONFIG_FSL_ULI1575 is not set
+
+#
+# Kernel options
+#
+CONFIG_HIGHMEM=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
+CONFIG_HIBERNATION_UP_POSSIBLE=y
+CONFIG_SECCOMP=y
+CONFIG_WANT_DEVICE_TREE=y
+CONFIG_DEVICE_TREE="qemu.dts"
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK=m
+# CONFIG_NF_CT_ACCT is not set
+# CONFIG_NF_CONNTRACK_MARK is not set
+# CONFIG_NF_CONNTRACK_EVENTS is not set
+# CONFIG_NF_CT_PROTO_SCTP is not set
+# CONFIG_NF_CT_PROTO_UDPLITE is not set
+# CONFIG_NF_CONNTRACK_AMANDA is not set
+CONFIG_NF_CONNTRACK_FTP=m
+# CONFIG_NF_CONNTRACK_H323 is not set
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+# CONFIG_NF_CONNTRACK_PPTP is not set
+# CONFIG_NF_CONNTRACK_SANE is not set
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XTABLES=m
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATE is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=m
+# CONFIG_IP_NF_MATCH_IPRANGE is not set
+# CONFIG_IP_NF_MATCH_TOS is not set
+# CONFIG_IP_NF_MATCH_RECENT is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+# CONFIG_IP_NF_MATCH_OWNER is not set
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+# CONFIG_IP_NF_TARGET_NETMAP is not set
+# CONFIG_IP_NF_TARGET_SAME is not set
+# CONFIG_NF_NAT_SNMP_BASIC is not set
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_TFTP=m
+# CONFIG_NF_NAT_AMANDA is not set
+# CONFIG_NF_NAT_PPTP is not set
+# CONFIG_NF_NAT_H323 is not set
+CONFIG_NF_NAT_SIP=m
+# CONFIG_IP_NF_MANGLE is not set
+# CONFIG_IP_NF_RAW is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+CONFIG_OF_DEVICE=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+CONFIG_BLK_DEV_FD=y
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+CONFIG_IDEPCI_PCIBUS_ORDER=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_PCNET32_NAPI is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=y
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_TSDEV=m
+CONFIG_INPUT_TSDEV_SCREEN_X=240
+CONFIG_INPUT_TSDEV_SCREEN_Y=320
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+CONFIG_INPUT_TABLET=y
+# CONFIG_TABLET_USB_ACECAD is not set
+# CONFIG_TABLET_USB_AIPTEK is not set
+# CONFIG_TABLET_USB_GTCO is not set
+# CONFIG_TABLET_USB_KBTAB is not set
+# CONFIG_TABLET_USB_WACOM is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+CONFIG_INPUT_UINPUT=y
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
+CONFIG_NVRAM=y
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_MPC is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=m
+
+#
+# Display hardware drivers
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_HCD_PPC_OF is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+# CONFIG_UCC_SLOW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+# CONFIG_KPROBES is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_DEBUGGER=y
+CONFIG_XMON=y
+CONFIG_XMON_DEFAULT=y
+CONFIG_XMON_DISASSEMBLY=y
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_HW is not set
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/2] qemu platform, v2
2007-09-21 23:08 ` [PATCH 1/2] qemu platform, v2 Milton Miller
@ 2007-09-22 9:55 ` Christoph Hellwig
2007-09-22 19:16 ` Rob Landley
2007-09-24 4:00 ` David Gibson
0 siblings, 2 replies; 55+ messages in thread
From: Christoph Hellwig @ 2007-09-22 9:55 UTC (permalink / raw)
To: Milton Miller; +Cc: linuxppc-dev, Paul Mackerras, Rob Landley, David Gibson
On Fri, Sep 21, 2007 at 06:08:31PM -0500, Milton Miller wrote:
> Here is the second rev of patches to boot a arch powerpc kernel on
> qemu with the prep architecture.
So if this is supposed to be prep why do you need additional kernel
support? And if you really needed why isn't it under platforms/prep?
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/2] qemu platform, v2
2007-09-22 9:55 ` Christoph Hellwig
@ 2007-09-22 19:16 ` Rob Landley
2007-09-23 4:27 ` Paul Mackerras
2007-09-24 4:00 ` David Gibson
1 sibling, 1 reply; 55+ messages in thread
From: Rob Landley @ 2007-09-22 19:16 UTC (permalink / raw)
To: Christoph Hellwig
Cc: linuxppc-dev, Paul Mackerras, Milton Miller, David Gibson
On Saturday 22 September 2007 4:55:46 am Christoph Hellwig wrote:
> On Fri, Sep 21, 2007 at 06:08:31PM -0500, Milton Miller wrote:
> > Here is the second rev of patches to boot a arch powerpc kernel on
> > qemu with the prep architecture.
>
> So if this is supposed to be prep why do you need additional kernel
> support? And if you really needed why isn't it under platforms/prep?
The device tree provided by qemu's open hackware violates some of the
assumptions the Linux kernel is making? (Although things like "the cpu cache
size is zero" are, technically speaking, probably correct. :)
There are three different problems here:
1) porting prep from arch=ppc to arch=powerpc so you can build it on an arch
that also supports make headers_install.
2) PowerPC uses a device tree supplied by the hardware to identify the
available hardware, even for stuff living on PCI busses which it could
theoretically probe for but doesn't.
3) The PPC firmware qemu comes with ("Open Hackware") sucks rocks, is hard to
modify, isn't quite being maintained. As mentioned above, the device tree it
passes in (including "prep residual data" from which more nodes in the device
tree can be constructed, and here my understanding goes all fuzzy) does not
make for a happy Linux kernel.
Proposed solutions to all this involve various combinations of creating a
target platform aimed directly at qemu and not pretending to be prep at all
(so it doesn't have to parse residual data), creating our own boot rom image
out of some of the wrapper code the linux kernel's already got and feeding
that to qemu instead of using open hackware at all, hard wiring a device tree
into the kernel and not looking at the one open hackware passes in...)
I'd be following this more closely if compiling a device tree didn't currently
require an external utility (dtc or some such) that doesn't come with the
Linux kernel. No other target platform I've built kernels for requires such
an environmental dependency. (This is a problem both for hardwiring the
device tree into the kernel and for building a new boot rom from the linux
kernel's ppc boot wrapper that would contain such a device tree to feed to
the kernel.)
Rob
--
"One of my most productive days was throwing away 1000 lines of code."
- Ken Thompson.
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/2] qemu platform, v2
2007-09-22 19:16 ` Rob Landley
@ 2007-09-23 4:27 ` Paul Mackerras
2007-09-23 22:01 ` Rob Landley
2007-09-28 16:53 ` Segher Boessenkool
0 siblings, 2 replies; 55+ messages in thread
From: Paul Mackerras @ 2007-09-23 4:27 UTC (permalink / raw)
To: Rob Landley; +Cc: linuxppc-dev, Christoph Hellwig, Milton Miller, David Gibson
Rob Landley writes:
Just to correct a few misconceptions:
> 2) PowerPC uses a device tree supplied by the hardware to identify the
> available hardware, even for stuff living on PCI busses which it could
> theoretically probe for but doesn't.
The device tree doesn't have to include anything that can be probed
for. On some platforms (e.g. pSeries) we choose to use the device
tree rather than probing, but on most other platforms we probe.
> I'd be following this more closely if compiling a device tree didn't currently
> require an external utility (dtc or some such) that doesn't come with the
> Linux kernel. No other target platform I've built kernels for requires such
> an environmental dependency.
No? You haven't built kernels for other platforms that have external
dependencies such as perl, gcc, make, binutils, etc.? :)
> (This is a problem both for hardwiring the
> device tree into the kernel and for building a new boot rom from the linux
> kernel's ppc boot wrapper that would contain such a device tree to feed to
> the kernel.)
It's only really been a problem for ps3 so far, since the embedded
guys don't seem to have any difficulty with installing dtc. We are
looking at what to do for ps3 and prep, and the answer may well
involve bundling dtc in the kernel source (it's not too big, around
3400 lines).
Paul.
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/2] qemu platform, v2
2007-09-23 4:27 ` Paul Mackerras
@ 2007-09-23 22:01 ` Rob Landley
2007-09-28 16:53 ` Segher Boessenkool
1 sibling, 0 replies; 55+ messages in thread
From: Rob Landley @ 2007-09-23 22:01 UTC (permalink / raw)
To: Paul Mackerras
Cc: linuxppc-dev, Christoph Hellwig, Milton Miller, David Gibson
On Saturday 22 September 2007 11:27:05 pm Paul Mackerras wrote:
> Rob Landley writes:
>
> Just to correct a few misconceptions:
> > 2) PowerPC uses a device tree supplied by the hardware to identify the
> > available hardware, even for stuff living on PCI busses which it could
> > theoretically probe for but doesn't.
>
> The device tree doesn't have to include anything that can be probed
> for. On some platforms (e.g. pSeries) we choose to use the device
> tree rather than probing, but on most other platforms we probe.
>
> > I'd be following this more closely if compiling a device tree didn't
> > currently require an external utility (dtc or some such) that doesn't
> > come with the Linux kernel. No other target platform I've built kernels
> > for requires such an environmental dependency.
>
> No? You haven't built kernels for other platforms that have external
> dependencies such as perl, gcc, make, binutils, etc.? :)
Lemme clarify.
1) All of the other platforms have the _same_ requirements. I never had to
install anything to build "for arm", "for mips", "for sparc", or
for "x86_64".
The minimal requirements are: A compiler (gcc/binutils although I'm working
on extending tcc to replace these), make, linux kernel, C library (uClibc),
busybox, and bash. That's it. You can rebuild it under itself from source
with that, on x86, x86-64, arm, mips... Presumably sparc and m68k too (still
debugging there).
2) Perl isn't needed to build any target platform I've tried. (I even sent in
some patches way back to turn a perl script into a sed script for User Mode
Linux to _make_ this the case.) Yes you need perl to build glibc, but not to
build uClibc. :)
3) What I'm pointing out is that ppc needs an external dependency none of the
other platforms I've tried need. I consider this a bug. I didn't start
using "make headers_install" until it stopped needing an external unifdef.
> > (This is a problem both for hardwiring the
> > device tree into the kernel and for building a new boot rom from the
> > linux kernel's ppc boot wrapper that would contain such a device tree to
> > feed to the kernel.)
>
> It's only really been a problem for ps3 so far, since the embedded
> guys don't seem to have any difficulty with installing dtc.
If the only target that interested me was ppc, then I'd happily install dtc
for it. But focusing on cross-platform support as I am, I notice when a
platform has different requirements from any of the others.
> We are
> looking at what to do for ps3 and prep, and the answer may well
> involve bundling dtc in the kernel source (it's not too big, around
> 3400 lines).
Sounds good to me...
> Paul.
Rob
--
"One of my most productive days was throwing away 1000 lines of code."
- Ken Thompson.
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/2] qemu platform, v2
2007-09-23 4:27 ` Paul Mackerras
2007-09-23 22:01 ` Rob Landley
@ 2007-09-28 16:53 ` Segher Boessenkool
2007-09-28 20:14 ` Rob Landley
2007-10-01 5:33 ` David Gibson
1 sibling, 2 replies; 55+ messages in thread
From: Segher Boessenkool @ 2007-09-28 16:53 UTC (permalink / raw)
To: Paul Mackerras
Cc: linuxppc-dev, David Gibson, Rob Landley, Milton Miller,
Christoph Hellwig
>> I'd be following this more closely if compiling a device tree didn't
>> currently
>> require an external utility (dtc or some such) that doesn't come with
>> the
>> Linux kernel. No other target platform I've built kernels for
>> requires such
>> an environmental dependency.
>
> No? You haven't built kernels for other platforms that have external
> dependencies such as perl, gcc, make, binutils, etc.? :)
Two of the supported Linux archs cannot be built with a mainline
compiler, even!
And I have to install GNU sed/awk to get builds to work, too.
OTOH, it would be nice if we didn't need DTC -- it itself doesn't
build out-of-the-box on all systems, either ;-)
>> (This is a problem both for hardwiring the
>> device tree into the kernel and for building a new boot rom from the
>> linux
>> kernel's ppc boot wrapper that would contain such a device tree to
>> feed to
>> the kernel.)
>
> It's only really been a problem for ps3 so far, since the embedded
> guys don't seem to have any difficulty with installing dtc. We are
> looking at what to do for ps3 and prep, and the answer may well
> involve bundling dtc in the kernel source (it's not too big, around
> 3400 lines).
If only a few platforms have this problem, we could instead include
their .dtb files in the kernel source tree.
Segher
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/2] qemu platform, v2
2007-09-28 16:53 ` Segher Boessenkool
@ 2007-09-28 20:14 ` Rob Landley
2007-10-01 5:33 ` David Gibson
1 sibling, 0 replies; 55+ messages in thread
From: Rob Landley @ 2007-09-28 20:14 UTC (permalink / raw)
To: Segher Boessenkool
Cc: linuxppc-dev, Paul Mackerras, Christoph Hellwig, Milton Miller,
David Gibson
On Friday 28 September 2007 11:53:28 am Segher Boessenkool wrote:
> >> I'd be following this more closely if compiling a device tree didn't
> >> currently
> >> require an external utility (dtc or some such) that doesn't come with
> >> the
> >> Linux kernel. No other target platform I've built kernels for
> >> requires such
> >> an environmental dependency.
> >
> > No? You haven't built kernels for other platforms that have external
> > dependencies such as perl, gcc, make, binutils, etc.? :)
>
> Two of the supported Linux archs cannot be built with a mainline
> compiler, even!
Strange definition of "supported"...
> And I have to install GNU sed/awk to get builds to work, too.
I extended busybox sed until it built everything I threw at it. (I even added
a "lie to autoconf" step that replies to --version to say "This is not gnu
sed 4.0" so a regex in autoconf doesn't do something stupid.)
That's how I got into busybox development in the first place...
> OTOH, it would be nice if we didn't need DTC -- it itself doesn't
> build out-of-the-box on all systems, either ;-)
I've built x86, x86-64, mips, arm, and sparc. None of them needed anything
but the seven packages I mentioned. I'm poking at adding m68k, alpha, bfin,
and powerpc, but my free time's been spoken for recently. (I'll become
interested in sh or parisc when qemu grows support for it. I'm only
interested in bfin because I was given some free blackfin hardware at OLS.)
I've even poked at running s390 under Hercules but the setup was insane enough
to throw it way the heck down on my todo list. (Step 1: download and
configure an IBM operating system image from the 1970's... Oh yeah, fills me
with enthusiasm...)
> >> (This is a problem both for hardwiring the
> >> device tree into the kernel and for building a new boot rom from the
> >> linux
> >> kernel's ppc boot wrapper that would contain such a device tree to
> >> feed to
> >> the kernel.)
> >
> > It's only really been a problem for ps3 so far, since the embedded
> > guys don't seem to have any difficulty with installing dtc. We are
> > looking at what to do for ps3 and prep, and the answer may well
> > involve bundling dtc in the kernel source (it's not too big, around
> > 3400 lines).
>
> If only a few platforms have this problem, we could instead include
> their .dtb files in the kernel source tree.
I've had it clarified that the recent qemu-ppc patches from Milton only
require dtc to build the ROM image to boot qemu with. The Linux kernel image
you build hasn't got a device tree in it (although that means it needs one
passed in from the rom image)...
Using some other patches that floated by, I did build a prep kernel a couple
of weeks ago, which qemu happily handed control off to... which then failed
to boot because it couldn't parse the incomplete residual data left over from
open hackware. The solution the ppc list recommended? Hardwire a device
tree into said linux kernel using dtc...
>
> Segher
Rob
--
"One of my most productive days was throwing away 1000 lines of code."
- Ken Thompson.
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/2] qemu platform, v2
2007-09-28 16:53 ` Segher Boessenkool
2007-09-28 20:14 ` Rob Landley
@ 2007-10-01 5:33 ` David Gibson
2007-10-17 20:28 ` Grant Likely
1 sibling, 1 reply; 55+ messages in thread
From: David Gibson @ 2007-10-01 5:33 UTC (permalink / raw)
To: Segher Boessenkool
Cc: linuxppc-dev, Paul Mackerras, Milton Miller, Rob Landley,
Christoph Hellwig
On Fri, Sep 28, 2007 at 06:53:28PM +0200, Segher Boessenkool wrote:
> >> I'd be following this more closely if compiling a device tree didn't
> >> currently
> >> require an external utility (dtc or some such) that doesn't come with
> >> the
> >> Linux kernel. No other target platform I've built kernels for
> >> requires such
> >> an environmental dependency.
> >
> > No? You haven't built kernels for other platforms that have external
> > dependencies such as perl, gcc, make, binutils, etc.? :)
>
> Two of the supported Linux archs cannot be built with a mainline
> compiler, even!
>
> And I have to install GNU sed/awk to get builds to work, too.
>
> OTOH, it would be nice if we didn't need DTC -- it itself doesn't
> build out-of-the-box on all systems, either ;-)
>
> >> (This is a problem both for hardwiring the
> >> device tree into the kernel and for building a new boot rom from the
> >> linux
> >> kernel's ppc boot wrapper that would contain such a device tree to
> >> feed to
> >> the kernel.)
> >
> > It's only really been a problem for ps3 so far, since the embedded
> > guys don't seem to have any difficulty with installing dtc. We are
> > looking at what to do for ps3 and prep, and the answer may well
> > involve bundling dtc in the kernel source (it's not too big, around
> > 3400 lines).
>
> If only a few platforms have this problem, we could instead include
> their .dtb files in the kernel source tree.
Including .dtbs in the kernel tree has a big practical problem:
they're binary, so can't be patch(1)ed, which makes updating them a
complete PITA.
I'm working on merging dtc into the kernel tree instead.
--
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
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/2] qemu platform, v2
2007-10-01 5:33 ` David Gibson
@ 2007-10-17 20:28 ` Grant Likely
2007-10-17 23:09 ` Rob Landley
2007-10-18 9:59 ` Matt Sealey
0 siblings, 2 replies; 55+ messages in thread
From: Grant Likely @ 2007-10-17 20:28 UTC (permalink / raw)
To: Segher Boessenkool, Paul Mackerras, linuxppc-dev, Rob Landley,
Milton Miller, Christoph Hellwig
On 9/30/07, David Gibson <david@gibson.dropbear.id.au> wrote:
> On Fri, Sep 28, 2007 at 06:53:28PM +0200, Segher Boessenkool wrote:
> > >> I'd be following this more closely if compiling a device tree didn't
> > >> currently
> > >> require an external utility (dtc or some such) that doesn't come with
> > >> the
> > >> Linux kernel. No other target platform I've built kernels for
> > >> requires such
> > >> an environmental dependency.
> > >
> > > No? You haven't built kernels for other platforms that have external
> > > dependencies such as perl, gcc, make, binutils, etc.? :)
> >
> > Two of the supported Linux archs cannot be built with a mainline
> > compiler, even!
> >
> > And I have to install GNU sed/awk to get builds to work, too.
> >
> > OTOH, it would be nice if we didn't need DTC -- it itself doesn't
> > build out-of-the-box on all systems, either ;-)
> >
> > >> (This is a problem both for hardwiring the
> > >> device tree into the kernel and for building a new boot rom from the
> > >> linux
> > >> kernel's ppc boot wrapper that would contain such a device tree to
> > >> feed to
> > >> the kernel.)
> > >
> > > It's only really been a problem for ps3 so far, since the embedded
> > > guys don't seem to have any difficulty with installing dtc. We are
> > > looking at what to do for ps3 and prep, and the answer may well
> > > involve bundling dtc in the kernel source (it's not too big, around
> > > 3400 lines).
> >
> > If only a few platforms have this problem, we could instead include
> > their .dtb files in the kernel source tree.
>
> Including .dtbs in the kernel tree has a big practical problem:
> they're binary, so can't be patch(1)ed, which makes updating them a
> complete PITA.
>
> I'm working on merging dtc into the kernel tree instead.
I'm kind of late to this party; but I have to say I disagree. Most of
us are doing just fine installing the dtc tool (and mkimage tool for
that matter). Cloning it in the kernel tree is just asking for
divergence.
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/2] qemu platform, v2
2007-10-17 20:28 ` Grant Likely
@ 2007-10-17 23:09 ` Rob Landley
2007-10-18 9:59 ` Matt Sealey
1 sibling, 0 replies; 55+ messages in thread
From: Rob Landley @ 2007-10-17 23:09 UTC (permalink / raw)
To: Grant Likely
Cc: linuxppc-dev, Paul Mackerras, Milton Miller, Christoph Hellwig
On Wednesday 17 October 2007 3:28:41 pm Grant Likely wrote:
> > Including .dtbs in the kernel tree has a big practical problem:
> > they're binary, so can't be patch(1)ed, which makes updating them a
> > complete PITA.
I note that kconfig includes the lex/yacc output files (blah.c_shipped) so you
don't have to have lex and yacc installed to run "menuconfig". It _also_
includes the lex/yacc source which is what you patch and rebuild the _shipped
files from when they need to be changed.
> > I'm working on merging dtc into the kernel tree instead.
>
> I'm kind of late to this party; but I have to say I disagree. Most of
> us are doing just fine installing the dtc tool (and mkimage tool for
> that matter). Cloning it in the kernel tree is just asking for
> divergence.
Milton Miller has some patches that make a "PPC qemu target" kernel image
which doesn't include a device tree, and generates a rom image to boot qemu
with which contains a device tree and hands it off to the Linux kernel. If
qemu can merge that rom image in its BIOS collection, this approach would
meet my immediate needs.
> Cheers,
> g.
Rob
--
"One of my most productive days was throwing away 1000 lines of code."
- Ken Thompson.
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/2] qemu platform, v2
2007-10-17 20:28 ` Grant Likely
2007-10-17 23:09 ` Rob Landley
@ 2007-10-18 9:59 ` Matt Sealey
2007-10-18 17:19 ` Milton Miller
1 sibling, 1 reply; 55+ messages in thread
From: Matt Sealey @ 2007-10-18 9:59 UTC (permalink / raw)
To: Grant Likely
Cc: Milton Miller, linuxppc-dev, Paul Mackerras, Rob Landley,
Christoph Hellwig
Grant Likely wrote:
> On 9/30/07, David Gibson <david@gibson.dropbear.id.au> wrote:
>> On Fri, Sep 28, 2007 at 06:53:28PM +0200, Segher Boessenkool wrote:
>>
>> I'm working on merging dtc into the kernel tree instead.
>
> I'm kind of late to this party; but I have to say I disagree. Most of
> us are doing just fine installing the dtc tool (and mkimage tool for
> that matter). Cloning it in the kernel tree is just asking for
> divergence.
Which begs the question; why cloning?
Why can't development be MOVED to in-kernel?
--
Matt Sealey <matt@genesi-usa.com>
Genesi, Manager, Developer Relations
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/2] qemu platform, v2
2007-10-18 9:59 ` Matt Sealey
@ 2007-10-18 17:19 ` Milton Miller
2007-10-18 17:29 ` Grant Likely
0 siblings, 1 reply; 55+ messages in thread
From: Milton Miller @ 2007-10-18 17:19 UTC (permalink / raw)
To: Matt Sealey; +Cc: linuxppc-dev, Paul Mackerras, Rob Landley, Christoph Hellwig
On Oct 18, 2007, at 4:59 AM, Matt Sealey wrote:
> Grant Likely wrote:
>> On 9/30/07, David Gibson <david@gibson.dropbear.id.au> wrote:
>>> On Fri, Sep 28, 2007 at 06:53:28PM +0200, Segher Boessenkool wrote:
>>>
>>> I'm working on merging dtc into the kernel tree instead.
>> I'm kind of late to this party; but I have to say I disagree. Most of
>> us are doing just fine installing the dtc tool (and mkimage tool for
>> that matter). Cloning it in the kernel tree is just asking for
>> divergence.
>
> Which begs the question; why cloning?
>
> Why can't development be MOVED to in-kernel?
Because we don't put userspace testsuites there for one.
And its a stand alone tool and should have its own packaging for a
second (ie the kernel provides the kernel and modules, but not random
user space utilities, in its tarbal).
If we say only some boards or ports are special and need to build then
I would vote for shipping asm files. If we think we need to build any
random embedded platform without installing dtc then we should merge
dtc.
PS the proposed kbuild integration is wrong; it should build it in the
subdirectory.
milton
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/2] qemu platform, v2
2007-10-18 17:19 ` Milton Miller
@ 2007-10-18 17:29 ` Grant Likely
2007-10-19 6:28 ` Rob Landley
0 siblings, 1 reply; 55+ messages in thread
From: Grant Likely @ 2007-10-18 17:29 UTC (permalink / raw)
To: Milton Miller
Cc: linuxppc-dev, Paul Mackerras, Rob Landley, Christoph Hellwig
On 10/18/07, Milton Miller <miltonm@bga.com> wrote:
> On Oct 18, 2007, at 4:59 AM, Matt Sealey wrote:
> > Which begs the question; why cloning?
> >
> > Why can't development be MOVED to in-kernel?
>
> Because we don't put userspace testsuites there for one.
>
> And its a stand alone tool and should have its own packaging for a
> second (ie the kernel provides the kernel and modules, but not random
> user space utilities, in its tarbal).
>
> If we say only some boards or ports are special and need to build then
> I would vote for shipping asm files. If we think we need to build any
> random embedded platform without installing dtc then we should merge
> dtc.
I don't think we do. It's looking like there are going to be out of
tree users of dtc also (The are some patches floating around for
u-boot to use the device tree for it's own initialization). I don't
think it's unreasonable to install dtc for embedded development.
I like the idea of shipping asm files to support the qemu target; at
least until qemu gets better firmware.
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/2] qemu platform, v2
2007-10-18 17:29 ` Grant Likely
@ 2007-10-19 6:28 ` Rob Landley
0 siblings, 0 replies; 55+ messages in thread
From: Rob Landley @ 2007-10-19 6:28 UTC (permalink / raw)
To: Grant Likely
Cc: Milton Miller, linuxppc-dev, Paul Mackerras, Christoph Hellwig
On Thursday 18 October 2007 12:29:08 pm Grant Likely wrote:
> On 10/18/07, Milton Miller <miltonm@bga.com> wrote:
> > If we say only some boards or ports are special and need to build then
> > I would vote for shipping asm files. If we think we need to build any
> > random embedded platform without installing dtc then we should merge
> > dtc.
>
> I don't think we do. It's looking like there are going to be out of
> tree users of dtc also (The are some patches floating around for
> u-boot to use the device tree for it's own initialization). I don't
> think it's unreasonable to install dtc for embedded development.
There are out of tree users of yacc and lex, but the kernel has *.c_shipped
files so as not to require that external tool of people who simply want to
build the sucker without modifying it. "make oldconfig" was modified not to
require curses.
How about *.S_shipped files?
> I like the idea of shipping asm files to support the qemu target; at
> least until qemu gets better firmware.
I've now gotten qemu to boot a kernel I built, using Milton's 1/2 patch and a
a self-contained build of a 4k ppc_boot.rom (which includes the dtc source
because I don't expect anybody else to have it installed, either).
Description and links to source, binaries, and build scripts in this message:
http://lists.gnu.org/archive/html/qemu-devel/2007-10/msg00415.html
There's a problem with qemu-cvs (detailed in the message), but qemu-system-ppc
0.9.0 boots fine, up to a shell prompt.
> Cheers,
> g.
Rob
--
"One of my most productive days was throwing away 1000 lines of code."
- Ken Thompson.
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/2] qemu platform, v2
2007-09-22 9:55 ` Christoph Hellwig
2007-09-22 19:16 ` Rob Landley
@ 2007-09-24 4:00 ` David Gibson
2007-09-24 7:46 ` Christoph Hellwig
1 sibling, 1 reply; 55+ messages in thread
From: David Gibson @ 2007-09-24 4:00 UTC (permalink / raw)
To: Christoph Hellwig
Cc: linuxppc-dev, Paul Mackerras, Rob Landley, Milton Miller
On Sat, Sep 22, 2007 at 11:55:46AM +0200, Christoph Hellwig wrote:
> On Fri, Sep 21, 2007 at 06:08:31PM -0500, Milton Miller wrote:
> > Here is the second rev of patches to boot a arch powerpc kernel on
> > qemu with the prep architecture.
>
> So if this is supposed to be prep why do you need additional kernel
> support? And if you really needed why isn't it under
> platforms/prep?
Basically because PReP support doesn't work under arch/powerpc.
Getting it working properly is something that should happen, but will
take a while. In the meantime, getting something that's sufficient to
get working under just qemu's version of prep, without using the
abominable openhackware is a quicker path to a usable arch/powerpc
kernel under qemu.
--
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
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/2] qemu platform, v2
2007-09-24 4:00 ` David Gibson
@ 2007-09-24 7:46 ` Christoph Hellwig
2007-09-24 9:48 ` Milton Miller
0 siblings, 1 reply; 55+ messages in thread
From: Christoph Hellwig @ 2007-09-24 7:46 UTC (permalink / raw)
To: Christoph Hellwig, Milton Miller, linuxppc-dev, Paul Mackerras,
Rob Landley
On Mon, Sep 24, 2007 at 02:00:47PM +1000, David Gibson wrote:
> Basically because PReP support doesn't work under arch/powerpc.
> Getting it working properly is something that should happen, but will
> take a while. In the meantime, getting something that's sufficient to
> get working under just qemu's version of prep, without using the
> abominable openhackware is a quicker path to a usable arch/powerpc
> kernel under qemu.
Sounds fair. Care to add something like this to the Kconfig help
text?
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/2] qemu platform, v2
2007-09-24 7:46 ` Christoph Hellwig
@ 2007-09-24 9:48 ` Milton Miller
0 siblings, 0 replies; 55+ messages in thread
From: Milton Miller @ 2007-09-24 9:48 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linuxppc-dev, Paul Mackerras, Rob Landley
On Sep 24, 2007, at 2:46 AM, Christoph Hellwig wrote:
> On Mon, Sep 24, 2007 at 02:00:47PM +1000, David Gibson wrote:
>> Basically because PReP support doesn't work under arch/powerpc.
>> Getting it working properly is something that should happen, but will
>> take a while. In the meantime, getting something that's sufficient to
>> get working under just qemu's version of prep, without using the
>> abominable openhackware is a quicker path to a usable arch/powerpc
>> kernel under qemu.
>
> Sounds fair. Care to add something like this to the Kconfig help
> text?
I suppose I could, but actually I wasn't asking for the two qemu
patches to be merged. Instead I was posting "here's something that
provides minimal function for me, hope you can use it too". For
instance, someone should track down pci memory so that ohci and/or
video works. Then test the isa ne2ks, or better yet get qemu to change
them to pci (except then it only works on the latest qemu).
I didn't put it under prep because it could be changed for the other
qemu platforms and doesn't use any thing that makes the machine prep
other than some memory map information. I kept prep because I didn't
want to deal with io to the scc on b&w G3, the other long-term platform
(or with hackware to see if that would just boot as pmac).
milton
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 2/2] qemu platform rom, v2
2007-09-21 23:02 [PATCH 0/15] bootwrapper: kexec and external payloads Milton Miller
` (15 preceding siblings ...)
2007-09-21 23:08 ` [PATCH 1/2] qemu platform, v2 Milton Miller
@ 2007-09-21 23:08 ` Milton Miller
16 siblings, 0 replies; 55+ messages in thread
From: Milton Miller @ 2007-09-21 23:08 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Rob Landley, David Gibson
Here is the second rev of patches to boot a powerpc port kernel on
qemu with the prep architecture.
The goal is to provide a environment for use with the existing qemu
hardware suppplied hardware, as oposed to changing the qemu
machine description.
This patch has the changes to the boot wrapper and the device tree.
It applies to the additon of my kexec series to the for-2.6.24 branch
as of 2007/09/21.
The wrapper code zBoot is packaged as ppc_rom.bin, provding a replacement
for OpenHackware. [OpenHackware requires the kernel boot device to
have a partition table, even if its laoded in memory (which prep sort
of provides). It also only gueses the execution of boot sripts and any
forth, and has noot seen any development in 3 years].
This rom copies its contents to ram where it then invokes the normal
wrapper starup path, using the serial port for the console. It proceeds
to locate the commandline, kernel, and initrd using nvram. It supports
only nvram at the prep location of 0x8000074 indicating a boot from
"memory" aka qemu -kernel or drive "m". The loaded image can be a
kernel or a zImage (in this mode it will ignore any attached device
tree preferring the one supplied via r3), but the contianed kernel and
optionally a initrd as per the normal build process will be used.
Specifically, the patch requrires (1) external vmlinux hook and wrapper
(2) check loader_info command line after fixups, and (3) obtain initrd
from device-tree, (4) several patches committed to the for-2.6.24 branch.
When building the rom, configure the device tree as "qemu.dts". When
building the vmlinux or zImage -kernel, you can use the empty string
("") to suppress the call to dtc as the code will ignore any attached dtb.
When invoking qemu, use the -L flag to specify the directory with the
ppc_rom.bin file.
Index: kernel/arch/powerpc/boot/qemu.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/boot/qemu.c 2007-09-21 04:53:32.000000000 -0500
@@ -0,0 +1,235 @@
+/*
+ * QEMU PReP-specific stuff for the zImage boot wrapper.
+ *
+ * Copyright (C) 2007 Milton Miller, IBM Corp. <miltonm@bga.com>
+ * Copyright (C) 2006 Paul Mackerras, IBM Corp. <paulus@samba.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License.
+ *
+ * nvram format obtained from OpenHackWare 0.4
+ * Copyright (C) 2004-2005 Jocelyn Mayer (l_indien@magic.fr)
+ *
+ */
+
+asm(
+/*
+ * gcc 4.1.2 seems to place this first, even with the block at the end of
+ * the file. Put it first for good measure. If the branch ends up at the
+ * beginning of the image then it can be started like a kernel.
+ */
+" b _zimage_start\n" /* gcc 4.1.2 places this first */
+
+/*
+ * This code will be loaded by qemu as a rom at the end of memory, and
+ * execution will start at address -4. Since the rom is read only, we
+ * and the zImage code wants to run where loaded, we must copy it to ram.
+ *
+ * move to linked place
+ * end with a branch to this code
+ * this code will be copied with dd to the end of the rom image
+ */
+
+" .globl copy_rom_start\n"
+"copy_rom_start:\n"
+" bl 1f\n"
+"1: mflr 4\n"
+" clrrwi 4,4,19\n" /* ROM_BITS -- get beginning of rom */
+" lis 5,_end@ha\n"
+" addi 5,5,_end@l\n"
+" lis 3,_start@ha\n"
+" addi 3,3,_start@l\n"
+" subf 5,3,5\n"
+" addi 5,5,0x1f\n"
+" srwi 5,5,5\n"
+" mtctr 5\n"
+"2: lwz 24,0(4)\n" /* copy to linked addresss */
+" lwz 25,4(4)\n"
+" lwz 26,8(4)\n"
+" lwz 27,12(4)\n"
+" lwz 28,16(4)\n"
+" lwz 29,20(4)\n"
+" lwz 30,24(4)\n"
+" lwz 31,28(4)\n"
+" stw 24,0(3)\n"
+" stw 25,4(3)\n"
+" stw 26,8(3)\n"
+" stw 27,12(3)\n"
+" stw 28,16(3)\n"
+" stw 29,20(3)\n"
+" stw 30,24(3)\n"
+" stw 31,28(3)\n"
+" dcbf 0,3\n"
+" sync\n"
+" icbi 0,3\n"
+" addi 3,3,32\n"
+" addi 4,4,32\n"
+" bdnz 2b\n"
+" sync\n"
+" isync\n"
+
+ /*
+ * Put a branch to self on a few vectors in case we get an unexpected
+ * interrupt. At least you can dump regs in the qemu monitor.
+ */
+" lis 0,0x48000000@h\n"
+" stw 0,0x700(0)\n"
+" stw 0,0x300(0)\n"
+" stw 0,0x400(0)\n"
+" stw 0,0x900(0)\n"
+" stw 0,0x800(0)\n"
+" stw 0,0x200(0)\n"
+
+ /* branch to linked address */
+" lis 0,_zimage_start@h\n"
+" ori 0,0,_zimage_start@l\n"
+" mtctr 0\n"
+" li 3,0\n"
+" bctrl\n"
+
+ /* must be last word before copy_rom_end */
+" b copy_rom_start\n"
+" .globl copy_rom_end\n"
+"copy_rom_end:\n"
+);
+
+
+#include <stddef.h>
+#include "string.h"
+#include "stdio.h"
+#include "ops.h"
+#include "page.h"
+#include "io.h"
+#include "gunzip_util.h"
+#include "flatdevtree.h"
+
+BSS_STACK(16*1024);
+
+unsigned char *nvram = (void *)0x80000074; /* address of nvram on PReP */
+
+static void qemu_nvram_write(unsigned short addr, char data)
+{
+ out_8(nvram + 0, addr & 0xff);
+ out_8(nvram + 1, addr >> 8);
+ out_8(nvram + 3, data);
+}
+
+static char qemu_nvram_read(unsigned short addr)
+{
+ char data;
+ out_8(nvram + 0, addr & 0xff);
+ out_8(nvram + 1, addr >> 8);
+ data = in_8(nvram + 3);
+
+ return data;
+}
+
+static void qemu_nvram_fetch(unsigned short addr, unsigned short len, void *p)
+{
+ char *buf = p;
+ int i;
+
+ for (i = 0; i < len; i ++)
+ buf[i] = qemu_nvram_read(addr + i); /* big endian */
+}
+
+static char arch[17];
+static void * image_start;
+static unsigned int image_len;
+
+void qemu_find_vmlinuz(struct gunzip_state *state, void **srcp,
+ unsigned long *lenp)
+{
+ *srcp = image_start;
+ *lenp = image_len;
+ gunzip_start(state, image_start, image_len);
+}
+
+/* if no device tree, read the nvram to find out about our system */
+/* based on openhackware 0.4 nvram.c get_nvram_config */
+static void qemu_fixups(void)
+{
+ char buf[32];
+ int word;
+
+ printf("qemu_fixups\n\r");
+
+ qemu_nvram_fetch(0, 16, buf);
+ printf("sig: %s", buf);
+ if (strcmp(buf, "QEMU_BIOS"))
+ fatal("no qemu sig found");
+ qemu_nvram_fetch(0x10, 16, &word);
+ if (word != 2)
+ fatal("wrong qemu nvram version");
+ /* compute crc over 0-0xfc, compare to crc in 0xfc */
+ /* size at 0x14, mult 256 0x400-0x2000 */
+ qemu_nvram_fetch(0x20, 16, buf);
+ strncpy(arch, buf, sizeof(arch)-1);
+ if (strcmp(arch,"PREP"))
+ fatal("don't understand arch %s", arch);
+
+ /* XXX: put the model in the device tree */
+
+ qemu_nvram_fetch(0x30, 16, &word);
+ printf("memory: %x\n\r", word);
+ dt_fixup_memory(0, word);
+ printf("boot device %c\n\r", qemu_nvram_read(0x34));
+ qemu_nvram_fetch(0x38, 16, &word);
+ image_start = (void *)word;
+ qemu_nvram_fetch(0x3c, 16, &word);
+ image_len = word;
+ printf("kernel %p %x\n\r", image_start, image_len);
+ qemu_nvram_fetch(0x40, 16, &word);
+ loader_info.cmdline = (void *)word;
+ qemu_nvram_fetch(0x44, 16, &word);
+ loader_info.cmdline_len = word;
+ printf("cmdline %p %x\n\r", loader_info.cmdline,
+ loader_info.cmdline_len);
+ printf("cmdline is %s\n\r", loader_info.cmdline);
+ qemu_nvram_fetch(0x48, 16, &word);
+ loader_info.initrd_addr = word;
+ qemu_nvram_fetch(0x4c, 16, &word);
+ loader_info.initrd_size = word;
+ printf("initrd %lx %lx\n\r", loader_info.initrd_addr,
+ loader_info.initrd_size);
+ /* XXX: nvram image addr at 50 */
+ /* XXX: vga width, height, depth = shorts at 54, 56, 58 */
+}
+
+/* If loaded with a device tree, then just read the tree */
+static void tree_fixups(void)
+{
+ /* get initrd from tree */
+ dt_find_initrd();
+
+ /* we must have an attached image for boot with supplied device-tree */
+}
+
+static void *heap_end; /* set in platform_init */
+
+static void *qemu_vmlinux_alloc(unsigned long size)
+{
+ if (size < (unsigned long)_start)
+ return 0;
+
+ return (void *)_ALIGN_UP((unsigned long) heap_end, 4096);
+}
+
+void platform_init(void *r3)
+{
+ struct boot_param_header *bph = r3;
+
+ heap_end = simple_alloc_init(_end, 4096*1024, 4096, 512);
+
+ if (bph) {
+ ft_init(bph, bph->totalsize, 128);
+ platform_ops.fixups = tree_fixups;
+ } else {
+ ft_init(_dtb_start, _dtb_end - _dtb_start, 128);
+ platform_ops.fixups = qemu_fixups;
+ platform_ops.find_vmlinuz = qemu_find_vmlinuz;
+ }
+ platform_ops.vmlinux_alloc = qemu_vmlinux_alloc;
+
+ serial_console_init();
+}
Index: kernel/arch/powerpc/boot/dts/qemu.dts
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/boot/dts/qemu.dts 2007-09-21 04:53:32.000000000 -0500
@@ -0,0 +1,132 @@
+/*
+ * QEMU PReP skeleton device tree
+ * from PReP skeleton device tree
+ * and qemu source
+ *
+ * Milton Miller
+ */
+
+/ {
+ device_type = "qemu";
+ model = "QEMU,PReP";
+ compatible = "qemu-prep";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ reg = <0>;
+ clock-frequency =<d#200000000>;
+ bus-frequency = <d#100000000>;
+ timebase-frequency = <d#100000000>;
+ i-cache-line-size = <d#32>;
+ d-cache-line-size = <d#32>;
+ d-cache-size = <0>;
+ i-cache-size = <0>;
+
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ // dummy range here, zImage wrapper will fill in the actual
+ // amount of memory from the nvram
+ reg = <00000000 01000000>;
+ };
+
+ pci@80800000 {
+ device_type = "pci";
+ compatible = "prep-pci";
+ clock-frequency = <01fca055>;
+ reg = <80800000 00400000>; /* pci config space */
+ 8259-interrupt-acknowledge = <bffffff0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges=<01000000 00000000 00000000 80000000 00000000 00800000
+ 02000000 00000000 00000000 c0000000 00000000 01000000>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0800 0 0 0>;
+ interrupt-map = <0800 0 0 0 &PIC8259 b 3
+ 0000 0 0 0 &PIC8259 9 3>;
+
+ isa {
+ device_type = "isa";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ #interrupt-cells = <2>;
+ ranges = <00000001 00000000
+ 01005800 00000000 00000000 00010000
+ 00000000 00000000
+ 02005800 00000000 00000000 01000000>;
+
+ parallel {
+ device_type = "parallel";
+ compatible = "pnpPNP,401", "pnpPNP,400";
+ reg = <00000001 000003bc 00000008
+ 00000001 000007bc 00000006>;
+ interrupts = <00000007 00000003>;
+ interrupt-parent = <&PIC8259>;
+ };
+
+ serial@3f8 {
+ device_type = "serial";
+ compatible = "pnpPNP,501", "pnpPNP,500",
+ "ns16550";
+ virtual-reg = <800003f8>;
+ clock-frequency = <001c2000>;
+ reg = <00000001 000003f8 00000008>;
+ interrupts = <00000004 00000003>;
+ interrupt-parent = <&PIC8259>;
+ };
+ PIC8259: interrupt-controller {
+ #interrupt-cells = <2>;
+ device_type = "i8259";
+ compatible = "prep,iic";
+ interrupt-controller;
+ reg = < 00000001 00000020 00000002
+ 00000001 000000a0 00000002
+ 00000001 000004d0 00000002>;
+ };
+ ne2000@300 {
+ reg = <00000001 00000300 00000020>;
+ interrupt-parent = <&PIC8259>;
+ interrupts=<9 3>;
+ };
+ ne2000@320 {
+ reg = <00000001 00000320 00000020>;
+ interrupt-parent = <&PIC8259>;
+ interrupts=<a 3>;
+ };
+ ne2000@340 {
+ reg = <00000001 00000340 00000020>;
+ interrupt-parent = <&PIC8259>;
+ interrupts=<b 3>;
+ };
+ ne2000@360 {
+ reg = <00000001 00000360 00000020>;
+ interrupt-parent = <&PIC8259>;
+ interrupts=<3 3>;
+ };
+ ne2000@280 {
+ reg = <00000001 00000280 00000020>;
+ interrupt-parent = <&PIC8259>;
+ interrupts=<4 3>;
+ };
+ ne2000@380 {
+ reg = <00000001 00000380 00000020>;
+ interrupt-parent = <&PIC8259>;
+ interrupts=<5 3>;
+ };
+
+ };
+ };
+
+ chosen {
+ linux,stdout-path = "/pci/isa/serial@3f8";
+ };
+};
+
Index: kernel/arch/powerpc/boot/wrapper
===================================================================
--- kernel.orig/arch/powerpc/boot/wrapper 2007-09-21 04:52:59.000000000 -0500
+++ kernel/arch/powerpc/boot/wrapper 2007-09-21 04:53:32.000000000 -0500
@@ -310,4 +310,53 @@ ps3)
gzip --force -9 --stdout "$ofile.bin" > "$object/otheros.bld"
;;
+qemu)
+ # this part makes the zBoot.qemu a bootrom for qemu.
+ #
+ # the qemu bootrom is 512k , located at the top of the 32 bit address
+ # space. The fixed entrypoint is address -4.
+
+ copy_rom_start=0x`${CROSS}nm "$ofile" \
+ | grep ' copy_rom_start$' \
+ | cut -d' ' -f1`
+ copy_rom_start=`printf "%d" $copy_rom_start`
+ copy_rom_end=0x`${CROSS}nm "$ofile" \
+ | grep ' copy_rom_end$' \
+ | cut -d' ' -f1`
+ copy_rom_end=`printf "%d" $copy_rom_end`
+ rom_start=0x`${CROSS}nm "$ofile" \
+ | grep ' _start$' \
+ | cut -d' ' -f1`
+
+ rom_start=`printf "%d" $rom_start`
+ rom_size=$((1<<19))
+ copy_rom_len=$(($copy_rom_end-$copy_rom_start))
+ copy_rom_dst=$(($rom_size-$copy_rom_len))
+ copy_rom_src=$(($copy_rom_start-$rom_start))
+
+ img_size=`${CROSS}size "$ofile" | tail -n1 | cut -f4`
+ if [ $img_size -gt $copy_rom_dst ]
+ then
+ echo Image "${ofile##*/}" too big to fit in rom, skipping rom build.
+ else
+ romfile="$object/ppc_rom.bin"
+ tmpfile="$object/ppc_rom.$$"
+
+ rm -f "$tmpfile"
+ ${CROSS}objcopy -O binary --pad-to=$(($rom_size+$rom_start)) \
+ --gap-fill=0xff "$ofile" "$tmpfile"
+
+ msg=$(dd if="$tmpfile" of="$tmpfile" conv=notrunc \
+ skip=$copy_rom_src seek=$copy_rom_dst \
+ count=$copy_rom_len bs=1 2>&1)
+
+ if [ $? -ne "0" ]; then
+ echo $msg
+ rm -f "$tmpfile"
+ exit 2
+ fi
+
+ mv "$tmpfile" "$romfile"
+ fi
+ ;;
esac
Index: kernel/arch/powerpc/boot/.gitignore
===================================================================
--- kernel.orig/arch/powerpc/boot/.gitignore 2007-09-21 04:51:30.000000000 -0500
+++ kernel/arch/powerpc/boot/.gitignore 2007-09-21 04:53:32.000000000 -0500
@@ -17,6 +17,7 @@ infutil.h
kernel-vmlinux.strip.c
kernel-vmlinux.strip.gz
mktree
+ppc_rom.bin
uImage
cuImage.*
zImage
Index: kernel/arch/powerpc/boot/Makefile
===================================================================
--- kernel.orig/arch/powerpc/boot/Makefile 2007-09-21 04:52:59.000000000 -0500
+++ kernel/arch/powerpc/boot/Makefile 2007-09-21 04:53:32.000000000 -0500
@@ -48,7 +48,7 @@ src-wlib := string.S crt0.S stdio.c main
4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
cpm-serial.c stdlib.c
src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c crt0_kexec.S \
- cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
+ cuboot-ebony.c treeboot-ebony.c prpmc2800.c qemu.c \
ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c cuboot-bamboo.c
src-boot := $(src-wlib) $(src-plat) empty.c
@@ -143,6 +143,7 @@ image-$(CONFIG_PPC_PMAC) += zImage.pmac
image-$(CONFIG_PPC_HOLLY) += zImage.holly
image-$(CONFIG_PPC_PRPMC2800) += zImage.prpmc2800
image-$(CONFIG_PPC_ISERIES) += zImage.iseries
+image-$(CONFIG_PPC_QEMU) += zImage.qemu zBoot.qemu
image-$(CONFIG_DEFAULT_UIMAGE) += uImage
image-$(CONFIG_KEXEC) += $(kexec-y)
image-$(CONFIG_KEXEC) += $(patsubst zImage%,zBoot%,$(kexec-y))
@@ -202,6 +203,9 @@ $(obj)/zImage.iseries: vmlinux
$(obj)/zBoot.%: $(wrapperbits) $(dts)
$(call if_changed,wrap,$*,$(dts),,,$(obj)/empty.o)
+# horrible hack to avoid overlapping calls to wrapper script clobbering dtb.
+$(obj)/zImage.qemu: $(obj)/zBoot.qemu
+
$(obj)/zImage.ps3: vmlinux $(wrapper) $(wrapperbits) $(srctree)/$(src)/dts/ps3.dts
$(STRIP) -s -R .comment $< -o vmlinux.strip
$(call cmd,wrap,ps3,$(srctree)/$(src)/dts/ps3.dts,,)
@@ -235,8 +239,8 @@ install: $(CONFIGURE) $(addprefix $(obj)
sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $<
# anything not in $(targets)
-clean-files += $(image-) $(initrd-) zImage zImage.initrd cuImage.* treeImage.* \
- otheros.bld $(kexec-)
+clean-files += $(image-) $(initrd-) zImage zImage.initrd cuImage.* treeImage.*
+clean-files += otheros.bld ppc_rom.bin $(kexec-)
# clean up files cached by wrapper
clean-kernel := vmlinux.strip vmlinux.bin empty.o.bin
^ permalink raw reply [flat|nested] 55+ messages in thread