aboutsummaryrefslogtreecommitdiffstats
path: root/package/kexec/kexec-tools-arm.patch
blob: 6765db7af01c40d28ef4ebb84ae6329dfca56877 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
diff -uNr kexec-tools-1.101.orig/configure kexec-tools-1.101/configure
--- kexec-tools-1.101.orig/configure	2005-02-16 13:37:44.000000000 +0100
+++ kexec-tools-1.101/configure	2006-12-17 23:05:16.000000000 +0100
@@ -1381,6 +1381,9 @@
 	i?86 )
 		host_cpu="i386"
 		;;
+	arm )
+		host_cpu="arm"
+		;;
 	powerpc )
 		host_cpu="ppc"
 		;;
@@ -1389,7 +1392,7 @@
 		;;
 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 -uNr 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	2006-12-17 23:05:16.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 -uNr 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	2006-12-17 23:05:16.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 -uNr 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	2006-12-17 23:05:16.000000000 +0100
@@ -0,0 +1,133 @@
+/*
+ * 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)
+{
+	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, unsigned long *flags)
+{
+	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)
+	{
+		*flags |= KEXEC_ARCH_ARM;
+	}
+	else {
+		fprintf(stderr, "Unsupported machine type: %s\n",
+			utsname.machine);
+		return -1;
+	}
+	return 0;
+}
+
+void arch_update_purgatory(struct kexec_info *info)
+{
+}
+
diff -uNr 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	2006-12-17 23:05:16.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 -uNr 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	2006-12-17 23:05:16.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 -uNr 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	2006-12-17 23:05:16.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 -uNr 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	2005-01-06 07:59:50.000000000 +0100
+++ kexec-tools-1.101/kexec/kexec-syscall.h	2006-12-17 23:05:16.000000000 +0100
@@ -37,6 +37,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
@@ -67,6 +70,7 @@
 #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 -uNr 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	2006-12-17 23:05:16.000000000 +0100
@@ -0,0 +1,7 @@
+#
+# Purgatory arm
+#
+
+PURGATORY_S_SRCS += 
+PURGATORY_C_SRCS += 
+
diff -uNr 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	2006-12-17 23:05:16.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 -uNr 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	2006-12-17 23:05:16.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 */
diff -ur kexec-tools-1.101/kexec/arch/arm/kexec-arm.c kexec-tools-1.101.patched/kexec/arch/arm/kexec-arm.c
--- kexec-tools-1.101.orig/kexec/arch/arm/kexec-arm.c	2006-12-20 16:41:12.000000000 +0100
+++ kexec-tools-1.101/kexec/arch/arm/kexec-arm.c	2006-12-20 16:40:19.000000000 +0100
@@ -105,7 +105,7 @@
 	return 0;
 }
 
-int arch_compat_trampoline(struct kexec_info *info, unsigned long *flags)
+int arch_compat_trampoline(struct kexec_info *info)
 {
 	int result;
 	struct utsname utsname;
@@ -115,11 +115,8 @@
 			strerror(errno));
 		return -1;
 	}
-	if (strncmp(utsname.machine, "arm",3) == 0)
+	if (strncmp(utsname.machine, "arm",3) != 0)
 	{
-		*flags |= KEXEC_ARCH_ARM;
-	}
-	else {
 		fprintf(stderr, "Unsupported machine type: %s\n",
 			utsname.machine);
 		return -1;
diff -ur kexec-tools-1.101/kexec/kexec.c kexec-tools-1.101.patched/kexec/kexec.c
--- kexec-tools-1.101.orig/kexec/kexec.c	2006-09-20 04:39:38.000000000 +0200
+++ kexec-tools-1.101/kexec/kexec.c	2006-12-20 16:39:10.000000000 +0100
@@ -532,8 +532,7 @@
 		kernel_buf, kernel_size);
 #endif
 
-	if (get_memory_ranges(&memory_range, &memory_ranges,
-		info.kexec_flags) < 0) {
+	if (get_memory_ranges(&memory_range, &memory_ranges) < 0) {
 		fprintf(stderr, "Could not get memory layout\n");
 		return -1;
 	}
diff -ur kexec-tools-1.101/kexec/kexec.h kexec-tools-1.101.patched/kexec/kexec.h
--- kexec-tools-1.101.orig/kexec/kexec.h	2006-09-20 04:39:38.000000000 +0200
+++ kexec-tools-1.101/kexec/kexec.h	2006-12-20 16:40:47.000000000 +0100
@@ -119,8 +119,7 @@
 };
 
 void usage(void);
-int get_memory_ranges(struct memory_range **range, int *ranges,
-						unsigned long kexec_flags);
+int get_memory_ranges(struct memory_range **range, int *ranges);
 int valid_memory_range(unsigned long sstart, unsigned long send);
 int valid_memory_segment(struct kexec_segment *segment);
 void print_segments(FILE *file, struct kexec_info *info);
diff -ur kexec-tools-1.101.orig/kexec/kexec.c kexec-tools-1.101/kexec/kexec.c
--- kexec-tools-1.101.orig/kexec/kexec.c	2006-12-20 17:04:59.000000000 +0100
+++ kexec-tools-1.101/kexec/kexec.c	2006-12-20 17:05:33.000000000 +0100
@@ -630,16 +630,11 @@
 static int my_shutdown(void)
 {
 	char *args[8];
-	int i = 0;
 
-	args[i++] = "shutdown";
-	args[i++] = "-r";
-	args[i++] = "now";
-	args[i++] = NULL;
-
-	execv("/sbin/shutdown", args);
-	execv("/etc/shutdown", args);
-	execv("/bin/shutdown", args);
+	args[0] = "reboot";
+	args[1] = NULL;
+
+	execv("/sbin/reboot", args);
 
 	perror("shutdown");
 	return -1;