From 103c946e39eb9dd57ccbda20ac12ccb01f883c17 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Thu, 21 Sep 2006 14:51:44 -0400 Subject: kexec-tools: x86_64 read kernel vaddr and size from /proc/kcore o With relocatable kernel in picture, the kernel text map offset (__START_KERNEL_map) is no longer constant. It depends on where kernel is loaded. o Now /proc/kcore is read to determine the virtual address the kernel is mapped at and /porc/iomem is read for determining the physical address where kernel is loaded at. This information is enough to create to fill virtual address and phy addr info for elf header mapping kernel text and data. o Virtual address for kernel text are needed by gdb as well as crash to retrieve the meaningful data from core file. o This patch requires "elf note memsz" fix in the kernel. Currently that fix is in -mm tree. It will still work with older kernels. It will display the warning messages (/proc/kcore could not be parsed) and hardcode the kernel virtual address and size. Signed-off-by: Vivek Goyal Signed-off-by: Simon Horman --- kexec/kexec.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'kexec/kexec.c') diff --git a/kexec/kexec.c b/kexec/kexec.c index a32cacb..ce0663e 100644 --- a/kexec/kexec.c +++ b/kexec/kexec.c @@ -392,6 +392,50 @@ char *slurp_file(const char *filename, off_t *r_size) return buf; } +/* This functions reads either specified number of bytes from the file or + lesser if EOF is met. */ + +char *slurp_file_len(const char *filename, off_t size) +{ + int fd; + char *buf; + off_t progress; + ssize_t result; + + if (!filename) + return 0; + fd = open(filename, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Cannot open %s: %s\n", filename, + strerror(errno)); + return 0; + } + buf = xmalloc(size); + progress = 0; + while(progress < size) { + result = read(fd, buf + progress, size - progress); + if (result < 0) { + if ((errno == EINTR) || (errno == EAGAIN)) + continue; + fprintf(stderr, "read on %s of %ld bytes failed: %s\n", + filename, (size - progress)+ 0UL, + strerror(errno)); + free(buf); + return 0; + } + if (result == 0) + /* EOF */ + break; + progress += result; + } + result = close(fd); + if (result < 0) { + die("Close of %s failed: %s\n", + filename, strerror(errno)); + } + return buf; +} + #if HAVE_ZLIB_H char *slurp_decompress_file(const char *filename, off_t *r_size) { -- cgit