* grub-core/loader/i386/coreboot/chainloader.c: Support lzma-compressed
payload.
This commit is contained in:
parent
3617c59bab
commit
8997730612
3 changed files with 61 additions and 4 deletions
|
@ -1,3 +1,8 @@
|
|||
2013-11-10 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/loader/i386/coreboot/chainloader.c: Support lzma-compressed
|
||||
payload.
|
||||
|
||||
2013-11-10 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* include/grub/lib/LzmaDec.h: Fix to include LzmaTypes.h and
|
||||
|
|
|
@ -1685,6 +1685,7 @@ module = {
|
|||
efi = loader/efi/chainloader.c;
|
||||
i386_pc = loader/i386/pc/chainloader.c;
|
||||
i386_coreboot = loader/i386/coreboot/chainloader.c;
|
||||
i386_coreboot = lib/LzmaDec.c;
|
||||
enable = i386_pc;
|
||||
enable = i386_coreboot;
|
||||
enable = efi;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/cbfs_core.h>
|
||||
#include <grub/lib/LzmaDec.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -124,16 +125,21 @@ load_elf (grub_file_t file, const char *filename)
|
|||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static void *SzAlloc(void *p __attribute__ ((unused)), size_t size) { return grub_malloc (size); }
|
||||
static void SzFree(void *p __attribute__ ((unused)), void *address) { grub_free (address); }
|
||||
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||
|
||||
|
||||
static grub_err_t
|
||||
load_segment (grub_file_t file, const char *filename,
|
||||
void *load_addr, grub_uint32_t comp,
|
||||
grub_size_t size)
|
||||
grub_size_t *size, grub_size_t max_size)
|
||||
{
|
||||
switch (comp)
|
||||
{
|
||||
case grub_cpu_to_be32_compile_time (CBFS_COMPRESS_NONE):
|
||||
if (grub_file_read (file, load_addr, size)
|
||||
!= (grub_ssize_t) size)
|
||||
if (grub_file_read (file, load_addr, *size)
|
||||
!= (grub_ssize_t) *size)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR,
|
||||
|
@ -142,6 +148,49 @@ load_segment (grub_file_t file, const char *filename,
|
|||
return grub_errno;
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
case grub_cpu_to_be32_compile_time (CBFS_COMPRESS_LZMA):
|
||||
{
|
||||
grub_uint8_t *buf;
|
||||
grub_size_t outsize, insize;
|
||||
SRes res;
|
||||
SizeT src_len, dst_len;
|
||||
ELzmaStatus status;
|
||||
if (*size < 13)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "invalid compressed chunk");
|
||||
buf = grub_malloc (*size);
|
||||
if (!buf)
|
||||
return grub_errno;
|
||||
if (grub_file_read (file, load_addr, *size)
|
||||
!= (grub_ssize_t) *size)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR,
|
||||
N_("premature end of file %s"),
|
||||
filename);
|
||||
grub_free (buf);
|
||||
return grub_errno;
|
||||
}
|
||||
outsize = grub_get_unaligned64 (buf + 5);
|
||||
if (outsize > max_size)
|
||||
{
|
||||
grub_free (buf);
|
||||
return grub_error (GRUB_ERR_BAD_OS, "invalid compressed chunk");
|
||||
}
|
||||
insize = *size - 13;
|
||||
|
||||
src_len = insize;
|
||||
dst_len = outsize;
|
||||
res = LzmaDecode (load_addr, &dst_len, buf + 13, &src_len,
|
||||
buf, 5, LZMA_FINISH_END, &status, &g_Alloc);
|
||||
/* ELzmaFinishMode finishMode,
|
||||
ELzmaStatus *status, ISzAlloc *alloc)*/
|
||||
grub_free (buf);
|
||||
if (res != SZ_OK
|
||||
|| src_len != insize || dst_len != outsize)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "decompression failure %d", res);
|
||||
*size = outsize;
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
default:
|
||||
return grub_error (GRUB_ERR_BAD_OS, "unsupported compression %d",
|
||||
grub_be_to_cpu32 (comp));
|
||||
|
@ -192,6 +241,8 @@ load_chewed (grub_file_t file, const char *filename)
|
|||
if (memsize < filesize)
|
||||
memsize = filesize;
|
||||
|
||||
grub_dprintf ("chain", "%x+%x\n", target, memsize);
|
||||
|
||||
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||
target, memsize);
|
||||
if (err)
|
||||
|
@ -206,7 +257,7 @@ load_chewed (grub_file_t file, const char *filename)
|
|||
return grub_errno;
|
||||
|
||||
err = load_segment (file, filename, load_addr,
|
||||
segment.compression, filesize);
|
||||
segment.compression, &filesize, memsize);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue