Compress base.img using FastLZ library

This commit is contained in:
2025-11-09 21:38:27 +01:00
parent e4a5c07b3d
commit 02d60129b1
58 changed files with 3676 additions and 10 deletions

115
kernel/FastLZ/6unpack_mem.c Normal file
View 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;
}

View 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
View File

@ -0,0 +1 @@
../../FastLZ/fastlz.c

1
kernel/FastLZ/fastlz.h Symbolic link
View File

@ -0,0 +1 @@
../../FastLZ/fastlz.h

View File

@ -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))

View File

@ -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);
}