Compress base.img using FastLZ library
This commit is contained in:
115
kernel/FastLZ/6unpack_mem.c
Normal file
115
kernel/FastLZ/6unpack_mem.c
Normal file
@ -0,0 +1,115 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "hal/hal.h"
|
||||
#include "fastlz.h"
|
||||
|
||||
#define SIXPACK_OK 0
|
||||
#define SIXPACK_ERR_MAGIC -1
|
||||
#define SIXPACK_ERR_CHECKSUM -2
|
||||
#define SIXPACK_ERR_DECOMPRESS -3
|
||||
#define SIXPACK_ERR_BAD_FORMAT -4
|
||||
#define SIXPACK_ERR_NO_SPACE -5
|
||||
|
||||
#define ADLER32_BASE 65521
|
||||
#define BLOCK_SIZE 65536
|
||||
|
||||
static const uint8_t sixpack_magic[8] = {137, '6', 'P', 'K', 13, 10, 26, 10};
|
||||
|
||||
static uint32_t update_adler32(uint32_t checksum, const void *buf, int len) {
|
||||
const uint8_t *ptr = (const uint8_t*)buf;
|
||||
uint32_t s1 = checksum & 0xffff;
|
||||
uint32_t s2 = (checksum >> 16) & 0xffff;
|
||||
|
||||
while (len > 0) {
|
||||
unsigned k = len < 5552 ? len : 5552;
|
||||
len -= k;
|
||||
while (k--) {
|
||||
s1 += *ptr++;
|
||||
if (s1 >= ADLER32_BASE) s1 -= ADLER32_BASE;
|
||||
s2 += s1;
|
||||
if (s2 >= ADLER32_BASE) s2 -= ADLER32_BASE;
|
||||
}
|
||||
}
|
||||
return (s2 << 16) + s1;
|
||||
}
|
||||
|
||||
static uint32_t readU16(const uint8_t *p) {
|
||||
return (uint32_t)p[0] | ((uint32_t)p[1] << 8);
|
||||
}
|
||||
static uint32_t readU32(const uint8_t *p) {
|
||||
return (uint32_t)p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24);
|
||||
}
|
||||
|
||||
static void read_chunk_header(const uint8_t *p, int *id, int *opts,
|
||||
uint32_t *size, uint32_t *checksum, uint32_t *extra) {
|
||||
*id = (int)readU16(p);
|
||||
*opts = (int)readU16(p + 2);
|
||||
*size = readU32(p + 4);
|
||||
*checksum = readU32(p + 8);
|
||||
*extra = readU32(p + 12);
|
||||
}
|
||||
|
||||
int sixpack_decompress_mem(const uint8_t *input, size_t in_size,
|
||||
uint8_t *output, size_t out_cap)
|
||||
{
|
||||
if (!input || in_size < 8)
|
||||
return SIXPACK_ERR_BAD_FORMAT;
|
||||
|
||||
/* Check magic */
|
||||
for (int i = 0; i < 8; i++)
|
||||
if (input[i] != sixpack_magic[i])
|
||||
return SIXPACK_ERR_MAGIC;
|
||||
|
||||
size_t pos = 8; /* skip magic */
|
||||
size_t written = 0;
|
||||
|
||||
while (pos + 16 <= in_size) {
|
||||
int chunk_id, opts;
|
||||
uint32_t size, checksum, extra;
|
||||
|
||||
read_chunk_header(input + pos, &chunk_id, &opts, &size, &checksum, &extra);
|
||||
pos += 16;
|
||||
|
||||
if (pos + size > in_size)
|
||||
return SIXPACK_ERR_BAD_FORMAT;
|
||||
|
||||
const uint8_t *chunk_data = input + pos;
|
||||
pos += size;
|
||||
|
||||
/* File header chunk */
|
||||
if (chunk_id == 1) {
|
||||
uint32_t decomp_size = readU32(chunk_data);
|
||||
(void)decomp_size; /* not strictly needed here */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Data chunk */
|
||||
if (chunk_id == 17) {
|
||||
uint32_t cksum = update_adler32(1L, chunk_data, size);
|
||||
if (cksum != checksum)
|
||||
return SIXPACK_ERR_CHECKSUM;
|
||||
|
||||
if (opts == 0) {
|
||||
/* Stored (uncompressed) */
|
||||
if (written + size > out_cap)
|
||||
return SIXPACK_ERR_NO_SPACE;
|
||||
hal_memcpy(output + written, chunk_data, size);
|
||||
written += size;
|
||||
} else if (opts == 1) {
|
||||
/* FastLZ compressed */
|
||||
if (written + extra > out_cap)
|
||||
return SIXPACK_ERR_NO_SPACE;
|
||||
|
||||
int dec = fastlz_decompress(chunk_data, size, output + written, extra);
|
||||
if (dec != (int)extra)
|
||||
return SIXPACK_ERR_DECOMPRESS;
|
||||
|
||||
written += extra;
|
||||
} else {
|
||||
return SIXPACK_ERR_BAD_FORMAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (int)written;
|
||||
}
|
||||
7
kernel/FastLZ/6unpack_mem.h
Normal file
7
kernel/FastLZ/6unpack_mem.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef SIXUNPACK_MEM_H_
|
||||
#define SIXUNPACK_MEM_H_
|
||||
|
||||
int sixpack_decompress_mem(const uint8_t *input, size_t in_size,
|
||||
uint8_t *output, size_t out_cap);
|
||||
|
||||
#endif // SIXUNPACK_MEM_H_
|
||||
1
kernel/FastLZ/fastlz.c
Symbolic link
1
kernel/FastLZ/fastlz.c
Symbolic link
@ -0,0 +1 @@
|
||||
../../FastLZ/fastlz.c
|
||||
1
kernel/FastLZ/fastlz.h
Symbolic link
1
kernel/FastLZ/fastlz.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../FastLZ/fastlz.h
|
||||
@ -20,6 +20,7 @@ CFLAGS += -I. \
|
||||
-DLFS_NO_DEBUG \
|
||||
-DLFS_NO_WARN \
|
||||
-DLFS_NO_ERROR \
|
||||
-DFASTLZ_USE_MEMMOVE=0 \
|
||||
|
||||
include arch/$(ARCH)/$(ARCH).mk
|
||||
include extconf/extra.mk
|
||||
@ -58,6 +59,7 @@ SRCFILES += $(call GRABSRC, \
|
||||
randcrypto \
|
||||
time \
|
||||
diskpart \
|
||||
FastLZ \
|
||||
)
|
||||
|
||||
CFILES := $(call GET_CFILES, $(SRCFILES))
|
||||
|
||||
@ -6,32 +6,40 @@
|
||||
#include "kprintf.h"
|
||||
#include "util/util.h"
|
||||
#include "hal/hal.h"
|
||||
#include "dlmalloc/malloc.h"
|
||||
#include "FastLZ/fastlz.h"
|
||||
#include "FastLZ/6unpack_mem.h"
|
||||
|
||||
struct limine_file *baseimg = NULL;
|
||||
#define BASEIMG_DECOMPRESSED (1024*1024*4)
|
||||
|
||||
size_t BASEIMG_DECOMP_SIZE;
|
||||
uint8_t *BASEIMG_DECOMP_ADDR;
|
||||
|
||||
uint64_t baseimg_getaddr(void) {
|
||||
return (uint64_t)baseimg->address;
|
||||
return (uint64_t)BASEIMG_DECOMP_ADDR;
|
||||
}
|
||||
|
||||
uint64_t baseimg_getsize(void) {
|
||||
return baseimg->size;
|
||||
return (uint64_t)BASEIMG_DECOMP_SIZE;
|
||||
}
|
||||
|
||||
void baseimg_init(void) {
|
||||
struct limine_file *baseimg = NULL;
|
||||
|
||||
LOG("baseimg", "looking for base image...\n");
|
||||
for (size_t i = 0; i < BOOT_INFO.modules->module_count; i++) {
|
||||
struct limine_file *module = BOOT_INFO.modules->modules[i];
|
||||
if (hal_strcmp(util_get_filename(module->path), "base.img") == 0) {
|
||||
if (hal_strcmp(util_get_filename(module->path), "base.img.6pack") == 0) {
|
||||
baseimg = module;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (baseimg == NULL) {
|
||||
ERR("baseimg", "base.img not found\n");
|
||||
ERR("baseimg", "base.img.6pack not found\n");
|
||||
hal_hang();
|
||||
} else {
|
||||
LOG("baseimg", "base.img found\n");
|
||||
LOG("baseimg", "base.img.6pack found\n");
|
||||
LOG("baseimg", "addr = %p, size = %lu\n", baseimg->address, baseimg->size);
|
||||
for (size_t i = 0; i < 30; i++) {
|
||||
kprintf("%02X ", ((uint8_t *)(baseimg->address))[i]);
|
||||
@ -40,4 +48,14 @@ void baseimg_init(void) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BASEIMG_DECOMP_ADDR = dlmalloc(BASEIMG_DECOMPRESSED);
|
||||
int res = sixpack_decompress_mem(baseimg->address, baseimg->size,
|
||||
BASEIMG_DECOMP_ADDR, BASEIMG_DECOMPRESSED);
|
||||
if (res < 0) {
|
||||
ERR("baseimg", "could not uncompress base.img.6pack\n");
|
||||
hal_hang();
|
||||
}
|
||||
BASEIMG_DECOMP_SIZE = res;
|
||||
kprintf("%p %zu\n", BASEIMG_DECOMP_ADDR, BASEIMG_DECOMP_SIZE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user