diff options
author | Vivek Goyal <vgoyal@in.ibm.com> | 2006-09-21 14:51:44 -0400 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2006-10-06 12:46:16 +0900 |
commit | 103c946e39eb9dd57ccbda20ac12ccb01f883c17 (patch) | |
tree | 439847d98ca015f0675690fd61cb3a16dd1c7216 /kexec/kexec.c | |
parent | f11123aa03a7e8bfee165a56f7f1f6d8baa1d163 (diff) |
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 <vgoyal@in.ibm.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'kexec/kexec.c')
-rw-r--r-- | kexec/kexec.c | 44 |
1 files changed, 44 insertions, 0 deletions
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) { |