summaryrefslogtreecommitdiff
path: root/kexec/kexec.c
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@in.ibm.com>2006-09-21 14:51:44 -0400
committerSimon Horman <horms@verge.net.au>2006-10-06 12:46:16 +0900
commit103c946e39eb9dd57ccbda20ac12ccb01f883c17 (patch)
tree439847d98ca015f0675690fd61cb3a16dd1c7216 /kexec/kexec.c
parentf11123aa03a7e8bfee165a56f7f1f6d8baa1d163 (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.c44
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)
{