Changeset 41940


Ignore:
Timestamp:
2014-08-01T23:56:31+02:00 (4 years ago)
Author:
jogo
Message:

brcm63xx: add working lzma-loader and use it for initramfs

Add a working lzma loader and use it for generating initramfs kernels
to allow easily netbooting elf kernels on devices with a 4 MiB CFE
size limit.

Based on ar71xx's lzma-loader.

Signed-off-by: Jonas Gorski <jogo@…>

Location:
trunk/target/linux/brcm63xx/image
Files:
13 added
4 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/brcm63xx/image/Makefile

    r41852 r41940  
    144144endef 
    145145 
     146define Image/PrepareLoader 
     147        # Standard LZMA kernel 
     148        $(STAGING_DIR_HOST)/bin/lzma e -d22 -fb64 -a1 $(KDIR)/vmlinux$(1) $(KDIR)/vmlinux$(1).lzma 
     149 
     150        # Build the LZMA loader 
     151        rm -rf $(KDIR)/lzma-loader 
     152        $(MAKE) -C lzma-loader \ 
     153                $(LOADER_MAKEOPTS) \ 
     154                BUILD_DIR="$(KDIR)" \ 
     155                TARGET_DIR="$(BIN_DIR)" \ 
     156                LOADER_DATA="$(KDIR)/vmlinux$(1).lzma" \ 
     157                LOADER=$(IMG_PREFIX)-loader$(1).elf \ 
     158                LZMA_TEXT_START=0x80a00000 \ 
     159                compile loader.elf 
     160 
     161        rm -f $(KDIR)/vmlinux$(1).lzma 
     162endef 
     163 
    146164define Image/Prepare 
    147         # Standard LZMA kernel 
    148         cat $(KDIR)/vmlinux | $(STAGING_DIR_HOST)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma 
    149165 
    150166        # CFE is a LZMA nazi! It took me hours to find out the parameters! 
     
    159175        rm -f $(KDIR)/vmlinux.lzma.tmp 
    160176 
    161         # Build the LZMA loader 
    162         rm -f $(KDIR)/loader.gz 
    163         $(MAKE) -C lzma-loader \ 
    164                 BUILD_DIR="$(KDIR)" \ 
    165                 TARGET="$(KDIR)" \ 
    166                 clean install 
    167  
    168         echo -ne "\\x00" >> $(KDIR)/loader.gz 
     177 ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y) 
     178        $(call Image/PrepareLoader,-initramfs) 
     179 endif 
    169180        rm -f $(KDIR)/fs_mark 
    170181        touch $(KDIR)/fs_mark 
  • trunk/target/linux/brcm63xx/image/lzma-loader/Makefile

    r15245 r41940  
    1 #  
    2 # Copyright (C) 2006 OpenWrt.org 
     1# 
     2# Copyright (C) 2011 OpenWrt.org 
     3# Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> 
    34# 
    45# This is free software, licensed under the GNU General Public License v2. 
     
    89include $(TOPDIR)/rules.mk 
    910 
     11LZMA_TEXT_START := 0x80a00000 
     12LOADER          := loader.bin 
     13LOADER_NAME     := $(basename $(notdir $(LOADER))) 
     14LOADER_DATA     := 
     15TARGET_DIR      := 
     16FLASH_OFFS      := 
     17FLASH_MAX       := 
     18 
     19ifeq ($(TARGET_DIR),) 
     20TARGET_DIR      := $(KDIR) 
     21endif 
     22 
     23LOADER_BIN      := $(TARGET_DIR)/$(LOADER_NAME).bin 
     24LOADER_GZ       := $(TARGET_DIR)/$(LOADER_NAME).gz 
     25LOADER_ELF      := $(TARGET_DIR)/$(LOADER_NAME).elf 
     26 
    1027PKG_NAME := lzma-loader 
    11 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) 
     28PKG_BUILD_DIR := $(KDIR)/$(PKG_NAME) 
     29 
     30.PHONY : loader-compile loader.bin loader.elf loader.gz 
    1231 
    1332$(PKG_BUILD_DIR)/.prepared: 
     
    1635        touch $@ 
    1736 
    18 $(PKG_BUILD_DIR)/loader.gz: $(PKG_BUILD_DIR)/.prepared 
    19         $(MAKE) -C $(PKG_BUILD_DIR) CC="$(TARGET_CC)" \ 
    20                 LD="$(TARGET_CROSS)ld" CROSS_COMPILE="$(TARGET_CROSS)" 
     37loader-compile: $(PKG_BUILD_DIR)/.prepared 
     38        $(MAKE) -C $(PKG_BUILD_DIR) CROSS_COMPILE="$(TARGET_CROSS)" \ 
     39                LZMA_TEXT_START=$(LZMA_TEXT_START) \ 
     40                LOADER_DATA=$(LOADER_DATA) \ 
     41                FLASH_OFFS=$(FLASH_OFFS) \ 
     42                FLASH_MAX=$(FLASH_MAX) \ 
     43                clean all 
    2144 
    22 download:  
     45loader.gz: $(PKG_BUILD_DIR)/loader.bin 
     46        gzip -nc9 $< > $(LOADER_GZ) 
     47 
     48loader.elf: $(PKG_BUILD_DIR)/loader.elf 
     49        $(CP) $< $(LOADER_ELF) 
     50 
     51loader.bin: $(PKG_BUILD_DIR)/loader.bin 
     52        $(CP) $< $(LOADER_BIN) 
     53 
     54download: 
    2355prepare: $(PKG_BUILD_DIR)/.prepared 
    24 compile: $(PKG_BUILD_DIR)/loader.gz 
     56compile: loader-compile 
     57 
    2558install: 
    26  
    27 ifneq ($(TARGET),) 
    28 install: compile 
    29         $(CP) $(PKG_BUILD_DIR)/loader.gz $(PKG_BUILD_DIR)/loader.elf $(TARGET)/ 
    30 endif 
    3159 
    3260clean: 
    3361        rm -rf $(PKG_BUILD_DIR) 
     62 
  • trunk/target/linux/brcm63xx/image/lzma-loader/src/LzmaDecode.c

    r15245 r41940  
    11/* 
    22  LzmaDecode.c 
    3   LZMA Decoder 
     3  LZMA Decoder (optimized for Speed version) 
    44   
    5   LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25) 
     5  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) 
    66  http://www.7-zip.org/ 
    77 
     
    1313 
    1414  SPECIAL EXCEPTION: 
    15   Igor Pavlov, as the author of this code, expressly permits you to  
    16   statically or dynamically link your code (or bind by name) to the  
    17   interfaces of this file without subjecting your linked code to the  
     15  Igor Pavlov, as the author of this Code, expressly permits you to  
     16  statically or dynamically link your Code (or bind by name) to the  
     17  interfaces of this file without subjecting your linked Code to the  
    1818  terms of the CPL or GNU LGPL. Any modifications or additions  
    1919  to this file, however, are subject to the LGPL or CPL terms. 
     
    2222#include "LzmaDecode.h" 
    2323 
    24 #ifndef Byte 
    25 #define Byte unsigned char 
    26 #endif 
    27  
    2824#define kNumTopBits 24 
    2925#define kTopValue ((UInt32)1 << kNumTopBits) 
     
    3329#define kNumMoveBits 5 
    3430 
    35 typedef struct _CRangeDecoder 
    36 { 
    37   Byte *Buffer; 
    38   Byte *BufferLim; 
    39   UInt32 Range; 
    40   UInt32 Code; 
    41   #ifdef _LZMA_IN_CB 
    42   ILzmaInCallback *InCallback; 
    43   int Result; 
    44   #endif 
    45   int ExtraBytes; 
    46 } CRangeDecoder; 
    47  
    48 Byte RangeDecoderReadByte(CRangeDecoder *rd) 
    49 { 
    50   if (rd->Buffer == rd->BufferLim) 
    51   { 
    52     #ifdef _LZMA_IN_CB 
    53     UInt32 size; 
    54     rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size); 
    55     rd->BufferLim = rd->Buffer + size; 
    56     if (size == 0) 
    57     #endif 
    58     { 
    59       rd->ExtraBytes = 1; 
    60       return 0xFF; 
    61     } 
    62   } 
    63   return (*rd->Buffer++); 
    64 } 
    65  
    66 /* #define ReadByte (*rd->Buffer++) */ 
    67 #define ReadByte (RangeDecoderReadByte(rd)) 
    68  
    69 void RangeDecoderInit(CRangeDecoder *rd, 
    70   #ifdef _LZMA_IN_CB 
    71     ILzmaInCallback *inCallback 
    72   #else 
    73     Byte *stream, UInt32 bufferSize 
    74   #endif 
    75     ) 
    76 { 
    77   int i; 
    78   #ifdef _LZMA_IN_CB 
    79   rd->InCallback = inCallback; 
    80   rd->Buffer = rd->BufferLim = 0; 
    81   #else 
    82   rd->Buffer = stream; 
    83   rd->BufferLim = stream + bufferSize; 
    84   #endif 
    85   rd->ExtraBytes = 0; 
    86   rd->Code = 0; 
    87   rd->Range = (0xFFFFFFFF); 
    88   for(i = 0; i < 5; i++) 
    89     rd->Code = (rd->Code << 8) | ReadByte; 
    90 } 
    91  
    92 #define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code;         
    93 #define RC_FLUSH_VAR rd->Range = range; rd->Code = code; 
    94 #define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; } 
    95  
    96 UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits) 
    97 { 
    98   RC_INIT_VAR 
    99   UInt32 result = 0; 
    100   int i; 
    101   for (i = numTotalBits; i > 0; i--) 
    102   { 
    103     /* UInt32 t; */ 
    104     range >>= 1; 
    105  
    106     result <<= 1; 
    107     if (code >= range) 
    108     { 
    109       code -= range; 
    110       result |= 1; 
    111     } 
    112     /* 
    113     t = (code - range) >> 31; 
    114     t &= 1; 
    115     code -= range & (t - 1); 
    116     result = (result + result) | (1 - t); 
    117     */ 
    118     RC_NORMALIZE 
    119   } 
    120   RC_FLUSH_VAR 
    121   return result; 
    122 } 
    123  
    124 int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd) 
    125 { 
    126   UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob; 
    127   if (rd->Code < bound) 
    128   { 
    129     rd->Range = bound; 
    130     *prob += (kBitModelTotal - *prob) >> kNumMoveBits; 
    131     if (rd->Range < kTopValue) 
    132     { 
    133       rd->Code = (rd->Code << 8) | ReadByte; 
    134       rd->Range <<= 8; 
    135     } 
    136     return 0; 
    137   } 
    138   else 
    139   { 
    140     rd->Range -= bound; 
    141     rd->Code -= bound; 
    142     *prob -= (*prob) >> kNumMoveBits; 
    143     if (rd->Range < kTopValue) 
    144     { 
    145       rd->Code = (rd->Code << 8) | ReadByte; 
    146       rd->Range <<= 8; 
    147     } 
    148     return 1; 
    149   } 
    150 } 
    151  
    152 #define RC_GET_BIT2(prob, mi, A0, A1) \ 
    153   UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \ 
    154   if (code < bound) \ 
    155     { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \ 
    156   else \ 
    157     { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \ 
    158   RC_NORMALIZE 
    159  
    160 #define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;)                
    161  
    162 int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) 
    163 { 
    164   int mi = 1; 
    165   int i; 
    166   #ifdef _LZMA_LOC_OPT 
    167   RC_INIT_VAR 
    168   #endif 
    169   for(i = numLevels; i > 0; i--) 
    170   { 
    171     #ifdef _LZMA_LOC_OPT 
    172     CProb *prob = probs + mi; 
    173     RC_GET_BIT(prob, mi) 
    174     #else 
    175     mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd); 
    176     #endif 
    177   } 
    178   #ifdef _LZMA_LOC_OPT 
    179   RC_FLUSH_VAR 
    180   #endif 
    181   return mi - (1 << numLevels); 
    182 } 
    183  
    184 int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) 
    185 { 
    186   int mi = 1; 
    187   int i; 
    188   int symbol = 0; 
    189   #ifdef _LZMA_LOC_OPT 
    190   RC_INIT_VAR 
    191   #endif 
    192   for(i = 0; i < numLevels; i++) 
    193   { 
    194     #ifdef _LZMA_LOC_OPT 
    195     CProb *prob = probs + mi; 
    196     RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i)) 
    197     #else 
    198     int bit = RangeDecoderBitDecode(probs + mi, rd); 
    199     mi = mi + mi + bit; 
    200     symbol |= (bit << i); 
    201     #endif 
    202   } 
    203   #ifdef _LZMA_LOC_OPT 
    204   RC_FLUSH_VAR 
    205   #endif 
    206   return symbol; 
    207 } 
    208  
    209 Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd) 
    210 {  
    211   int symbol = 1; 
    212   #ifdef _LZMA_LOC_OPT 
    213   RC_INIT_VAR 
    214   #endif 
    215   do 
    216   { 
    217     #ifdef _LZMA_LOC_OPT 
    218     CProb *prob = probs + symbol; 
    219     RC_GET_BIT(prob, symbol) 
    220     #else 
    221     symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); 
    222     #endif 
    223   } 
    224   while (symbol < 0x100); 
    225   #ifdef _LZMA_LOC_OPT 
    226   RC_FLUSH_VAR 
    227   #endif 
    228   return symbol; 
    229 } 
    230  
    231 Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte) 
    232 {  
    233   int symbol = 1; 
    234   #ifdef _LZMA_LOC_OPT 
    235   RC_INIT_VAR 
    236   #endif 
    237   do 
    238   { 
    239     int bit; 
    240     int matchBit = (matchByte >> 7) & 1; 
    241     matchByte <<= 1; 
    242     #ifdef _LZMA_LOC_OPT 
    243     { 
    244       CProb *prob = probs + ((1 + matchBit) << 8) + symbol; 
    245       RC_GET_BIT2(prob, symbol, bit = 0, bit = 1) 
    246     } 
    247     #else 
    248     bit = RangeDecoderBitDecode(probs + ((1 + matchBit) << 8) + symbol, rd); 
    249     symbol = (symbol << 1) | bit; 
    250     #endif 
    251     if (matchBit != bit) 
    252     { 
    253       while (symbol < 0x100) 
    254       { 
    255         #ifdef _LZMA_LOC_OPT 
    256         CProb *prob = probs + symbol; 
    257         RC_GET_BIT(prob, symbol) 
    258         #else 
    259         symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); 
    260         #endif 
    261       } 
    262       break; 
    263     } 
    264   } 
    265   while (symbol < 0x100); 
    266   #ifdef _LZMA_LOC_OPT 
    267   RC_FLUSH_VAR 
    268   #endif 
    269   return symbol; 
    270 } 
     31#define RC_READ_BYTE (*Buffer++) 
     32 
     33#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ 
     34  { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} 
     35 
     36#ifdef _LZMA_IN_CB 
     37 
     38#define RC_TEST { if (Buffer == BufferLim) \ 
     39  { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \ 
     40  BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }} 
     41 
     42#define RC_INIT Buffer = BufferLim = 0; RC_INIT2 
     43 
     44#else 
     45 
     46#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; } 
     47 
     48#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 
     49  
     50#endif 
     51 
     52#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } 
     53 
     54#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) 
     55#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; 
     56#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; 
     57 
     58#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ 
     59  { UpdateBit0(p); mi <<= 1; A0; } else \ 
     60  { UpdateBit1(p); mi = (mi + mi) + 1; A1; }  
     61   
     62#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)                
     63 
     64#define RangeDecoderBitTreeDecode(probs, numLevels, res) \ 
     65  { int i = numLevels; res = 1; \ 
     66  do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \ 
     67  res -= (1 << numLevels); } 
     68 
    27169 
    27270#define kNumPosBitsMax 4 
     
    28785#define kNumLenProbs (LenHigh + kLenNumHighSymbols)  
    28886 
    289 int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState) 
    290 { 
    291   if(RangeDecoderBitDecode(p + LenChoice, rd) == 0) 
    292     return RangeDecoderBitTreeDecode(p + LenLow + 
    293         (posState << kLenNumLowBits), kLenNumLowBits, rd); 
    294   if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0) 
    295     return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid + 
    296         (posState << kLenNumMidBits), kLenNumMidBits, rd); 
    297   return kLenNumLowSymbols + kLenNumMidSymbols +  
    298       RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd); 
    299 } 
    30087 
    30188#define kNumStates 12 
     89#define kNumLitStates 7 
    30290 
    30391#define kStartPosModelIndex 4 
     
    330118#endif 
    331119 
    332 #ifdef _LZMA_OUT_READ 
    333  
    334 typedef struct _LzmaVarState 
     120int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) 
    335121{ 
    336   CRangeDecoder RangeDecoder; 
    337   Byte *Dictionary; 
    338   UInt32 DictionarySize; 
    339   UInt32 DictionaryPos; 
    340   UInt32 GlobalPos; 
    341   UInt32 Reps[4]; 
    342   int lc; 
    343   int lp; 
    344   int pb; 
    345   int State; 
    346   int PreviousIsMatch; 
    347   int RemainLen; 
    348 } LzmaVarState; 
    349  
    350 int LzmaDecoderInit( 
    351     unsigned char *buffer, UInt32 bufferSize, 
    352     int lc, int lp, int pb, 
    353     unsigned char *dictionary, UInt32 dictionarySize, 
    354     #ifdef _LZMA_IN_CB 
    355     ILzmaInCallback *inCallback 
    356     #else 
    357     unsigned char *inStream, UInt32 inSize 
    358     #endif 
    359     ) 
    360 { 
    361   LzmaVarState *vs = (LzmaVarState *)buffer; 
    362   CProb *p = (CProb *)(buffer + sizeof(LzmaVarState)); 
    363   UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp)); 
    364   UInt32 i; 
    365   if (bufferSize < numProbs * sizeof(CProb) + sizeof(LzmaVarState)) 
    366     return LZMA_RESULT_NOT_ENOUGH_MEM; 
    367   vs->Dictionary = dictionary; 
    368   vs->DictionarySize = dictionarySize; 
    369   vs->DictionaryPos = 0; 
    370   vs->GlobalPos = 0; 
    371   vs->Reps[0] = vs->Reps[1] = vs->Reps[2] = vs->Reps[3] = 1; 
    372   vs->lc = lc; 
    373   vs->lp = lp; 
    374   vs->pb = pb; 
    375   vs->State = 0; 
    376   vs->PreviousIsMatch = 0; 
    377   vs->RemainLen = 0; 
    378   dictionary[dictionarySize - 1] = 0; 
    379   for (i = 0; i < numProbs; i++) 
    380     p[i] = kBitModelTotal >> 1;  
    381   RangeDecoderInit(&vs->RangeDecoder,  
    382       #ifdef _LZMA_IN_CB 
    383       inCallback 
    384       #else 
    385       inStream, inSize 
    386       #endif 
    387   ); 
     122  unsigned char prop0; 
     123  if (size < LZMA_PROPERTIES_SIZE) 
     124    return LZMA_RESULT_DATA_ERROR; 
     125  prop0 = propsData[0]; 
     126  if (prop0 >= (9 * 5 * 5)) 
     127    return LZMA_RESULT_DATA_ERROR; 
     128  { 
     129    for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); 
     130    for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); 
     131    propsRes->lc = prop0; 
     132    /* 
     133    unsigned char remainder = (unsigned char)(prop0 / 9); 
     134    propsRes->lc = prop0 % 9; 
     135    propsRes->pb = remainder / 5; 
     136    propsRes->lp = remainder % 5; 
     137    */ 
     138  } 
     139 
     140  #ifdef _LZMA_OUT_READ 
     141  { 
     142    int i; 
     143    propsRes->DictionarySize = 0; 
     144    for (i = 0; i < 4; i++) 
     145      propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); 
     146    if (propsRes->DictionarySize == 0) 
     147      propsRes->DictionarySize = 1; 
     148  } 
     149  #endif 
    388150  return LZMA_RESULT_OK; 
    389151} 
    390152 
    391 int LzmaDecode(unsigned char *buffer,  
    392     unsigned char *outStream, UInt32 outSize, 
    393     UInt32 *outSizeProcessed) 
     153#define kLzmaStreamWasFinishedId (-1) 
     154 
     155int LzmaDecode(CLzmaDecoderState *vs, 
     156    #ifdef _LZMA_IN_CB 
     157    ILzmaInCallback *InCallback, 
     158    #else 
     159    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, 
     160    #endif 
     161    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) 
    394162{ 
    395   LzmaVarState *vs = (LzmaVarState *)buffer; 
    396   CProb *p = (CProb *)(buffer + sizeof(LzmaVarState)); 
    397   CRangeDecoder rd = vs->RangeDecoder; 
     163  CProb *p = vs->Probs; 
     164  SizeT nowPos = 0; 
     165  Byte previousByte = 0; 
     166  UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; 
     167  UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; 
     168  int lc = vs->Properties.lc; 
     169 
     170  #ifdef _LZMA_OUT_READ 
     171   
     172  UInt32 Range = vs->Range; 
     173  UInt32 Code = vs->Code; 
     174  #ifdef _LZMA_IN_CB 
     175  const Byte *Buffer = vs->Buffer; 
     176  const Byte *BufferLim = vs->BufferLim; 
     177  #else 
     178  const Byte *Buffer = inStream; 
     179  const Byte *BufferLim = inStream + inSize; 
     180  #endif 
    398181  int state = vs->State; 
    399   int previousIsMatch = vs->PreviousIsMatch; 
    400   Byte previousByte; 
    401182  UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; 
    402   UInt32 nowPos = 0; 
    403   UInt32 posStateMask = (1 << (vs->pb)) - 1; 
    404   UInt32 literalPosMask = (1 << (vs->lp)) - 1; 
    405   int lc = vs->lc; 
    406183  int len = vs->RemainLen; 
    407184  UInt32 globalPos = vs->GlobalPos; 
     185  UInt32 distanceLimit = vs->DistanceLimit; 
    408186 
    409187  Byte *dictionary = vs->Dictionary; 
    410   UInt32 dictionarySize = vs->DictionarySize; 
     188  UInt32 dictionarySize = vs->Properties.DictionarySize; 
    411189  UInt32 dictionaryPos = vs->DictionaryPos; 
    412190 
    413   if (len == -1) 
    414   { 
    415     *outSizeProcessed = 0; 
     191  Byte tempDictionary[4]; 
     192 
     193  #ifndef _LZMA_IN_CB 
     194  *inSizeProcessed = 0; 
     195  #endif 
     196  *outSizeProcessed = 0; 
     197  if (len == kLzmaStreamWasFinishedId) 
    416198    return LZMA_RESULT_OK; 
    417   } 
    418  
    419   while(len > 0 && nowPos < outSize) 
     199 
     200  if (dictionarySize == 0) 
     201  { 
     202    dictionary = tempDictionary; 
     203    dictionarySize = 1; 
     204    tempDictionary[0] = vs->TempDictionary[0]; 
     205  } 
     206 
     207  if (len == kLzmaNeedInitId) 
     208  { 
     209    { 
     210      UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); 
     211      UInt32 i; 
     212      for (i = 0; i < numProbs; i++) 
     213        p[i] = kBitModelTotal >> 1;  
     214      rep0 = rep1 = rep2 = rep3 = 1; 
     215      state = 0; 
     216      globalPos = 0; 
     217      distanceLimit = 0; 
     218      dictionaryPos = 0; 
     219      dictionary[dictionarySize - 1] = 0; 
     220      #ifdef _LZMA_IN_CB 
     221      RC_INIT; 
     222      #else 
     223      RC_INIT(inStream, inSize); 
     224      #endif 
     225    } 
     226    len = 0; 
     227  } 
     228  while(len != 0 && nowPos < outSize) 
    420229  { 
    421230    UInt32 pos = dictionaryPos - rep0; 
     
    431240  else 
    432241    previousByte = dictionary[dictionaryPos - 1]; 
    433 #else 
    434  
    435 int LzmaDecode( 
    436     Byte *buffer, UInt32 bufferSize, 
    437     int lc, int lp, int pb, 
    438     #ifdef _LZMA_IN_CB 
    439     ILzmaInCallback *inCallback, 
    440     #else 
    441     unsigned char *inStream, UInt32 inSize, 
    442     #endif 
    443     unsigned char *outStream, UInt32 outSize, 
    444     UInt32 *outSizeProcessed) 
    445 { 
    446   UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp)); 
    447   CProb *p = (CProb *)buffer; 
    448   CRangeDecoder rd; 
    449   UInt32 i; 
     242 
     243  #else /* if !_LZMA_OUT_READ */ 
     244 
    450245  int state = 0; 
    451   int previousIsMatch = 0; 
    452   Byte previousByte = 0; 
    453246  UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; 
    454   UInt32 nowPos = 0; 
    455   UInt32 posStateMask = (1 << pb) - 1; 
    456   UInt32 literalPosMask = (1 << lp) - 1; 
    457247  int len = 0; 
    458   if (bufferSize < numProbs * sizeof(CProb)) 
    459     return LZMA_RESULT_NOT_ENOUGH_MEM; 
    460   for (i = 0; i < numProbs; i++) 
    461     p[i] = kBitModelTotal >> 1;  
    462   RangeDecoderInit(&rd,  
    463       #ifdef _LZMA_IN_CB 
    464       inCallback 
    465       #else 
    466       inStream, inSize 
    467       #endif 
    468       ); 
    469 #endif 
    470  
     248  const Byte *Buffer; 
     249  const Byte *BufferLim; 
     250  UInt32 Range; 
     251  UInt32 Code; 
     252 
     253  #ifndef _LZMA_IN_CB 
     254  *inSizeProcessed = 0; 
     255  #endif 
    471256  *outSizeProcessed = 0; 
     257 
     258  { 
     259    UInt32 i; 
     260    UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); 
     261    for (i = 0; i < numProbs; i++) 
     262      p[i] = kBitModelTotal >> 1; 
     263  } 
     264   
     265  #ifdef _LZMA_IN_CB 
     266  RC_INIT; 
     267  #else 
     268  RC_INIT(inStream, inSize); 
     269  #endif 
     270 
     271  #endif /* _LZMA_OUT_READ */ 
     272 
    472273  while(nowPos < outSize) 
    473274  { 
     275    CProb *prob; 
     276    UInt32 bound; 
    474277    int posState = (int)( 
    475278        (nowPos  
     
    479282        ) 
    480283        & posStateMask); 
    481     #ifdef _LZMA_IN_CB 
    482     if (rd.Result != LZMA_RESULT_OK) 
    483       return rd.Result; 
    484     #endif 
    485     if (rd.ExtraBytes != 0) 
    486       return LZMA_RESULT_DATA_ERROR; 
    487     if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0) 
     284 
     285    prob = p + IsMatch + (state << kNumPosBitsMax) + posState; 
     286    IfBit0(prob) 
    488287    { 
    489       CProb *probs = p + Literal + (LZMA_LIT_SIZE *  
     288      int symbol = 1; 
     289      UpdateBit0(prob) 
     290      prob = p + Literal + (LZMA_LIT_SIZE *  
    490291        ((( 
    491292        (nowPos  
     
    496297        & literalPosMask) << lc) + (previousByte >> (8 - lc)))); 
    497298 
    498       if (state < 4) state = 0; 
    499       else if (state < 10) state -= 3; 
    500       else state -= 6; 
    501       if (previousIsMatch) 
    502       { 
    503         Byte matchByte; 
     299      if (state >= kNumLitStates) 
     300      { 
     301        int matchByte; 
    504302        #ifdef _LZMA_OUT_READ 
    505303        UInt32 pos = dictionaryPos - rep0; 
     
    510308        matchByte = outStream[nowPos - rep0]; 
    511309        #endif 
    512         previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte); 
    513         previousIsMatch = 0; 
    514       } 
    515       else 
    516         previousByte = LzmaLiteralDecode(probs, &rd); 
     310        do 
     311        { 
     312          int bit; 
     313          CProb *probLit; 
     314          matchByte <<= 1; 
     315          bit = (matchByte & 0x100); 
     316          probLit = prob + 0x100 + bit + symbol; 
     317          RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) 
     318        } 
     319        while (symbol < 0x100); 
     320      } 
     321      while (symbol < 0x100) 
     322      { 
     323        CProb *probLit = prob + symbol; 
     324        RC_GET_BIT(probLit, symbol) 
     325      } 
     326      previousByte = (Byte)symbol; 
     327 
    517328      outStream[nowPos++] = previousByte; 
    518329      #ifdef _LZMA_OUT_READ 
     330      if (distanceLimit < dictionarySize) 
     331        distanceLimit++; 
     332 
    519333      dictionary[dictionaryPos] = previousByte; 
    520334      if (++dictionaryPos == dictionarySize) 
    521335        dictionaryPos = 0; 
    522336      #endif 
     337      if (state < 4) state = 0; 
     338      else if (state < 10) state -= 3; 
     339      else state -= 6; 
    523340    } 
    524341    else              
    525342    { 
    526       previousIsMatch = 1; 
    527       if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1) 
    528       { 
    529         if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0) 
    530         { 
    531           if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0) 
     343      UpdateBit1(prob); 
     344      prob = p + IsRep + state; 
     345      IfBit0(prob) 
     346      { 
     347        UpdateBit0(prob); 
     348        rep3 = rep2; 
     349        rep2 = rep1; 
     350        rep1 = rep0; 
     351        state = state < kNumLitStates ? 0 : 3; 
     352        prob = p + LenCoder; 
     353      } 
     354      else 
     355      { 
     356        UpdateBit1(prob); 
     357        prob = p + IsRepG0 + state; 
     358        IfBit0(prob) 
     359        { 
     360          UpdateBit0(prob); 
     361          prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; 
     362          IfBit0(prob) 
    532363          { 
    533364            #ifdef _LZMA_OUT_READ 
    534365            UInt32 pos; 
    535366            #endif 
    536             if ( 
    537                (nowPos  
    538                 #ifdef _LZMA_OUT_READ 
    539                 + globalPos 
    540                 #endif 
    541                ) 
    542                == 0) 
     367            UpdateBit0(prob); 
     368             
     369            #ifdef _LZMA_OUT_READ 
     370            if (distanceLimit == 0) 
     371            #else 
     372            if (nowPos == 0) 
     373            #endif 
    543374              return LZMA_RESULT_DATA_ERROR; 
    544             state = state < 7 ? 9 : 11; 
     375             
     376            state = state < kNumLitStates ? 9 : 11; 
    545377            #ifdef _LZMA_OUT_READ 
    546378            pos = dictionaryPos - rep0; 
     
    555387            #endif 
    556388            outStream[nowPos++] = previousByte; 
     389            #ifdef _LZMA_OUT_READ 
     390            if (distanceLimit < dictionarySize) 
     391              distanceLimit++; 
     392            #endif 
     393 
    557394            continue; 
    558395          } 
     396          else 
     397          { 
     398            UpdateBit1(prob); 
     399          } 
    559400        } 
    560401        else 
    561402        { 
    562403          UInt32 distance; 
    563           if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0) 
     404          UpdateBit1(prob); 
     405          prob = p + IsRepG1 + state; 
     406          IfBit0(prob) 
     407          { 
     408            UpdateBit0(prob); 
    564409            distance = rep1; 
     410          } 
    565411          else  
    566412          { 
    567             if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0) 
     413            UpdateBit1(prob); 
     414            prob = p + IsRepG2 + state; 
     415            IfBit0(prob) 
     416            { 
     417              UpdateBit0(prob); 
    568418              distance = rep2; 
     419            } 
    569420            else 
    570421            { 
     422              UpdateBit1(prob); 
    571423              distance = rep3; 
    572424              rep3 = rep2; 
     
    577429          rep0 = distance; 
    578430        } 
    579         len = LzmaLenDecode(p + RepLenCoder, &rd, posState); 
    580         state = state < 7 ? 8 : 11; 
    581       } 
    582       else 
     431        state = state < kNumLitStates ? 8 : 11; 
     432        prob = p + RepLenCoder; 
     433      } 
     434      { 
     435        int numBits, offset; 
     436        CProb *probLen = prob + LenChoice; 
     437        IfBit0(probLen) 
     438        { 
     439          UpdateBit0(probLen); 
     440          probLen = prob + LenLow + (posState << kLenNumLowBits); 
     441          offset = 0; 
     442          numBits = kLenNumLowBits; 
     443        } 
     444        else 
     445        { 
     446          UpdateBit1(probLen); 
     447          probLen = prob + LenChoice2; 
     448          IfBit0(probLen) 
     449          { 
     450            UpdateBit0(probLen); 
     451            probLen = prob + LenMid + (posState << kLenNumMidBits); 
     452            offset = kLenNumLowSymbols; 
     453            numBits = kLenNumMidBits; 
     454          } 
     455          else 
     456          { 
     457            UpdateBit1(probLen); 
     458            probLen = prob + LenHigh; 
     459            offset = kLenNumLowSymbols + kLenNumMidSymbols; 
     460            numBits = kLenNumHighBits; 
     461          } 
     462        } 
     463        RangeDecoderBitTreeDecode(probLen, numBits, len); 
     464        len += offset; 
     465      } 
     466 
     467      if (state < 4) 
    583468      { 
    584469        int posSlot; 
    585         rep3 = rep2; 
    586         rep2 = rep1; 
    587         rep1 = rep0; 
    588         state = state < 7 ? 7 : 10; 
    589         len = LzmaLenDecode(p + LenCoder, &rd, posState); 
    590         posSlot = RangeDecoderBitTreeDecode(p + PosSlot + 
     470        state += kNumLitStates; 
     471        prob = p + PosSlot + 
    591472            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<  
    592             kNumPosSlotBits), kNumPosSlotBits, &rd); 
     473            kNumPosSlotBits); 
     474        RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); 
    593475        if (posSlot >= kStartPosModelIndex) 
    594476        { 
    595477          int numDirectBits = ((posSlot >> 1) - 1); 
    596           rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits); 
     478          rep0 = (2 | ((UInt32)posSlot & 1)); 
    597479          if (posSlot < kEndPosModelIndex) 
    598480          { 
    599             rep0 += RangeDecoderReverseBitTreeDecode( 
    600                 p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd); 
     481            rep0 <<= numDirectBits; 
     482            prob = p + SpecPos + rep0 - posSlot - 1; 
    601483          } 
    602484          else 
    603485          { 
    604             rep0 += RangeDecoderDecodeDirectBits(&rd,  
    605                 numDirectBits - kNumAlignBits) << kNumAlignBits; 
    606             rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd); 
     486            numDirectBits -= kNumAlignBits; 
     487            do 
     488            { 
     489              RC_NORMALIZE 
     490              Range >>= 1; 
     491              rep0 <<= 1; 
     492              if (Code >= Range) 
     493              { 
     494                Code -= Range; 
     495                rep0 |= 1; 
     496              } 
     497            } 
     498            while (--numDirectBits != 0); 
     499            prob = p + Align; 
     500            rep0 <<= kNumAlignBits; 
     501            numDirectBits = kNumAlignBits; 
     502          } 
     503          { 
     504            int i = 1; 
     505            int mi = 1; 
     506            do 
     507            { 
     508              CProb *prob3 = prob + mi; 
     509              RC_GET_BIT2(prob3, mi, ; , rep0 |= i); 
     510              i <<= 1; 
     511            } 
     512            while(--numDirectBits != 0); 
    607513          } 
    608514        } 
    609515        else 
    610516          rep0 = posSlot; 
    611         rep0++; 
    612       } 
    613       if (rep0 == (UInt32)(0)) 
    614       { 
    615         /* it's for stream version */ 
    616         len = -1; 
    617         break; 
    618       } 
    619       if (rep0 > nowPos  
    620         #ifdef _LZMA_OUT_READ 
    621         + globalPos 
    622         #endif 
    623         ) 
    624       { 
     517        if (++rep0 == (UInt32)(0)) 
     518        { 
     519          /* it's for stream version */ 
     520          len = kLzmaStreamWasFinishedId; 
     521          break; 
     522        } 
     523      } 
     524 
     525      len += kMatchMinLen; 
     526      #ifdef _LZMA_OUT_READ 
     527      if (rep0 > distanceLimit)  
     528      #else 
     529      if (rep0 > nowPos) 
     530      #endif 
    625531        return LZMA_RESULT_DATA_ERROR; 
    626       } 
    627       len += kMatchMinLen; 
     532 
     533      #ifdef _LZMA_OUT_READ 
     534      if (dictionarySize - distanceLimit > (UInt32)len) 
     535        distanceLimit += len; 
     536      else 
     537        distanceLimit = dictionarySize; 
     538      #endif 
     539 
    628540      do 
    629541      { 
     
    639551        previousByte = outStream[nowPos - rep0]; 
    640552        #endif 
     553        len--; 
    641554        outStream[nowPos++] = previousByte; 
    642         len--; 
    643       } 
    644       while(len > 0 && nowPos < outSize); 
     555      } 
     556      while(len != 0 && nowPos < outSize); 
    645557    } 
    646558  } 
     559  RC_NORMALIZE; 
    647560 
    648561  #ifdef _LZMA_OUT_READ 
    649   vs->RangeDecoder = rd; 
     562  vs->Range = Range; 
     563  vs->Code = Code; 
    650564  vs->DictionaryPos = dictionaryPos; 
    651   vs->GlobalPos = globalPos + nowPos; 
     565  vs->GlobalPos = globalPos + (UInt32)nowPos; 
     566  vs->DistanceLimit = distanceLimit; 
    652567  vs->Reps[0] = rep0; 
    653568  vs->Reps[1] = rep1; 
     
    655570  vs->Reps[3] = rep3; 
    656571  vs->State = state; 
    657   vs->PreviousIsMatch = previousIsMatch; 
    658572  vs->RemainLen = len; 
    659   #endif 
    660  
     573  vs->TempDictionary[0] = tempDictionary[0]; 
     574  #endif 
     575 
     576  #ifdef _LZMA_IN_CB 
     577  vs->Buffer = Buffer; 
     578  vs->BufferLim = BufferLim; 
     579  #else 
     580  *inSizeProcessed = (SizeT)(Buffer - inStream); 
     581  #endif 
    661582  *outSizeProcessed = nowPos; 
    662583  return LZMA_RESULT_OK; 
  • trunk/target/linux/brcm63xx/image/lzma-loader/src/LzmaDecode.h

    r15245 r41940  
    33  LZMA Decoder interface 
    44 
    5   LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25) 
     5  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) 
    66  http://www.7-zip.org/ 
    77 
     
    2323#define __LZMADECODE_H 
    2424 
     25#include "LzmaTypes.h" 
     26 
    2527/* #define _LZMA_IN_CB */ 
    2628/* Use callback for input data */ 
     
    3638/* Enable local speed optimizations inside code */ 
    3739 
    38 #ifndef UInt32 
    39 #ifdef _LZMA_UINT32_IS_ULONG 
    40 #define UInt32 unsigned long 
    41 #else 
    42 #define UInt32 unsigned int 
    43 #endif 
    44 #endif 
    45  
    4640#ifdef _LZMA_PROB32 
    4741#define CProb UInt32 
    4842#else 
    49 #define CProb unsigned short 
     43#define CProb UInt16 
    5044#endif 
    5145 
    5246#define LZMA_RESULT_OK 0 
    5347#define LZMA_RESULT_DATA_ERROR 1 
    54 #define LZMA_RESULT_NOT_ENOUGH_MEM 2 
    5548 
    5649#ifdef _LZMA_IN_CB 
    5750typedef struct _ILzmaInCallback 
    5851{ 
    59   int (*Read)(void *object, unsigned char **buffer, UInt32 *bufferSize); 
     52  int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize); 
    6053} ILzmaInCallback; 
    6154#endif 
     
    6457#define LZMA_LIT_SIZE 768 
    6558 
    66 /*  
    67 bufferSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(CProb) 
    68 bufferSize += 100 in case of _LZMA_OUT_READ 
    69 by default CProb is unsigned short,  
    70 but if specify _LZMA_PROB_32, CProb will be UInt32(unsigned int) 
    71 */ 
     59#define LZMA_PROPERTIES_SIZE 5 
     60 
     61typedef struct _CLzmaProperties 
     62{ 
     63  int lc; 
     64  int lp; 
     65  int pb; 
     66  #ifdef _LZMA_OUT_READ 
     67  UInt32 DictionarySize; 
     68  #endif 
     69}CLzmaProperties; 
     70 
     71int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size); 
     72 
     73#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp))) 
     74 
     75#define kLzmaNeedInitId (-2) 
     76 
     77typedef struct _CLzmaDecoderState 
     78{ 
     79  CLzmaProperties Properties; 
     80  CProb *Probs; 
     81 
     82  #ifdef _LZMA_IN_CB 
     83  const unsigned char *Buffer; 
     84  const unsigned char *BufferLim; 
     85  #endif 
     86 
     87  #ifdef _LZMA_OUT_READ 
     88  unsigned char *Dictionary; 
     89  UInt32 Range; 
     90  UInt32 Code; 
     91  UInt32 DictionaryPos; 
     92  UInt32 GlobalPos; 
     93  UInt32 DistanceLimit; 
     94  UInt32 Reps[4]; 
     95  int State; 
     96  int RemainLen; 
     97  unsigned char TempDictionary[4]; 
     98  #endif 
     99} CLzmaDecoderState; 
    72100 
    73101#ifdef _LZMA_OUT_READ 
    74 int LzmaDecoderInit( 
    75     unsigned char *buffer, UInt32 bufferSize, 
    76     int lc, int lp, int pb, 
    77     unsigned char *dictionary, UInt32 dictionarySize, 
    78   #ifdef _LZMA_IN_CB 
    79     ILzmaInCallback *inCallback 
    80   #else 
    81     unsigned char *inStream, UInt32 inSize 
    82   #endif 
    83 ); 
     102#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; } 
    84103#endif 
    85104 
    86 int LzmaDecode( 
    87     unsigned char *buffer,  
    88   #ifndef _LZMA_OUT_READ 
    89     UInt32 bufferSize, 
    90     int lc, int lp, int pb, 
    91   #ifdef _LZMA_IN_CB 
     105int LzmaDecode(CLzmaDecoderState *vs, 
     106    #ifdef _LZMA_IN_CB 
    92107    ILzmaInCallback *inCallback, 
    93   #else 
    94     unsigned char *inStream, UInt32 inSize, 
    95   #endif 
    96   #endif 
    97     unsigned char *outStream, UInt32 outSize, 
    98     UInt32 *outSizeProcessed); 
     108    #else 
     109    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, 
     110    #endif 
     111    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed); 
    99112 
    100113#endif 
  • trunk/target/linux/brcm63xx/image/lzma-loader/src/Makefile

    r15245 r41940  
    11# 
    2 # Makefile for Broadcom BCM947XX boards 
     2# Makefile for the LZMA compressed kernel loader for 
     3# Atheros AR7XXX/AR9XXX based boards 
    34# 
    4 # Copyright 2001-2003, Broadcom Corporation 
    5 # All Rights Reserved. 
    6 #  
    7 # THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 
    8 # KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 
    9 # SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 
    10 # FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 
     5# Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> 
    116# 
    12 # Copyright 2004  Manuel Novoa III <mjn3@codepoet.org> 
    13 #   Modified to support bzip'd kernels. 
    14 #   Of course, it would be better to integrate bunzip capability into CFE. 
     7# Some parts of this file was based on the OpenWrt specific lzma-loader 
     8# for the BCM47xx and ADM5120 based boards: 
     9#       Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) 
     10#       Copyright (C) 2005 Mineharu Takahara <mtakahar@yahoo.com> 
     11#       Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su> 
    1512# 
    16 # Copyright 2005  Oleg I. Vdovikin <oleg@cs.msu.su> 
    17 #   Cleaned up, modified for lzma support, removed from kernel 
     13# This program is free software; you can redistribute it and/or modify it 
     14# under the terms of the GNU General Public License version 2 as published 
     15# by the Free Software Foundation. 
    1816# 
    1917 
    20 TEXT_START      := 0x80010000 
    21 BZ_TEXT_START   := 0x80300000 
     18LOADADDR        := 
     19LZMA_TEXT_START := 0x80a00000 
     20LOADER_DATA     := 
    2221 
    23 OBJCOPY         := $(CROSS_COMPILE)objcopy -O binary -R .reginfo -R .note -R .comment -R .mdebug -S 
     22CC              := $(CROSS_COMPILE)gcc 
     23LD              := $(CROSS_COMPILE)ld 
     24OBJCOPY         := $(CROSS_COMPILE)objcopy 
     25OBJDUMP         := $(CROSS_COMPILE)objdump 
     26 
     27BIN_FLAGS       := -O binary -R .reginfo -R .note -R .comment -R .mdebug -S 
    2428 
    2529CFLAGS          = -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -Os \ 
    26                   -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic \ 
    27                   -ffunction-sections -pipe -mlong-calls -fno-common \ 
    28                   -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap 
    29 CFLAGS          += -DLOADADDR=$(TEXT_START) -D_LZMA_IN_CB 
     30                  -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 \ 
     31                  -mno-abicalls -fno-pic -ffunction-sections -pipe \ 
     32                  -ffreestanding -fhonour-copts \ 
     33                  -mabi=32 -march=mips32 \ 
     34                  -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap 
     35CFLAGS          += -D_LZMA_PROB32 
    3036 
    31 ASFLAGS         = $(CFLAGS) -D__ASSEMBLY__ -DBZ_TEXT_START=$(BZ_TEXT_START) 
     37ASFLAGS         = $(CFLAGS) -D__ASSEMBLY__ 
    3238 
    33 SEDFLAGS        := s/BZ_TEXT_START/$(BZ_TEXT_START)/;s/TEXT_START/$(TEXT_START)/ 
     39LDFLAGS         = -static --gc-sections -no-warn-mismatch 
     40LDFLAGS         += -e startup -T loader.lds -Ttext $(LZMA_TEXT_START) 
    3441 
    35 OBJECTS         := head.o data.o 
     42O_FORMAT        = $(shell $(OBJDUMP) -i | head -2 | grep elf32) 
    3643 
    37 all: loader.gz loader.elf 
     44OBJECTS         := head.o loader.o cache.o board.o printf.o LzmaDecode.o 
     45 
     46ifneq ($(strip $(LOADER_DATA)),) 
     47OBJECTS         += data.o 
     48CFLAGS          += -DLZMA_WRAPPER=1 -DLOADADDR=$(LOADADDR) 
     49endif 
     50 
     51 
     52all: loader.elf 
    3853 
    3954# Don't build dependencies, this may die if $(CC) isn't gcc 
     
    4257install: 
    4358 
    44 loader.gz: loader 
    45         gzip -nc9 $< > $@ 
     59%.o : %.c 
     60        $(CC) $(CFLAGS) -c -o $@ $< 
    4661 
    47 loader.elf: loader.o 
    48         cp $< $@ 
     62%.o : %.S 
     63        $(CC) $(ASFLAGS) -c -o $@ $< 
    4964 
    50 loader: loader.o 
    51         $(OBJCOPY) $< $@ 
     65data.o: $(LOADER_DATA) 
     66        $(LD) -r -b binary --oformat $(O_FORMAT) -T lzma-data.lds -o $@ $< 
    5267 
    53 loader.o: loader.lds $(OBJECTS) 
    54         $(LD) -static --gc-sections -no-warn-mismatch -T loader.lds -o $@ $(OBJECTS) 
     68loader: $(OBJECTS) 
     69        $(LD) $(LDFLAGS) -o $@ $(OBJECTS) 
    5570 
    56 loader.lds: loader.lds.in Makefile 
    57         @sed "$(SEDFLAGS)" < $< > $@ 
     71loader.bin: loader 
     72        $(OBJCOPY) $(BIN_FLAGS) $< $@ 
    5873 
    59 data.o: data.lds decompress.image 
    60         $(LD) -no-warn-mismatch -T data.lds -r -o $@ -b binary decompress.image -b elf32-tradlittlemips 
     74loader2.o: loader.bin 
     75        $(LD) -r -b binary --oformat $(O_FORMAT) -o $@ $< 
    6176 
    62 data.lds: 
    63         @echo "SECTIONS { .data : { code_start = .; *(.data) code_stop = .; }}" > $@ 
    64  
    65 decompress.image: decompress 
    66         $(OBJCOPY) $< $@ 
    67  
    68 decompress: decompress.lds decompress.o LzmaDecode.o 
    69         $(LD) -static --gc-sections -no-warn-mismatch -T decompress.lds -o $@ decompress.o LzmaDecode.o 
    70  
    71 decompress.lds: decompress.lds.in Makefile 
    72         @sed "$(SEDFLAGS)" < $< > $@ 
     77loader.elf: loader2.o 
     78        $(LD) -e startup -T loader2.lds -Ttext $(LOADADDR) -o $@ $< 
    7379 
    7480mrproper: clean 
    7581 
    7682clean: 
    77         rm -f loader.gz loader decompress *.lds *.o *.image 
     83        rm -f loader *.elf *.bin *.o 
     84 
     85 
     86 
  • trunk/target/linux/brcm63xx/image/lzma-loader/src/head.S

    r15245 r41940  
    1 /* Copyright 2005 Oleg I. Vdovikin (oleg@cs.msu.su)     */ 
    2 /* cache manipulation adapted from Broadcom code        */ 
    3 /* idea taken from original bunzip2 decompressor code   */ 
    4 /* Copyright 2004 Manuel Novoa III (mjn3@codepoet.org)  */ 
    5 /* Licensed under the linux kernel's version of the GPL.*/ 
     1/* 
     2 * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards 
     3 * 
     4 * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> 
     5 * 
     6 * Some parts of this code was based on the OpenWrt specific lzma-loader 
     7 * for the BCM47xx and ADM5120 based boards: 
     8 *      Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) 
     9 *      Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su> 
     10 * 
     11 * This program is free software; you can redistribute it and/or modify it 
     12 * under the terms of the GNU General Public License version 2 as published 
     13 * by the Free Software Foundation. 
     14 */ 
    615 
    716#include <asm/asm.h> 
    817#include <asm/regdef.h> 
     18#include "cp0regdef.h" 
     19#include "cacheops.h" 
     20#include "config.h" 
    921 
    1022#define KSEG0           0x80000000 
    1123 
    12 #define C0_CONFIG       $16 
    13 #define C0_TAGLO        $28 
    14 #define C0_TAGHI        $29 
    15  
    16 #define CONF1_DA_SHIFT  7                       /* D$ associativity */ 
    17 #define CONF1_DA_MASK   0x00000380 
    18 #define CONF1_DA_BASE   1 
    19 #define CONF1_DL_SHIFT  10                      /* D$ line size */ 
    20 #define CONF1_DL_MASK   0x00001c00 
    21 #define CONF1_DL_BASE   2 
    22 #define CONF1_DS_SHIFT  13                      /* D$ sets/way */ 
    23 #define CONF1_DS_MASK   0x0000e000 
    24 #define CONF1_DS_BASE   64 
    25 #define CONF1_IA_SHIFT  16                      /* I$ associativity */ 
    26 #define CONF1_IA_MASK   0x00070000 
    27 #define CONF1_IA_BASE   1 
    28 #define CONF1_IL_SHIFT  19                      /* I$ line size */ 
    29 #define CONF1_IL_MASK   0x00380000 
    30 #define CONF1_IL_BASE   2 
    31 #define CONF1_IS_SHIFT  22                      /* Instruction cache sets/way */ 
    32 #define CONF1_IS_MASK   0x01c00000 
    33 #define CONF1_IS_BASE   64 
    34  
    35 #define Index_Invalidate_I      0x00 
    36 #define Index_Writeback_Inv_D   0x01 
     24        .macro  ehb 
     25        sll     zero, 3 
     26        .endm 
    3727 
    3828        .text 
    39         LEAF(startup) 
     29 
     30LEAF(startup) 
    4031        .set noreorder 
    41          
    42         /* Copy decompressor code to the right place */ 
    43         li      t2, BZ_TEXT_START 
    44         add     a0, t2, 0 
    45         la      a1, code_start 
    46         la      a2, code_stop 
    47 $L1: 
    48         lw      t0, 0(a1) 
    49         sw      t0, 0(a0) 
    50         add     a1, 4 
    51         add     a0, 4 
    52         blt     a1, a2, $L1 
    53         nop 
    54          
    55         /* At this point we need to invalidate dcache and */ 
    56         /* icache before jumping to new code */ 
     32        .set mips32 
    5733 
    58 1:      /* Get cache sizes */ 
    59         .set    mips32 
    60         mfc0    s0,C0_CONFIG,1 
    61         .set    mips0 
     34        mtc0    zero, CP0_WATCHLO       # clear watch registers 
     35        mtc0    zero, CP0_WATCHHI 
     36        mtc0    zero, CP0_CAUSE         # clear before writing status register 
    6237 
    63         li      s1,CONF1_DL_MASK 
    64         and     s1,s0 
    65         beq     s1,zero,nodc 
     38        mfc0    t0, CP0_STATUS 
     39        li      t1, 0x1000001f 
     40        or      t0, t1 
     41        xori    t0, 0x1f 
     42        mtc0    t0, CP0_STATUS 
     43        ehb 
     44 
     45        mtc0    zero, CP0_COUNT 
     46        mtc0    zero, CP0_COMPARE 
     47        ehb 
     48 
     49        la      t0, __reloc_label       # get linked address of label 
     50        bal     __reloc_label           # branch and link to label to 
     51        nop                             # get actual address 
     52__reloc_label: 
     53        subu    t0, ra, t0              # get reloc_delta 
     54 
     55        beqz    t0, __reloc_done         # if delta is 0 we are in the right place 
    6656        nop 
    6757 
    68         srl     s1,CONF1_DL_SHIFT 
    69         li      t0,CONF1_DL_BASE 
    70         sll     s1,t0,s1                /* s1 has D$ cache line size */ 
     58        /* Copy our code to the right place */ 
     59        la      t1, _code_start         # get linked address of _code_start 
     60        la      t2, _code_end           # get linked address of _code_end 
     61        addu    t0, t0, t1              # calculate actual address of _code_start 
    7162 
    72         li      s2,CONF1_DA_MASK 
    73         and     s2,s0 
    74         srl     s2,CONF1_DA_SHIFT 
    75         addiu   s2,CONF1_DA_BASE        /* s2 now has D$ associativity */ 
     63__reloc_copy: 
     64        lw      t3, 0(t0) 
     65        sw      t3, 0(t1) 
     66        add     t1, 4 
     67        blt     t1, t2, __reloc_copy 
     68        add     t0, 4 
    7669 
    77         li      t0,CONF1_DS_MASK 
    78         and     t0,s0 
    79         srl     t0,CONF1_DS_SHIFT 
    80         li      s3,CONF1_DS_BASE 
    81         sll     s3,s3,t0                /* s3 has D$ sets per way */ 
     70        /* flush cache */ 
     71        la      t0, _code_start 
     72        la      t1, _code_end 
    8273 
    83         multu   s2,s3                   /* sets/way * associativity */ 
    84         mflo    t0                      /* total cache lines */ 
     74        li      t2, ~(CONFIG_CACHELINE_SIZE - 1) 
     75        and     t0, t2 
     76        and     t1, t2 
     77        li      t2, CONFIG_CACHELINE_SIZE 
    8578 
    86         multu   s1,t0                   /* D$ linesize * lines */ 
    87         mflo    s2                      /* s2 is now D$ size in bytes */ 
    88  
    89         /* Initilize the D$: */ 
    90         mtc0    zero,C0_TAGLO 
    91         mtc0    zero,C0_TAGHI 
    92  
    93         li      t0,KSEG0                /* Just an address for the first $ line */ 
    94         addu    t1,t0,s2                /*  + size of cache == end */ 
    95  
    96         .set    mips3 
    97 1:      cache   Index_Writeback_Inv_D,0(t0) 
    98         .set    mips0 
    99         bne     t0,t1,1b 
    100         addu    t0,s1 
    101          
    102 nodc: 
    103         /* Now we get to do it all again for the I$ */ 
    104          
    105         move    s3,zero                 /* just in case there is no icache */ 
    106         move    s4,zero 
    107  
    108         li      t0,CONF1_IL_MASK 
    109         and     t0,s0 
    110         beq     t0,zero,noic 
     79        b       __flush_check 
    11180        nop 
    11281 
    113         srl     t0,CONF1_IL_SHIFT 
    114         li      s3,CONF1_IL_BASE 
    115         sll     s3,t0                   /* s3 has I$ cache line size */ 
     82__flush_line: 
     83        cache   Hit_Writeback_Inv_D, 0(t0) 
     84        cache   Hit_Invalidate_I, 0(t0) 
     85        add     t0, t2 
    11686 
    117         li      t0,CONF1_IA_MASK 
    118         and     t0,s0 
    119         srl     t0,CONF1_IA_SHIFT 
    120         addiu   s4,t0,CONF1_IA_BASE     /* s4 now has I$ associativity */ 
     87__flush_check: 
     88        bne     t0, t1, __flush_line 
     89        nop 
    12190 
    122         li      t0,CONF1_IS_MASK 
    123         and     t0,s0 
    124         srl     t0,CONF1_IS_SHIFT 
    125         li      s5,CONF1_IS_BASE 
    126         sll     s5,t0                   /* s5 has I$ sets per way */ 
     91        sync 
    12792 
    128         multu   s4,s5                   /* sets/way * associativity */ 
    129         mflo    t0                      /* s4 is now total cache lines */ 
     93__reloc_done: 
    13094 
    131         multu   s3,t0                   /* I$ linesize * lines */ 
    132         mflo    s4                      /* s4 is cache size in bytes */ 
     95        /* clear bss */ 
     96        la      t0, _bss_start 
     97        la      t1, _bss_end 
     98        b       __bss_check 
     99        nop 
    133100 
    134         /* Initilize the I$: */ 
    135         mtc0    zero,C0_TAGLO 
    136         mtc0    zero,C0_TAGHI 
     101__bss_fill: 
     102        sw      zero, 0(t0) 
     103        addi    t0, 4 
    137104 
    138         li      t0,KSEG0                /* Just an address for the first $ line */ 
    139         addu    t1,t0,s4                /*  + size of cache == end */ 
     105__bss_check: 
     106        bne     t0, t1, __bss_fill 
     107        nop 
    140108 
    141         .set    mips3 
    142 1:      cache   Index_Invalidate_I,0(t0) 
    143         .set    mips0 
    144         bne     t0,t1,1b 
    145         addu    t0,s3 
     109        /* Setup new "C" stack */ 
     110        la      sp, _stack 
    146111 
    147 noic: 
    148         move    a0,s3                   /* icache line size */ 
    149         move    a1,s4                   /* icache size */ 
    150         move    a2,s1                   /* dcache line size */ 
    151         jal     t2 
    152         move    a3,s2                   /* dcache size */ 
    153          
     112        /* jump to the decompressor routine */ 
     113        la      t0, loader_main 
     114        jr      t0 
     115        nop 
     116 
    154117        .set reorder 
    155         END(startup) 
     118END(startup) 
Note: See TracChangeset for help on using the changeset viewer.