809 lines
25 KiB
Diff
809 lines
25 KiB
Diff
--- kexec-tools-1.101/Makefile.orig 2006-10-20 13:38:53.000000000 -0400
|
|
+++ kexec-tools-1.101/Makefile 2006-10-20 13:39:08.000000000 -0400
|
|
@@ -43,6 +43,7 @@
|
|
PKGINCLUDEIR=$(INCLUDEDIR)/$(PACKAGE)
|
|
|
|
MAN_PAGES:= kexec/kexec.8
|
|
+MAN_PAGES+= kdump/kdump.8
|
|
BINARIES_i386:= $(SBINDIR)/kexec $(PKGLIBDIR)/kexec_test $(SBINDIR)/kdump
|
|
BINARIES_x86_64:=$(SBINDIR)/kexec $(PKGLIBDIR)/kexec_test
|
|
BINARIES:=$(SBINDIR)/kexec $(BINARIES_$(ARCH))
|
|
--- /dev/null 2006-10-19 09:27:39.770809345 -0400
|
|
+++ kexec-tools-1.101/kdump/kdump.8 2006-10-20 13:39:08.000000000 -0400
|
|
@@ -0,0 +1,39 @@
|
|
+.\" Hey, EMACS: -*- nroff -*-
|
|
+.\" First parameter, NAME, should be all caps
|
|
+.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
|
+.\" other parameters are allowed: see man(7), man(1)
|
|
+.TH KDUMP 8 "Jul 27, 2005"
|
|
+.\" Please adjust this date whenever revising the manpage.
|
|
+.\"
|
|
+.\" Some roff macros, for reference:
|
|
+.\" .nh disable hyphenation
|
|
+.\" .hy enable hyphenation
|
|
+.\" .ad l left justify
|
|
+.\" .ad b justify to both left and right margins
|
|
+.\" .nf disable filling
|
|
+.\" .fi enable filling
|
|
+.\" .br insert line break
|
|
+.\" .sp <n> insert n+1 empty lines
|
|
+.\" for manpage-specific macros, see man(7)
|
|
+.SH NAME
|
|
+kdump \- This is just a placeholder until real man page has been written
|
|
+.SH SYNOPSIS
|
|
+.B kdump
|
|
+.RI [ options ] " start_address" ...
|
|
+.SH DESCRIPTION
|
|
+.PP
|
|
+.\" TeX users may be more comfortable with the \fB<whatever>\fP and
|
|
+.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
|
|
+.\" respectively.
|
|
+\fBkdump\fP does not have a man page yet.
|
|
+.SH OPTIONS
|
|
+.\"These programs follow the usual GNU command line syntax, with long
|
|
+.\"options starting with two dashes (`-').
|
|
+.\"A summary of options is included below.
|
|
+.\"For a complete description, see the Info files.
|
|
+.SH SEE ALSO
|
|
+.SH AUTHOR
|
|
+kdump was written by Eric Biederman.
|
|
+.PP
|
|
+This manual page was written by Khalid Aziz <khalid.aziz@hp.com>,
|
|
+for the Debian project (but may be used by others).
|
|
--- kexec-tools-1.101/purgatory/arch/ia64/Makefile.orig 2004-12-20 17:44:22.000000000 -0500
|
|
+++ kexec-tools-1.101/purgatory/arch/ia64/Makefile 2006-10-20 13:39:08.000000000 -0400
|
|
@@ -1,8 +1,8 @@
|
|
#
|
|
# Purgatory ia64
|
|
#
|
|
-
|
|
-PURGATORY_S_SRCS+=
|
|
+PCFLAGS += -ffixed-r28
|
|
+PURGATORY_S_SRCS+= purgatory/arch/ia64/entry.S
|
|
PURGATORY_C_SRCS+= purgatory/arch/ia64/purgatory-ia64.c
|
|
PURGATORY_C_SRCS+= purgatory/arch/ia64/console-ia64.c
|
|
PURGATORY_C_SRCS+=
|
|
--- /dev/null 2006-10-19 09:27:39.770809345 -0400
|
|
+++ kexec-tools-1.101/purgatory/arch/ia64/include/arch/io.h 2006-10-20 13:39:08.000000000 -0400
|
|
@@ -0,0 +1,25 @@
|
|
+#ifndef ARCH_IO_H
|
|
+#define ARCH_IO_H
|
|
+
|
|
+#include <stdint.h>
|
|
+/* Helper functions for directly doing I/O */
|
|
+
|
|
+extern inline uint8_t inb(void *port)
|
|
+{
|
|
+ volatile unsigned char *addr = (unsigned char *)port;
|
|
+ uint8_t result;
|
|
+
|
|
+ result = *addr;
|
|
+ asm volatile ("mf.a"::: "memory");
|
|
+ return result;
|
|
+}
|
|
+
|
|
+extern inline void outb (uint8_t value, void *port)
|
|
+{
|
|
+ volatile unsigned char *addr = (unsigned char *)port;
|
|
+
|
|
+ *addr = value;
|
|
+ asm volatile ("mf.a"::: "memory");
|
|
+}
|
|
+
|
|
+#endif /* ARCH_IO_H */
|
|
--- /dev/null 2006-10-19 09:27:39.770809345 -0400
|
|
+++ kexec-tools-1.101/purgatory/arch/ia64/entry.S 2006-10-20 13:39:08.000000000 -0400
|
|
@@ -0,0 +1,85 @@
|
|
+/*
|
|
+ * purgatory: setup code
|
|
+ *
|
|
+ * Copyright (C) 2005 Zou Nan hai (nanhai.zou@intel.com)
|
|
+ *
|
|
+ * 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 (version 2 of the License).
|
|
+ *
|
|
+ * 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
+ */
|
|
+
|
|
+.global __dummy_efi_function
|
|
+.align 32
|
|
+.proc __dummy_efi_function
|
|
+__dummy_efi_function:
|
|
+ mov r8=r0;;
|
|
+ br.ret.sptk.many rp;;
|
|
+.global __dummy_efi_function_end
|
|
+__dummy_efi_function_end:
|
|
+.endp __dummy_efi_function
|
|
+
|
|
+.global purgatory_start
|
|
+.align 32
|
|
+.proc purgatory_start
|
|
+purgatory_start:
|
|
+ movl r2=__gp_value;;
|
|
+ ld8 gp=[r2];;
|
|
+ br.call.sptk.many b0=purgatory
|
|
+ ;;
|
|
+ alloc r2 = ar.pfs, 0, 0, 5, 0
|
|
+ ;;
|
|
+ mov out0=r28
|
|
+
|
|
+ movl r2=__command_line;;
|
|
+ ld8 out1=[r2];;
|
|
+ movl r2=__command_line_len;;
|
|
+ ld8 out2=[r2];;
|
|
+ movl r2=__ramdisk_base;;
|
|
+ ld8 out3=[r2];;
|
|
+ movl r2=__ramdisk_size;;
|
|
+ ld8 out4=[r2];;
|
|
+ br.call.sptk.many b0=ia64_env_setup
|
|
+ movl r10=__kernel_entry;;
|
|
+ ld8 r14=[r10];;
|
|
+ mov b6=r14;;
|
|
+ mov ar.lc=r0
|
|
+ mov ar.ec=r0
|
|
+ cover;;
|
|
+ invala;;
|
|
+ br.call.sptk.many b0=b6
|
|
+.endp purgatory_start
|
|
+
|
|
+.align 32
|
|
+.global __kernel_entry
|
|
+.size __kernel_entry, 8
|
|
+__kernel_entry:
|
|
+ data8 0x0
|
|
+.global __command_line
|
|
+.size __command_line, 8
|
|
+__command_line:
|
|
+ data8 0x0
|
|
+.global __command_line_len
|
|
+.size __command_line_len, 8
|
|
+__command_line_len:
|
|
+ data8 0x0
|
|
+.global __ramdisk_base
|
|
+.size __ramdisk_base, 8
|
|
+__ramdisk_base:
|
|
+ data8 0x0
|
|
+.global __ramdisk_size
|
|
+.size __ramdisk_size, 8
|
|
+__ramdisk_size:
|
|
+ data8 0x0
|
|
+.global __gp_value
|
|
+.size __gp_value, 8
|
|
+__gp_value:
|
|
+ data8 0x0
|
|
--- kexec-tools-1.101/purgatory/arch/ia64/purgatory-ia64.c.orig 2006-10-20 13:38:53.000000000 -0400
|
|
+++ kexec-tools-1.101/purgatory/arch/ia64/purgatory-ia64.c 2006-10-20 13:39:08.000000000 -0400
|
|
@@ -1,10 +1,116 @@
|
|
#include <purgatory.h>
|
|
+#include <stdint.h>
|
|
+#include <string.h>
|
|
#include "purgatory-ia64.h"
|
|
|
|
+#define PAGE_OFFSET 0xe000000000000000
|
|
+
|
|
+typedef struct {
|
|
+ uint64_t signature;
|
|
+ uint32_t revision;
|
|
+ uint32_t headersize;
|
|
+ uint32_t crc32;
|
|
+ uint32_t reserved;
|
|
+} efi_table_hdr_t;
|
|
+
|
|
+typedef struct {
|
|
+ efi_table_hdr_t hdr;
|
|
+ unsigned long get_time;
|
|
+ unsigned long set_time;
|
|
+ unsigned long get_wakeup_time;
|
|
+ unsigned long set_wakeup_time;
|
|
+ unsigned long set_virtual_address_map;
|
|
+ unsigned long convert_pointer;
|
|
+ unsigned long get_variable;
|
|
+ unsigned long get_next_variable;
|
|
+ unsigned long set_variable;
|
|
+ unsigned long get_next_high_mono_count;
|
|
+ unsigned long reset_system;
|
|
+} efi_runtime_services_t;
|
|
+
|
|
+typedef struct {
|
|
+ efi_table_hdr_t hdr;
|
|
+ unsigned long fw_vendor; /* physical addr of CHAR16 vendor string
|
|
+ */
|
|
+ uint32_t fw_revision;
|
|
+ unsigned long con_in_handle;
|
|
+ unsigned long con_in;
|
|
+ unsigned long con_out_handle;
|
|
+ unsigned long con_out;
|
|
+ unsigned long stderr_handle;
|
|
+ unsigned long stderr;
|
|
+ unsigned long runtime;
|
|
+ unsigned long boottime;
|
|
+ unsigned long nr_tables;
|
|
+ unsigned long tables;
|
|
+} efi_system_table_t;
|
|
+
|
|
+struct ia64_boot_param {
|
|
+ uint64_t command_line; /* physical address of command line arguments */
|
|
+ uint64_t efi_systab; /* physical address of EFI system table */
|
|
+ uint64_t efi_memmap; /* physical address of EFI memory map */
|
|
+ uint64_t efi_memmap_size; /* size of EFI memory map */
|
|
+ uint64_t efi_memdesc_size; /* size of an EFI memory map descriptor */
|
|
+ uint32_t efi_memdesc_version; /* memory descriptor version */
|
|
+ struct {
|
|
+ uint16_t num_cols; /* number of columns on console output device */
|
|
+ uint16_t num_rows; /* number of rows on console output device */
|
|
+ uint16_t orig_x; /* cursor's x position */
|
|
+ uint16_t orig_y; /* cursor's y position */
|
|
+ } console_info;
|
|
+ uint64_t fpswa; /* physical address of the fpswa interface */
|
|
+ uint64_t initrd_start;
|
|
+ uint64_t initrd_size;
|
|
+};
|
|
+
|
|
void setup_arch(void)
|
|
{
|
|
/* Nothing for now */
|
|
}
|
|
+inline unsigned long PA(unsigned long addr)
|
|
+{
|
|
+ return addr - PAGE_OFFSET;
|
|
+}
|
|
+
|
|
+void flush_icache_range(char *start, unsigned long len)
|
|
+{
|
|
+ unsigned long i;
|
|
+ for (i = 0;i < len; i += 32)
|
|
+ asm volatile("fc.i %0"::"r"(start+i):"memory");
|
|
+ asm volatile (";;sync.i;;":::"memory");
|
|
+ asm volatile ("srlz.i":::"memory");
|
|
+}
|
|
+
|
|
+extern char __dummy_efi_function[], __dummy_efi_function_end[];
|
|
+
|
|
+void ia64_env_setup(struct ia64_boot_param *boot_param,
|
|
+ uint64_t command_line, uint64_t command_line_len,
|
|
+ uint64_t ramdisk_base, uint64_t ramdisk_size)
|
|
+{
|
|
+ unsigned long len;
|
|
+ efi_system_table_t *systab;
|
|
+ efi_runtime_services_t *runtime;
|
|
+ unsigned long *set_virtual_address_map;
|
|
+
|
|
+ // patch efi_runtime->set_virtual_address_map to a
|
|
+ // dummy function
|
|
+ len = __dummy_efi_function_end - __dummy_efi_function;
|
|
+ memcpy((char *)command_line + command_line_len, __dummy_efi_function,
|
|
+ len);
|
|
+ systab = (efi_system_table_t *)boot_param->efi_systab;
|
|
+ runtime = (efi_runtime_services_t *)PA(systab->runtime);
|
|
+ set_virtual_address_map =
|
|
+ (unsigned long *)PA(runtime->set_virtual_address_map);
|
|
+ *(set_virtual_address_map)=
|
|
+ (unsigned long)((char *)command_line + command_line_len);
|
|
+ flush_icache_range((char *)command_line+command_line_len, len);
|
|
+
|
|
+ boot_param->command_line = command_line;
|
|
+ boot_param->console_info.orig_x = 0;
|
|
+ boot_param->console_info.orig_y = 0;
|
|
+ boot_param->initrd_start = ramdisk_base;
|
|
+ boot_param->initrd_size = ramdisk_size;
|
|
+}
|
|
|
|
/* This function can be used to execute after the SHA256 verification. */
|
|
void post_verification_setup_arch(void)
|
|
--- kexec-tools-1.101/kexec/Makefile.orig 2006-10-20 13:38:53.000000000 -0400
|
|
+++ kexec-tools-1.101/kexec/Makefile 2006-10-20 13:39:08.000000000 -0400
|
|
@@ -28,6 +28,7 @@
|
|
KEXEC_OBJS:= $(KEXEC_C_OBJS) $(KEXEC_S_OBJS)
|
|
KEXEC_DEPS:= $(KEXEC_C_DEPS) $(KEXEC_S_DEPS)
|
|
KEXEC:= $(SBINDIR)/kexec
|
|
+KEXEC_MANPAGE:= $(MANDIR)/man8/kexec.8
|
|
|
|
include $(KEXEC_DEPS)
|
|
|
|
@@ -51,6 +52,9 @@
|
|
mkdir -p $(@D)
|
|
$(CC) $(KCFLAGS) -o $@ $(KEXEC_OBJS) $(UTIL_LIB) $(LIBS)
|
|
|
|
+$(KEXEC_MANPAGE): kexec/kexec.8
|
|
+ $(MKDIR) -p $(MANDIR)/man8
|
|
+ cp kexec/kexec.8 $(KEXEC_MANPAGE)
|
|
echo::
|
|
@echo "KEXEC_C_SRCS $(KEXEC_C_SRCS)"
|
|
@echo "KEXEC_C_DEPS $(KEXEC_C_DEPS)"
|
|
--- kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.h.orig 2004-12-19 18:52:38.000000000 -0500
|
|
+++ kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.h 2006-10-20 13:39:08.000000000 -0400
|
|
@@ -1,6 +1,8 @@
|
|
#ifndef KEXEC_IA64_H
|
|
#define KEXEC_IA64_H
|
|
|
|
+#define MAX_MEMORY_RANGES 1024
|
|
+
|
|
int elf_ia64_probe(const char *buf, off_t len);
|
|
int elf_ia64_load(int argc, char **argv, const char *buf, off_t len,
|
|
struct kexec_info *info);
|
|
--- kexec-tools-1.101/kexec/arch/ia64/kexec-elf-rel-ia64.c.orig 2004-12-20 17:43:23.000000000 -0500
|
|
+++ kexec-tools-1.101/kexec/arch/ia64/kexec-elf-rel-ia64.c 2006-10-20 13:39:08.000000000 -0400
|
|
@@ -1,8 +1,14 @@
|
|
+/* Most of the code in this file is
|
|
+ * based on arch/ia64/kernel/module.c in Linux kernel
|
|
+ */
|
|
+
|
|
#include <stdio.h>
|
|
#include <elf.h>
|
|
#include "../../kexec.h"
|
|
#include "../../kexec-elf.h"
|
|
|
|
+#define MAX_LTOFF ((uint64_t) (1 << 22))
|
|
+
|
|
int machine_verify_elf_rel(struct mem_ehdr *ehdr)
|
|
{
|
|
if (ehdr->ei_data != ELFDATA2LSB) {
|
|
@@ -17,12 +23,40 @@
|
|
return 1;
|
|
}
|
|
|
|
+static void
|
|
+ia64_patch (uint64_t insn_addr, uint64_t mask, uint64_t val)
|
|
+{
|
|
+ uint64_t m0, m1, v0, v1, b0, b1, *b = (uint64_t *) (insn_addr & -16);
|
|
+# define insn_mask ((1UL << 41) - 1)
|
|
+ unsigned long shift;
|
|
+
|
|
+ b0 = b[0]; b1 = b[1];
|
|
+ shift = 5 + 41 * (insn_addr % 16); /* 5 bits of template, then 3 x 41-bit instructions */
|
|
+ if (shift >= 64) {
|
|
+ m1 = mask << (shift - 64);
|
|
+ v1 = val << (shift - 64);
|
|
+ } else {
|
|
+ m0 = mask << shift; m1 = mask >> (64 - shift);
|
|
+ v0 = val << shift; v1 = val >> (64 - shift);
|
|
+ b[0] = (b0 & ~m0) | (v0 & m0);
|
|
+ }
|
|
+ b[1] = (b1 & ~m1) | (v1 & m1);
|
|
+}
|
|
+
|
|
+static inline uint64_t
|
|
+bundle (const uint64_t insn)
|
|
+{
|
|
+ return insn & ~0xfUL;
|
|
+}
|
|
+
|
|
void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type,
|
|
void *location, unsigned long address, unsigned long value)
|
|
{
|
|
+ uint64_t gp_value = ehdr->rel_addr + 0x200000;
|
|
switch(r_type) {
|
|
case R_IA64_NONE:
|
|
break;
|
|
+ case R_IA64_SEGREL64LSB:
|
|
case R_IA64_DIR64LSB:
|
|
*((uint64_t *)location) = value;
|
|
break;
|
|
@@ -31,15 +65,67 @@
|
|
if (value != *((uint32_t *)location))
|
|
goto overflow;
|
|
break;
|
|
- case R_IA64_PCREL21B:
|
|
+ case R_IA64_IMM64:
|
|
+ ia64_patch((uint64_t)location, 0x01fffefe000UL,
|
|
+ /* bit 63 -> 36 */
|
|
+ (((value & 0x8000000000000000UL) >> 27)
|
|
+ /* bit 21 -> 21 */
|
|
+ | ((value & 0x0000000000200000UL) << 0)
|
|
+ /* bit 16 -> 22 */
|
|
+ | ((value & 0x00000000001f0000UL) << 6)
|
|
+ /* bit 7 -> 27 */
|
|
+ | ((value & 0x000000000000ff80UL) << 20)
|
|
+ /* bit 0 -> 13 */
|
|
+ | ((value & 0x000000000000007fUL) << 13)));
|
|
+ ia64_patch((uint64_t)location - 1, 0x1ffffffffffUL, value>>22);
|
|
+ break;
|
|
+ case R_IA64_IMM22:
|
|
+ if (value + (1 << 21) >= (1 << 22))
|
|
+ die("value out of IMM22 range\n");
|
|
+ ia64_patch((uint64_t)location, 0x01fffcfe000UL,
|
|
+ /* bit 21 -> 36 */
|
|
+ (((value & 0x200000UL) << 15)
|
|
+ /* bit 16 -> 22 */
|
|
+ | ((value & 0x1f0000UL) << 6)
|
|
+ /* bit 7 -> 27 */
|
|
+ | ((value & 0x00ff80UL) << 20)
|
|
+ /* bit 0 -> 13 */
|
|
+ | ((value & 0x00007fUL) << 13) ));
|
|
+ break;
|
|
+ case R_IA64_PCREL21B: {
|
|
+ uint64_t delta = ((int64_t)value - (int64_t)address)/16;
|
|
+ if (delta + (1 << 20) >= (1 << 21))
|
|
+ die("value out of IMM21B range\n");
|
|
+ value = ((int64_t)(value - bundle(address)))/16;
|
|
+ ia64_patch((uint64_t)location, 0x11ffffe000UL,
|
|
+ (((value & 0x100000UL) << 16) /* bit 20 -> 36 */
|
|
+ | ((value & 0x0fffffUL) << 13) /* bit 0 -> 13 */));
|
|
+ }
|
|
+ break;
|
|
+ case R_IA64_LTOFF22X:
|
|
+ if (value - gp_value + MAX_LTOFF/2 >= MAX_LTOFF)
|
|
+ die("value out of gp relative range");
|
|
+ value -= gp_value;
|
|
+ ia64_patch((uint64_t)location, 0x01fffcfe000UL,
|
|
+ (((value & 0x200000UL) << 15) /* bit 21 -> 36 */
|
|
+ |((value & 0x1f0000UL) << 6) /* bit 16 -> 22 */
|
|
+ |((value & 0x00ff80UL) << 20) /* bit 7 -> 27 */
|
|
+ |((value & 0x00007fUL) << 13) /* bit 0 -> 13 */));
|
|
+ break;
|
|
+ case R_IA64_LDXMOV:
|
|
+ if (value - gp_value + MAX_LTOFF/2 >= MAX_LTOFF)
|
|
+ die("value out of gp relative range");
|
|
+ ia64_patch((uint64_t)location, 0x1fff80fe000UL, 0x10000000000UL);
|
|
+ break;
|
|
case R_IA64_LTOFF22:
|
|
- case R_IA64_SEGREL64LSB:
|
|
+
|
|
default:
|
|
- die("Unknown rela relocation: %lu\n", r_type);
|
|
+ die("Unknown rela relocation: 0x%lx 0x%lx\n",
|
|
+ r_type, address);
|
|
break;
|
|
}
|
|
return;
|
|
- overflow:
|
|
+overflow:
|
|
die("overflow in relocation type %lu val %Lx\n",
|
|
- r_type, value);
|
|
+ r_type, value);
|
|
}
|
|
--- kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c.orig 2004-12-21 15:01:37.000000000 -0500
|
|
+++ kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c 2006-10-20 13:39:08.000000000 -0400
|
|
@@ -6,6 +6,7 @@
|
|
* Copyright (C) 2004 Silicon Graphics, Inc.
|
|
* Jesse Barnes <jbarnes@sgi.com>
|
|
* Copyright (C) 2004 Khalid Aziz <khalid.aziz@hp.com> Hewlett Packard Co
|
|
+ * Copyright (C) 2005 Zou Nan hai <nanhai.zou@intel.com> Intel Corp
|
|
*
|
|
* 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
|
|
@@ -34,6 +35,7 @@
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <getopt.h>
|
|
+#include <limits.h>
|
|
#include <elf.h>
|
|
#include <boot/elf_boot.h>
|
|
#include <ip_checksum.h>
|
|
@@ -74,23 +76,29 @@
|
|
{
|
|
printf(
|
|
" --command-line=STRING Set the kernel command line to STRING.\n"
|
|
- " --append=STRING Set the kernel command line to STRING.\n");
|
|
+ " --append=STRING Set the kernel command line to STRING.\n"
|
|
+ " --initrd=FILE Use FILE as the kernel's initial ramdisk.\n");
|
|
}
|
|
|
|
int elf_ia64_load(int argc, char **argv, const char *buf, off_t len,
|
|
struct kexec_info *info)
|
|
{
|
|
struct mem_ehdr ehdr;
|
|
- const char *command_line;
|
|
- int command_line_len;
|
|
- unsigned long entry, max_addr;
|
|
+ const char *command_line, *ramdisk=0;
|
|
+ char *ramdisk_buf = NULL;
|
|
+ off_t ramdisk_size = 0;
|
|
+ unsigned long command_line_len;
|
|
+ unsigned long entry, max_addr, gp_value;
|
|
+ unsigned command_line_base, ramdisk_base;
|
|
int result;
|
|
int opt;
|
|
#define OPT_APPEND (OPT_ARCH_MAX+0)
|
|
+#define OPT_RAMDISK (OPT_ARCH_MAX+1)
|
|
static const struct option options[] = {
|
|
KEXEC_ARCH_OPTIONS
|
|
{"command-line", 1, 0, OPT_APPEND},
|
|
{"append", 1, 0, OPT_APPEND},
|
|
+ {"initrd", 1, 0, OPT_RAMDISK},
|
|
{0, 0, 0, 0},
|
|
};
|
|
|
|
@@ -110,11 +118,14 @@
|
|
case OPT_APPEND:
|
|
command_line = optarg;
|
|
break;
|
|
+ case OPT_RAMDISK:
|
|
+ ramdisk = optarg;
|
|
+ break;
|
|
}
|
|
}
|
|
command_line_len = 0;
|
|
if (command_line) {
|
|
- command_line_len = strlen(command_line) + 1;
|
|
+ command_line_len = strlen(command_line) + 16;
|
|
}
|
|
|
|
/* Parse the Elf file */
|
|
@@ -129,13 +140,46 @@
|
|
|
|
/* Load the Elf data */
|
|
result = elf_exec_load(&ehdr, info);
|
|
- free_elf_info(&ehdr);
|
|
if (result < 0) {
|
|
fprintf(stderr, "ELF load failed\n");
|
|
+ free_elf_info(&ehdr);
|
|
return result;
|
|
}
|
|
+
|
|
+
|
|
+ /* Load the setup code */
|
|
+ elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size,
|
|
+ 0x80000, ULONG_MAX, 1);
|
|
+
|
|
+ if (command_line_len) {
|
|
+ char *cmdline = xmalloc(command_line_len);
|
|
+ strcpy(cmdline, command_line);
|
|
+ command_line_len = (command_line_len + 15)&(~15);
|
|
+ elf_rel_set_symbol(&info->rhdr, "__command_line_len",
|
|
+ &command_line_len, sizeof(long));
|
|
+ command_line_base = add_buffer(info, cmdline,
|
|
+ command_line_len, command_line_len,
|
|
+ 16, 0, max_addr, 1);
|
|
+ elf_rel_set_symbol(&info->rhdr, "__command_line",
|
|
+ &command_line_base, sizeof(long));
|
|
+ }
|
|
|
|
- /* For now we don't have arguments to pass :( */
|
|
- info->entry = (void *)entry;
|
|
+ if (ramdisk) {
|
|
+ ramdisk_buf = slurp_file(ramdisk, &ramdisk_size);
|
|
+ ramdisk_base = add_buffer(info, ramdisk_buf, ramdisk_size,
|
|
+ ramdisk_size,
|
|
+ getpagesize(), 0, max_addr, 1);
|
|
+ elf_rel_set_symbol(&info->rhdr, "__ramdisk_base",
|
|
+ &ramdisk_base, sizeof(long));
|
|
+ elf_rel_set_symbol(&info->rhdr, "__ramdisk_size",
|
|
+ &ramdisk_size, sizeof(long));
|
|
+ }
|
|
+
|
|
+ gp_value = info->rhdr.rel_addr + 0x200000;
|
|
+ elf_rel_set_symbol(&info->rhdr, "__gp_value", &gp_value,
|
|
+ sizeof(gp_value));
|
|
+
|
|
+ elf_rel_set_symbol(&info->rhdr, "__kernel_entry", &entry, sizeof(entry));
|
|
+ free_elf_info(&ehdr);
|
|
return 0;
|
|
}
|
|
--- kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.c.orig 2006-10-20 13:38:53.000000000 -0400
|
|
+++ kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.c 2006-10-20 13:39:08.000000000 -0400
|
|
@@ -27,42 +27,87 @@
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <getopt.h>
|
|
+#include <sched.h>
|
|
#include <sys/utsname.h>
|
|
#include "../../kexec.h"
|
|
#include "../../kexec-syscall.h"
|
|
#include "kexec-ia64.h"
|
|
#include <arch/options.h>
|
|
|
|
-#define MAX_MEMORY_RANGES 64
|
|
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)
|
|
{
|
|
- int memory_ranges;
|
|
- /*
|
|
- * /proc/iomem on ia64 does not show where all memory is. If
|
|
- * that is fixed up, we can make use of that to validate
|
|
- * the memory range kernel will be loade din. Until then.....
|
|
- * -- Khalid Aziz
|
|
- */
|
|
-
|
|
- /* Note that the ia64 architecture mandates all systems will
|
|
- * have at least 64MB at 0-64M. The SGI altix does not follow
|
|
- * that restriction, but a reasonable guess is better than nothing
|
|
- * at all.
|
|
- * -- Eric Biederman
|
|
- */
|
|
- fprintf(stderr, "Warning assuming memory at 0-64MB is present\n");
|
|
- memory_ranges = 0;
|
|
- memory_range[memory_ranges].start = 0x00010000;
|
|
- memory_range[memory_ranges].end = 0x10000000;
|
|
- memory_range[memory_ranges].type = RANGE_RAM;
|
|
- memory_ranges++;
|
|
- *range = memory_range;
|
|
- *ranges = memory_ranges;
|
|
- return 0;
|
|
+ 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 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 if (memcmp(str, "Crash kernel\n", 13) == 0) {
|
|
+ /* Redefine the memory region boundaries if kernel
|
|
+ * exports the limits and if it is panic kernel.
|
|
+ * Override user values only if kernel exported
|
|
+ * values are subset of user defined values.
|
|
+ */
|
|
+
|
|
+ if (kexec_flags & KEXEC_ON_CRASH) {
|
|
+ if (start > mem_min)
|
|
+ mem_min = start;
|
|
+ if (end < mem_max)
|
|
+ mem_max = end;
|
|
+ }
|
|
+ continue;
|
|
+ } else
|
|
+ continue;
|
|
+ /*
|
|
+ * Check if this memory range can be coalesced with
|
|
+ * the previous range
|
|
+ */
|
|
+ if ((memory_ranges > 0) &&
|
|
+ (start == memory_range[memory_ranges-1].end) &&
|
|
+ (type == memory_range[memory_ranges-1].type)) {
|
|
+ memory_range[memory_ranges-1].end = end;
|
|
+ }
|
|
+ else {
|
|
+ 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 */
|
|
@@ -76,9 +121,6 @@
|
|
{
|
|
}
|
|
|
|
-static struct {
|
|
-} arch_options = {
|
|
-};
|
|
int arch_process_options(int argc, char **argv)
|
|
{
|
|
static const struct option options[] = {
|
|
@@ -88,6 +130,12 @@
|
|
static const char short_options[] = KEXEC_ARCH_OPT_STR;
|
|
int opt;
|
|
|
|
+ /* execute from monarch processor */
|
|
+ cpu_set_t affinity;
|
|
+ CPU_ZERO(&affinity);
|
|
+ CPU_SET(0, &affinity);
|
|
+ sched_setaffinity(0, sizeof(affinity), &affinity);
|
|
+
|
|
opterr = 0; /* Don't complain about unrecognized options here */
|
|
while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) {
|
|
switch(opt) {
|
|
@@ -113,10 +161,7 @@
|
|
}
|
|
if (strcmp(utsname.machine, "ia64") == 0)
|
|
{
|
|
- /* For compatibility with older patches
|
|
- * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_IA64 here.
|
|
- */
|
|
- info->kexec_flags |= KEXEC_ARCH_DEFAULT;
|
|
+ info->kexec_flags |= KEXEC_ARCH_IA_64;
|
|
}
|
|
else {
|
|
fprintf(stderr, "Unsupported machine type: %s\n",
|
|
--- kexec-tools-1.101/kexec/kexec.8.orig 2004-12-19 17:27:31.000000000 -0500
|
|
+++ kexec-tools-1.101/kexec/kexec.8 2006-10-20 13:39:08.000000000 -0400
|
|
@@ -2,7 +2,7 @@
|
|
.\" First parameter, NAME, should be all caps
|
|
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
|
.\" other parameters are allowed: see man(7), man(1)
|
|
-.TH KEXEC-TOOLS 8 "October 13, 2004"
|
|
+.TH KEXEC 8 "October 13, 2004"
|
|
.\" Please adjust this date whenever revising the manpage.
|
|
.\"
|
|
.\" Some roff macros, for reference:
|
|
@@ -16,30 +16,60 @@
|
|
.\" .sp <n> insert n+1 empty lines
|
|
.\" for manpage-specific macros, see man(7)
|
|
.SH NAME
|
|
-kexec-tools \- Tool to load a kernel for warm reboot and initiate a warm reboot
|
|
+kexec \- Tool to load a kernel for warm reboot and initiate a warm reboot
|
|
.SH SYNOPSIS
|
|
-.B kexec-tools
|
|
+.B kexec
|
|
.RI [ options ] " files" ...
|
|
.SH DESCRIPTION
|
|
.PP
|
|
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
|
|
.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
|
|
.\" respectively.
|
|
-\fBkexec-tools\fP does not have a man page yet. Please use "kexec -h" for help.
|
|
+\fBkexec\fP allows one to load another kernel from the currently running
|
|
+Linux kernel. Normally one would load a kernel, and possibly an initial
|
|
+ramdisk, into the currently running kernel using kexec and then initiate
|
|
+a warm reboot by executing kexec again with appropriate option.
|
|
.SH OPTIONS
|
|
These programs follow the usual GNU command line syntax, with long
|
|
options starting with two dashes (`-').
|
|
A summary of options is included below.
|
|
-For a complete description, see the Info files.
|
|
.TP
|
|
.B \-h, \-\-help
|
|
Show summary of options.
|
|
.TP
|
|
.B \-v, \-\-version
|
|
Show version of program.
|
|
-.SH SEE ALSO
|
|
+.TP
|
|
+.B \-f, \-\-force
|
|
+Force an immediate kexec without calling shutdown.
|
|
+.TP
|
|
+.B \-x, \-\-no-ifdown
|
|
+Don't bring down network interfaces. (if used, must be last option specified)
|
|
+.TP
|
|
+.B \-l, \-\-load
|
|
+Load the new kernel into the current kernel.
|
|
+.TP
|
|
+.B \-p, \-\-load-panic
|
|
+Load the new kernel for use on panic.
|
|
+.TP
|
|
+.B \-u, \-\-unload
|
|
+Unload the current kexec target kernel.
|
|
+.TP
|
|
+.B \-e, \-\-exec
|
|
+Execute a currently loaded kernel.
|
|
+.TP
|
|
+.B \-t, \-\-type=TYPE
|
|
+Specify the new kernel is of this type.
|
|
+.TP
|
|
+.B \-\-mem\-min=<addr>
|
|
+Specify the lowest memory addres to load code into.
|
|
+.TP
|
|
+.B \-\-mem\-max=<addr>
|
|
+Specify the highest memory addres to load code into.
|
|
+.TP
|
|
+There may be additional options supported on individual architectures. Use --help option to see those options.
|
|
.SH AUTHOR
|
|
-kexec-tools was written by Eric Biederman.
|
|
+kexec was written by Eric Biederman.
|
|
.PP
|
|
-This manual page was written by Khalid Aziz <khalid_aziz@hp.com>,
|
|
+This manual page was written by Khalid Aziz <khalid.aziz@hp.com>,
|
|
for the Debian project (but may be used by others).
|