You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
bzip2/lzma: library support for gzip, bzip2 and lzma decompression
Impact: Replaces inflate.c with a wrapper around zlib_inflate; new library code This is the first part of the bzip2/lzma patch The bzip patch is based on an idea by Christian Ludwig, includes support for compressing the kernel with bzip2 or lzma rather than gzip. Both compressors give smaller sizes than gzip. Lzma's decompresses faster than bzip2. It also supports ramdisks and initramfs' compressed using these two compressors. The functionality has been successfully used for a couple of years by the udpcast project This version applies to "tip" kernel 2.6.28 This part contains: - changed inflate.c to accomodate rest of patch - implementation of bzip2 compression (not used at this stage yet) - implementation of lzma compression (not used at this stage yet) - Makefile routines to support bzip2 and lzma kernel compression Signed-off-by: Alain Knaff <alain@knaff.lu> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
committed by
H. Peter Anvin
parent
7d3b56ba37
commit
bc22c17e12
10
include/linux/decompress/bunzip2.h
Normal file
10
include/linux/decompress/bunzip2.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef DECOMPRESS_BUNZIP2_H
|
||||||
|
#define DECOMPRESS_BUNZIP2_H
|
||||||
|
|
||||||
|
int bunzip2(unsigned char *inbuf, int len,
|
||||||
|
int(*fill)(void*, unsigned int),
|
||||||
|
int(*flush)(void*, unsigned int),
|
||||||
|
unsigned char *output,
|
||||||
|
int *pos,
|
||||||
|
void(*error)(char *x));
|
||||||
|
#endif
|
||||||
30
include/linux/decompress/generic.h
Normal file
30
include/linux/decompress/generic.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#ifndef DECOMPRESS_GENERIC_H
|
||||||
|
#define DECOMPRESS_GENERIC_H
|
||||||
|
|
||||||
|
/* Minimal chunksize to be read.
|
||||||
|
*Bzip2 prefers at least 4096
|
||||||
|
*Lzma prefers 0x10000 */
|
||||||
|
#define COMPR_IOBUF_SIZE 4096
|
||||||
|
|
||||||
|
typedef int (*decompress_fn) (unsigned char *inbuf, int len,
|
||||||
|
int(*fill)(void*, unsigned int),
|
||||||
|
int(*writebb)(void*, unsigned int),
|
||||||
|
unsigned char *output,
|
||||||
|
int *posp,
|
||||||
|
void(*error)(char *x));
|
||||||
|
|
||||||
|
/* inbuf - input buffer
|
||||||
|
*len - len of pre-read data in inbuf
|
||||||
|
*fill - function to fill inbuf if empty
|
||||||
|
*writebb - function to write out outbug
|
||||||
|
*posp - if non-null, input position (number of bytes read) will be
|
||||||
|
* returned here
|
||||||
|
*
|
||||||
|
*If len != 0, the inbuf is initialized (with as much data), and fill
|
||||||
|
*should not be called
|
||||||
|
*If len = 0, the inbuf is allocated, but empty. Its size is IOBUF_SIZE
|
||||||
|
*fill should be called (repeatedly...) to read data, at most IOBUF_SIZE
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
13
include/linux/decompress/inflate.h
Normal file
13
include/linux/decompress/inflate.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef INFLATE_H
|
||||||
|
#define INFLATE_H
|
||||||
|
|
||||||
|
/* Other housekeeping constants */
|
||||||
|
#define INBUFSIZ 4096
|
||||||
|
|
||||||
|
int gunzip(unsigned char *inbuf, int len,
|
||||||
|
int(*fill)(void*, unsigned int),
|
||||||
|
int(*flush)(void*, unsigned int),
|
||||||
|
unsigned char *output,
|
||||||
|
int *pos,
|
||||||
|
void(*error_fn)(char *x));
|
||||||
|
#endif
|
||||||
87
include/linux/decompress/mm.h
Normal file
87
include/linux/decompress/mm.h
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* linux/compr_mm.h
|
||||||
|
*
|
||||||
|
* Memory management for pre-boot and ramdisk uncompressors
|
||||||
|
*
|
||||||
|
* Authors: Alain Knaff <alain@knaff.lu>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DECOMPR_MM_H
|
||||||
|
#define DECOMPR_MM_H
|
||||||
|
|
||||||
|
#ifdef STATIC
|
||||||
|
|
||||||
|
/* Code active when included from pre-boot environment: */
|
||||||
|
|
||||||
|
/* A trivial malloc implementation, adapted from
|
||||||
|
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
|
||||||
|
*/
|
||||||
|
static unsigned long malloc_ptr;
|
||||||
|
static int malloc_count;
|
||||||
|
|
||||||
|
static void *malloc(int size)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
if (size < 0)
|
||||||
|
error("Malloc error");
|
||||||
|
if (!malloc_ptr)
|
||||||
|
malloc_ptr = free_mem_ptr;
|
||||||
|
|
||||||
|
malloc_ptr = (malloc_ptr + 3) & ~3; /* Align */
|
||||||
|
|
||||||
|
p = (void *)malloc_ptr;
|
||||||
|
malloc_ptr += size;
|
||||||
|
|
||||||
|
if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
|
||||||
|
error("Out of memory");
|
||||||
|
|
||||||
|
malloc_count++;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free(void *where)
|
||||||
|
{
|
||||||
|
malloc_count--;
|
||||||
|
if (!malloc_count)
|
||||||
|
malloc_ptr = free_mem_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define large_malloc(a) malloc(a)
|
||||||
|
#define large_free(a) free(a)
|
||||||
|
|
||||||
|
#define set_error_fn(x)
|
||||||
|
|
||||||
|
#define INIT
|
||||||
|
|
||||||
|
#else /* STATIC */
|
||||||
|
|
||||||
|
/* Code active when compiled standalone for use when loading ramdisk: */
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/vmalloc.h>
|
||||||
|
|
||||||
|
/* Use defines rather than static inline in order to avoid spurious
|
||||||
|
* warnings when not needed (indeed large_malloc / large_free are not
|
||||||
|
* needed by inflate */
|
||||||
|
|
||||||
|
#define malloc(a) kmalloc(a, GFP_KERNEL)
|
||||||
|
#define free(a) kfree(a)
|
||||||
|
|
||||||
|
#define large_malloc(a) vmalloc(a)
|
||||||
|
#define large_free(a) vfree(a)
|
||||||
|
|
||||||
|
static void(*error)(char *m);
|
||||||
|
#define set_error_fn(x) error = x;
|
||||||
|
|
||||||
|
#define INIT __init
|
||||||
|
#define STATIC
|
||||||
|
|
||||||
|
#include <linux/init.h>
|
||||||
|
|
||||||
|
#endif /* STATIC */
|
||||||
|
|
||||||
|
#endif /* DECOMPR_MM_H */
|
||||||
12
include/linux/decompress/unlzma.h
Normal file
12
include/linux/decompress/unlzma.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef DECOMPRESS_UNLZMA_H
|
||||||
|
#define DECOMPRESS_UNLZMA_H
|
||||||
|
|
||||||
|
int unlzma(unsigned char *, int,
|
||||||
|
int(*fill)(void*, unsigned int),
|
||||||
|
int(*flush)(void*, unsigned int),
|
||||||
|
unsigned char *output,
|
||||||
|
int *posp,
|
||||||
|
void(*error)(char *x)
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
735
lib/decompress_bunzip2.c
Normal file
735
lib/decompress_bunzip2.c
Normal file
File diff suppressed because it is too large
Load Diff
167
lib/decompress_inflate.c
Normal file
167
lib/decompress_inflate.c
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
#ifdef STATIC
|
||||||
|
/* Pre-boot environment: included */
|
||||||
|
|
||||||
|
/* prevent inclusion of _LINUX_KERNEL_H in pre-boot environment: lots
|
||||||
|
* errors about console_printk etc... on ARM */
|
||||||
|
#define _LINUX_KERNEL_H
|
||||||
|
|
||||||
|
#include "zlib_inflate/inftrees.c"
|
||||||
|
#include "zlib_inflate/inffast.c"
|
||||||
|
#include "zlib_inflate/inflate.c"
|
||||||
|
|
||||||
|
#else /* STATIC */
|
||||||
|
/* initramfs et al: linked */
|
||||||
|
|
||||||
|
#include <linux/zutil.h>
|
||||||
|
|
||||||
|
#include "zlib_inflate/inftrees.h"
|
||||||
|
#include "zlib_inflate/inffast.h"
|
||||||
|
#include "zlib_inflate/inflate.h"
|
||||||
|
|
||||||
|
#include "zlib_inflate/infutil.h"
|
||||||
|
|
||||||
|
#endif /* STATIC */
|
||||||
|
|
||||||
|
#include <linux/decompress/mm.h>
|
||||||
|
|
||||||
|
#define INBUF_LEN (16*1024)
|
||||||
|
|
||||||
|
/* Included from initramfs et al code */
|
||||||
|
STATIC int INIT gunzip(unsigned char *buf, int len,
|
||||||
|
int(*fill)(void*, unsigned int),
|
||||||
|
int(*flush)(void*, unsigned int),
|
||||||
|
unsigned char *out_buf,
|
||||||
|
int *pos,
|
||||||
|
void(*error_fn)(char *x)) {
|
||||||
|
u8 *zbuf;
|
||||||
|
struct z_stream_s *strm;
|
||||||
|
int rc;
|
||||||
|
size_t out_len;
|
||||||
|
|
||||||
|
set_error_fn(error_fn);
|
||||||
|
rc = -1;
|
||||||
|
if (flush) {
|
||||||
|
out_len = 0x8100; /* 32 K */
|
||||||
|
out_buf = malloc(out_len);
|
||||||
|
} else {
|
||||||
|
out_len = 0x7fffffff; /* no limit */
|
||||||
|
}
|
||||||
|
if (!out_buf) {
|
||||||
|
error("Out of memory while allocating output buffer");
|
||||||
|
goto gunzip_nomem1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf)
|
||||||
|
zbuf = buf;
|
||||||
|
else {
|
||||||
|
zbuf = malloc(INBUF_LEN);
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
if (!zbuf) {
|
||||||
|
error("Out of memory while allocating input buffer");
|
||||||
|
goto gunzip_nomem2;
|
||||||
|
}
|
||||||
|
|
||||||
|
strm = malloc(sizeof(*strm));
|
||||||
|
if (strm == NULL) {
|
||||||
|
error("Out of memory while allocating z_stream");
|
||||||
|
goto gunzip_nomem3;
|
||||||
|
}
|
||||||
|
|
||||||
|
strm->workspace = malloc(flush ? zlib_inflate_workspacesize() :
|
||||||
|
sizeof(struct inflate_state));
|
||||||
|
if (strm->workspace == NULL) {
|
||||||
|
error("Out of memory while allocating workspace");
|
||||||
|
goto gunzip_nomem4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
len = fill(zbuf, INBUF_LEN);
|
||||||
|
|
||||||
|
/* verify the gzip header */
|
||||||
|
if (len < 10 ||
|
||||||
|
zbuf[0] != 0x1f || zbuf[1] != 0x8b || zbuf[2] != 0x08) {
|
||||||
|
if (pos)
|
||||||
|
*pos = 0;
|
||||||
|
error("Not a gzip file");
|
||||||
|
goto gunzip_5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* skip over gzip header (1f,8b,08... 10 bytes total +
|
||||||
|
* possible asciz filename)
|
||||||
|
*/
|
||||||
|
strm->next_in = zbuf + 10;
|
||||||
|
/* skip over asciz filename */
|
||||||
|
if (zbuf[3] & 0x8) {
|
||||||
|
while (strm->next_in[0])
|
||||||
|
strm->next_in++;
|
||||||
|
strm->next_in++;
|
||||||
|
}
|
||||||
|
strm->avail_in = len - 10;
|
||||||
|
|
||||||
|
strm->next_out = out_buf;
|
||||||
|
strm->avail_out = out_len;
|
||||||
|
|
||||||
|
rc = zlib_inflateInit2(strm, -MAX_WBITS);
|
||||||
|
|
||||||
|
if (!flush) {
|
||||||
|
WS(strm)->inflate_state.wsize = 0;
|
||||||
|
WS(strm)->inflate_state.window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (rc == Z_OK) {
|
||||||
|
if (strm->avail_in == 0) {
|
||||||
|
/* TODO: handle case where both pos and fill are set */
|
||||||
|
len = fill(zbuf, INBUF_LEN);
|
||||||
|
if (len < 0) {
|
||||||
|
rc = -1;
|
||||||
|
error("read error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
strm->next_in = zbuf;
|
||||||
|
strm->avail_in = len;
|
||||||
|
}
|
||||||
|
rc = zlib_inflate(strm, 0);
|
||||||
|
|
||||||
|
/* Write any data generated */
|
||||||
|
if (flush && strm->next_out > out_buf) {
|
||||||
|
int l = strm->next_out - out_buf;
|
||||||
|
if (l != flush(out_buf, l)) {
|
||||||
|
rc = -1;
|
||||||
|
error("write error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
strm->next_out = out_buf;
|
||||||
|
strm->avail_out = out_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */
|
||||||
|
if (rc == Z_STREAM_END) {
|
||||||
|
rc = 0;
|
||||||
|
break;
|
||||||
|
} else if (rc != Z_OK) {
|
||||||
|
error("uncompression error");
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zlib_inflateEnd(strm);
|
||||||
|
if (pos)
|
||||||
|
/* add + 8 to skip over trailer */
|
||||||
|
*pos = strm->next_in - zbuf+8;
|
||||||
|
|
||||||
|
gunzip_5:
|
||||||
|
free(strm->workspace);
|
||||||
|
gunzip_nomem4:
|
||||||
|
free(strm);
|
||||||
|
gunzip_nomem3:
|
||||||
|
if (!buf)
|
||||||
|
free(zbuf);
|
||||||
|
gunzip_nomem2:
|
||||||
|
if (flush)
|
||||||
|
free(out_buf);
|
||||||
|
gunzip_nomem1:
|
||||||
|
return rc; /* returns Z_OK (0) if successful */
|
||||||
|
}
|
||||||
|
|
||||||
|
#define decompress gunzip
|
||||||
647
lib/decompress_unlzma.c
Normal file
647
lib/decompress_unlzma.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,6 @@
|
|||||||
|
#ifndef INFLATE_H
|
||||||
|
#define INFLATE_H
|
||||||
|
|
||||||
/* inflate.h -- internal inflate state definition
|
/* inflate.h -- internal inflate state definition
|
||||||
* Copyright (C) 1995-2004 Mark Adler
|
* Copyright (C) 1995-2004 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
@@ -105,3 +108,4 @@ struct inflate_state {
|
|||||||
unsigned short work[288]; /* work area for code table building */
|
unsigned short work[288]; /* work area for code table building */
|
||||||
code codes[ENOUGH]; /* space for code tables */
|
code codes[ENOUGH]; /* space for code tables */
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
#ifndef INFTREES_H
|
||||||
|
#define INFTREES_H
|
||||||
|
|
||||||
/* inftrees.h -- header to use inftrees.c
|
/* inftrees.h -- header to use inftrees.c
|
||||||
* Copyright (C) 1995-2005 Mark Adler
|
* Copyright (C) 1995-2005 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
@@ -53,3 +56,4 @@ typedef enum {
|
|||||||
extern int zlib_inflate_table (codetype type, unsigned short *lens,
|
extern int zlib_inflate_table (codetype type, unsigned short *lens,
|
||||||
unsigned codes, code **table,
|
unsigned codes, code **table,
|
||||||
unsigned *bits, unsigned short *work);
|
unsigned *bits, unsigned short *work);
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -186,3 +186,17 @@ quiet_cmd_gzip = GZIP $@
|
|||||||
cmd_gzip = gzip -f -9 < $< > $@
|
cmd_gzip = gzip -f -9 < $< > $@
|
||||||
|
|
||||||
|
|
||||||
|
# Bzip2
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Bzip2 does not include size in file... so we have to fake that
|
||||||
|
size_append=$(CONFIG_SHELL) $(srctree)/scripts/bin_size
|
||||||
|
|
||||||
|
quiet_cmd_bzip2 = BZIP2 $@
|
||||||
|
cmd_bzip2 = (bzip2 -9 < $< ; $(size_append) $<) > $@ || (rm -f $@ ; false)
|
||||||
|
|
||||||
|
# Lzma
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
quiet_cmd_lzma = LZMA $@
|
||||||
|
cmd_lzma = (lzma -9 -c $< ; $(size_append) $<) >$@ || (rm -f $@ ; false)
|
||||||
|
|||||||
10
scripts/bin_size
Normal file
10
scripts/bin_size
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ $# = 0 ] ; then
|
||||||
|
echo Usage: $0 file
|
||||||
|
fi
|
||||||
|
|
||||||
|
size_dec=`stat -c "%s" $1`
|
||||||
|
size_hex_echo_string=`printf "%08x" $size_dec |
|
||||||
|
sed 's/\(..\)\(..\)\(..\)\(..\)/\\\\x\4\\\\x\3\\\\x\2\\\\x\1/g'`
|
||||||
|
/bin/echo -ne $size_hex_echo_string
|
||||||
Reference in New Issue
Block a user