diff options
author | Florian Fainelli <florian@openwrt.org> | 2009-11-19 00:17:22 +0100 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2009-11-30 16:06:14 +1100 |
commit | 4c2d9b93150d36d15bf75b050ed97cabd9a94774 (patch) | |
tree | 32d6b5e8180ebc0b88c3df1bdce8cf825e97e3bc /kexec/kexec.c | |
parent | d61381a70a57a01b87afee90c976675f047d447d (diff) |
add support for loading lzma compressed kernels
This patch allows one to load a lzma compressed kernel using kexec -l.
As I wanted the lzma code to be very similar to the existing
zlib slurp_decompress I took lzread and associated routines
from the cpio lzma support. Tested on my x86 laptop using the
following commands:
lzma e bzImage bzImage.lzma
kexec -l bzImage.lzma
Having lzma support is particularly useful on some embedded
systems on which we have the kernel already lzma compressed
and available on a mtd partition.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'kexec/kexec.c')
-rw-r--r-- | kexec/kexec.c | 68 |
1 files changed, 9 insertions, 59 deletions
diff --git a/kexec/kexec.c b/kexec/kexec.c index 4480d9a..a1cec86 100644 --- a/kexec/kexec.c +++ b/kexec/kexec.c @@ -38,14 +38,13 @@ #include "config.h" -#ifdef HAVE_LIBZ -#include <zlib.h> -#endif #include <sha256.h> #include "kexec.h" #include "kexec-syscall.h" #include "kexec-elf.h" #include "kexec-sha256.h" +#include "kexec-zlib.h" +#include "kexec-lzma.h" #include <arch/options.h> unsigned long long mem_min = 0; @@ -554,67 +553,18 @@ char *slurp_file_len(const char *filename, off_t size) return buf; } -#if HAVE_LIBZ char *slurp_decompress_file(const char *filename, off_t *r_size) { - gzFile fp; - int errnum; - const char *msg; - char *buf; - off_t size, allocated; - ssize_t result; - - if (!filename) { - *r_size = 0; - return 0; - } - fp = gzopen(filename, "rb"); - if (fp == 0) { - msg = gzerror(fp, &errnum); - if (errnum == Z_ERRNO) { - msg = strerror(errno); - } - die("Cannot open `%s': %s\n", filename, msg); - } - size = 0; - allocated = 65536; - buf = xmalloc(allocated); - do { - if (size == allocated) { - allocated <<= 1; - buf = xrealloc(buf, allocated); - } - result = gzread(fp, buf + size, allocated - size); - if (result < 0) { - if ((errno == EINTR) || (errno == EAGAIN)) - continue; + char *kernel_buf; - msg = gzerror(fp, &errnum); - if (errnum == Z_ERRNO) { - msg = strerror(errno); - } - die ("read on %s of %ld bytes failed: %s\n", - filename, (allocated - size) + 0UL, msg); - } - size += result; - } while(result > 0); - result = gzclose(fp); - if (result != Z_OK) { - msg = gzerror(fp, &errnum); - if (errnum == Z_ERRNO) { - msg = strerror(errno); - } - die ("Close of %s failed: %s\n", filename, msg); + kernel_buf = zlib_decompress_file(filename, r_size); + if (!kernel_buf) { + kernel_buf = lzma_decompress_file(filename, r_size); + if (!kernel_buf) + return slurp_file(filename, r_size); } - *r_size = size; - return buf; + return kernel_buf; } -#else -char *slurp_decompress_file(const char *filename, off_t *r_size) -{ - return slurp_file(filename, r_size); -} -#endif static void update_purgatory(struct kexec_info *info) { |