| diff -rduNp kexec-tools-1.101.orig/configure kexec-tools-1.101/configure |
| --- kexec-tools-1.101.orig/configure 2006-09-20 04:39:38.000000000 +0200 |
| +++ kexec-tools-1.101/configure 2007-01-22 15:54:14.000000000 +0100 |
| @@ -1381,6 +1381,9 @@ case $host_cpu in |
| i?86 ) |
| host_cpu="i386" |
| ;; |
| + arm* ) |
| + host_cpu="arm" |
| + ;; |
| powerpc ) |
| host_cpu="ppc" |
| ;; |
| @@ -1395,7 +1398,7 @@ case $host_cpu in |
| ;; |
| esac |
| case $host_cpu in |
| - i386|ppc|x86_64|alpha|ppc64|ia64|s390) |
| + i386|ppc|x86_64|alpha|ppc64|ia64|s390|arm) |
| ;; |
| * ) |
| { { echo "$as_me:$LINENO: error: unsupported architecture $host_cpu" >&5 |
| diff -rduNp kexec-tools-1.101.orig/kexec/arch/arm/Makefile kexec-tools-1.101/kexec/arch/arm/Makefile |
| --- kexec-tools-1.101.orig/kexec/arch/arm/Makefile 1970-01-01 01:00:00.000000000 +0100 |
| +++ kexec-tools-1.101/kexec/arch/arm/Makefile 2007-01-22 15:54:14.000000000 +0100 |
| @@ -0,0 +1,8 @@ |
| +# |
| +# kexec arm (linux booting linux) |
| +# |
| +KEXEC_C_SRCS+= kexec/arch/arm/kexec-elf-rel-arm.c |
| +KEXEC_C_SRCS+= kexec/arch/arm/kexec-zImage-arm.c |
| +KEXEC_C_SRCS+= kexec/arch/arm/kexec-arm.c |
| + |
| +KEXEC_S_SRCS+= |
| diff -rduNp kexec-tools-1.101.orig/kexec/arch/arm/include/arch/options.h kexec-tools-1.101/kexec/arch/arm/include/arch/options.h |
| --- kexec-tools-1.101.orig/kexec/arch/arm/include/arch/options.h 1970-01-01 01:00:00.000000000 +0100 |
| +++ kexec-tools-1.101/kexec/arch/arm/include/arch/options.h 2007-01-22 15:54:14.000000000 +0100 |
| @@ -0,0 +1,11 @@ |
| +#ifndef KEXEC_ARCH_ARM_OPTIONS_H |
| +#define KEXEC_ARCH_ARM_OPTIONS_H |
| + |
| +#define OPT_ARCH_MAX (OPT_MAX+0) |
| + |
| +#define KEXEC_ARCH_OPTIONS \ |
| + KEXEC_OPTIONS \ |
| + |
| +#define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" |
| + |
| +#endif /* KEXEC_ARCH_ARM_OPTIONS_H */ |
| diff -rduNp kexec-tools-1.101.orig/kexec/arch/arm/kexec-arm.c kexec-tools-1.101/kexec/arch/arm/kexec-arm.c |
| --- kexec-tools-1.101.orig/kexec/arch/arm/kexec-arm.c 1970-01-01 01:00:00.000000000 +0100 |
| +++ kexec-tools-1.101/kexec/arch/arm/kexec-arm.c 2007-01-22 15:54:14.000000000 +0100 |
| @@ -0,0 +1,130 @@ |
| +/* |
| + * kexec: Linux boots Linux |
| + * |
| + * modified from kexec-ppc.c |
| + * |
| + */ |
| + |
| +#define _GNU_SOURCE |
| +#include <stddef.h> |
| +#include <stdio.h> |
| +#include <errno.h> |
| +#include <stdint.h> |
| +#include <string.h> |
| +#include <getopt.h> |
| +#include <sys/utsname.h> |
| +#include "../../kexec.h" |
| +#include "../../kexec-syscall.h" |
| +#include "kexec-arm.h" |
| +#include <arch/options.h> |
| + |
| +#define MAX_MEMORY_RANGES 64 |
| +#define MAX_LINE 160 |
| +static struct memory_range memory_range[MAX_MEMORY_RANGES]; |
| + |
| +/* Return a sorted list of available memory ranges. */ |
| +int get_memory_ranges(struct memory_range **range, int *ranges, unsigned long kexec_flags) |
| +{ |
| + const char iomem[]= "/proc/iomem"; |
| + int memory_ranges = 0; |
| + char line[MAX_LINE]; |
| + FILE *fp; |
| + fp = fopen(iomem, "r"); |
| + if (!fp) { |
| + fprintf(stderr, "Cannot open %s: %s\n", |
| + iomem, strerror(errno)); |
| + return -1; |
| + } |
| + |
| + while(fgets(line, sizeof(line), fp) != 0) { |
| + unsigned long long start, end; |
| + char *str; |
| + int type; |
| + int consumed; |
| + int count; |
| + if (memory_ranges >= MAX_MEMORY_RANGES) |
| + break; |
| + count = sscanf(line, "%Lx-%Lx : %n", |
| + &start, &end, &consumed); |
| + if (count != 2) |
| + continue; |
| + str = line + consumed; |
| + end = end + 1; |
| + |
| + if (memcmp(str, "System RAM\n", 11) == 0) { |
| + type = RANGE_RAM; |
| + } |
| + else if (memcmp(str, "reserved\n", 9) == 0) { |
| + type = RANGE_RESERVED; |
| + } |
| + else { |
| + continue; |
| + } |
| + |
| + memory_range[memory_ranges].start = start; |
| + memory_range[memory_ranges].end = end; |
| + memory_range[memory_ranges].type = type; |
| + memory_ranges++; |
| + } |
| + fclose(fp); |
| + *range = memory_range; |
| + *ranges = memory_ranges; |
| + return 0; |
| +} |
| + |
| +/* Supported file types and callbacks */ |
| +struct file_type file_type[] = { |
| + {"zImage", zImage_arm_probe, zImage_arm_load, zImage_arm_usage}, |
| +}; |
| +int file_types = sizeof(file_type) / sizeof(file_type[0]); |
| + |
| + |
| +void arch_usage(void) |
| +{ |
| +} |
| + |
| +int arch_process_options(int argc, char **argv) |
| +{ |
| + static const struct option options[] = { |
| + KEXEC_ARCH_OPTIONS |
| + { 0, 0, NULL, 0 }, |
| + }; |
| + static const char short_options[] = KEXEC_ARCH_OPT_STR; |
| + int opt; |
| + |
| + opterr = 0; /* Don't complain about unrecognized options here */ |
| + while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { |
| + switch(opt) { |
| + default: |
| + break; |
| + } |
| + } |
| + /* Reset getopt for the next pass; called in other source modules */ |
| + opterr = 1; |
| + optind = 1; |
| + return 0; |
| +} |
| + |
| +int arch_compat_trampoline(struct kexec_info *info) |
| +{ |
| + int result; |
| + struct utsname utsname; |
| + result = uname(&utsname); |
| + if (result < 0) { |
| + fprintf(stderr, "uname failed: %s\n", |
| + strerror(errno)); |
| + return -1; |
| + } |
| + if (strncmp(utsname.machine, "arm",3) != 0) |
| + { |
| + fprintf(stderr, "Unsupported machine type: %s\n", |
| + utsname.machine); |
| + return -1; |
| + } |
| + return 0; |
| +} |
| + |
| +void arch_update_purgatory(struct kexec_info *info) |
| +{ |
| +} |
| + |
| diff -rduNp kexec-tools-1.101.orig/kexec/arch/arm/kexec-arm.h kexec-tools-1.101/kexec/arch/arm/kexec-arm.h |
| --- kexec-tools-1.101.orig/kexec/arch/arm/kexec-arm.h 1970-01-01 01:00:00.000000000 +0100 |
| +++ kexec-tools-1.101/kexec/arch/arm/kexec-arm.h 2007-01-22 15:54:14.000000000 +0100 |
| @@ -0,0 +1,9 @@ |
| +#ifndef KEXEC_ARM_H |
| +#define KEXEC_ARM_H |
| + |
| +int zImage_arm_probe(const char *buf, off_t len); |
| +int zImage_arm_load(int argc, char **argv, const char *buf, off_t len, |
| + struct kexec_info *info); |
| +void zImage_arm_usage(void); |
| + |
| +#endif /* KEXEC_ARM_H */ |
| diff -rduNp kexec-tools-1.101.orig/kexec/arch/arm/kexec-elf-rel-arm.c kexec-tools-1.101/kexec/arch/arm/kexec-elf-rel-arm.c |
| --- kexec-tools-1.101.orig/kexec/arch/arm/kexec-elf-rel-arm.c 1970-01-01 01:00:00.000000000 +0100 |
| +++ kexec-tools-1.101/kexec/arch/arm/kexec-elf-rel-arm.c 2007-01-22 15:54:14.000000000 +0100 |
| @@ -0,0 +1,35 @@ |
| +#include <stdio.h> |
| +#include <elf.h> |
| +#include "../../kexec.h" |
| +#include "../../kexec-elf.h" |
| + |
| +int machine_verify_elf_rel(struct mem_ehdr *ehdr) |
| +{ |
| + if (ehdr->ei_data != ELFDATA2MSB) { |
| + return 0; |
| + } |
| + if (ehdr->ei_class != ELFCLASS32) { |
| + return 0; |
| + } |
| + if (ehdr->e_machine != EM_ARM) |
| + { |
| + return 0; |
| + } |
| + return 1; |
| +} |
| + |
| +void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type, |
| + void *location, unsigned long address, unsigned long value) |
| +{ |
| + switch(r_type) { |
| + case R_ARM_ABS32: |
| + *((uint32_t *)location) += value; |
| + break; |
| + case R_ARM_REL32: |
| + *((uint32_t *)location) += value - address; |
| + break; |
| + default: |
| + die("Unknown rel relocation: %lu\n", r_type); |
| + break; |
| + } |
| +} |
| diff -rduNp kexec-tools-1.101.orig/kexec/arch/arm/kexec-zImage-arm.c kexec-tools-1.101/kexec/arch/arm/kexec-zImage-arm.c |
| --- kexec-tools-1.101.orig/kexec/arch/arm/kexec-zImage-arm.c 1970-01-01 01:00:00.000000000 +0100 |
| +++ kexec-tools-1.101/kexec/arch/arm/kexec-zImage-arm.c 2007-01-22 15:54:14.000000000 +0100 |
| @@ -0,0 +1,34 @@ |
| +#define _GNU_SOURCE |
| +#include <stdio.h> |
| +#include <string.h> |
| +#include <stdlib.h> |
| +#include <errno.h> |
| +#include <limits.h> |
| +#include "../../kexec.h" |
| + |
| +int zImage_arm_probe(const char *buf, off_t len) |
| +{ |
| + /* |
| + * Only zImage loading is supported. Do not check if |
| + * the buffer is valid kernel image |
| + */ |
| + return 0; |
| +} |
| +void zImage_arm_usage(void) |
| +{ |
| +} |
| +int zImage_arm_load(int argc, char **argv, const char *buf, off_t len, |
| + struct kexec_info *info) |
| +{ |
| + unsigned long base; |
| + unsigned int offset = 0x8000; /* 32k offset from memory start */ |
| + base = locate_hole(info,len+offset,0,0,ULONG_MAX,INT_MAX); |
| + if (base == ULONG_MAX) |
| + { |
| + return -1; |
| + } |
| + base += offset; |
| + add_segment(info,buf,len,base,len); |
| + info->entry = (void*)base; |
| + return 0; |
| +} |
| diff -rduNp kexec-tools-1.101.orig/kexec/kexec-syscall.h kexec-tools-1.101/kexec/kexec-syscall.h |
| --- kexec-tools-1.101.orig/kexec/kexec-syscall.h 2006-09-20 04:39:38.000000000 +0200 |
| +++ kexec-tools-1.101/kexec/kexec-syscall.h 2007-01-22 15:54:14.000000000 +0100 |
| @@ -43,6 +43,9 @@ |
| #ifdef __s390__ |
| #define __NR_kexec_load 277 |
| #endif |
| +#ifdef __arm__ |
| +#define __NR_kexec_load __NR_SYSCALL_BASE + 189 |
| +#endif |
| #ifndef __NR_kexec_load |
| #error Unknown processor architecture. Needs a kexec_load syscall number. |
| #endif |
| @@ -74,6 +77,7 @@ static inline long kexec_reboot(void) |
| #define KEXEC_ARCH_PPC64 (21 << 16) |
| #define KEXEC_ARCH_IA_64 (50 << 16) |
| #define KEXEC_ARCH_S390 (22 << 16) |
| +#define KEXEC_ARCH_ARM (40 << 16) |
| |
| #define KEXEC_MAX_SEGMENTS 16 |
| |
| diff -rduNp kexec-tools-1.101.orig/purgatory/arch/arm/Makefile kexec-tools-1.101/purgatory/arch/arm/Makefile |
| --- kexec-tools-1.101.orig/purgatory/arch/arm/Makefile 1970-01-01 01:00:00.000000000 +0100 |
| +++ kexec-tools-1.101/purgatory/arch/arm/Makefile 2007-01-22 15:54:14.000000000 +0100 |
| @@ -0,0 +1,7 @@ |
| +# |
| +# Purgatory arm |
| +# |
| + |
| +PURGATORY_S_SRCS += |
| +PURGATORY_C_SRCS += |
| + |
| diff -rduNp kexec-tools-1.101.orig/purgatory/arch/arm/include/limits.h kexec-tools-1.101/purgatory/arch/arm/include/limits.h |
| --- kexec-tools-1.101.orig/purgatory/arch/arm/include/limits.h 1970-01-01 01:00:00.000000000 +0100 |
| +++ kexec-tools-1.101/purgatory/arch/arm/include/limits.h 2007-01-22 15:54:14.000000000 +0100 |
| @@ -0,0 +1,58 @@ |
| +#ifndef LIMITS_H |
| +#define LIMITS_H 1 |
| + |
| + |
| +/* Number of bits in a `char' */ |
| +#define CHAR_BIT 8 |
| + |
| +/* Minimum and maximum values a `signed char' can hold */ |
| +#define SCHAR_MIN (-128) |
| +#define SCHAR_MAX 127 |
| + |
| +/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */ |
| +#define UCHAR_MAX 255 |
| + |
| +/* Minimum and maximum values a `char' can hold */ |
| +#define CHAR_MIN SCHAR_MIN |
| +#define CHAR_MAX SCHAR_MAX |
| + |
| +/* Minimum and maximum values a `signed short int' can hold */ |
| +#define SHRT_MIN (-32768) |
| +#define SHRT_MAX 32767 |
| + |
| +/* Maximum value an `unsigned short' can hold. (Minimum is 0.) */ |
| +#define USHRT_MAX 65535 |
| + |
| + |
| +/* Minimum and maximum values a `signed int' can hold */ |
| +#define INT_MIN (-INT_MAX - 1) |
| +#define INT_MAX 2147483647 |
| + |
| +/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */ |
| +#define UINT_MAX 4294967295U |
| + |
| + |
| +/* Minimum and maximum values a `signed int' can hold */ |
| +#define INT_MIN (-INT_MAX - 1) |
| +#define INT_MAX 2147483647 |
| + |
| +/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */ |
| +#define UINT_MAX 4294967295U |
| + |
| +/* Minimum and maximum values a `signed long' can hold */ |
| +#define LONG_MAX 2147483647L |
| +#define LONG_MIN (-LONG_MAX - 1L) |
| + |
| +/* Maximum value an `unsigned long' can hold. (Minimum is 0.) */ |
| +#define ULONG_MAX 4294967295UL |
| + |
| +/* Minimum and maximum values a `signed long long' can hold */ |
| +#define LLONG_MAX 9223372036854775807LL |
| +#define LLONG_MIN (-LONG_MAX - 1LL) |
| + |
| + |
| +/* Maximum value an `unsigned long long' can hold. (Minimum is 0.) */ |
| +#define ULLONG_MAX 18446744073709551615ULL |
| + |
| + |
| +#endif /* LIMITS_H */ |
| diff -rduNp kexec-tools-1.101.orig/purgatory/arch/arm/include/stdint.h kexec-tools-1.101/purgatory/arch/arm/include/stdint.h |
| --- kexec-tools-1.101.orig/purgatory/arch/arm/include/stdint.h 1970-01-01 01:00:00.000000000 +0100 |
| +++ kexec-tools-1.101/purgatory/arch/arm/include/stdint.h 2007-01-22 15:54:14.000000000 +0100 |
| @@ -0,0 +1,16 @@ |
| +#ifndef STDINT_H |
| +#define STDINT_H |
| + |
| +typedef unsigned long size_t; |
| + |
| +typedef unsigned char uint8_t; |
| +typedef unsigned short uint16_t; |
| +typedef unsigned int uint32_t; |
| +typedef unsigned long long uint64_t; |
| + |
| +typedef signed char int8_t; |
| +typedef signed short int16_t; |
| +typedef signed int int32_t; |
| +typedef signed long long int64_t; |
| + |
| +#endif /* STDINT_H */ |
| --- kexec-tools-1.101/kexec/kexec-syscall.h.orig 2007-10-18 14:28:44.000000000 +1000 |
| +++ kexec-tools-1.101/kexec/kexec-syscall.h 2007-10-18 14:28:57.000000000 +1000 |
| @@ -44,7 +44,7 @@ |
| #define __NR_kexec_load 277 |
| #endif |
| #ifdef __arm__ |
| -#define __NR_kexec_load __NR_SYSCALL_BASE + 189 |
| +#define __NR_kexec_load __NR_SYSCALL_BASE + 347 |
| #endif |
| #ifndef __NR_kexec_load |
| #error Unknown processor architecture. Needs a kexec_load syscall number. |