1 --- a/arch/arm/boot/compressed/Makefile
2 +++ b/arch/arm/boot/compressed/Makefile
3 @@ -63,7 +63,7 @@ endif
5 SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
7 -targets := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \
8 +targets := vmlinux vmlinux.lds piggy.lzma piggy.o font.o font.c \
11 ifeq ($(CONFIG_FUNCTION_TRACER),y)
12 @@ -96,10 +96,10 @@ $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj
16 -$(obj)/piggy.gz: $(obj)/../Image FORCE
17 - $(call if_changed,gzip)
18 +$(obj)/piggy.lzma: $(obj)/../Image FORCE
19 + $(call if_changed,lzma)
21 -$(obj)/piggy.o: $(obj)/piggy.gz FORCE
22 +$(obj)/piggy.o: $(obj)/piggy.lzma FORCE
24 CFLAGS_font.o := -Dstatic=
26 --- a/arch/arm/boot/compressed/misc.c
27 +++ b/arch/arm/boot/compressed/misc.c
28 @@ -186,36 +186,10 @@ static inline __ptr_t memcpy(__ptr_t __d
35 -#define OF(args) args
36 -#define STATIC static
38 -typedef unsigned char uch;
39 -typedef unsigned short ush;
40 -typedef unsigned long ulg;
42 -#define WSIZE 0x8000 /* Window size must be at least 32k, */
43 +#define WSIZE 0x20000 /* Window size must be at least 128k, */
44 /* and a power of two */
46 -static uch *inbuf; /* input buffer */
47 -static uch window[WSIZE]; /* Sliding window buffer */
49 -static unsigned insize; /* valid bytes in inbuf */
50 -static unsigned inptr; /* index of next byte to be processed in inbuf */
51 -static unsigned outcnt; /* bytes in output buffer */
54 -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
55 -#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
56 -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
57 -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
58 -#define COMMENT 0x10 /* bit 4 set: file comment present */
59 -#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
60 -#define RESERVED 0xC0 /* bit 6,7: reserved */
62 -#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
63 +static u8 window[WSIZE]; /* Sliding window buffer */
65 /* Diagnostic functions */
67 @@ -234,24 +208,21 @@ static unsigned outcnt; /* bytes in out
71 -static int fill_inbuf(void);
72 -static void flush_window(void);
73 static void error(char *m);
75 extern char input_data[];
76 extern char input_data_end[];
78 -static uch *output_data;
79 -static ulg output_ptr;
80 -static ulg bytes_out;
81 +static unsigned long output_ptr;
82 +static unsigned long bytes_out;
84 static void error(char *m);
86 static void putstr(const char *);
89 -static ulg free_mem_ptr;
90 -static ulg free_mem_end_ptr;
91 +static unsigned long free_mem_ptr;
92 +static unsigned long free_mem_end_ptr;
94 #ifdef STANDALONE_DEBUG
95 #define NO_INFLATE_MALLOC
96 @@ -259,50 +230,10 @@ static ulg free_mem_end_ptr;
98 #define ARCH_HAS_DECOMP_WDOG
100 -#include "../../../../lib/inflate.c"
102 -/* ===========================================================================
103 - * Fill the input buffer. This is called only when the buffer is empty
104 - * and at least one byte is really needed.
106 -int fill_inbuf(void)
109 - error("ran out of input data");
111 - inbuf = input_data;
112 - insize = &input_data_end[0] - &input_data[0];
118 -/* ===========================================================================
119 - * Write the output window window[0..outcnt-1] and update crc and bytes_out.
120 - * (Used for the decompressed data only.)
122 -void flush_window(void)
129 - out = &output_data[output_ptr];
130 - for (n = 0; n < outcnt; n++) {
131 - ch = *out++ = *in++;
132 - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
135 - bytes_out += (ulg)outcnt;
136 - output_ptr += (ulg)outcnt;
142 #define arch_error(x)
146 static void error(char *x)
148 @@ -317,20 +248,16 @@ static void error(char *x)
150 #ifndef STANDALONE_DEBUG
153 -decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
155 +decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, unsigned long free_mem_ptr_end_p,
158 - output_data = (uch *)output_start; /* Points to kernel start */
159 - free_mem_ptr = free_mem_ptr_p;
160 - free_mem_end_ptr = free_mem_ptr_end_p;
161 __machine_arch_type = arch_id;
166 putstr("Uncompressing Linux...");
168 + output_ptr += unlzma((u8 *) output_start, input_data, window);
169 putstr(" done, booting the kernel.\n");
172 @@ -340,11 +267,8 @@ char output_buffer[1500*1024];
176 - output_data = output_buffer;
179 putstr("Uncompressing Linux...");
181 + unlzma((u8 *) output_buffer, input_data, window);
185 --- a/arch/arm/boot/compressed/piggy.S
186 +++ b/arch/arm/boot/compressed/piggy.S
188 .section .piggydata,#alloc
191 - .incbin "arch/arm/boot/compressed/piggy.gz"
192 + .incbin "arch/arm/boot/compressed/piggy.lzma"
193 .globl input_data_end
196 +++ b/arch/arm/boot/compressed/unlzma.c
199 + * Copyright (c) 2009 Felix Fietkau <nbd@openwrt.org>
201 + * This program is free software; you can redistribute it and/or
202 + * modify it under the terms of the GNU General Public License
203 + * as published by the Free Software Foundation; either version 2,
204 + * or (at your option) any later version.
206 + * This program is distributed in the hope that it will be useful,
207 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
208 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
209 + * GNU General Public License for more details.
211 + * You should have received a copy of the GNU General Public License
212 + * along with this program; if not, write to the Free Software
213 + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
218 +#include <linux/types.h>
219 +#include <asm/byteorder.h>
238 + u32 rep0, rep1, rep2, rep3;
243 +static int inbs = 0;
248 + if (unlikely(++inbs > 16 * 1024)) {
253 + return *(ctx.next_in++);
260 + ctx.code = (ctx.code << 8) | rc_read();
266 + if (ctx.range < (1 << RC_TOP_BITS)) {
276 + ctx.bound = *p * (ctx.range >> RC_MODEL_TOTAL_BITS);
277 + return ctx.code < ctx.bound;
281 +rc_update_bit_0(u16 *p)
283 + ctx.range = ctx.bound;
284 + *p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS;
288 +rc_update_bit_1(u16 *p)
290 + ctx.range -= ctx.bound;
291 + ctx.code -= ctx.bound;
292 + *p -= *p >> RC_MOVE_BITS;
296 +rc_get_bit(u16 *p, int *symbol)
298 + if (rc_is_bit_0(p)) {
299 + rc_update_bit_0(p);
303 + rc_update_bit_1(p);
304 + *symbol = *symbol * 2 + 1;
314 + if (ctx.code >= ctx.range) {
315 + ctx.code -= ctx.range;
322 +rc_bit_tree_decode(u16 *p, int num_levels, int *symbol)
324 + int i = num_levels;
328 + rc_get_bit(p + *symbol, symbol);
329 + *symbol -= 1 << num_levels;
333 +peek_old_byte(u32 offs)
335 + u32 pos = ctx.pos - offs;
336 + return ctx.outbuf[pos];
342 + ctx.previous_byte = byte;
343 + *(ctx.next_out++) = byte;
351 + write_byte(peek_old_byte(offs));
355 +copy_bytes(u32 rep0, int len)
360 + } while (len != 0);
364 +process_bit0(u16 *p, int pos_state, u16 *prob,
365 + int lc, u32 literal_pos_mask)
368 + rc_update_bit_0(prob);
369 + prob = (p + LZMA_LITERAL +
371 + * (((ctx.pos & literal_pos_mask) << lc)
372 + + (ctx.previous_byte >> (8 - lc))))
375 + if (ctx.state >= LZMA_NUM_LIT_STATES) {
376 + int match_byte = peek_old_byte(ctx.rep0);
382 + bit = match_byte & 0x100;
383 + prob_lit = prob + 0x100 + bit + mi;
384 + if (rc_get_bit(prob_lit, &mi) != !!bit)
386 + } while (mi < 0x100);
388 + while (mi < 0x100) {
389 + u16 *prob_lit = prob + mi;
390 + rc_get_bit(prob_lit, &mi);
395 + else if (ctx.state < 10)
402 +process_bit1(u16 *p, int pos_state, u16 *prob)
409 + rc_update_bit_1(prob);
410 + prob = p + LZMA_IS_REP + ctx.state;
411 + if (rc_is_bit_0(prob)) {
412 + rc_update_bit_0(prob);
413 + ctx.rep3 = ctx.rep2;
414 + ctx.rep2 = ctx.rep1;
415 + ctx.rep1 = ctx.rep0;
416 + ctx.state = ctx.state < LZMA_NUM_LIT_STATES ? 0 : 3;
417 + prob = p + LZMA_LEN_CODER;
419 + rc_update_bit_1(prob);
420 + prob = p + LZMA_IS_REP_G0 + ctx.state;
421 + if (rc_is_bit_0(prob)) {
422 + rc_update_bit_0(prob);
423 + prob = (p + LZMA_IS_REP_0_LONG
425 + LZMA_NUM_POS_BITS_MAX) +
427 + if (rc_is_bit_0(prob)) {
428 + rc_update_bit_0(prob);
430 + ctx.state = ctx.state < LZMA_NUM_LIT_STATES ?
432 + copy_byte(ctx.rep0);
435 + rc_update_bit_1(prob);
440 + rc_update_bit_1(prob);
441 + prob = p + LZMA_IS_REP_G1 + ctx.state;
442 + if (rc_is_bit_0(prob)) {
443 + rc_update_bit_0(prob);
444 + distance = ctx.rep1;
446 + rc_update_bit_1(prob);
447 + prob = p + LZMA_IS_REP_G2 + ctx.state;
448 + if (rc_is_bit_0(prob)) {
449 + rc_update_bit_0(prob);
450 + distance = ctx.rep2;
452 + rc_update_bit_1(prob);
453 + distance = ctx.rep3;
454 + ctx.rep3 = ctx.rep2;
456 + ctx.rep2 = ctx.rep1;
458 + ctx.rep1 = ctx.rep0;
459 + ctx.rep0 = distance;
461 + ctx.state = ctx.state < LZMA_NUM_LIT_STATES ? 8 : 11;
462 + prob = p + LZMA_REP_LEN_CODER;
465 + prob_len = prob + LZMA_LEN_CHOICE;
466 + if (rc_is_bit_0(prob_len)) {
467 + rc_update_bit_0(prob_len);
468 + prob_len = (prob + LZMA_LEN_LOW
470 + LZMA_LEN_NUM_LOW_BITS));
472 + num_bits = LZMA_LEN_NUM_LOW_BITS;
474 + rc_update_bit_1(prob_len);
475 + prob_len = prob + LZMA_LEN_CHOICE_2;
476 + if (rc_is_bit_0(prob_len)) {
477 + rc_update_bit_0(prob_len);
478 + prob_len = (prob + LZMA_LEN_MID
480 + LZMA_LEN_NUM_MID_BITS));
481 + offset = 1 << LZMA_LEN_NUM_LOW_BITS;
482 + num_bits = LZMA_LEN_NUM_MID_BITS;
484 + rc_update_bit_1(prob_len);
485 + prob_len = prob + LZMA_LEN_HIGH;
486 + offset = ((1 << LZMA_LEN_NUM_LOW_BITS)
487 + + (1 << LZMA_LEN_NUM_MID_BITS));
488 + num_bits = LZMA_LEN_NUM_HIGH_BITS;
492 + rc_bit_tree_decode(prob_len, num_bits, &len);
495 + if (ctx.state < 4) {
498 + ctx.state += LZMA_NUM_LIT_STATES;
500 + p + LZMA_POS_SLOT +
502 + LZMA_NUM_LEN_TO_POS_STATES ? len :
503 + LZMA_NUM_LEN_TO_POS_STATES - 1)
504 + << LZMA_NUM_POS_SLOT_BITS);
505 + rc_bit_tree_decode(prob,
506 + LZMA_NUM_POS_SLOT_BITS,
508 + if (pos_slot >= LZMA_START_POS_MODEL_INDEX) {
510 + num_bits = (pos_slot >> 1) - 1;
511 + ctx.rep0 = 2 | (pos_slot & 1);
512 + if (pos_slot < LZMA_END_POS_MODEL_INDEX) {
513 + ctx.rep0 <<= num_bits;
514 + prob = p + LZMA_SPEC_POS +
515 + ctx.rep0 - pos_slot - 1;
517 + num_bits -= LZMA_NUM_ALIGN_BITS;
519 + ctx.rep0 = (ctx.rep0 << 1) |
521 + prob = p + LZMA_ALIGN;
522 + ctx.rep0 <<= LZMA_NUM_ALIGN_BITS;
523 + num_bits = LZMA_NUM_ALIGN_BITS;
527 + while (num_bits--) {
528 + if (rc_get_bit(prob + mi, &mi))
533 + ctx.rep0 = pos_slot;
534 + if (++(ctx.rep0) == 0)
538 + len += LZMA_MATCH_MIN_LEN;
540 + copy_bytes(ctx.rep0, len);
547 + u8 hdr_buf[sizeof(struct lzma_header)];
548 + struct lzma_header *header = (struct lzma_header *)hdr_buf;
549 + u32 pos_state_mask;
550 + u32 literal_pos_mask;
556 + for (i = 0; i < sizeof(struct lzma_header); i++) {
557 + hdr_buf[i] = rc_read();
562 + ctx.rep0 = ctx.rep1 = ctx.rep2 = ctx.rep3 = 1;
564 + ctx.previous_byte = 0;
566 + ctx.range = 0xFFFFFFFF;
568 + if (header->pos >= (9 * 5 * 5))
583 + pos_state_mask = (1 << pb) - 1;
584 + literal_pos_mask = (1 << lp) - 1;
586 + p = (u16 *) ctx.workspace;
590 + num_probs = LZMA_LITERAL + (LZMA_LIT_SIZE << (lc + lp));
591 + for (i = 0; i < num_probs; i++)
592 + p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
594 + for (i = 0; i < 5; i++)
598 + int pos_state = ctx.pos & pos_state_mask;
599 + u16 *prob = p + LZMA_IS_MATCH +
600 + (ctx.state << LZMA_NUM_POS_BITS_MAX) + pos_state;
601 + if (rc_is_bit_0(prob))
602 + process_bit0(p, pos_state, prob,
603 + lc, literal_pos_mask);
605 + process_bit1(p, pos_state, prob);
615 +static int unlzma(unsigned char *dest, const unsigned char *src, unsigned char *workspace)
617 + memset(&ctx, 0, sizeof(ctx));
620 + ctx.next_out = dest;
621 + ctx.workspace = workspace;
623 + return do_unlzma();
628 +++ b/arch/arm/boot/compressed/unlzma.h
630 +/* LZMA uncompresion module for pcomp
631 + * Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
634 + * Initial Linux kernel adaptation
635 + * Copyright (C) 2006 Alain < alain@knaff.lu >
637 + * Based on small lzma deflate implementation/Small range coder
638 + * implementation for lzma.
639 + * Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org >
641 + * Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/)
642 + * Copyright (C) 1999-2005 Igor Pavlov
644 + * This program is free software; you can redistribute it and/or modify it
645 + * under the terms of the GNU General Public License version 2 as published
646 + * by the Free Software Foundation.
651 +struct lzma_header {
654 + __le64 uncompr_size;
655 +} __attribute__ ((packed));
658 +#define RC_TOP_BITS 24
659 +#define RC_MOVE_BITS 5
660 +#define RC_MODEL_TOTAL_BITS 11
662 +#define LZMA_BASE_SIZE 1846
663 +#define LZMA_LIT_SIZE 768
665 +#define LZMA_NUM_POS_BITS_MAX 4
667 +#define LZMA_LEN_NUM_LOW_BITS 3
668 +#define LZMA_LEN_NUM_MID_BITS 3
669 +#define LZMA_LEN_NUM_HIGH_BITS 8
671 +#define LZMA_LEN_CHOICE 0
672 +#define LZMA_LEN_CHOICE_2 (LZMA_LEN_CHOICE + 1)
673 +#define LZMA_LEN_LOW (LZMA_LEN_CHOICE_2 + 1)
674 +#define LZMA_LEN_MID (LZMA_LEN_LOW \
675 + + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS)))
676 +#define LZMA_LEN_HIGH (LZMA_LEN_MID \
677 + +(1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS)))
678 +#define LZMA_NUM_LEN_PROBS (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS))
680 +#define LZMA_NUM_STATES 12
681 +#define LZMA_NUM_LIT_STATES 7
683 +#define LZMA_START_POS_MODEL_INDEX 4
684 +#define LZMA_END_POS_MODEL_INDEX 14
685 +#define LZMA_NUM_FULL_DISTANCES (1 << (LZMA_END_POS_MODEL_INDEX >> 1))
687 +#define LZMA_NUM_POS_SLOT_BITS 6
688 +#define LZMA_NUM_LEN_TO_POS_STATES 4
690 +#define LZMA_NUM_ALIGN_BITS 4
692 +#define LZMA_MATCH_MIN_LEN 2
694 +#define LZMA_IS_MATCH 0
695 +#define LZMA_IS_REP (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX))
696 +#define LZMA_IS_REP_G0 (LZMA_IS_REP + LZMA_NUM_STATES)
697 +#define LZMA_IS_REP_G1 (LZMA_IS_REP_G0 + LZMA_NUM_STATES)
698 +#define LZMA_IS_REP_G2 (LZMA_IS_REP_G1 + LZMA_NUM_STATES)
699 +#define LZMA_IS_REP_0_LONG (LZMA_IS_REP_G2 + LZMA_NUM_STATES)
700 +#define LZMA_POS_SLOT (LZMA_IS_REP_0_LONG \
701 + + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX))
702 +#define LZMA_SPEC_POS (LZMA_POS_SLOT \
703 + +(LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS))
704 +#define LZMA_ALIGN (LZMA_SPEC_POS \
705 + + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX)
706 +#define LZMA_LEN_CODER (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS))
707 +#define LZMA_REP_LEN_CODER (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS)
708 +#define LZMA_LITERAL (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS)