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

Milton Miller tkfpda at attglobal.net
Sat Jun 16 03:34:30 EST 2007


Some platforms have a boot agent that can create or modifiy
properties in the device-tree and load images into memory.
Provide a helper to set the loader-info used by prep_initrd().

The code supports the 8-byte properties required by kernels
before 2.6.22 and 4-byte properties generated by prep_initrd()
and current 32 bit kernels (new kernels will read either size).

The types.h header now includes libgcc limits.h for UINT_MAX.

Signed-off-by: Milton Miller <miltonm at bga.com>
--- 
The file name dtscan reflects the possibility that simiar functions
like the rmo_top might be added to the file.

This is the first patch in a series of 18 that udpates and rediffs
of my kexec zImage support against 2.6.22-rc4.  Unfornately I left
the series file behind but I wanted to get this first patch sent
for Matt to use.

Index: kernel/arch/powerpc/boot/dtscan.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ kernel/arch/powerpc/boot/dtscan.c	2007-06-15 03:45:16.000000000 -0500
@@ -0,0 +1,86 @@
+/*
+ * 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 at bga.com>
+ *
+ */
+
+#include "ops.h"
+#include "stdio.h"
+
+/**
+ * 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;
+	}
+
+	/* The properties had to be 8 bytes until 2.6.22  */
+	rc = getprop(devp, start_prop, &initrd_start, sizeof(initrd_start));
+	if (rc < 0)
+		return;
+	if (rc == sizeof(unsigned long)) {
+		unsigned long tmp;
+		memcpy(&tmp, &initrd_start, rc);
+		initrd_start = tmp;
+	} else if (rc != sizeof(initrd_start)) {
+		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;
+	}
+
+	if (!initrd_start)
+		return;
+
+	/* if the initrd is above 4G, its untouchable in 32 bit mode */
+	if (initrd_end <= UINT_MAX && initrd_start < initrd_end) {
+		loader_info.initrd_addr = initrd_start;
+		loader_info.initrd_size  = initrd_end - initrd_start;
+	} else {
+		printf("ignoring loader supplied initrd parameters\n");
+	}
+}
Index: kernel/arch/powerpc/boot/ops.h
===================================================================
--- kernel.orig/arch/powerpc/boot/ops.h	2007-06-15 03:43:36.000000000 -0500
+++ kernel/arch/powerpc/boot/ops.h	2007-06-15 03:44:34.000000000 -0500
@@ -151,6 +151,7 @@ static inline void *find_node_by_devtype
 	return find_node_by_prop_value_str(prev, "device_type", type);
 }
 
+void dt_find_initrd(void);
 void dt_fixup_memory(u64 start, u64 size);
 void dt_fixup_cpu_clocks(u32 cpufreq, u32 tbfreq, u32 busfreq);
 void dt_fixup_clock(const char *path, u32 freq);
Index: kernel/arch/powerpc/boot/Makefile
===================================================================
--- kernel.orig/arch/powerpc/boot/Makefile	2007-06-15 03:43:36.000000000 -0500
+++ kernel/arch/powerpc/boot/Makefile	2007-06-15 03:44:34.000000000 -0500
@@ -43,7 +43,7 @@ $(addprefix $(obj)/,$(zlib) gunzip_util.
 
 src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
 		ns16550.c serial.c simple_alloc.c div64.S util.S \
-		gunzip_util.c elf_util.c $(zlib) devtree.c \
+		gunzip_util.c elf_util.c $(zlib) devtree.c dtscan.c \
 		44x.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c
 src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \
 		cuboot-ebony.c treeboot-ebony.c prpmc2800.c
Index: kernel/arch/powerpc/boot/types.h
===================================================================
--- kernel.orig/arch/powerpc/boot/types.h	2007-06-15 03:36:21.000000000 -0500
+++ kernel/arch/powerpc/boot/types.h	2007-06-15 03:44:34.000000000 -0500
@@ -1,6 +1,9 @@
 #ifndef _TYPES_H_
 #define _TYPES_H_
 
+#define _LIBC_LIMITS_H_		/* don't recurse to system's headers */
+#include <limits.h>		/* MAX_UINT, etc */
+
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
 typedef unsigned char		u8;



More information about the Linuxppc-dev mailing list