From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from kcout01.prserv.net (kcout01.prserv.net [12.154.55.31]) by ozlabs.org (Postfix) with ESMTP id E750FDDFFA for ; Sat, 16 Jun 2007 05:01:03 +1000 (EST) Date: Fri, 15 Jun 2007 12:34:30 -0500 From: Milton Miller To: linuxppc-dev@ozlabs.org, Subject: [PATCH] boot: find initrd location from device-tree Message-Id: <11181928870643c98691.1714636915.tkfpda@attglobal.net> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Cc: paulus@samba.org, david@gibson.dropbear.id.au List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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 --- 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 + * + */ + +#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 /* MAX_UINT, etc */ + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) typedef unsigned char u8;