diff options
author | Roman Yeryomin <roman@advem.lv> | 2012-09-13 00:40:35 +0300 |
---|---|---|
committer | Roman Yeryomin <roman@advem.lv> | 2012-12-03 00:13:21 +0200 |
commit | 5deb3317cb51ac52de922bb55f8492624018906d (patch) | |
tree | c2fbe6346699d9bb0f2100490c3029519bb8fde8 /target/linux/realtek/files/rtkload | |
parent | 0239d37124f9184b478a42de8a7fa1bc85a6a6fe (diff) |
Add realtek target files
Signed-off-by: Roman Yeryomin <roman@advem.lv>
Diffstat (limited to 'target/linux/realtek/files/rtkload')
23 files changed, 5020 insertions, 0 deletions
diff --git a/target/linux/realtek/files/rtkload/COPYING b/target/linux/realtek/files/rtkload/COPYING new file mode 100644 index 000000000..60549be51 --- /dev/null +++ b/target/linux/realtek/files/rtkload/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/target/linux/realtek/files/rtkload/LzmaDecode.c b/target/linux/realtek/files/rtkload/LzmaDecode.c new file mode 100644 index 000000000..5c9d67f71 --- /dev/null +++ b/target/linux/realtek/files/rtkload/LzmaDecode.c @@ -0,0 +1,588 @@ +/*
+ LzmaDecode.c
+ LZMA Decoder (optimized for Speed version)
+
+ LZMA SDK 4.22 Copyright (c) 1999-2005 Igor Pavlov (2005-06-10)
+ http://www.7-zip.org/
+
+ LZMA SDK is licensed under two licenses:
+ 1) GNU Lesser General Public License (GNU LGPL)
+ 2) Common Public License (CPL)
+ It means that you can select one of these two licenses and
+ follow rules of that license.
+
+ SPECIAL EXCEPTION:
+ Igor Pavlov, as the author of this Code, expressly permits you to
+ statically or dynamically link your Code (or bind by name) to the
+ interfaces of this file without subjecting your linked Code to the
+ terms of the CPL or GNU LGPL. Any modifications or additions
+ to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#include "LzmaDecode.h"
+
+#ifndef Byte
+#define Byte unsigned char
+#endif
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*Buffer++)
+
+#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
+ { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
+
+#ifdef _LZMA_IN_CB
+
+#define RC_TEST { if (Buffer == BufferLim) \
+ { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
+ BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
+
+#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
+
+#else
+
+#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
+
+#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
+
+#endif
+
+#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+
+#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
+ { UpdateBit0(p); mi <<= 1; A0; } else \
+ { UpdateBit1(p); mi = (mi + mi) + 1; A1; }
+
+#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
+
+#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
+ { int i = numLevels; res = 1; \
+ do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
+ res -= (1 << numLevels); }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+ unsigned char prop0;
+ if (size < LZMA_PROPERTIES_SIZE)
+ return LZMA_RESULT_DATA_ERROR;
+ prop0 = propsData[0];
+ if (prop0 >= (9 * 5 * 5))
+ return LZMA_RESULT_DATA_ERROR;
+ {
+ for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+ for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+ propsRes->lc = prop0;
+ /*
+ unsigned char remainder = (unsigned char)(prop0 / 9);
+ propsRes->lc = prop0 % 9;
+ propsRes->pb = remainder / 5;
+ propsRes->lp = remainder % 5;
+ */
+ }
+
+ #ifdef _LZMA_OUT_READ
+ {
+ int i;
+ propsRes->DictionarySize = 0;
+ for (i = 0; i < 4; i++)
+ propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
+ if (propsRes->DictionarySize == 0)
+ propsRes->DictionarySize = 1;
+ }
+ #endif
+ return LZMA_RESULT_OK;
+}
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecode(CLzmaDecoderState *vs,
+ #ifdef _LZMA_IN_CB
+ ILzmaInCallback *InCallback,
+ #else
+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+ #endif
+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
+{
+ CProb *p = vs->Probs;
+ SizeT nowPos = 0;
+ Byte previousByte = 0;
+ UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+ UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+ int lc = vs->Properties.lc;
+
+ #ifdef _LZMA_OUT_READ
+
+ UInt32 Range = vs->Range;
+ UInt32 Code = vs->Code;
+ #ifdef _LZMA_IN_CB
+ const Byte *Buffer = vs->Buffer;
+ const Byte *BufferLim = vs->BufferLim;
+ #else
+ const Byte *Buffer = inStream;
+ const Byte *BufferLim = inStream + inSize;
+ #endif
+ int state = vs->State;
+ UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+ int len = vs->RemainLen;
+ UInt32 globalPos = vs->GlobalPos;
+ UInt32 distanceLimit = vs->DistanceLimit;
+
+ Byte *dictionary = vs->Dictionary;
+ UInt32 dictionarySize = vs->Properties.DictionarySize;
+ UInt32 dictionaryPos = vs->DictionaryPos;
+
+ Byte tempDictionary[4];
+
+ #ifndef _LZMA_IN_CB
+ *inSizeProcessed = 0;
+ #endif
+ *outSizeProcessed = 0;
+ if (len == kLzmaStreamWasFinishedId)
+ return LZMA_RESULT_OK;
+
+ if (dictionarySize == 0)
+ {
+ dictionary = tempDictionary;
+ dictionarySize = 1;
+ tempDictionary[0] = vs->TempDictionary[0];
+ }
+
+ if (len == kLzmaNeedInitId)
+ {
+ {
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+ UInt32 i;
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
+ rep0 = rep1 = rep2 = rep3 = 1;
+ state = 0;
+ globalPos = 0;
+ distanceLimit = 0;
+ dictionaryPos = 0;
+ dictionary[dictionarySize - 1] = 0;
+ #ifdef _LZMA_IN_CB
+ RC_INIT;
+ #else
+ RC_INIT(inStream, inSize);
+ #endif
+ }
+ len = 0;
+ }
+ while(len != 0 && nowPos < outSize)
+ {
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ len--;
+ }
+ if (dictionaryPos == 0)
+ previousByte = dictionary[dictionarySize - 1];
+ else
+ previousByte = dictionary[dictionaryPos - 1];
+
+ #else /* if !_LZMA_OUT_READ */
+
+ int state = 0;
+ UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+ int len = 0;
+ const Byte *Buffer;
+ const Byte *BufferLim;
+ UInt32 Range;
+ UInt32 Code;
+
+ #ifndef _LZMA_IN_CB
+ *inSizeProcessed = 0;
+ #endif
+ *outSizeProcessed = 0;
+
+ {
+ UInt32 i;
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
+ }
+
+ #ifdef _LZMA_IN_CB
+ RC_INIT;
+ #else
+ RC_INIT(inStream, inSize);
+ #endif
+
+ #endif /* _LZMA_OUT_READ */
+
+ while(nowPos < outSize)
+ {
+ CProb *prob;
+ UInt32 bound;
+ int posState = (int)(
+ (nowPos
+ #ifdef _LZMA_OUT_READ
+ + globalPos
+ #endif
+ )
+ & posStateMask);
+
+ prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
+ IfBit0(prob)
+ {
+ int symbol = 1;
+ UpdateBit0(prob)
+ prob = p + Literal + (LZMA_LIT_SIZE *
+ (((
+ (nowPos
+ #ifdef _LZMA_OUT_READ
+ + globalPos
+ #endif
+ )
+ & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+ if (state >= kNumLitStates)
+ {
+ int matchByte;
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ matchByte = dictionary[pos];
+ #else
+ matchByte = outStream[nowPos - rep0];
+ #endif
+ do
+ {
+ int bit;
+ CProb *probLit;
+ matchByte <<= 1;
+ bit = (matchByte & 0x100);
+ probLit = prob + 0x100 + bit + symbol;
+ RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
+ }
+ while (symbol < 0x100);
+ }
+ while (symbol < 0x100)
+ {
+ CProb *probLit = prob + symbol;
+ RC_GET_BIT(probLit, symbol)
+ }
+ previousByte = (Byte)symbol;
+
+ outStream[nowPos++] = previousByte;
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #endif
+ if (state < 4) state = 0;
+ else if (state < 10) state -= 3;
+ else state -= 6;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRep + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ state = state < kNumLitStates ? 0 : 3;
+ prob = p + LenCoder;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRepG0 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
+ IfBit0(prob)
+ {
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos;
+ #endif
+ UpdateBit0(prob);
+
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit == 0)
+ #else
+ if (nowPos == 0)
+ #endif
+ return LZMA_RESULT_DATA_ERROR;
+
+ state = state < kNumLitStates ? 9 : 11;
+ #ifdef _LZMA_OUT_READ
+ pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #else
+ previousByte = outStream[nowPos - rep0];
+ #endif
+ outStream[nowPos++] = previousByte;
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+ #endif
+
+ continue;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ }
+ }
+ else
+ {
+ UInt32 distance;
+ UpdateBit1(prob);
+ prob = p + IsRepG1 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ distance = rep1;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRepG2 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ distance = rep2;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ state = state < kNumLitStates ? 8 : 11;
+ prob = p + RepLenCoder;
+ }
+ {
+ int numBits, offset;
+ CProb *probLen = prob + LenChoice;
+ IfBit0(probLen)
+ {
+ UpdateBit0(probLen);
+ probLen = prob + LenLow + (posState << kLenNumLowBits);
+ offset = 0;
+ numBits = kLenNumLowBits;
+ }
+ else
+ {
+ UpdateBit1(probLen);
+ probLen = prob + LenChoice2;
+ IfBit0(probLen)
+ {
+ UpdateBit0(probLen);
+ probLen = prob + LenMid + (posState << kLenNumMidBits);
+ offset = kLenNumLowSymbols;
+ numBits = kLenNumMidBits;
+ }
+ else
+ {
+ UpdateBit1(probLen);
+ probLen = prob + LenHigh;
+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
+ numBits = kLenNumHighBits;
+ }
+ }
+ RangeDecoderBitTreeDecode(probLen, numBits, len);
+ len += offset;
+ }
+
+ if (state < 4)
+ {
+ int posSlot;
+ state += kNumLitStates;
+ prob = p + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+ kNumPosSlotBits);
+ RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ int numDirectBits = ((posSlot >> 1) - 1);
+ rep0 = (2 | ((UInt32)posSlot & 1));
+ if (posSlot < kEndPosModelIndex)
+ {
+ rep0 <<= numDirectBits;
+ prob = p + SpecPos + rep0 - posSlot - 1;
+ }
+ else
+ {
+ numDirectBits -= kNumAlignBits;
+ do
+ {
+ RC_NORMALIZE
+ Range >>= 1;
+ rep0 <<= 1;
+ if (Code >= Range)
+ {
+ Code -= Range;
+ rep0 |= 1;
+ }
+ }
+ while (--numDirectBits != 0);
+ prob = p + Align;
+ rep0 <<= kNumAlignBits;
+ numDirectBits = kNumAlignBits;
+ }
+ {
+ int i = 1;
+ int mi = 1;
+ do
+ {
+ CProb *prob3 = prob + mi;
+ RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
+ i <<= 1;
+ }
+ while(--numDirectBits != 0);
+ }
+ }
+ else
+ rep0 = posSlot;
+ if (++rep0 == (UInt32)(0))
+ {
+ /* it's for stream version */
+ len = kLzmaStreamWasFinishedId;
+ break;
+ }
+ }
+
+ len += kMatchMinLen;
+ #ifdef _LZMA_OUT_READ
+ if (rep0 > distanceLimit)
+ #else
+ if (rep0 > nowPos)
+ #endif
+ return LZMA_RESULT_DATA_ERROR;
+
+ #ifdef _LZMA_OUT_READ
+ if (dictionarySize - distanceLimit > (UInt32)len)
+ distanceLimit += len;
+ else
+ distanceLimit = dictionarySize;
+ #endif
+
+ do
+ {
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #else
+ previousByte = outStream[nowPos - rep0];
+ #endif
+ len--;
+ outStream[nowPos++] = previousByte;
+ }
+ while(len != 0 && nowPos < outSize);
+ }
+ }
+ RC_NORMALIZE;
+
+ #ifdef _LZMA_OUT_READ
+ vs->Range = Range;
+ vs->Code = Code;
+ vs->DictionaryPos = dictionaryPos;
+ vs->GlobalPos = globalPos + (UInt32)nowPos;
+ vs->DistanceLimit = distanceLimit;
+ vs->Reps[0] = rep0;
+ vs->Reps[1] = rep1;
+ vs->Reps[2] = rep2;
+ vs->Reps[3] = rep3;
+ vs->State = state;
+ vs->RemainLen = len;
+ vs->TempDictionary[0] = tempDictionary[0];
+ #endif
+
+ #ifdef _LZMA_IN_CB
+ vs->Buffer = Buffer;
+ vs->BufferLim = BufferLim;
+ #else
+ *inSizeProcessed = (SizeT)(Buffer - inStream);
+ #endif
+ *outSizeProcessed = nowPos;
+ return LZMA_RESULT_OK;
+}
diff --git a/target/linux/realtek/files/rtkload/LzmaDecode.h b/target/linux/realtek/files/rtkload/LzmaDecode.h new file mode 100644 index 000000000..35e37ed0d --- /dev/null +++ b/target/linux/realtek/files/rtkload/LzmaDecode.h @@ -0,0 +1,131 @@ +/*
+ LzmaDecode.h
+ LZMA Decoder interface
+
+ LZMA SDK 4.21 Copyright (c) 1999-2005 Igor Pavlov (2005-06-08)
+ http://www.7-zip.org/
+
+ LZMA SDK is licensed under two licenses:
+ 1) GNU Lesser General Public License (GNU LGPL)
+ 2) Common Public License (CPL)
+ It means that you can select one of these two licenses and
+ follow rules of that license.
+
+ SPECIAL EXCEPTION:
+ Igor Pavlov, as the author of this code, expressly permits you to
+ statically or dynamically link your code (or bind by name) to the
+ interfaces of this file without subjecting your linked code to the
+ terms of the CPL or GNU LGPL. Any modifications or additions
+ to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#ifndef __LZMADECODE_H
+#define __LZMADECODE_H
+
+/* #define _LZMA_IN_CB */
+/* Use callback for input data */
+
+/* #define _LZMA_OUT_READ */
+/* Use read function for output data */
+
+/* #define _LZMA_PROB32 */
+/* It can increase speed on some 32-bit CPUs,
+ but memory usage will be doubled in that case */
+
+/* #define _LZMA_LOC_OPT */
+/* Enable local speed optimizations inside code */
+
+/* #define _LZMA_SYSTEM_SIZE_T */
+/* Use system's size_t. You can use it to enable 64-bit sizes supporting*/
+
+#ifndef UInt32
+#ifdef _LZMA_UINT32_IS_ULONG
+#define UInt32 unsigned long
+#else
+#define UInt32 unsigned int
+#endif
+#endif
+
+#ifndef SizeT
+#ifdef _LZMA_SYSTEM_SIZE_T
+#include <stddef.h>
+#define SizeT size_t
+#else
+#define SizeT UInt32
+#endif
+#endif
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb unsigned short
+#endif
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+#ifdef _LZMA_IN_CB
+typedef struct _ILzmaInCallback
+{
+ int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
+} ILzmaInCallback;
+#endif
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_PROPERTIES_SIZE 5
+
+typedef struct _CLzmaProperties
+{
+ int lc;
+ int lp;
+ int pb;
+ #ifdef _LZMA_OUT_READ
+ UInt32 DictionarySize;
+ #endif
+}CLzmaProperties;
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
+
+#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
+
+#define kLzmaNeedInitId (-2)
+
+typedef struct _CLzmaDecoderState
+{
+ CLzmaProperties Properties;
+ CProb *Probs;
+
+ #ifdef _LZMA_IN_CB
+ const unsigned char *Buffer;
+ const unsigned char *BufferLim;
+ #endif
+
+ #ifdef _LZMA_OUT_READ
+ unsigned char *Dictionary;
+ UInt32 Range;
+ UInt32 Code;
+ UInt32 DictionaryPos;
+ UInt32 GlobalPos;
+ UInt32 DistanceLimit;
+ UInt32 Reps[4];
+ int State;
+ int RemainLen;
+ unsigned char TempDictionary[4];
+ #endif
+} CLzmaDecoderState;
+
+#ifdef _LZMA_OUT_READ
+#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
+#endif
+
+int LzmaDecode(CLzmaDecoderState *vs,
+ #ifdef _LZMA_IN_CB
+ ILzmaInCallback *inCallback,
+ #else
+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+ #endif
+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
+
+#endif
diff --git a/target/linux/realtek/files/rtkload/Makefile b/target/linux/realtek/files/rtkload/Makefile new file mode 100644 index 000000000..b3f560205 --- /dev/null +++ b/target/linux/realtek/files/rtkload/Makefile @@ -0,0 +1,281 @@ +# The kernel tree you do builds in. +# Uncomment if you're building for the emulator +include ../.config +#include ../../.config # to check toolchain CONFIG_RSDK_rsdk-1.5.4-5281-EB-2.6.30-0.9.30.3-uls-101110 +DOQUIET = false +#DOQUIET = true +#EMULATOR = true +#KERNEL_ROOT = /home/john/RealTek/linux-2.5/linux +KERNEL_ROOT = .. +ifeq ($(wildcard $(DIR_USERS)/boa/tools/cvimg),) +ifeq ($(wildcard $(DIR_USERS)/goahead-2.1.1/LINUX/cvimg),) +CVIMG=./cvimg +else +CVIMG=$(DIR_USERS)/goahead-2.1.1/LINUX/cvimg +endif +else +CVIMG=$(DIR_USERS)/boa/tools/cvimg +endif +# ---- shouldn't need to modify below this line. + +ifdef EMULATOR +EMUOPTS = -DEMULATOR +LDSCRIPT = ld-emu.script +else +EMUOPTS = +LDSCRIPT = ld.script +endif + +COPTIONS = -DROM_MEMORY -DCOMPRESSED_KERNEL -D__KERNEL__ + +#SOURCES = vsprintf.c string.c ctype.c prom_printf.c misc.c hfload.c start.S read_memory.c +ifdef BZ2_COMPRESS + SOURCES = misc.c hfload.c start.S cache.c +else +ifdef GZIP_COMPRESS + SOURCES = string.c ctype.c misc.c hfload.c start.S read_memory.c cache.c +else + SOURCES = string.c ctype.c misc.c hfload.c start.S read_memory.c cache.c LzmaDecode.c +endif +endif + +LOADER_FILES = hfload.o read_memory.o +#LOADER_FILES = hfload.o +ifdef BZ2_COMPRESS + SUPPORT_FILES = misc.o cache.o +else +ifdef GZIP_COMPRESS + SUPPORT_FILES = vsprintf.o prom_printf.o string.o ctype.o misc.o cache.o +else +ifeq ($(strip $(DOQUIET)),true) + SUPPORT_FILES = string.o ctype.o misc.o cache.o LzmaDecode.o +else + SUPPORT_FILES = vsprintf.o prom_printf.o string.o ctype.o misc.o cache.o LzmaDecode.o +endif +endif +endif + +CFLAGS =-Os -g -fno-pic -mno-abicalls $(EMUOPTS) +ifeq ($(strip $(DOQUIET)),true) +CFLAGS += $(WARNINGS) -D__DO_QUIET__ +endif +CFLAGS += -DEMBEDDED -I$(KERNEL_ROOT)/include/linux -I$(KERNEL_ROOT)/include -I$(KERNEL_ROOT)/lib $(COPTIONS) -G 0 +CFLAGS += -I$(KERNEL_ROOT)/arch/rlx/bsp -I$(KERNEL_ROOT)/arch/rlx/include -I$(KERNEL_ROOT)/arch/rlx/include/asm/mach-generic +#ASFLAGS = -g $(EMUOPTS) -DEMBEDDED -I$(KERNEL_ROOT)/include -I$(KERNEL_ROOT)/arch/rlx/include +#CFLAGS += -I$(KERNEL_ROOT)/arch/mips/include -I$(KERNEL_ROOT)/arch/mips/include/asm/mach-generic +#ASFLAGS = -g $(EMUOPTS) -DEMBEDDED -I$(KERNEL_ROOT)/include -I$(KERNEL_ROOT)/arch/mips/include +ASFLAGS = -g -fno-pic -mno-abicalls $(EMUOPTS) -DEMBEDDED -I$(KERNEL_ROOT)/include -I$(KERNEL_ROOT)/arch/rlx/include + +LDFLAGS=-static -nostdlib + +ifdef BZ2_COMPRESS +CFLAGS += -DBZ2_COMPRESS +ASFLAGS += -DBZ2_COMPRESS +else +ifndef GZIP_COMPRESS +CFLAGS += -DLZMA_COMPRESS +ASFLAGS += -DLZMA_COMPRESS +endif +endif + +START_FILE = start.o + + +#RTL_819X normal LOAD_START_ADDR and FLASH_OFFSET +ifdef CONFIG_RTL_819X +LOAD_START_ADDR=0x80500000 +FLASH_OFFSET=30000 +endif + +ifdef CONFIG_RTL_8196B_GW +ifdef CONFIG_MTD_RTL_8196_SPI +LOAD_START_ADDR=0x80A00000 +else +LOAD_START_ADDR=0x80500000 +endif +ifdef CONFIG_RTL_8196B_GW_8M +FLASH_OFFSET=10000 +else +ifeq ($(CONFIG_RTL_FLASH_MAPPING_ENABLE),y) +ifeq ($(CONFIG_RTL_LINUX_IMAGE_OFFSET),) +FLASH_OFFSET=30000 +else +FLASH_OFFSET=$(CONFIG_RTL_LINUX_IMAGE_OFFSET) +endif +else +FLASH_OFFSET=30000 +endif +endif +endif + +ifdef CONFIG_RTL_8198_GW +ifdef CONFIG_MTD_RTL_8196_SPI +LOAD_START_ADDR=0x80A00000 +else +LOAD_START_ADDR=0x80500000 +endif +ifdef CONFIG_RTL_8196B_GW_8M +FLASH_OFFSET=10000 +else +FLASH_OFFSET=30000 +endif +endif + +ifdef CONFIG_RTL_8196B_ICT +LOAD_START_ADDR=0x80500000 +FLASH_OFFSET=30000 +endif + +ifdef CONFIG_RTL_865X_PANAHOST +LOAD_START_ADDR=0x80500000 +FLASH_OFFSET=20000 +endif + +ifdef CONFIG_RTL_8197B_PANA +LOAD_START_ADDR=0x80700000 +FLASH_OFFSET=30000 +endif + +ifdef CONFIG_RTL_8196B_AP_ROOT +LOAD_START_ADDR=0x80500000 +FLASH_OFFSET=30000 +endif + +ifeq ($(CONFIG_RTL_FLASH_MAPPING_ENABLE),y) +ifeq ($(CONFIG_RTL_LINUX_IMAGE_OFFSET),) +FLASH_OFFSET=20000 +else +FLASH_OFFSET=$(CONFIG_RTL_LINUX_IMAGE_OFFSET) +endif +else +FLASH_OFFSET=20000 +endif + +ifdef CONFIG_RTK_VOIP_BOARD +LOAD_START_ADDR=0x80C00000 +endif + +CV_SIGNATURE= +ifdef CONFIG_RTL_8197B_PANA +#CV_OPTION=linux +CV_OPTION=signature +CV_SIGNATURE=csys +else +ifdef CONFIG_SQUASHFS +CV_OPTION=linux-ro +else +CV_OPTION=linux +endif +endif + +ifdef CONFIG_RTL_8198_NFBI_BOARD +LOAD_START_ADDR=0x80700000 +FLASH_OFFSET=30000 +CV_OPTION=signature +CV_SIGNATURE=csys +endif + +#ifdef CONFIG_RTL_8196C_iNIC +#LOAD_START_ADDR=0x80500000 +#FLASH_OFFSET=30000 +#CV_OPTION=signature +#CV_SIGNATURE=cs6c +#endif + +CROSS_COMPILE ?= rsdk-linux- + +LD=$(CROSS_COMPILE)ld +CC=$(CROSS_COMPILE)gcc +CPP=$(CROSS_COMPILE)gcc +STRIP=$(CROSS_COMPILE)strip +AS=$(CROSS_COMPILE)as +NM=$(CROSS_COMPILE)nm +OBJCOPY=$(CROSS_COMPILE)objcopy + +SEDFLAGS = s/LOAD_ADDR/$(LOAD_START_ADDR)/; + +ifdef CONFIG_RTK_VOIP_BOARD +STRIP-OPTIONS-$(CONFIG_RSDK_rsdk-1.5.4-5281-EB-2.6.30-0.9.30.3-uls-101110) = --remove-section=.bss +endif + +# jffs2 related definitions +DIR_ROMFS_BOOT = $(DIR_ROMFS)/boot/ +MKJFFS2 = ./mkfs.jffs2 +MKIMAGE_UBOOT = ./mkimage-uboot + +O_TARGET := rtk +obj-y := vmlinux_img.o $(START_FILE) $(LOADER_FILES) $(SUPPORT_FILES) + +ifdef CONFIG_ROOTFS_JFFS2 +all: rtk-clean rtk-vmlinux_img vmlinux_img.gzip.uboot.jffs2 +else +all: rtk-clean rtk-vmlinux_img $(START_FILE) $(LOADER_FILES) $(SUPPORT_FILES) +endif + +#memload-partial +ifdef CONFIG_ROOTFS_JFFS2 +jffs2_no_this: +endif + $(CC) -fno-pic -mno-abicalls -Os -fomit-frame-pointer -D__KERNEL__ -c vmlinux_img.c -o vmlinux_img.o + $(OBJCOPY) --add-section .vmlinux=vmlinux_img.gz vmlinux_img.o + @sed "$(SEDFLAGS)" < ld.script.in > $(LDSCRIPT) + $(LD) $(LDFLAGS) -G 0 -T $(LDSCRIPT) -o memload-partial $(START_FILE) $(LOADER_FILES) $(SUPPORT_FILES) vmlinux_img.o + $(NM) memload-partial | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > system.map + + cp memload-partial memload-full + $(OBJCOPY) -Obinary memload-full nfjrom + $(CVIMG) $(CV_OPTION) nfjrom linux.bin $(LOAD_START_ADDR) $(FLASH_OFFSET) $(CV_SIGNATURE) +# @./size_chk vmlinux_img $(LOAD_START_ADDR) + @$(CVIMG) size_chk vmlinux_img $(LOAD_START_ADDR) || exit $$? +ifeq ($(CONFIG_BLK_DEV_INITRD),y) + @echo "RAMFS no need to check flash size" +else +ifeq ($(CONFIG_RTL_FLASH_MAPPING_ENABLE),y) + @$(CVIMG) flash_size_chk linux.bin || exit $$? +endif +endif + +rtk-clean: + rm -f *.o memload system.map nfjrom memload-partial memload-full vmlinux_img.gz target target.img strip1 linux.bin vmlinux-stripped $(LDSCRIPT) vmlinux_img vmlinux_img.gzip.uboot.jffs2 + +rtk-vmlinux_img: + cp $(KERNEL_ROOT)/vmlinux vmlinux-stripped + $(STRIP) vmlinux-stripped $(STRIP-OPTIONS-y) + $(OBJCOPY) -Obinary vmlinux-stripped vmlinux_img + rm -f vmlinux_img.gz +ifndef CONFIG_ROOTFS_JFFS2 +ifdef BZ2_COMPRESS + cat vmlinux_img | bzip2 -9v > vmlinux_img.gz +else +ifdef GZIP_COMPRESS + cat vmlinux_img | gzip -9v > vmlinux_img.gz +else + ./lzma e vmlinux_img vmlinux_img.gz +endif +endif + $(CVIMG) vmlinuxhdr vmlinux_img.gz vmlinux_img.gz $(KERNEL_ROOT)/vmlinux +endif # CONFIG_ROOTFS_JFFS2 + +target: nfjrom $(BOOT_CODE) $(EXT2_IMG) +# Pading boot code to 512 bytes long (but only 256 bytes are allowed, 512 is to make it page alignment) + $(OBJCOPY) -Obinary --pad-to=0x80000200 $(BOOT_CODE) bootcode + $(OBJCOPY) -Obinary --remove-section=.bss --remove-section=.data --remove-section=.mdebug --pad-to=0x806FFE00 memload-full nandrom + $(LD) -G0 -Ttarget.script -o target -bbinary bootcode -bbinary nandrom -bbinary $(EXT2_IMG) + $(OBJCOPY) -Obinary target target.img + cp -f ./target.img /tftpboot +depend: + rm -f .depend + $(CC) $(CFLAGS) -MM $(SOURCES) >.depend + +bz2: + @make BZ2_COMPRESS=1 + +gzip: + @make GZIP_COMPRESS=1 + +vmlinux_img.gzip.uboot.jffs2: + cat vmlinux_img | gzip -9v > vmlinux_img.gzip + mkdir -p $(DIR_ROMFS_BOOT) + $(MKIMAGE_UBOOT) -A mips -O linux -T kernel -C gzip -a 80000000 -e 80000000 -n 8954c_kernel -d vmlinux_img.gzip $(DIR_ROMFS_BOOT)/vmlinux_img.gzip.uboot + $(MKJFFS2) -n -p -b -e $(CONFIG_JFFS2_ERASE_SIZE) -o $(DIR_IMAGE)/vmlinux_img.gzip.uboot.jffs2 -d $(DIR_ROMFS) + diff --git a/target/linux/realtek/files/rtkload/README b/target/linux/realtek/files/rtkload/README new file mode 100644 index 000000000..236e144a1 --- /dev/null +++ b/target/linux/realtek/files/rtkload/README @@ -0,0 +1,115 @@ +hfload is a simple, second stage ELF bootloader for the VTech Helio. +It is probably generalizable to other Philips R3912 devices with a +friendly boot rom and flash. + +It works on both real Helio hardware and the Helio emulator. + +LEGAL STUFF +=========== + +This software is subject to the terms and conditions of the GNU +General Public License. See the file "COPYING" in the main directory +of this archive for more details. + +Copyright (C) 2000 by Jay Carlson. + +Many files originated in the Linux kernel. + +Note that my intent is that the last two stages of the build process +(production of the ELF memory image, and conversion to a raw ROM +image) are "mere aggregation [...] on a volume of a storage or +distribution medium" in the sense of the last paragraph of section 2 +of the GPL. If necessary, I will arrange that the aggregation +mechanism is "/bin/cat" or a simple C program, if anyone has a problem +with my use of a "linker" to throw together files in a single box. No +real linking is done at this stage; the Linux kernel is treated as +pure data. + +QUICK START +=========== + +Point the Makefile at your kernel build directory. If building for +the emulator, uncomment the EMULATOR line in the Makefile. + +If you don't have a romdisk image, touch romdisk. + +Put the first 64K of a 2M VT-OS rom image in "vtboot"; if you're +building for the real hardware you can fake it with "make fake-vtboot". + +"make" produces "tryrom" and "linux.bin". tryrom is a full 2M ROM +image for the emulator containing the VTOS bootloader, hfload, a +compressed stripped copy of your vmlinux, and the contents of romdisk. +linux.bin is a 2M-128k OS upgrade image without the VTOS bootloader, +suitable for use with the VTech "dt.exe" flash programming tool. + +WHAT IT DOES +============ + +On startup, the VT-OS bootroom sets up the hardware a little, installs +a 4k stack, and jumps to 0x9fc10000 in ROM. hfload begins here. + +Setup +----- + +start.S zeroes the hfload bss area. It moves the stack to somewhere +more spacious (paranoia), and jumps to main(). (It should turn on the +serial port too.) + +main() immediately prints a message on serial port A. (It used to try +to initialize the Helio LCD hardware, but that's commented out now.) + +Decompression +------------- + +The contents of the input_data-input_data_end region are gunzip'd from +flash to the 4M mark in memory, at the start of the second DRAM bank. + +input_data typically points to a gzip'd stripped Linux kernel. + +ELF load +-------- + +main() reads in the ELF header from the decompressed data. +(Currently, the only error checking is verification that the declared +sizes of structures match the expected sizes; this catches most +errors.) The ELF image is copied to its destinations declared in the +program headers, and excess memory is properly zeroed. + +Kernel start +------------ + +main() hands the ELF entry address to start.S:start_kernel. +start_kernel places the address of the romdisk area at 0x80030000, +restores the stack, and calls entry_address(0,0,0). + +WHY THE IMAGE READ FUNCTIONS ARE SO UGLY +======================================== + +I originally debugged this application as a userland binary, reading +the image from a file descriptor. I then realized I could mmap() the +kernel image. The restrictions on read_struct, copy_to_region, and +seek_forward came out of this. As it turns out, the "can only seek +forward, must be aligned" characteristics may be useful in the future. +There's no reason why the entire kernel has to be uncompressed as a +big blob; the stream reading functions could be rewritten to process +the 32k decompressed windows as a coroutine to the decompression +process. ELF images over about 2M are going to need this. + +WHY THIS WHOLE APP IS SO UGLY +============================= + +Most of this will be rewritten once I understand better what I'm +trying to do. Why make throwaway code pretty? + +VTBOOT +====== + +The file "vtboot" is not included with this distribution. It is an +image of the VTech VT-OS bootloader that's hardwired into real Helio +devices. It's the first 64k of a full VT-OS rom image. Given such a +rom image, it can be extracted by: + + dd if=VTOS-1-1-03.rom of=vtboot bs=64k count=1 + +If you're building for the real hardware, you don't need this file. +"make fake-vtboot" produces 64k of zeroes. diff --git a/target/linux/realtek/files/rtkload/cache.c b/target/linux/realtek/files/rtkload/cache.c new file mode 100644 index 000000000..8e4ca57d8 --- /dev/null +++ b/target/linux/realtek/files/rtkload/cache.c @@ -0,0 +1,197 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994 - 1999 by Ralf Baechle + * Modified for R3000 by Paul M. Antoine, 1995, 1996 + * Complete output from die() by Ulf Carlsson, 1998 + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +//#include <linux/config.h> +#include <linux/autoconf.h> +#include <linux/linkage.h> +#include <asm/ptrace.h> +//#include <asm/mipsregs.h> +#include <asm/rlxregs.h> +#include <asm/addrspace.h> +//#include <asm/system.h> + +#if defined(CONFIG_RTL_819X) +/* For Realtek RTL865XC Network platform series */ +#define _ICACHE_SIZE (16 * 1024) /* 16K bytes */ +#define _DCACHE_SIZE (8 * 1024) /* 8K bytes */ +#define _CACHE_LINE_SIZE 4 /* 4 words */ +#endif + +#define PROM_DEBUG + +#ifdef PROM_DEBUG +extern int prom_printf(char *, ...); +#endif + +/*Cyrus Tsai*/ +void flush_cache(void); +void flush_icache(unsigned int start, unsigned int end); +void flush_dcache(unsigned int start, unsigned int end); +/*Cyrus Tsai*/ + + +void flush_cache(void) +{ +#ifdef CONFIG_RTL_EB8186 + flush_dcache(0,0); + flush_icache(0,0); +#endif +#if defined(CONFIG_RTL_819X) + flush_dcache(KSEG0, KSEG0+_DCACHE_SIZE); + flush_icache(KSEG0, KSEG0+_ICACHE_SIZE); +#endif +} + + +/*Cyrus Tsai*/ +void flush_icache(unsigned int start, unsigned int end) +{ +#if defined(CONFIG_RTL_819X) + /* + Flush data cache at first in write-back platform. + + Ghhuang (2007/3/9): + + RD-Center suggest that we need to flush D-cache entries which + might match to same address as I-cache ... when we flush + I-cache. + ( Maybe some data is treated as data/instruction, both. ) + */ + flush_dcache(start, end); + + /*Invalidate I-Cache*/ + __asm__ volatile( + "mtc0 $0,$20\n\t" + "nop\n\t" + "li $8,2\n\t" + "mtc0 $8,$20\n\t" + "nop\n\t" + "nop\n\t" + "mtc0 $0,$20\n\t" + "nop" + : /* no output */ + : /* no input */ + ); + +#endif + +#ifdef CONFIG_RTL_EB8186 + unsigned long flags; + volatile unsigned int reg; + save_flags(flags);cli(); + reg=read_32bit_cp0_register(CP0_XCONTEXT); + __asm__ volatile("nop"); + __asm__ volatile("nop"); + write_32bit_cp0_register(CP0_XCONTEXT, (reg &(~0x2))); //write '0' to bit 0,1 + __asm__ volatile("nop"); + __asm__ volatile("nop"); + write_32bit_cp0_register(CP0_XCONTEXT, (reg | 0x2)); //wirte '1' to bit 0, 1 + __asm__ volatile("nop"); + __asm__ volatile("nop"); + restore_flags(flags); +#endif +} + +void flush_dcache(unsigned int start, unsigned int end) +{ +#ifdef CONFIG_RTL_EB8186 + unsigned long flags; + volatile unsigned int reg; + save_flags(flags);cli(); + reg=read_32bit_cp0_register(CP0_XCONTEXT); + __asm__ volatile("nop"); + __asm__ volatile("nop"); + write_32bit_cp0_register(CP0_XCONTEXT, (reg & (~0x1))); //write '0' to bit 0,1 + __asm__ volatile("nop"); + __asm__ volatile("nop"); + write_32bit_cp0_register(CP0_XCONTEXT, (reg | 0x1)); //wirte '1' to bit 0, 1 + __asm__ volatile("nop"); + __asm__ volatile("nop"); + restore_flags(flags); +#endif + +#if defined(CONFIG_RTL_819X) + /* Flush D-Cache using its range */ + unsigned char *p; + unsigned int size; + unsigned int flags; + unsigned int i; + + size = end - start; + + /* correctness check : flush all if any parameter is illegal */ +// david +// if ( (size >= dcache_size) || + if ((size >= _DCACHE_SIZE) || (KSEGX(start) != KSEG0) ) + { + /* + * ghhguang + * => For Realtek Lextra CPU, + * the cache would NOT be flushed only if the Address to-be-flushed + * is the EXPLICIT address ( which is really stored in that cache line ). + * For the aliasd addresses, the cache entry would NOT be flushed even + * it matchs same cache-index. + * + * => This is different from traditional MIPS-based CPU's configuration. + * So if we want to flush ALL-cache entries, we would need to use "mtc0" + * instruction instead of simply modifying the "size" to "dcache_size" + * and "start" to "KSEG0". + * + */ + __asm__ volatile( + "mtc0 $0,$20\n\t" + "nop\n\t" + "li $8,512\n\t" + "mtc0 $8,$20\n\t" + "nop\n\t" + "nop\n\t" + "mtc0 $0,$20\n\t" + "nop" + : /* no output */ + : /* no input */ + ); + } +#if 1 + else + { + /* Start to isolate cache space */ + p = (char *)start; + + flags = read_c0_status(); + + /* isolate cache space */ + write_c0_status( (ST0_ISC | flags) &~ ST0_IEC ); + + for (i = 0; i < size; i += 0x040) + { + asm ( + #ifdef OPEN_RSDK_RTL865x + ".word 0xbc750000\n\t" + ".word 0xbc750010\n\t" + ".word 0xbc750020\n\t" + ".word 0xbc750030\n\t" + #endif + "cache 0x15, 0x000(%0)\n\t" + "cache 0x15, 0x010(%0)\n\t" + "cache 0x15, 0x020(%0)\n\t" + "cache 0x15, 0x030(%0)\n\t" + : /* No output registers */ + :"r"(p) /* input : 'p' as %0 */ + ); + p += 0x040; + } + + write_c0_status(flags); + } +#endif +#endif + +} +/*Cyrus Tsai*/ diff --git a/target/linux/realtek/files/rtkload/ctype.c b/target/linux/realtek/files/rtkload/ctype.c new file mode 100644 index 000000000..604f341ee --- /dev/null +++ b/target/linux/realtek/files/rtkload/ctype.c @@ -0,0 +1,37 @@ +/* + * linux/lib/ctype.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +#define _ctype ctype_hideme +#include <linux/ctype.h> +#undef _ctype + +const unsigned char _ctype[] = { +_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ +_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ +_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ +_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ +_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ +_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ +_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ +_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ +_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ +_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ +_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ +_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ +_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ +_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ + + diff --git a/target/linux/realtek/files/rtkload/hfload.c b/target/linux/realtek/files/rtkload/hfload.c new file mode 100644 index 000000000..05bdb4772 --- /dev/null +++ b/target/linux/realtek/files/rtkload/hfload.c @@ -0,0 +1,117 @@ +/* hfload.c + * + * This file is subject to the terms and conditions of the GNU + * General Public License. See the file "COPYING" in the main + * directory of this archive for more details. + * + * Copyright (C) 2000, Jay Carlson + */ + +/* + * Boot loader main program. + */ +//#include <linux/config.h> +#include <linux/autoconf.h> + +#include <unistd.h> +//#include <linux/elf.h> +#include "hfload.h" + +#define REG32(reg) (*(volatile unsigned int *)((unsigned int)reg)) + +#if defined(CONFIG_RTL_819X) + #define BASE_ADDR 0xB8000000 + #define set_io_port_base(base) \ + do { * (unsigned long *) &mips_io_port_base = (base); } while (0) + + const unsigned long mips_io_port_base; +#endif + +int file_offset; +unsigned long kernelStartAddr; +/* +int old_stack_pointer; + +#define MAX_PHDRS_SIZE 8 + +Elf32_Ehdr header; +Elf32_Phdr phdrs[MAX_PHDRS_SIZE]; +*/ +extern void flush_cache(void); + +/* +void +zero_region(char *start, char *end) +{ + char *addr; + int count; + + count = end - start; +#ifndef __DO_QUIET__ + printf("zeroing from %08x to to %08x, 0x%x bytes\n", start, end, count); +#endif + +#ifndef FAKE_COPYING + memset(start, 0, count); +#endif +} + +void +load_phdr(Elf32_Phdr *phdr) +{ + char *addr, *end; + + seek_forward(phdr->p_offset); + + addr = (char *)phdr->p_vaddr; + end = ((char *)addr) + phdr->p_memsz; + + copy_to_region(addr, phdr->p_filesz); + + addr = ((char *)addr) + phdr->p_filesz; + + zero_region(addr, end); +} +*/ + +int main(unsigned long stack_start_addr) +{ + int i; + //Elf32_Ehdr *pHdr; + + file_offset = 0; + +#if defined(CONFIG_RTL_819X) + set_io_port_base(BASE_ADDR); +#endif + +#ifndef __DO_QUIET__ + printf("decompressing kernel:\n"); +#endif + +#ifdef CONFIG_RTL8197B_PANA + extern int is_vmlinux_checksum_ok(); + + REG32(0xB801900C) = REG32(0xB801900C) & (~0x0400); //SYSSR, AllSoftwareReady=0 + if (!is_vmlinux_checksum_ok()) { + printf("Linux image corrupted!\n"); + for (;;); + } +#endif + +#ifndef BZ2_COMPRESS + decompress_kernel(UNCOMPRESS_OUT, stack_start_addr+4096, FREEMEM_END, 0); +#else + decompress_kernel(UNCOMPRESS_OUT, stack_start_addr+4096, FREEMEM_END, 0); +#endif + +#ifndef __DO_QUIET__ + printf("done decompressing kernel.\n"); +#endif + + flush_cache(); + + printf("start address: 0x%08x\n", kernelStartAddr); + start_kernel(kernelStartAddr); + //start_kernel(0x80000000); +} diff --git a/target/linux/realtek/files/rtkload/hfload.h b/target/linux/realtek/files/rtkload/hfload.h new file mode 100644 index 000000000..a9da81e0f --- /dev/null +++ b/target/linux/realtek/files/rtkload/hfload.h @@ -0,0 +1,63 @@ +/* hfload.h + * + * This file is subject to the terms and conditions of the GNU + * General Public License. See the file "COPYING" in the main + * directory of this archive for more details. + * + * Copyright (C) 2000, Jay Carlson + */ + +#ifndef HELLOAD_H +#define HELLOAD_H + +//sc_yang +//#include <linux/config.h> +#include <linux/autoconf.h> +#ifdef EMBEDDED +#include <linux/string.h> +#define printf prom_printf +#else +#include <string.h> +#endif + + +#ifdef LANGUAGE_C +extern int file_offset; +#endif + + +#ifdef COMPRESSED_KERNEL + #define UNCOMPRESS_OUT 0x80000000 +#if 0 +#ifndef boot32 + #define FREEMEM_START 0x80680000 + #define FREEMEM_END 0x80800000 +#else + #define FREEMEM_START 0x80a00000 + #define FREEMEM_END 0x81000000 +#endif +#endif //sc_yang +//Brad comment, since rtl865x platform use 16M && define CONFIG_RTL_GW_8M +//#if (defined(CONFIG_RTL8186_AP) || defined(CONFIG_RTL8186_GW_8M) || defined(CONFIG_RTL8186_KB)) +#if (defined(CONFIG_RTL8186_AP) || defined(CONFIG_RTL8186_KB) || defined(CONFIG_RTL865X_PANAHOST)) + #define FREEMEM_END 0x80800000 +#else + #define FREEMEM_END 0x81000000 +#endif +#endif + +#ifdef CONFIG_RTK_VOIP + #undef FREEMEM_END + #define FREEMEM_END 0x81000000 +#endif + +// david ----------------- +#ifdef BZ2_COMPRESS + #define prom_printf + #undef FREEMEM_START + #define FREEMEM_START 0x80500000 +#endif +//----------------------- + +#endif + diff --git a/target/linux/realtek/files/rtkload/inflate.c b/target/linux/realtek/files/rtkload/inflate.c new file mode 100644 index 000000000..6db6e98d1 --- /dev/null +++ b/target/linux/realtek/files/rtkload/inflate.c @@ -0,0 +1,1212 @@ +#define DEBG(x) +#define DEBG1(x) +/* inflate.c -- Not copyrighted 1992 by Mark Adler + version c10p1, 10 January 1993 */ + +/* + * Adapted for booting Linux by Hannu Savolainen 1993 + * based on gzip-1.0.3 + * + * Nicolas Pitre <nico@cam.org>, 1999/04/14 : + * Little mods for all variable to reside either into rodata or bss segments + * by marking constant variables with 'const' and initializing all the others + * at run-time only. This allows for the kernel uncompressor to run + * directly from Flash or ROM memory on embedded systems. + */ + +/* + Inflate deflated (PKZIP's method 8 compressed) data. The compression + method searches for as much of the current string of bytes (up to a + length of 258) in the previous 32 K bytes. If it doesn't find any + matches (of at least length 3), it codes the next byte. Otherwise, it + codes the length of the matched string and its distance backwards from + the current position. There is a single Huffman code that codes both + single bytes (called "literals") and match lengths. A second Huffman + code codes the distance information, which follows a length code. Each + length or distance code actually represents a base value and a number + of "extra" (sometimes zero) bits to get to add to the base value. At + the end of each deflated block is a special end-of-block (EOB) literal/ + length code. The decoding process is basically: get a literal/length + code; if EOB then done; if a literal, emit the decoded byte; if a + length then get the distance and emit the referred-to bytes from the + sliding window of previously emitted data. + + There are (currently) three kinds of inflate blocks: stored, fixed, and + dynamic. The compressor deals with some chunk of data at a time, and + decides which method to use on a chunk-by-chunk basis. A chunk might + typically be 32 K or 64 K. If the chunk is incompressible, then the + "stored" method is used. In this case, the bytes are simply stored as + is, eight bits per byte, with none of the above coding. The bytes are + preceded by a count, since there is no longer an EOB code. + + If the data is compressible, then either the fixed or dynamic methods + are used. In the dynamic method, the compressed data is preceded by + an encoding of the literal/length and distance Huffman codes that are + to be used to decode this block. The representation is itself Huffman + coded, and so is preceded by a description of that code. These code + descriptions take up a little space, and so for small blocks, there is + a predefined set of codes, called the fixed codes. The fixed method is + used if the block codes up smaller that way (usually for quite small + chunks), otherwise the dynamic method is used. In the latter case, the + codes are customized to the probabilities in the current block, and so + can code it much better than the pre-determined fixed codes. + + The Huffman codes themselves are decoded using a multi-level table + lookup, in order to maximize the speed of decoding plus the speed of + building the decoding tables. See the comments below that precede the + lbits and dbits tuning parameters. + */ + + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarly, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + */ +#include <linux/compiler.h> + +#ifdef RCSID +static char rcsid[] = "#Id: inflate.c,v 0.14 1993/06/10 13:27:04 jloup Exp #"; +#endif + +#ifndef STATIC + +#if defined(STDC_HEADERS) || defined(HAVE_STDLIB_H) +# include <sys/types.h> +# include <stdlib.h> +#endif + +#include "gzip.h" +#define STATIC +#endif /* !STATIC */ + +#ifndef INIT +#define INIT +#endif + +#define slide window + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). + Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16 + means that v is a literal, 16 < e < 32 means that v is a pointer to + the next table, which codes e - 16 bits, and lastly e == 99 indicates + an unused code. If a code with e == 99 is looked up, this implies an + error in the data. */ +struct huft { + uch e; /* number of extra bits or operation */ + uch b; /* number of bits in this code or subcode */ + union { + ush n; /* literal, length base, or distance base */ + struct huft *t; /* pointer to next level of table */ + } v; +}; + + +/* Function prototypes */ +STATIC int INIT huft_build OF((unsigned *, unsigned, unsigned, + const ush *, const ush *, struct huft **, int *)); +STATIC int INIT huft_free OF((struct huft *)); +STATIC int INIT inflate_codes OF((struct huft *, struct huft *, int, int)); +STATIC int INIT inflate_stored OF((void)); +STATIC int INIT inflate_fixed OF((void)); +STATIC int INIT inflate_dynamic OF((void)); +STATIC int INIT inflate_block OF((int *)); +STATIC int INIT inflate OF((void)); + + +/* The inflate algorithm uses a sliding 32 K byte window on the uncompressed + stream to find repeated byte strings. This is implemented here as a + circular buffer. The index is updated simply by incrementing and then + ANDing with 0x7fff (32K-1). */ +/* It is left to other modules to supply the 32 K area. It is assumed + to be usable as if it were declared "uch slide[32768];" or as just + "uch *slide;" and then malloc'ed in the latter case. The definition + must be in unzip.h, included above. */ +/* unsigned wp; current position in slide */ +#define wp outcnt +#define flush_output(w) (wp=(w),flush_window()) + +/* Tables for deflate from PKZIP's appnote.txt. */ +static const unsigned border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; +static const ush cplens[] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* note: see note #13 above about the 258 in this list. */ +static const ush cplext[] = { /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ +static const ush cpdist[] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +static const ush cpdext[] = { /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + + + +/* Macros for inflate() bit peeking and grabbing. + The usage is: + + NEEDBITS(j) + x = b & mask_bits[j]; + DUMPBITS(j) + + where NEEDBITS makes sure that b has at least j bits in it, and + DUMPBITS removes the bits from b. The macros use the variable k + for the number of bits in b. Normally, b and k are register + variables for speed, and are initialized at the beginning of a + routine that uses these macros from a global bit buffer and count. + + If we assume that EOB will be the longest code, then we will never + ask for bits with NEEDBITS that are beyond the end of the stream. + So, NEEDBITS should not read any more bytes than are needed to + meet the request. Then no bytes need to be "returned" to the buffer + at the end of the last block. + + However, this assumption is not true for fixed blocks--the EOB code + is 7 bits, but the other literal/length codes can be 8 or 9 bits. + (The EOB code is shorter than other codes because fixed blocks are + generally short. So, while a block always has an EOB, many other + literal/length codes have a significantly lower probability of + showing up at all.) However, by making the first table have a + lookup of seven bits, the EOB code will be found in that first + lookup, and so will not require that too many bits be pulled from + the stream. + */ + +STATIC ulg bb; /* bit buffer */ +STATIC unsigned bk; /* bits in bit buffer */ + +STATIC const ush mask_bits[] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + +#define NEXTBYTE() ({ int v = get_byte(); if (v < 0) goto underrun; (uch)v; }) +#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}} +#define DUMPBITS(n) {b>>=(n);k-=(n);} + + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +STATIC const int lbits = 9; /* bits in base literal/length lookup table */ +STATIC const int dbits = 6; /* bits in base distance lookup table */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ +#define BMAX 16 /* maximum bit length of any code (16 for explode) */ +#define N_MAX 288 /* maximum number of codes in any set */ + + +STATIC unsigned hufts; /* track memory usage */ + + +STATIC int INIT huft_build( + unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ + unsigned n, /* number of codes (assumed <= N_MAX) */ + unsigned s, /* number of simple-valued codes (0..s-1) */ + const ush *d, /* list of base values for non-simple codes */ + const ush *e, /* list of extra bits for non-simple codes */ + struct huft **t, /* result: starting table */ + int *m /* maximum lookup bits, returns actual */ + ) +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return zero on success, one if + the given code set is incomplete (the tables are still built in this + case), two if the input is invalid (all zero length codes or an + oversubscribed set of lengths), and three if not enough memory. */ +{ + unsigned a; /* counter for codes of length k */ + unsigned c[BMAX+1]; /* bit length count table */ + unsigned f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register unsigned i; /* counter, current code */ + register unsigned j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + register unsigned *p; /* pointer into c[], b[], or v[] */ + register struct huft *q; /* points to current table */ + struct huft r; /* table entry for structure assignment */ + struct huft *u[BMAX]; /* table stack */ + unsigned v[N_MAX]; /* values in order of bit length */ + register int w; /* bits before this table == (l * h) */ + unsigned x[BMAX+1]; /* bit offsets, then code stack */ + unsigned *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + unsigned z; /* number of entries in current table */ + +DEBG("huft1 "); + + /* Generate counts for each bit length */ + memzero(c, sizeof(c)); + p = b; i = n; + do { + Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"), + n-i, *p)); + c[*p]++; /* assume all entries <= BMAX */ + p++; /* Can't combine with above line (Solaris bug) */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (struct huft *)NULL; + *m = 0; + return 2; + } + +DEBG("huft2 "); + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((unsigned)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((unsigned)l > i) + l = i; + *m = l; + +DEBG("huft3 "); + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return 2; /* bad input: more codes than bits */ + if ((y -= c[i]) < 0) + return 2; + c[i] += y; + +DEBG("huft4 "); + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + +DEBG("huft5 "); + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + n = x[g]; /* set n to length of v */ + +DEBG("h6 "); + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (struct huft *)NULL; /* just to keep compilers happy */ + q = (struct huft *)NULL; /* ditto */ + z = 0; /* ditto */ +DEBG("h6a "); + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { +DEBG("h6b "); + a = c[k]; + while (a--) + { +DEBG("h6b1 "); + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { +DEBG1("1 "); + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = (z = g - w) > (unsigned)l ? l : z; /* upper limit on table size */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ +DEBG1("2 "); + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } +DEBG1("3 "); + z = 1 << j; /* table entries for j-bit table */ + + /* allocate and link in new table */ + if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) == + (struct huft *)NULL) + { + if (h) + huft_free(u[0]); + return 3; /* not enough memory */ + } +DEBG1("4 "); + hufts += z + 1; /* track memory usage */ + *t = q + 1; /* link to list for huft_free() */ + *(t = &(q->v.t)) = (struct huft *)NULL; + u[h] = ++q; /* table starts after link */ + +DEBG1("5 "); + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.b = (uch)l; /* bits to dump before this table */ + r.e = (uch)(16 + j); /* bits in this table */ + r.v.t = q; /* pointer to this table */ + j = i >> (w - l); /* (get around Turbo C bug) */ + u[h-1][j] = r; /* connect to last table */ + } +DEBG1("6 "); + } +DEBG("h6c "); + + /* set up table entry in r */ + r.b = (uch)(k - w); + if (p >= v + n) + r.e = 99; /* out of values--invalid code */ + else if (*p < s) + { + r.e = (uch)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ + r.v.n = (ush)(*p); /* simple code is just the value */ + p++; /* one compiler does not like *p++ */ + } + else + { + r.e = (uch)e[*p - s]; /* non-simple--look up in lists */ + r.v.n = d[*p++ - s]; + } +DEBG("h6d "); + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + while ((i & ((1 << w) - 1)) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + } +DEBG("h6e "); + } +DEBG("h6f "); + } + +DEBG("huft7 "); + + /* Return true (1) if we were given an incomplete table */ + return y != 0 && g != 1; +} + + + +STATIC int INIT huft_free( + struct huft *t /* table to free */ + ) +/* Free the malloc'ed tables built by huft_build(), which makes a linked + list of the tables it made, with the links in a dummy first entry of + each table. */ +{ + register struct huft *p, *q; + + + /* Go through linked list, freeing from the malloced (t[-1]) address. */ + p = t; + while (p != (struct huft *)NULL) + { + q = (--p)->v.t; + free((char*)p); + p = q; + } + return 0; +} + + +STATIC int INIT inflate_codes( + struct huft *tl, /* literal/length decoder tables */ + struct huft *td, /* distance decoder tables */ + int bl, /* number of bits decoded by tl[] */ + int bd /* number of bits decoded by td[] */ + ) +/* inflate (decompress) the codes in a deflated (compressed) block. + Return an error code or zero if it all goes ok. */ +{ + register unsigned e; /* table entry flag/number of extra bits */ + unsigned n, d; /* length and index for copy */ + unsigned w; /* current window position */ + struct huft *t; /* pointer to table entry */ + unsigned ml, md; /* masks for bl and bd bits */ + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + + + /* make local copies of globals */ + b = bb; /* initialize bit buffer */ + k = bk; + w = wp; /* initialize window position */ + + /* inflate the coded data */ + ml = mask_bits[bl]; /* precompute masks for speed */ + md = mask_bits[bd]; + for (;;) /* do until end of block */ + { + NEEDBITS((unsigned)bl) + if ((e = (t = tl + ((unsigned)b & ml))->e) > 16) + do { + if (e == 99) + return 1; + DUMPBITS(t->b) + e -= 16; + NEEDBITS(e) + } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); + DUMPBITS(t->b) + if (e == 16) /* then it's a literal */ + { + slide[w++] = (uch)t->v.n; + Tracevv((stderr, "%c", slide[w-1])); + if (w == WSIZE) + { + flush_output(w); + w = 0; + } + } + else /* it's an EOB or a length */ + { + /* exit if end of block */ + if (e == 15) + break; + + /* get length of block to copy */ + NEEDBITS(e) + n = t->v.n + ((unsigned)b & mask_bits[e]); + DUMPBITS(e); + + /* decode distance of block to copy */ + NEEDBITS((unsigned)bd) + if ((e = (t = td + ((unsigned)b & md))->e) > 16) + do { + if (e == 99) + return 1; + DUMPBITS(t->b) + e -= 16; + NEEDBITS(e) + } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); + DUMPBITS(t->b) + NEEDBITS(e) + d = w - t->v.n - ((unsigned)b & mask_bits[e]); + DUMPBITS(e) + Tracevv((stderr,"\\[%d,%d]", w-d, n)); + + /* do the copy */ + do { + n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); +#if !defined(NOMEMCPY) && !defined(DEBUG) + if (w - d >= e) /* (this test assumes unsigned comparison) */ + { + memcpy(slide + w, slide + d, e); + w += e; + d += e; + } + else /* do it slow to avoid memcpy() overlap */ +#endif /* !NOMEMCPY */ + do { + slide[w++] = slide[d++]; + Tracevv((stderr, "%c", slide[w-1])); + } while (--e); + if (w == WSIZE) + { + flush_output(w); + w = 0; + } + } while (n); + } + } + + + /* restore the globals from the locals */ + wp = w; /* restore global window pointer */ + bb = b; /* restore global bit buffer */ + bk = k; + + /* done */ + return 0; + + underrun: + return 4; /* Input underrun */ +} + + + +STATIC int INIT inflate_stored(void) +/* "decompress" an inflated type 0 (stored) block. */ +{ + unsigned n; /* number of bytes in block */ + unsigned w; /* current window position */ + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + +DEBG("<stor"); + + /* make local copies of globals */ + b = bb; /* initialize bit buffer */ + k = bk; + w = wp; /* initialize window position */ + + + /* go to byte boundary */ + n = k & 7; + DUMPBITS(n); + + + /* get the length and its complement */ + NEEDBITS(16) + n = ((unsigned)b & 0xffff); + DUMPBITS(16) + NEEDBITS(16) + if (n != (unsigned)((~b) & 0xffff)) + return 1; /* error in compressed data */ + DUMPBITS(16) + + + /* read and output the compressed data */ + while (n--) + { + NEEDBITS(8) + slide[w++] = (uch)b; + if (w == WSIZE) + { + flush_output(w); + w = 0; + } + DUMPBITS(8) + } + + + /* restore the globals from the locals */ + wp = w; /* restore global window pointer */ + bb = b; /* restore global bit buffer */ + bk = k; + + DEBG(">"); + return 0; + + underrun: + return 4; /* Input underrun */ +} + + +/* + * We use `noinline' here to prevent gcc-3.5 from using too much stack space + */ +STATIC int noinline INIT inflate_fixed(void) +/* decompress an inflated type 1 (fixed Huffman codes) block. We should + either replace this with a custom decoder, or at least precompute the + Huffman tables. */ +{ + int i; /* temporary variable */ + struct huft *tl; /* literal/length code table */ + struct huft *td; /* distance code table */ + int bl; /* lookup bits for tl */ + int bd; /* lookup bits for td */ + unsigned l[288]; /* length list for huft_build */ + +DEBG("<fix"); + + /* set up literal table */ + for (i = 0; i < 144; i++) + l[i] = 8; + for (; i < 256; i++) + l[i] = 9; + for (; i < 280; i++) + l[i] = 7; + for (; i < 288; i++) /* make a complete, but wrong code set */ + l[i] = 8; + bl = 7; + if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0) + return i; + + + /* set up distance table */ + for (i = 0; i < 30; i++) /* make an incomplete code set */ + l[i] = 5; + bd = 5; + if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1) + { + huft_free(tl); + + DEBG(">"); + return i; + } + + + /* decompress until an end-of-block code */ + if (inflate_codes(tl, td, bl, bd)) + return 1; + + + /* free the decoding tables, return */ + huft_free(tl); + huft_free(td); + return 0; +} + + +/* + * We use `noinline' here to prevent gcc-3.5 from using too much stack space + */ +STATIC int noinline INIT inflate_dynamic(void) +/* decompress an inflated type 2 (dynamic Huffman codes) block. */ +{ + int i; /* temporary variables */ + unsigned j; + unsigned l; /* last length */ + unsigned m; /* mask for bit lengths table */ + unsigned n; /* number of lengths to get */ + struct huft *tl; /* literal/length code table */ + struct huft *td; /* distance code table */ + int bl; /* lookup bits for tl */ + int bd; /* lookup bits for td */ + unsigned nb; /* number of bit length codes */ + unsigned nl; /* number of literal/length codes */ + unsigned nd; /* number of distance codes */ +#ifdef PKZIP_BUG_WORKAROUND + unsigned ll[288+32]; /* literal/length and distance code lengths */ +#else + unsigned ll[286+30]; /* literal/length and distance code lengths */ +#endif + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + +DEBG("<dyn"); + + /* make local bit buffer */ + b = bb; + k = bk; + + + /* read in table lengths */ + NEEDBITS(5) + nl = 257 + ((unsigned)b & 0x1f); /* number of literal/length codes */ + DUMPBITS(5) + NEEDBITS(5) + nd = 1 + ((unsigned)b & 0x1f); /* number of distance codes */ + DUMPBITS(5) + NEEDBITS(4) + nb = 4 + ((unsigned)b & 0xf); /* number of bit length codes */ + DUMPBITS(4) +#ifdef PKZIP_BUG_WORKAROUND + if (nl > 288 || nd > 32) +#else + if (nl > 286 || nd > 30) +#endif + return 1; /* bad lengths */ + +DEBG("dyn1 "); + + /* read in bit-length-code lengths */ + for (j = 0; j < nb; j++) + { + NEEDBITS(3) + ll[border[j]] = (unsigned)b & 7; + DUMPBITS(3) + } + for (; j < 19; j++) + ll[border[j]] = 0; + +DEBG("dyn2 "); + + /* build decoding table for trees--single level, 7 bit lookup */ + bl = 7; + if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0) + { + if (i == 1) + huft_free(tl); + return i; /* incomplete code set */ + } + +DEBG("dyn3 "); + + /* read in literal and distance code lengths */ + n = nl + nd; + m = mask_bits[bl]; + i = l = 0; + while ((unsigned)i < n) + { + NEEDBITS((unsigned)bl) + j = (td = tl + ((unsigned)b & m))->b; + DUMPBITS(j) + j = td->v.n; + if (j < 16) /* length of code in bits (0..15) */ + ll[i++] = l = j; /* save last length in l */ + else if (j == 16) /* repeat last length 3 to 6 times */ + { + NEEDBITS(2) + j = 3 + ((unsigned)b & 3); + DUMPBITS(2) + if ((unsigned)i + j > n) + return 1; + while (j--) + ll[i++] = l; + } + else if (j == 17) /* 3 to 10 zero length codes */ + { + NEEDBITS(3) + j = 3 + ((unsigned)b & 7); + DUMPBITS(3) + if ((unsigned)i + j > n) + return 1; + while (j--) + ll[i++] = 0; + l = 0; + } + else /* j == 18: 11 to 138 zero length codes */ + { + NEEDBITS(7) + j = 11 + ((unsigned)b & 0x7f); + DUMPBITS(7) + if ((unsigned)i + j > n) + return 1; + while (j--) + ll[i++] = 0; + l = 0; + } + } + +DEBG("dyn4 "); + + /* free decoding table for trees */ + huft_free(tl); + +DEBG("dyn5 "); + + /* restore the global bit buffer */ + bb = b; + bk = k; + +DEBG("dyn5a "); + + /* build the decoding tables for literal/length and distance codes */ + bl = lbits; + if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) + { +DEBG("dyn5b "); + if (i == 1) { + error("incomplete literal tree"); + huft_free(tl); + } + return i; /* incomplete code set */ + } +DEBG("dyn5c "); + bd = dbits; + if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) + { +DEBG("dyn5d "); + if (i == 1) { + error("incomplete distance tree"); +#ifdef PKZIP_BUG_WORKAROUND + i = 0; + } +#else + huft_free(td); + } + huft_free(tl); + return i; /* incomplete code set */ +#endif + } + +DEBG("dyn6 "); + + /* decompress until an end-of-block code */ + if (inflate_codes(tl, td, bl, bd)) + return 1; + +DEBG("dyn7 "); + + /* free the decoding tables, return */ + huft_free(tl); + huft_free(td); + + DEBG(">"); + return 0; + + underrun: + return 4; /* Input underrun */ +} + + + +STATIC int INIT inflate_block( + int *e /* last block flag */ + ) +/* decompress an inflated block */ +{ + unsigned t; /* block type */ + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + + DEBG("<blk"); + + /* make local bit buffer */ + b = bb; + k = bk; + + + /* read in last block bit */ + NEEDBITS(1) + *e = (int)b & 1; + DUMPBITS(1) + + + /* read in block type */ + NEEDBITS(2) + t = (unsigned)b & 3; + DUMPBITS(2) + + + /* restore the global bit buffer */ + bb = b; + bk = k; + + /* inflate that block type */ + if (t == 2) + return inflate_dynamic(); + if (t == 0) + return inflate_stored(); + if (t == 1) + return inflate_fixed(); + + DEBG(">"); + + /* bad block type */ + return 2; + + underrun: + return 4; /* Input underrun */ +} + + + +STATIC int INIT inflate(void) +/* decompress an inflated entry */ +{ + int e; /* last block flag */ + int r; /* result code */ + unsigned h; /* maximum struct huft's malloc'ed */ + void *ptr; + + /* initialize window, bit buffer */ + wp = 0; + bk = 0; + bb = 0; + + + /* decompress until the last block */ + h = 0; + do { + hufts = 0; + gzip_mark(&ptr); + if ((r = inflate_block(&e)) != 0) { + gzip_release(&ptr); + return r; + } + gzip_release(&ptr); + if (hufts > h) + h = hufts; + } while (!e); + + /* Undo too much lookahead. The next read will be byte aligned so we + * can discard unused bits in the last meaningful byte. + */ + while (bk >= 8) { + bk -= 8; + inptr--; + } + + /* flush out slide */ + flush_output(wp); + + + /* return success */ +#ifdef DEBUG + fprintf(stderr, "<%u> ", h); +#endif /* DEBUG */ + return 0; +} + +/********************************************************************** + * + * The following are support routines for inflate.c + * + **********************************************************************/ + +static ulg crc_32_tab[256]; +static ulg crc; /* initialized in makecrc() so it'll reside in bss */ +#define CRC_VALUE (crc ^ 0xffffffffUL) + +/* + * Code to compute the CRC-32 table. Borrowed from + * gzip-1.0.3/makecrc.c. + */ + +static void INIT +makecrc(void) +{ +/* Not copyrighted 1990 Mark Adler */ + + unsigned long c; /* crc shift register */ + unsigned long e; /* polynomial exclusive-or pattern */ + int i; /* counter for all possible eight bit values */ + int k; /* byte being shifted into crc apparatus */ + + /* terms of polynomial defining this crc (except x^32): */ + static const int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* Make exclusive-or pattern from polynomial */ + e = 0; + for (i = 0; i < sizeof(p)/sizeof(int); i++) + e |= 1L << (31 - p[i]); + + crc_32_tab[0] = 0; + + for (i = 1; i < 256; i++) + { + c = 0; + for (k = i | 256; k != 1; k >>= 1) + { + c = c & 1 ? (c >> 1) ^ e : c >> 1; + if (k & 1) + c ^= e; + } + crc_32_tab[i] = c; + } + + /* this is initialized here so this code could reside in ROM */ + crc = (ulg)0xffffffffUL; /* shift register contents */ +} + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ +#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ +#define RESERVED 0xC0 /* bit 6,7: reserved */ + +/* + * Do the uncompression! + */ +static int INIT gunzip(void) +{ + uch flags; + unsigned char magic[2]; /* magic header */ + char method; + ulg orig_crc = 0; /* original crc */ + ulg orig_len = 0; /* original uncompressed length */ + int res; + + magic[0] = NEXTBYTE(); + magic[1] = NEXTBYTE(); + method = NEXTBYTE(); + + if (magic[0] != 037 || + ((magic[1] != 0213) && (magic[1] != 0236))) { + error("bad gzip magic numbers"); + return -1; + } + + /* We only support method #8, DEFLATED */ + if (method != 8) { + error("internal error, invalid method"); + return -1; + } + + flags = (uch)get_byte(); + if ((flags & ENCRYPTED) != 0) { + error("Input is encrypted"); + return -1; + } + if ((flags & CONTINUATION) != 0) { + error("Multi part input"); + return -1; + } + if ((flags & RESERVED) != 0) { + error("Input has invalid flags"); + return -1; + } + NEXTBYTE(); /* Get timestamp */ + NEXTBYTE(); + NEXTBYTE(); + NEXTBYTE(); + + (void)NEXTBYTE(); /* Ignore extra flags for the moment */ + (void)NEXTBYTE(); /* Ignore OS type for the moment */ + + if ((flags & EXTRA_FIELD) != 0) { + unsigned len = (unsigned)NEXTBYTE(); + len |= ((unsigned)NEXTBYTE())<<8; + while (len--) (void)NEXTBYTE(); + } + + /* Get original file name if it was truncated */ + if ((flags & ORIG_NAME) != 0) { + /* Discard the old name */ + while (NEXTBYTE() != 0) /* null */ ; + } + + /* Discard file comment if any */ + if ((flags & COMMENT) != 0) { + while (NEXTBYTE() != 0) /* null */ ; + } + + /* Decompress */ + if ((res = inflate())) { + switch (res) { + case 0: + break; + case 1: + error("invalid compressed format (err=1)"); + break; + case 2: + error("invalid compressed format (err=2)"); + break; + case 3: + error("out of memory"); + break; + case 4: + error("out of input data"); + break; + default: + error("invalid compressed format (other)"); + } + return -1; + } + + /* Get the crc and original length */ + /* crc32 (see algorithm.doc) + * uncompressed input size modulo 2^32 + */ + orig_crc = (ulg) NEXTBYTE(); + orig_crc |= (ulg) NEXTBYTE() << 8; + orig_crc |= (ulg) NEXTBYTE() << 16; + orig_crc |= (ulg) NEXTBYTE() << 24; + + orig_len = (ulg) NEXTBYTE(); + orig_len |= (ulg) NEXTBYTE() << 8; + orig_len |= (ulg) NEXTBYTE() << 16; + orig_len |= (ulg) NEXTBYTE() << 24; + + /* Validate decompression */ + if (orig_crc != CRC_VALUE) { + error("crc error"); + return -1; + } + if (orig_len != bytes_out) { + error("length error"); + return -1; + } + return 0; + + underrun: /* NEXTBYTE() goto's here if needed */ + error("out of input data"); + return -1; +} + + diff --git a/target/linux/realtek/files/rtkload/ld-emu.script b/target/linux/realtek/files/rtkload/ld-emu.script new file mode 100644 index 000000000..f152a18a2 --- /dev/null +++ b/target/linux/realtek/files/rtkload/ld-emu.script @@ -0,0 +1,56 @@ +/* ld.script + * + * This file is subject to the terms and conditions of the GNU + * General Public License. See the file "COPYING" in the main + * directory of this archive for more details. + * + * Copyright (C) 2000, Jay Carlson + */ + +OUTPUT_FORMAT("elf32-littlemips") +OUTPUT_ARCH(mips) +ENTRY(__start) + +/* Someday I'll figure out how this works */ +/* MEMORY { vtboot : ORIGIN = 0x9fc00000, LENGTH = 64k } */ +/* MEMORY { rom : ORIGIN = 0x9fc00000, LENGTH = 2M } */ + + +SECTIONS +{ + /* VT-OS boot rom lives here in real hardware */ + . = 0x9fc00000 ; + vtboot : { vtboot* } + + /* The loader itself */ + . = 0x9fc10000 ; + .text : { *(.text) } + .rodata : { *(.rodata) } + + . = ALIGN(4); + /* Compressed kernel ELF image */ + input_data = . ; + source_memory_start = . ; + vmlinux : { vmlinux-stripped.gz* } + input_data_end = . ; + + . = ALIGN(4); + /* Romdisk, if any. An empty file is OK. */ + romdisk_start = . ; + romdisk : { romdisk* } + romdisk_end = . ; + + + /* . = 0x80700000 ; */ + /* Oops, second 4M is in the second DRAM bank. Put our BSS at the 7M mark. */ + . = 0x82300000 ; /* emulator */ + /* . = 0x82500000 ; */ /* real hardware */ + .bss : { _bstart = . ; *(.bss) ; *(.sbss) ; *(COMMON) ; _bend = . ; } + + /* /DISCARD/ : { *(.reginfo) ; *(.mdebug) ; *(.note) ; *(.comment) *(__ex_table) ; } */ + /DISCARD/ : { *(.reginfo) ; *(.note) ; *(.comment) *(__ex_table) ; } + + /* .filler : */ +} + + diff --git a/target/linux/realtek/files/rtkload/ld.script.in b/target/linux/realtek/files/rtkload/ld.script.in new file mode 100644 index 000000000..719f3f4d7 --- /dev/null +++ b/target/linux/realtek/files/rtkload/ld.script.in @@ -0,0 +1,49 @@ +/* ld.script + * + * This file is subject to the terms and conditions of the GNU + * General Public License. See the file "COPYING" in the main + * directory of this archive for more details. + * + * Copyright (C) 2000, Jay Carlson + */ + +OUTPUT_ARCH(mips) +ENTRY(__start) + +/* Someday I'll figure out how this works */ +/* MEMORY { vtboot : ORIGIN = 0x80400000, LENGTH = 64k } */ +/* MEMORY { rom : ORIGIN = 0x80410000, LENGTH = 2M } */ + + +SECTIONS +{ + /* The loader itself */ + . = LOAD_ADDR; + .text : { *(.text) } + .rodata : { *(.rodata) } + + . = ALIGN(4); + /* Compressed kernel ELF image */ + + + .data : + { + _fdata = . ; + *(.data) + . = ALIGN(1024); + __vmlinux_start = .; + *(.vmlinux) + __vmlinux_end = .; + . = ALIGN(1024); + CONSTRUCTORS + } + + .bss : { _bstart = . ; *(.bss) ; *(.sbss) ; *(COMMON) ; _bend = . ; } + + /* /DISCARD/ : { *(.reginfo) ; *(.mdebug) ; *(.note) ; *(.comment) *(__ex_table) ; } */ + /DISCARD/ : { *(.reginfo) ; *(.note) ; *(.comment) *(__ex_table) ; } + + /* .filler : */ +} + + diff --git a/target/linux/realtek/files/rtkload/misc.c b/target/linux/realtek/files/rtkload/misc.c new file mode 100644 index 000000000..11bc20830 --- /dev/null +++ b/target/linux/realtek/files/rtkload/misc.c @@ -0,0 +1,387 @@ +/* + * misc.c + * + * This is a collection of several routines from gzip-1.0.3 + * adapted for Linux. + * + * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 + * + * Modified for ARM Linux by Russell King + * + * Nicolas Pitre <nico@visuaide.com> 1999/04/14 : + * For this code to run directly from Flash, all constant variables must + * be marked with 'const' and all other variables initialized at run-time + * only. This way all non constant variables will end up in the bss segment, + * which should point to addresses in RAM and cleared to 0 on start. + * This allows for a much quicker boot time. + * + * Stolen for mips loader to handle decompression by Jay Carlson + * <nop@nop.com> 2000/04/17 + */ +#include <linux/autoconf.h> + +// david ------------------ +#ifdef BZ2_COMPRESS +#define __DO_QUIET__ +#endif +//------------------------- + +extern unsigned long kernelStartAddr; +unsigned int __machine_arch_type; + +#ifndef __DO_QUIET__ +#define puts prom_printf +#else +#define puts +#endif +#define arch_decomp_wdog() +#define arch_decomp_setup() +#define proc_decomp_setup() /* this is where cache flushing, clock, etc lived */ + +#define memzero(d, count) (memset((d), 0, (count))) + +#define __ptr_t void * +#define NULL ((void *) 0) + +typedef unsigned long __u32; +#define ___swab32(x) \ + ({ \ + __u32 __x = (x); \ + ((__u32)( \ + (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \ + (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \ + (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \ + (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \ + }) + +#define le32_to_cpu(x) ___swab32(x) + + +/* + * gzip declarations + */ +#define OF(args) args +#define STATIC static + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +#define WSIZE 0x8000 /* Window size must be at least 32k, */ + /* and a power of two */ + +static uch *inbuf; /* input buffer */ +static uch window[WSIZE]; /* Sliding window buffer */ +static unsigned insize; /* valid bytes in inbuf */ +static unsigned inptr; /* index of next byte to be processed in inbuf */ +static unsigned outcnt; /* bytes in output buffer */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ +#define RESERVED 0xC0 /* bit 6,7: reserved */ + +#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) + +/* Diagnostic functions */ +#ifdef DEBUG +# define Assert(cond,msg) {if(!(cond)) error(msg);} +# define Trace(x) fprintf x +# define Tracev(x) {if (verbose) fprintf x ;} +# define Tracevv(x) {if (verbose>1) fprintf x ;} +# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} +# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +static int fill_inbuf(void); +static void flush_window(void); +static void error(char *m); +static void gzip_mark(void **); +static void gzip_release(void **); + +extern char __vmlinux_start[]; +extern char __vmlinux_end[]; + +static uch *output_data; +static ulg output_ptr; +static ulg bytes_out; + +static void *malloc(int size); +static void free(void *where); +static void error(char *m); +static void gzip_mark(void **); +static void gzip_release(void **); + +/* static void puts(const char *); */ + +/* extern int end; */ +static ulg free_mem_ptr; +static ulg free_mem_ptr_end; + +#define HEAP_SIZE 0x2000 + +/* #include "../../../../lib/inflate.c" */ +/* #include "../lib/inflate.c"*/ + +// david ---------------- +//#include <inflate.c> + +#ifndef BZ2_COMPRESS +#include "inflate.c" +#else +#include "../lib/bzip2_inflate.c" +#endif +//---------------------- + +#ifdef CONFIG_RTL8197B_PANA +int is_vmlinux_checksum_ok(void) +{ + unsigned long sum = 0; + //unsigned long *buf = (unsigned long *)(((long)__vmlinux_start)+4); + //unsigned long image_len = (unsigned long)(__vmlinux_end -__vmlinux_start-4); + unsigned long *buf = (unsigned long *)(((long)__vmlinux_start)+8); + unsigned long image_len = (unsigned long)(__vmlinux_end -__vmlinux_start-8); + + for (; ((unsigned long)buf)<((unsigned long)__vmlinux_end); buf++) + sum += *buf; + + return ((sum == 0) ? 1 : 0); +} +#endif + +#ifndef STANDALONE_DEBUG +static void *malloc(int size) +{ + void *p; + + if (size <0) error("Malloc error\n"); + if (free_mem_ptr <= 0) error("Memory error\n"); + + free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ + + p = (void *)free_mem_ptr; + free_mem_ptr += size; + + if (free_mem_ptr >= free_mem_ptr_end) + error("Out of memory"); + return p; +} + +static void free(void *where) +{ /* gzip_mark & gzip_release do the free */ +} + +static void gzip_mark(void **ptr) +{ + arch_decomp_wdog(); + *ptr = (void *) free_mem_ptr; +} + +static void gzip_release(void **ptr) +{ + arch_decomp_wdog(); + free_mem_ptr = (long) *ptr; +} +#else +static void gzip_mark(void **ptr) +{ +} + +static void gzip_release(void **ptr) +{ +} +#endif + +// david +#ifndef BZ2_COMPRESS +/* =========================================================================== + * Fill the input buffer. This is called only when the buffer is empty + * and at least one byte is really needed. + */ +int fill_inbuf(void) +{ + if (insize != 0) + error("ran out of input data\n"); + + inbuf = __vmlinux_start; + insize = &__vmlinux_end[0] - &__vmlinux_start[0]; + + inptr = 1; + return inbuf[0]; +} + +/* =========================================================================== + * Write the output window window[0..outcnt-1] and update crc and bytes_out. + * (Used for the decompressed data only.) + */ +void flush_window(void) +{ + ulg c = crc; + unsigned n; + uch *in, *out, ch; + + in = window; + out = &output_data[output_ptr]; + for (n = 0; n < outcnt; n++) { + ch = *out++ = *in++; + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + bytes_out += (ulg)outcnt; + output_ptr += (ulg)outcnt; + outcnt = 0; + //puts("."); +} +#endif // BZ2_COMPRESS, david + + +static void error(char *x) +{ + int ptr; + + puts("\n\n"); + puts(x); + puts("\n\n -- System halted"); + + while(1); /* Halt */ +} + +#ifndef STANDALONE_DEBUG + +ulg +decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, + int arch_id) +{ + output_data = (uch *)output_start; /* Points to kernel start */ + free_mem_ptr = free_mem_ptr_p; + free_mem_ptr_end = free_mem_ptr_end_p; + __machine_arch_type = arch_id; + + proc_decomp_setup(); + arch_decomp_setup(); + +// david +// makecrc(); + puts("Uncompressing Linux..."); +// david --------------------------------- +// gunzip(); +#ifdef LZMA_COMPRESS +{ + #include "LzmaDecode.h" + + unsigned char *startBuf=__vmlinux_start; + unsigned char *outBuf = (unsigned char *)output_start; + unsigned int inLen=__vmlinux_end - __vmlinux_start; + + SizeT compressedSize; + unsigned char *inStream; + UInt32 outSize = 0; + UInt32 outSizeHigh = 0; + SizeT outSizeFull; + int res; + SizeT inProcessed; + SizeT outProcessed; + char tmpbuf[100]; + CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */ + unsigned char properties[LZMA_PROPERTIES_SIZE]; + +//#ifdef CONFIG_RTL8197B_PANA +// unsigned long pending_len = *((unsigned long *)__vmlinux_start); +// startBuf += 4; +// inLen -= (4+pending_len); +//#else + unsigned long pending_len = *((unsigned long *)__vmlinux_start); + kernelStartAddr = *((unsigned long *)(startBuf+4)); + startBuf += 8; + inLen -= (8+pending_len); +//#endif + + compressedSize = (SizeT)(inLen - (LZMA_PROPERTIES_SIZE + 8)); + + memcpy(properties, startBuf, sizeof(properties)); + startBuf += sizeof(properties); + + memcpy((char *)&outSize, startBuf, 4); + outSize = le32_to_cpu(outSize); + + memcpy((char *)&outSizeHigh, startBuf+4, 4); + outSizeHigh = le32_to_cpu(outSizeHigh); + + outSizeFull = (SizeT)outSize; + if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize) { + puts("LZMA: Too big uncompressed stream\n"); + return 0; + } + startBuf += 8; + + /* Decode LZMA properties and allocate memory */ + if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK) { + puts("LZMA: Incorrect stream properties\n"); + return 0; + } + state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); + + res = LzmaDecode(&state, startBuf, compressedSize, &inProcessed, + outBuf, outSizeFull, &outProcessed); + if (res != 0) { +#ifndef __DO_QUIET__ + sprintf(tmpbuf, "LZMA: Decoding error = %d\n", res); +#else + memcpy(tmpbuf, "LZMA: Decoding error = ", 23); + memcpy((tmpbuf+23), &res, 4); +#endif + puts(tmpbuf); + return 0; + } +} + +#else // !LZMA_COMPRESS +#ifndef BZ2_COMPRESS + makecrc(); + gunzip(); +#else + +// david ------------ +{ + unsigned char *startBuf=__vmlinux_start; + unsigned char *outBuf = (unsigned char *)output_start; + unsigned int inLen=__vmlinux_end - __vmlinux_start; + int outLen=-1; + + BZ2_bzBuffToBuffDecompress(outBuf, &outLen, startBuf, inLen, 0, 0); +} +#endif // BZ2_COMPRESS +//---------------------------------------- + +#endif // LZMA_COMPRESS + + puts(" done, booting the kernel.\n"); + return output_ptr; +} +#else + +char output_buffer[1500*1024]; + +int main() +{ + output_data = output_buffer; + + makecrc(); + puts("Uncompressing Linux..."); + gunzip(); + puts("done.\n"); + return 0; +} +#endif + diff --git a/target/linux/realtek/files/rtkload/prom_printf.c b/target/linux/realtek/files/rtkload/prom_printf.c new file mode 100644 index 000000000..7bf58cdb3 --- /dev/null +++ b/target/linux/realtek/files/rtkload/prom_printf.c @@ -0,0 +1,87 @@ +/* + * Borrowed from arch/mips/r39xx/prom/init.c + * + */ + +/* + * init.c: early initialisation code for R39XX Class PDAs + * + * Copyright (C) 1999 Harald Koerfgen + * + * $Id: prom_printf.c,v 1.2 2008/08/04 08:54:44 michael Exp $ + */ + + + +#define CONFIG_SERIAL + +#include <stdarg.h> + +//#include <linux/config.h> +#include <linux/autoconf.h> + +#ifdef CONFIG_RTL_EB8186 +#include <asm/rtl8181.h> +#endif + +#if 1 + //#define __KERNEL__ + + //#include <asm/types.h> + //#include <asm/serial.h> + #include <asm/io.h> + + #define UART_THR 0x2000 + #define UART_LSR 0x2014 + + #define rtl_outb(port,val) outb(val,port) + #define rtl_inb(port) inb(port) +#endif + +void serial_outc(char c) +{ + int i=0; + while (1) + { + i++; + if (i >=0x6000) + break; + + if (rtl_inb(UART_LSR) & 0x20) + break; + } + rtl_outb(UART_THR, c); +} + + +/* + * Helpful for debugging :-) + */ +int prom_printf(const char * fmt, ...) +{ +#ifdef CONFIG_SERIAL + //extern void serial_outc(char); + static char buf[1024]; + va_list args; + char c; + int i = 0; + + /* + * Printing messages via serial port + */ + va_start(args, fmt); + vsprintf(buf, fmt, args); + va_end(args); + + for (i = 0; buf[i] != '\0'; i++) { + c = buf[i]; + if (c == '\n') + serial_outc('\r'); + serial_outc(c); + } + + return i; +#else + return 0; +#endif +} diff --git a/target/linux/realtek/files/rtkload/read_fd.c b/target/linux/realtek/files/rtkload/read_fd.c new file mode 100644 index 000000000..bf40fb30e --- /dev/null +++ b/target/linux/realtek/files/rtkload/read_fd.c @@ -0,0 +1,69 @@ +/* This file has not been tested for ages. */ + +#include "hfload.h" + +#include <sys/stat.h> +#include <sys/mman.h> +#include <unistd.h> + +void +read_struct(void *s, ssize_t size) +{ + ssize_t real; + + real = read(0, s, size); + if (size != real) { + printf("trying to read %d, got %d; dying.\n", size, real); + exit(1); + } + file_offset += real; +} + +void +seek_forward(int offset) { + int dummy, i; + ssize_t real; + + if (offset % 4 != 0) { + printf("Can't seek by a non-word aligned amount\n"); + exit(1); + } + + if (offset < file_offset) { + printf("can't seek backwards\n"); + exit(1); + } + + for (; offset < file_offset; file_offset += 4) { + real = read(0, &dummy, 4); + if (real != 4) { + printf("error seeking forward at offset %d\n", file_offset); + exit(1); + } + } +} + +void +copy_to_region(int *addr, ssize_t size) { + int i, dummy, real; + + printf("copying %x bytes from file offset %x to address %08x\n", + size, file_offset, addr); + +#ifdef FAKE_COPYING + for (i = 0; i < size; i += 4) { + read_struct(&dummy, sizeof(int)); + } +#else + real = read(0, addr, size); + if (real != size) { + printf("failed to read %d bytes, exiting\n"); + exit(1); + } + file_offset += real; +#endif +} + +void +init_read() { +} diff --git a/target/linux/realtek/files/rtkload/read_memory.c b/target/linux/realtek/files/rtkload/read_memory.c new file mode 100644 index 000000000..2596911e9 --- /dev/null +++ b/target/linux/realtek/files/rtkload/read_memory.c @@ -0,0 +1,124 @@ +/* read_memory.c + * + * This file is subject to the terms and conditions of the GNU + * General Public License. See the file "COPYING" in the main + * directory of this archive for more details. + * + * Copyright (C) 2000, Jay Carlson + */ + +/* read_memory is the memory-based back end for the image-reading + * functions. + * + * Support for non-compressed kernels has probably rotted. + */ + + +#include <linux/types.h> +#include "hfload.h" + +#ifndef EMBEDDED +#include <unistd.h> +#include <sys/mman.h> +#include <sys/stat.h> +#endif + +char *source_memory; + +#ifdef EMBEDDED +#ifndef COMPRESSED_KERNEL +extern char source_memory_start; +#endif +#endif + +// david ----------------------- +//#include <linux/config.h> +#include <linux/autoconf.h> + +//#ifdef BZ2_COMPRESS //sc_yang +void * memcpy(void * dest,const void *src,size_t count) +{ + char *tmp = (char *) dest, *s = (char *) src; + + while (count--) + *tmp++ = *s++; + + return dest; +} +#if 0 +void * memset(void * s, int c, size_t count) +{ + char *xs = (char *) s; + + while (count--) + *xs++ = (char) c; + + return s; +} +#endif // CONFIG_NINO_8MB +//------------------------------ + + +void +read_struct(void *s, ssize_t size) +{ + memcpy(s, source_memory+file_offset, size); + file_offset += size; +} + +void +seek_forward(int offset) { + if (offset % 4 != 0) { + #ifndef __DO_QUIET__ + printf("Can't seek by a non-word aligned amount\n"); + #endif + exit(1); + } + + if (offset < file_offset) { + #ifndef __DO_QUIET__ + printf("can't seek backwards\n"); + #endif + exit(1); + } + + file_offset = offset; +} + +void +copy_to_region(int *addr, ssize_t size) { + int i, dummy; + + int *source, *dest; +#ifndef __DO_QUIET__ + printf("copying 0x%x bytes from file offset 0x%x to address 0x%08x\n", + size, file_offset, addr); +#endif +#ifndef FAKE_COPYING + memcpy(addr, source_memory+file_offset, size); +#endif + + file_offset += size; +} + +void +init_read() { +#ifndef EMBEDDED + struct stat buf; + if (fstat(0, &buf)) { + perror("stat"); + exit(1); + } + source_memory = mmap(0, buf.st_size & ~(4095), PROT_READ, MAP_PRIVATE, 0, 0); + if (!source_memory) { + perror("mmap"); + exit(1); + } +#else +#ifdef COMPRESSED_KERNEL + source_memory = (char *)UNCOMPRESS_OUT; +#else + source_memory = &source_memory_start; +#endif +#endif +} diff --git a/target/linux/realtek/files/rtkload/start.S b/target/linux/realtek/files/rtkload/start.S new file mode 100644 index 000000000..32df1f6f7 --- /dev/null +++ b/target/linux/realtek/files/rtkload/start.S @@ -0,0 +1,263 @@ +//#include <linux/config.h> +#include <linux/autoconf.h> +#include <asm/asm.h> +#include <asm/regdef.h> +//#include <asm/mipsregs.h> + +#if defined(CONFIG_RTL_819X) +#define CONFIG_DONOT_ADJUST_SYSCLK_MEMSP +#endif + +#include "start.h" +#ifndef boot32 +#define NEWSTACK (0x80670000) +#else +#define NEWSTACK (0x809FFF00) +#endif + .globl old_stack_pointer + + .extern __start_dram + + .text + .globl __start +__start: + +#ifdef CONFIG_DONOT_ADJUST_SYSCLK_MEMSP + nop +#else + // Set PLLMNR and SYSCLKR + jal hfclock_setting + nop +#endif + + move s0, zero + mtc0 s0, $12 + nop + nop + +#if 0 + /* Clock */ + li a0,0xbd010108 + li a1,0x0000000b + sw a1,0(a0) + nop + nop + nop + nop +#endif + +#ifdef CONFIG_RTL_EB8186 + /* Memory Controllor */ + li a0,0xbd011008 + li a1,0x00000884 + li a1,0x000008c7 + li a1,0x00000cda + li a1,0x00000886 + li a1,0x000008c7 // <victor> for 187/124 + /*sw a1,0(a0) */ + nop + nop + nop + nop + + + + + /*--- initialize and start COP3*/ + mfc0 $8,$12 + nop + nop + or $8,0x80000000 + mtc0 $8,$12 + nop + nop + + +#if 1 + la a0, 0x90000000 + mtc0 a0, $12 + nop + nop + mfc0 t0, $20 + nop + nop + ori t0, 0x1 + mtc0 t0, $20 + nop + nop +#if 0 + la a0, 0x10000000 + mtc3 a0, $4 + la a0, 0x10000fff + nop + mtc3 a0, $5 + nop + la a0, 0x90000000 + sw zero, 0(a0) + lw t0, 0(a0) + nop + la a0, 0x90000fff + sb zero, 0(a0) + lb t0, 0(a0) +#endif +#endif +#endif // CONFIG_RTL_EB8186 + + + nop + + +#if 0 + /*la t0, __start_dram */ + /*and t0, 0x0fffffff*/ # translate to physical address + la t0, 0x81000000 + and t0, 0x0fffffff # translate to physical address + mtc3 t0, $4 # $4: d-ram base + nop + addi t0, t0, 0x1000 - 1 # total 2k bytes used//2003-07-04//TKIP_encryption + mtc3 t0, $5 # $5: d-ram top + nop +#endif + + + + la s0, _bstart + la s1, _bend + + move t0, s0 + +1: + sw zero, 0(t0) + addi t0, 4 + bne t0, s1, 1b + + //sw sp, old_stack_pointer +// david ------------------------ +// li sp, NEWSTACK +//sc_yang +//#ifndef BZ2_COMPRESS +// li sp, NEWSTACK +//#else + move t0, s1 + addi t0, t0, 4096 + move sp, t0 + move a0, t0 +//#endif +//------------------------------- + + j main + nop + + .globl exit +exit: + j exit + nop + + .globl start_kernel +start_kernel: + move t0, a0 + li a0, 0 + li a1, 0 + li a2, 0 + jr t0 + nop + + +hfclock_setting: + // Check chip version to set divider register + li t1, REG_REVISION + lw t0, 0(t1) + li t1, 0xf0000000 + and t0, t0, t1 + srl t0, t0, 0x1c // Right shift 28 bits + + beq t0, VERSION_D, version_8186_C //set D cut keep 108MHz + nop + +// bne t0, VERSION_D, 1f +// nop +// j ra // 8186 D cut doesn't need watch dog reset. +// nop + +1: + beq t0, VERSION_C, version_8186_C + nop + + +version_8186_B: + // Check PLLMNR and SYSCLKR Registers. + la a0, REG_PLLMNR + lw t0, 0(a0) + and t0, t0, 0x3FFFF //You must mask other bits!! + li t1, VAL_PLLMNR_8186B + bne t0, t1, set_B + nop + + la a0, REG_SYSCLKR + lw t0, 0(a0) + and t0, t0, 0xFFF //You must mask other bits!! + li t1, VAL_SYSCLKR_8186B + bne t0, t1, set_B + nop + + j ra //PLLMNR and SYSCLKR are set already. + nop + +set_B: + // Set CPU/MEM Clock and Watch Dog Reset. + li t0, VAL_PLLMNR_8186B + la a0, REG_PLLMNR + sw t0, 0(a0) + + li t0, VAL_SYSCLKR_8186B + la a0, REG_SYSCLKR + sw t0, 0(a0) + + j start_watch_dog + nop + +version_8186_C: + // Check PLLMNR and SYSCLKR Registers. + la a0, REG_PLLMNR + lw t0, 0(a0) + and t0, t0, 0x3FFFF //You must mask other bits!! + li t1, VAL_PLLMNR_8186C + bne t0, t1, set_C + nop + + la a0, REG_SYSCLKR + lw t0, 0(a0) + and t0, t0, 0xFFF //You must mask other bits!! + li t1, VAL_SYSCLKR_8186C + bne t0, t1, set_C + nop + + j ra + nop + +set_C: + // Set CPU/MEM Clock and Watch Dog Reset. + li t0, VAL_PLLMNR_8186C + la a0, REG_PLLMNR + sw t0, 0(a0) + + li t0, VAL_SYSCLKR_8186C + la a0, REG_SYSCLKR + sw t0, 0(a0) + + j start_watch_dog + nop + +start_watch_dog: + // start WDTDOG + la a0, REG_CDBR + la t0, 0x2 + sw t0, 0(a0) + la t0, 0x100 + la a0, REG_WDTCNR + sw t0, 0(a0) +1: + b 1b + nop + + diff --git a/target/linux/realtek/files/rtkload/start.h b/target/linux/realtek/files/rtkload/start.h new file mode 100644 index 000000000..c5397d2b9 --- /dev/null +++ b/target/linux/realtek/files/rtkload/start.h @@ -0,0 +1,46 @@ +#ifndef __RTL_START_H__
+#define __RTL_START_H__
+ +//#include <linux/config.h>
+#include <linux/autoconf.h> +
+//----- System Registers ------------------------------------------------
+#define REG_REVISION 0xbd01010c
+#define REG_PLLMNR 0xbd010104
+#define REG_SYSCLKR 0xbd010108
+#define REG_GPEFDIR 0xbd010144
+#define REG_GPEFDATA 0xbd010140
+#define REG_MTCR0 0xbd011004
+#define REG_MCR 0xbd011000
+#define REG_MTCR1 0xbd011008
+#define REG_TKNR 0xbd010110
+#define REG_GISR 0xbd010004
+#define REG_WDTCNR 0xbd01005c
+#define REG_CDBR 0xbd010058
+
+//----- Revision bit ----------------------------------------------------
+#define VERSION_B 0x0 //0000
+#define VERSION_C 0x8 //1000
+#define VERSION_D 0x4 //0100
+
+//----- DPLL and Clock Setting ------------------------------------------
+#define VAL_PLLMNR_8186B 0x36704 // 160/128
+#define VAL_SYSCLKR_8186B 0xa0b // CPU=320/2 MEM=320/2.5
+
+#define VAL_PLLMNR_8186C 0x35a03 // 180/108
+#define VAL_SYSCLKR_8186C 0x090b // CPU=270/1.5 MEM=270/2.5
+
+//----- Memory Setting --------------------------------------------------
+#define VAL_FLASH_TIMING 0x88880000
+//#define VAL_FLASH_TIMING 0x33330000 //high speed.
+
+
+#if (defined(CONFIG_SKIP_ADJUST_SYSCLK) ) + #define CONFIG_DONOT_ADJUST_SYSCLK_MEMSP +#endif
+//----- Others ----------------------------------------------------------
+#define PCI_LOW_COUNTER 0xFFFF
+#define BOOT_ADDR 0x80100000
+
+#endif
+
diff --git a/target/linux/realtek/files/rtkload/string.c b/target/linux/realtek/files/rtkload/string.c new file mode 100644 index 000000000..6f787844e --- /dev/null +++ b/target/linux/realtek/files/rtkload/string.c @@ -0,0 +1,382 @@ +/* + * linux/lib/string.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +/* + * stupid library routines.. The optimized versions should generally be found + * as inline code in <asm-xx/string.h> + * + * These are buggy as well.. + * + * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de> + * - Added strsep() which will replace strtok() soon (because strsep() is + * reentrant and should be faster). Use only strsep() in new code, please. + */ + +#include <linux/types.h> +#include <linux/string.h> +#include <linux/ctype.h> + +#ifndef __HAVE_ARCH_STRNICMP +int strnicmp(const char *s1, const char *s2, size_t len) +{ + /* Yes, Virginia, it had better be unsigned */ + unsigned char c1, c2; + + c1 = 0; c2 = 0; + if (len) { + do { + c1 = *s1; c2 = *s2; + s1++; s2++; + if (!c1) + break; + if (!c2) + break; + if (c1 == c2) + continue; + c1 = tolower(c1); + c2 = tolower(c2); + if (c1 != c2) + break; + } while (--len); + } + return (int)c1 - (int)c2; +} +#endif + +/* char * ___strtok = NULL; */ +char * ___strtok; /* live in BSS, please */ + +#ifndef __HAVE_ARCH_STRCPY +char * strcpy(char * dest,const char *src) +{ + char *tmp = dest; + + while ((*dest++ = *src++) != '\0') + /* nothing */; + return tmp; +} +#endif + +#ifndef __HAVE_ARCH_STRNCPY +char * strncpy(char * dest,const char *src,size_t count) +{ + char *tmp = dest; + + while (count-- && (*dest++ = *src++) != '\0') + /* nothing */; + + return tmp; +} +#endif + +#ifndef __HAVE_ARCH_STRCAT +char * strcat(char * dest, const char * src) +{ + char *tmp = dest; + + while (*dest) + dest++; + while ((*dest++ = *src++) != '\0') + ; + + return tmp; +} +#endif + +#ifndef __HAVE_ARCH_STRNCAT +char * strncat(char *dest, const char *src, size_t count) +{ + char *tmp = dest; + + if (count) { + while (*dest) + dest++; + while ((*dest++ = *src++)) { + if (--count == 0) { + *dest = '\0'; + break; + } + } + } + + return tmp; +} +#endif + +#ifndef __HAVE_ARCH_STRCMP +int strcmp(const char * cs,const char * ct) +{ + register signed char __res; + + while (1) { + if ((__res = *cs - *ct++) != 0 || !*cs++) + break; + } + + return __res; +} +#endif + +#ifndef __HAVE_ARCH_STRNCMP +int strncmp(const char * cs,const char * ct,size_t count) +{ + register signed char __res = 0; + + while (count) { + if ((__res = *cs - *ct++) != 0 || !*cs++) + break; + count--; + } + + return __res; +} +#endif + +#ifndef __HAVE_ARCH_STRCHR +char * strchr(const char * s, int c) +{ + for(; *s != (char) c; ++s) + if (*s == '\0') + return NULL; + return (char *) s; +} +#endif + +#ifndef __HAVE_ARCH_STRRCHR +char * strrchr(const char * s, int c) +{ + const char *p = s + strlen(s); + do { + if (*p == (char)c) + return (char *)p; + } while (--p >= s); + return NULL; +} +#endif + +#ifndef __HAVE_ARCH_STRLEN +size_t strlen(const char * s) +{ + const char *sc; + + for (sc = s; *sc != '\0'; ++sc) + /* nothing */; + return sc - s; +} +#endif + +#ifndef __HAVE_ARCH_STRNLEN +size_t strnlen(const char * s, size_t count) +{ + const char *sc; + + for (sc = s; count-- && *sc != '\0'; ++sc) + /* nothing */; + return sc - s; +} +#endif + +#ifndef __HAVE_ARCH_STRSPN +size_t strspn(const char *s, const char *accept) +{ + const char *p; + const char *a; + size_t count = 0; + + for (p = s; *p != '\0'; ++p) { + for (a = accept; *a != '\0'; ++a) { + if (*p == *a) + break; + } + if (*a == '\0') + return count; + ++count; + } + + return count; +} +#endif + +#ifndef __HAVE_ARCH_STRPBRK +char * strpbrk(const char * cs,const char * ct) +{ + const char *sc1,*sc2; + + for( sc1 = cs; *sc1 != '\0'; ++sc1) { + for( sc2 = ct; *sc2 != '\0'; ++sc2) { + if (*sc1 == *sc2) + return (char *) sc1; + } + } + return NULL; +} +#endif + +#ifndef __HAVE_ARCH_STRTOK +char * strtok(char * s,const char * ct) +{ + char *sbegin, *send; + + sbegin = s ? s : ___strtok; + if (!sbegin) { + return NULL; + } + sbegin += strspn(sbegin,ct); + if (*sbegin == '\0') { + ___strtok = NULL; + return( NULL ); + } + send = strpbrk( sbegin, ct); + if (send && *send != '\0') + *send++ = '\0'; + ___strtok = send; + return (sbegin); +} +#endif + +#ifndef __HAVE_ARCH_STRSEP + +char * strsep(char **s, const char * ct) +{ + char *sbegin=*s; + if (!sbegin) + return NULL; + + sbegin += strspn(sbegin,ct); + if (*sbegin == '\0') + return NULL; + + *s = strpbrk( sbegin, ct); + if (*s && **s != '\0') + **s++ = '\0'; + return (sbegin); +} +#endif + +#ifndef __HAVE_ARCH_MEMSET +void * memset(void * s, int c, size_t count) +{ + char *xs = (char *) s; + + while (count--) + *xs++ = (char) c; + + return s; +} +#endif + +/* +#ifndef __HAVE_ARCH_BCOPY +char * bcopy(const char * src, char * dest, int count) +{ + char *tmp = dest; + + while (count--) + *tmp++ = *src++; + + return dest; +} +#endif +*/ + +#ifndef __HAVE_ARCH_MEMCPY +void * memcpy(void * dest,const void *src,size_t count) +{ + char *tmp = (char *) dest, *s = (char *) src; + + while (count--) + *tmp++ = *s++; + + return dest; +} +#endif + +#ifndef __HAVE_ARCH_MEMMOVE +void * memmove(void * dest,const void *src,size_t count) +{ + char *tmp, *s; + + if (dest <= src) { + tmp = (char *) dest; + s = (char *) src; + while (count--) + *tmp++ = *s++; + } + else { + tmp = (char *) dest + count; + s = (char *) src + count; + while (count--) + *--tmp = *--s; + } + + return dest; +} +#endif + +#ifndef __HAVE_ARCH_MEMCMP +int memcmp(const void * cs,const void * ct,size_t count) +{ + const unsigned char *su1, *su2; + signed char res = 0; + + for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) + if ((res = *su1 - *su2) != 0) + break; + return res; +} +#endif + +/* + * find the first occurrence of byte 'c', or 1 past the area if none + */ +#ifndef __HAVE_ARCH_MEMSCAN +void * memscan(void * addr, int c, size_t size) +{ + unsigned char * p = (unsigned char *) addr; + unsigned char * e = p + size; + + while (p != e) { + if (*p == c) + return (void *) p; + p++; + } + + return (void *) p; +} +#endif + +#ifndef __HAVE_ARCH_STRSTR +char * strstr(const char * s1,const char * s2) +{ + int l1, l2; + + l2 = strlen(s2); + if (!l2) + return (char *) s1; + l1 = strlen(s1); + while (l1 >= l2) { + l1--; + if (!memcmp(s1,s2,l2)) + return (char *) s1; + s1++; + } + return NULL; +} +#endif + +#ifndef __HAVE_ARCH_MEMCHR +void *memchr(const void *s, int c, size_t n) +{ + const unsigned char *p = s; + while (n-- != 0) { + if ((unsigned char)c == *p++) { + return (void *)(p-1); + } + } + return NULL; +} + +#endif diff --git a/target/linux/realtek/files/rtkload/system.map b/target/linux/realtek/files/rtkload/system.map new file mode 100644 index 000000000..a7b192a30 --- /dev/null +++ b/target/linux/realtek/files/rtkload/system.map @@ -0,0 +1,75 @@ +80500000 T __start +80500058 T exit +80500064 T start_kernel +80500080 t hfclock_setting +805000b8 t version_8186_B +80500114 t set_B +80500144 t version_8186_C +805001a0 t set_C +805001d0 t start_watch_dog +80500200 T main +80500280 T memcpy +805002b0 T read_struct +80500300 T seek_forward +8050035c T copy_to_region +805003d0 T init_read +805003e0 W __div64_32 +80500520 T simple_strtoul +80500600 T simple_strtol +8050063c t skip_atoi +805006a0 t number +805009ac T vsprintf +80500f9c T sprintf +80500fd0 T serial_outc +80501020 T prom_printf +805010d0 T strlen +805010f8 T strnicmp +80501184 T strcat +805011c0 T strncat +80501214 T strchr +80501254 T strrchr +805012b8 T strnlen +805012fc T strspn +80501368 T strpbrk +805013c4 T strtok +8050146c T strsep +80501500 T memcmp +80501538 T memscan +80501564 T strstr +80501604 T memchr +80501640 t error +80501678 T decompress_kernel +80501920 T flush_dcache +805019b4 T flush_icache +805019f4 T flush_cache +80501a30 T LzmaDecodeProperties +80501ab0 T LzmaDecode +80502550 T vmlinux_entry +80502690 R _ctype +80502870 D _fdata +80502c00 D __vmlinux_start +805e79f8 D __vmlinux_end +805e7c00 B _bstart +805e7c00 b buf.0 +805e8000 b inbuf +805e8004 b window +805f0004 b insize +805f0008 b inptr +805f000c b outcnt +805f0010 b output_data +805f0014 b output_ptr +805f0018 b bytes_out +805f001c b free_mem_ptr +805f0020 b free_mem_ptr_end +805f0024 b bb +805f0028 b bk +805f002c b hufts +805f0030 b crc_32_tab +805f0430 b crc +805f0440 B file_offset +805f0444 B mips_io_port_base +805f0448 B kernelStartAddr +805f044c B source_memory +805f0450 B ___strtok +805f0454 B __machine_arch_type +805f0458 B _bend diff --git a/target/linux/realtek/files/rtkload/target.script b/target/linux/realtek/files/rtkload/target.script new file mode 100644 index 000000000..a62023f89 --- /dev/null +++ b/target/linux/realtek/files/rtkload/target.script @@ -0,0 +1,27 @@ +/* ld.script + * + * This file is subject to the terms and conditions of the GNU + * General Public License. See the file "COPYING" in the main + * directory of this archive for more details. + * + * Copyright (C) 2000, Jay Carlson + */ + +OUTPUT_FORMAT("elf32-littlemips") +OUTPUT_ARCH(mips) + +/* Someday I'll figure out how this works */ +/* MEMORY { bootcode : ORIGIN = 0x80000000, LENGTH = 512 bytes } */ +/* MEMORY { nandjrom : ORIGIN = 0x80000200, LENGTH = 2M - 512 bytes } */ +/* MEMORY { ext2n : ORIGIN = 0x80200000, LENGTH = 2M bytes } */ + +SECTIONS +{ + . = 0x80000000 ; + BOOTCODE : { bootcode* } + NANDJROM : { nandrom* } + EXT2N : { ext2n* } + +} + + diff --git a/target/linux/realtek/files/rtkload/vmlinux_img.c b/target/linux/realtek/files/rtkload/vmlinux_img.c new file mode 100644 index 000000000..163a1ac1c --- /dev/null +++ b/target/linux/realtek/files/rtkload/vmlinux_img.c @@ -0,0 +1,8 @@ + +void vmlinux_entry(void); + +void vmlinux_entry(void) +{ + + +} diff --git a/target/linux/realtek/files/rtkload/vsprintf.c b/target/linux/realtek/files/rtkload/vsprintf.c new file mode 100644 index 000000000..501a05985 --- /dev/null +++ b/target/linux/realtek/files/rtkload/vsprintf.c @@ -0,0 +1,366 @@ +/* + * linux/lib/vsprintf.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ +/* + * Wirzenius wrote this portably, Torvalds fucked it up :-) + */ + +#include <stdarg.h> +#include <linux/types.h> +#include <linux/string.h> +#include <linux/ctype.h> + +#include <asm/div64.h> + +#if 1 +/* Not needed on 64bit architectures */ +//#if BITS_PER_LONG == 32 +//porting from linux-2.6.30/lib/div64.c +uint32_t __attribute__((weak)) __div64_32(uint64_t *n, uint32_t base) +{ + uint64_t rem = *n; + uint64_t b = base; + uint64_t res, d = 1; + uint32_t high = rem >> 32; + + /* Reduce the thing a bit first */ + res = 0; + if (high >= base) { + high /= base; + res = (uint64_t) high << 32; + rem -= (uint64_t) (high*base) << 32; + } + + while ((int64_t)b > 0 && b < rem) { + b = b+b; + d = d+d; + } + + do { + if (rem >= b) { + rem -= b; + res += d; + } + b >>= 1; + d >>= 1; + } while (d); + + *n = res; + return rem; +} +//#endif /* BITS_PER_LONG == 32 */ +#endif + +unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) +{ + unsigned long result = 0,value; + + if (!base) { + base = 10; + if (*cp == '0') { + base = 8; + cp++; + if ((*cp == 'x') && isxdigit(cp[1])) { + cp++; + base = 16; + } + } + } + while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp) + ? toupper(*cp) : *cp)-'A'+10) < base) { + result = result*base + value; + cp++; + } + if (endp) + *endp = (char *)cp; + return result; +} + +long simple_strtol(const char *cp,char **endp,unsigned int base) +{ + if(*cp=='-') + return -simple_strtoul(cp+1,endp,base); + return simple_strtoul(cp,endp,base); +} + +/* we use this so that we can do without the ctype library */ +#define is_digit(c) ((c) >= '0' && (c) <= '9') + +static int skip_atoi(const char **s) +{ + int i=0; + + while (is_digit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ + +//static char * number(char * str, long long num, int base, int size, int precision, int type) +static char * number(char * str, uint64_t num, int base, int size, int precision, int type) +{ + char c,sign,tmp[66]; + const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; + int i; + + if (type & LARGE) + digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (type & LEFT) + type &= ~ZEROPAD; + if (base < 2 || base > 36) + return 0; + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & SIGN) { + if (num < 0) { + sign = '-'; + num = -num; + size--; + } else if (type & PLUS) { + sign = '+'; + size--; + } else if (type & SPACE) { + sign = ' '; + size--; + } + } + if (type & SPECIAL) { + if (base == 16) + size -= 2; + else if (base == 8) + size--; + } + i = 0; + if (num == 0) + tmp[i++]='0'; + else while (num != 0) + tmp[i++] = digits[do_div(num,base)]; + if (i > precision) + precision = i; + size -= precision; + if (!(type&(ZEROPAD+LEFT))) + while(size-->0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (type & SPECIAL) { + if (base==8) + *str++ = '0'; + else if (base==16) { + *str++ = '0'; + *str++ = digits[33]; + } + } + if (!(type & LEFT)) + while (size-- > 0) + *str++ = c; + while (i < precision--) + *str++ = '0'; + while (i-- > 0) + *str++ = tmp[i]; + while (size-- > 0) + *str++ = ' '; + return str; +} + +/* Forward decl. needed for IP address printing stuff... */ +int sprintf(char * buf, const char *fmt, ...); + +int vsprintf(char *buf, const char *fmt, va_list args) +{ + int len; + unsigned long long num; + int i, base; + char * str; + const char *s; + + int flags; /* flags to number() */ + + int field_width; /* width of output field */ + int precision; /* min. # of digits for integers; max + number of chars for from string */ + int qualifier; /* 'h', 'l', or 'L' for integer fields */ + /* 'z' support added 23/7/1999 S.H. */ + /* 'z' changed to 'Z' --davidm 1/25/99 */ + + + for (str=buf ; *fmt ; ++fmt) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= LEFT; goto repeat; + case '+': flags |= PLUS; goto repeat; + case ' ': flags |= SPACE; goto repeat; + case '#': flags |= SPECIAL; goto repeat; + case '0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if (is_digit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (is_digit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { + qualifier = *fmt; + ++fmt; + } + + /* default base */ + base = 10; + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + continue; + + case 's': + s = va_arg(args, char *); + if (!s) + s = "<NULL>"; + + len = strnlen(s, precision); + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + continue; + + case 'p': + if (field_width == -1) { + field_width = 2*sizeof(void *); + flags |= ZEROPAD; + } + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + continue; + + + case 'n': + if (qualifier == 'l') { + long * ip = va_arg(args, long *); + *ip = (str - buf); + } else if (qualifier == 'Z') { + size_t * ip = va_arg(args, size_t *); + *ip = (str - buf); + } else { + int * ip = va_arg(args, int *); + *ip = (str - buf); + } + continue; + + case '%': + *str++ = '%'; + continue; + + /* integer number formats - set up the flags and "break" */ + case 'o': + base = 8; + break; + + case 'X': + flags |= LARGE; + case 'x': + base = 16; + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + break; + + default: + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + continue; + } + if (qualifier == 'L') + num = va_arg(args, long long); + else if (qualifier == 'l') { + num = va_arg(args, unsigned long); + if (flags & SIGN) + num = (signed long) num; + } else if (qualifier == 'Z') { + num = va_arg(args, size_t); + } else if (qualifier == 'h') { + num = (unsigned short) va_arg(args, int); + if (flags & SIGN) + num = (signed short) num; + } else { + num = va_arg(args, unsigned int); + if (flags & SIGN) + num = (signed int) num; + } + str = number(str, num, base, field_width, precision, flags); + } + *str = '\0'; + return str-buf; +} + +int sprintf(char * buf, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i=vsprintf(buf,fmt,args); + va_end(args); + return i; +} |