126 lines
3.6 KiB
Diff
126 lines
3.6 KiB
Diff
--- kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.h.orig 2006-12-01 14:36:39.000000000 -0500
|
|
+++ kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.h 2006-12-01 14:49:13.000000000 -0500
|
|
@@ -7,6 +7,10 @@
|
|
int elf_ia64_load(int argc, char **argv, const char *buf, off_t len,
|
|
struct kexec_info *info);
|
|
void elf_ia64_usage(void);
|
|
+int update_loaded_segments(struct kexec_info *info, struct mem_ehdr *ehdr);
|
|
+void move_loaded_segments(struct kexec_info *info, struct mem_ehdr *ehdr,
|
|
+ unsigned long addr);
|
|
+
|
|
#define MAX_MEMORY_RANGES 1024
|
|
#define EFI_PAGE_SIZE (1UL<<12)
|
|
#define ELF_PAGE_SIZE (1UL<<16)
|
|
--- kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.c.orig 2006-12-01 14:36:39.000000000 -0500
|
|
+++ kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.c 2006-12-01 14:55:16.000000000 -0500
|
|
@@ -28,14 +28,16 @@
|
|
#include <string.h>
|
|
#include <getopt.h>
|
|
#include <sched.h>
|
|
+#include <limits.h>
|
|
#include <sys/utsname.h>
|
|
#include "../../kexec.h"
|
|
#include "../../kexec-syscall.h"
|
|
+#include "elf.h"
|
|
#include "kexec-ia64.h"
|
|
#include <arch/options.h>
|
|
|
|
static struct memory_range memory_range[MAX_MEMORY_RANGES];
|
|
-
|
|
+static int memory_ranges;
|
|
/* Reserve range for EFI memmap and Boot parameter */
|
|
static int split_range(int range, unsigned long start, unsigned long end)
|
|
{
|
|
@@ -73,7 +75,6 @@
|
|
unsigned long kexec_flags)
|
|
{
|
|
const char iomem[]= "/proc/iomem";
|
|
- int memory_ranges = 0;
|
|
char line[MAX_LINE];
|
|
FILE *fp;
|
|
fp = fopen(iomem, "r");
|
|
@@ -209,6 +210,45 @@
|
|
return 0;
|
|
}
|
|
|
|
+int update_loaded_segments(struct kexec_info *info, struct mem_ehdr *ehdr)
|
|
+{
|
|
+ int i;
|
|
+ struct mem_phdr *phdr;
|
|
+ unsigned long start_addr = ULONG_MAX, end_addr = 0;
|
|
+ unsigned long align = 1UL<<26; // 64M
|
|
+ for(i = 0; i < ehdr->e_phnum; i++) {
|
|
+ phdr = &ehdr->e_phdr[i];
|
|
+ if (phdr->p_type == PT_LOAD) {
|
|
+ if (phdr->p_paddr < start_addr)
|
|
+ start_addr = phdr->p_paddr;
|
|
+ if ((phdr->p_paddr + phdr->p_memsz) > end_addr)
|
|
+ end_addr = phdr->p_paddr + phdr->p_memsz;
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < memory_ranges
|
|
+ && memory_range[i].start <= start_addr; i++) {
|
|
+ if (memory_range[i].type == RANGE_RAM &&
|
|
+ memory_range[i].end > end_addr)
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < memory_ranges; i++) {
|
|
+ if (memory_range[i].type == RANGE_RAM) {
|
|
+ unsigned long start =
|
|
+ (memory_range[i].start + align - 1)&~(align - 1);
|
|
+ unsigned long end = memory_range[i].end;
|
|
+ if (end > start &&
|
|
+ (end - start) > (end_addr - start_addr)) {
|
|
+ move_loaded_segments(info, ehdr, start);
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return 1;
|
|
+}
|
|
+
|
|
void arch_update_purgatory(struct kexec_info *info)
|
|
{
|
|
}
|
|
--- kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c.orig 2006-12-01 14:36:39.000000000 -0500
|
|
+++ kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c 2006-12-01 14:59:29.000000000 -0500
|
|
@@ -84,7 +84,8 @@
|
|
|
|
/* Move the crash kerenl physical offset to reserved region
|
|
*/
|
|
-static void move_loaded_segments(struct kexec_info *info, struct mem_ehdr *ehdr)
|
|
+void move_loaded_segments(struct kexec_info *info, struct mem_ehdr *ehdr,
|
|
+ unsigned long addr)
|
|
{
|
|
int i;
|
|
long offset;
|
|
@@ -92,7 +93,7 @@
|
|
for(i = 0; i < ehdr->e_phnum; i++) {
|
|
phdr = &ehdr->e_phdr[i];
|
|
if (phdr->p_type == PT_LOAD) {
|
|
- offset = mem_min - phdr->p_paddr;
|
|
+ offset = addr - phdr->p_paddr;
|
|
break;
|
|
}
|
|
}
|
|
@@ -174,8 +175,14 @@
|
|
fprintf(stderr, "Failed to find crash kernel region in /proc/iomem\n");
|
|
return -1;
|
|
}
|
|
- move_loaded_segments(info, &ehdr);
|
|
- }
|
|
+ move_loaded_segments(info, &ehdr, mem_min);
|
|
+ } else {
|
|
+ if (update_loaded_segments(info, &ehdr)) {
|
|
+ fprintf(stderr, "Failed to place kernel\n");
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
|
|
entry = ehdr.e_entry;
|
|
max_addr = elf_max_addr(&ehdr);
|