added an option to do LZMA decompress on the splash data, in order to do this, adjusted some code in other files.
Signed-off-by: Wayne Xia xiawenc@linux.vnet.ibm.com --- src/bootsplash.c | 35 ++++++++++++++++++++++++++++++++--- src/coreboot.c | 47 ++++++----------------------------------------- src/lzmadecode.c | 28 ++++++++++++++++++++++++++++ src/lzmadecode.h | 2 ++ 4 files changed, 68 insertions(+), 44 deletions(-)
diff --git a/src/bootsplash.c b/src/bootsplash.c index a68766c..67491bf 100644 --- a/src/bootsplash.c +++ b/src/bootsplash.c @@ -13,6 +13,7 @@ #include "biosvar.h" // SET_EBDA #include "paravirt.h" // romfile_find #include "bmp.h" +#include "lzmadecode.h"
/**************************************************************** * VESA structures @@ -155,17 +156,22 @@ enable_bootsplash(void) return; dprintf(3, "start showing bootsplash\n"); u8 type = 0; /* 0 means jpg, 1 means bmp, default is 0=jpg */ + u8 lzma_flag = 0; /* indicate whether need lzma decompress */ int filesize; u8 *filedata; int romsize; u8 *romdata; + u8 *lzma_output = NULL;
/* load rom data */ romdata = romfile_loadfile("bootsplash.jpg", &romsize); if (!romdata) { romdata = romfile_loadfile("bootsplash.bmp", &romsize); if (!romdata) { - return; + romdata = romfile_loadfile("bootsplash.lzma", &romsize); + if (!romdata) + return; + lzma_flag = 1; } } if (romsize < 16) { @@ -173,8 +179,27 @@ enable_bootsplash(void) return; }
- filedata = romdata; - filesize = romsize; + /* decompress the lzma data */ + if (lzma_flag == 1) { + filesize = *(int *)&romdata[5]; /* max = 4G/2 */ + if (filesize < 0) { + dprintf(1, "lzma data have a wrong size\n"); + } + lzma_output = malloc_tmphigh(filesize); + if (!lzma_output) { + warn_noalloc(); + return; + } + int ulzma_ret = ulzma(lzma_output, filesize, romdata, romsize); + if (ulzma_ret < 0) { + dprintf(1, "lzma decompress failed with code %d\n", ulzma_ret); + return; + } + filedata = lzma_output; + } else { + filedata = romdata; + filesize = romsize; + }
/* discover the file type */ u16 magic_id = *(u16 *)filedata; @@ -185,6 +210,8 @@ enable_bootsplash(void) type = 1; } else { dprintf(1, "splash file have a wrong magci id %x\n", magic_id); + if (lzma_output != NULL) + free(lzma_output); return; } } @@ -324,6 +351,8 @@ done: free(jpeg); if (bmp != NULL) free(bmp); + if (lzma_output != NULL) + free(lzma_output); return; }
diff --git a/src/coreboot.c b/src/coreboot.c index 6e22919..ffcfe7b 100644 --- a/src/coreboot.c +++ b/src/coreboot.c @@ -227,46 +227,6 @@ coreboot_copy_biostable(void) smbios_init(); }
- -/**************************************************************** - * ulzma - ****************************************************************/ - -// Uncompress data in flash to an area of memory. -static int -ulzma(u8 *dst, u32 maxlen, const u8 *src, u32 srclen) -{ - dprintf(3, "Uncompressing data %d@%p to %d@%p\n", srclen, src, maxlen, dst); - CLzmaDecoderState state; - int ret = LzmaDecodeProperties(&state.Properties, src, LZMA_PROPERTIES_SIZE); - if (ret != LZMA_RESULT_OK) { - dprintf(1, "LzmaDecodeProperties error - %d\n", ret); - return -1; - } - u8 scratch[15980]; - int need = (LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); - if (need > sizeof(scratch)) { - dprintf(1, "LzmaDecode need %d have %d\n", need, (unsigned int)sizeof(scratch)); - return -1; - } - state.Probs = (CProb *)scratch; - - u32 dstlen = *(u32*)(src + LZMA_PROPERTIES_SIZE); - if (dstlen > maxlen) { - dprintf(1, "LzmaDecode too large (max %d need %d)\n", maxlen, dstlen); - return -1; - } - u32 inProcessed, outProcessed; - ret = LzmaDecode(&state, src + LZMA_PROPERTIES_SIZE + 8, srclen - , &inProcessed, dst, dstlen, &outProcessed); - if (ret) { - dprintf(1, "LzmaDecode returned %d\n", ret); - return -1; - } - return dstlen; -} - - /**************************************************************** * Coreboot flash format ****************************************************************/ @@ -435,6 +395,8 @@ cbfs_copyfile(struct cbfs_file *file, void *dst, u32 maxlen) return -1; iomemcpy(temp, src, size); int ret = ulzma(dst, maxlen, temp, size); + if (ret < 0) + dprintf(1, "lzma decompress failed with code %d\n", ret); yield(); free(temp); return ret; @@ -503,8 +465,11 @@ cbfs_run_payload(struct cbfs_file *file) } else if (CONFIG_LZMA && seg->compression == htonl(CBFS_COMPRESS_LZMA)) { int ret = ulzma(dest, dest_len, src, src_len); - if (ret < 0) + if (ret < 0) { + dprintf(1, "lzma decompress failed with code %d\n", + ret); return; + } src_len = ret; } else { dprintf(1, "No support for compression type %x\n" diff --git a/src/lzmadecode.c b/src/lzmadecode.c index 65819b5..89d1836 100644 --- a/src/lzmadecode.c +++ b/src/lzmadecode.c @@ -396,3 +396,31 @@ int LzmaDecode(CLzmaDecoderState *vs, *outSizeProcessed = nowPos; return LZMA_RESULT_OK; } + +int ulzma(Byte *dst, SizeT maxlen, const Byte *src, SizeT srclen) +{ + CLzmaDecoderState state; + int ret = LzmaDecodeProperties(&state.Properties, src, + LZMA_PROPERTIES_SIZE); + if (ret != LZMA_RESULT_OK) { + return -2; + } + Byte scratch[15980]; + int need = (LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); + if (need > sizeof(scratch)) { + return -3; + } + state.Probs = (CProb *)scratch; + + SizeT dstlen = *(SizeT *)(src + LZMA_PROPERTIES_SIZE); + if (dstlen > maxlen) { + return -4; + } + SizeT inProcessed, outProcessed; + ret = LzmaDecode(&state, src + LZMA_PROPERTIES_SIZE + 8, srclen + , &inProcessed, dst, dstlen, &outProcessed); + if (ret) { + return -1; + } + return dstlen; +} diff --git a/src/lzmadecode.h b/src/lzmadecode.h index dedde0d..8991b36 100644 --- a/src/lzmadecode.h +++ b/src/lzmadecode.h @@ -64,4 +64,6 @@ int LzmaDecode(CLzmaDecoderState *vs, const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
+int ulzma(Byte *dst, SizeT maxlen, const Byte *src, SizeT srclen); + #endif