summaryrefslogtreecommitdiff
path: root/utils/ypr0tools
diff options
context:
space:
mode:
Diffstat (limited to 'utils/ypr0tools')
-rw-r--r--utils/ypr0tools/Makefile13
-rwxr-xr-xutils/ypr0tools/MuonEncryptbin0 -> 11006 bytes
-rw-r--r--utils/ypr0tools/README12
-rw-r--r--utils/ypr0tools/cramfs-1.1/COPYING340
-rw-r--r--utils/ypr0tools/cramfs-1.1/GNUmakefile12
-rw-r--r--utils/ypr0tools/cramfs-1.1/NOTES168
-rw-r--r--utils/ypr0tools/cramfs-1.1/README76
-rw-r--r--utils/ypr0tools/cramfs-1.1/cramfsck.c716
-rw-r--r--utils/ypr0tools/cramfs-1.1/linux/cramfs_fs.h98
-rw-r--r--utils/ypr0tools/cramfs-1.1/linux/cramfs_fs_sb.h15
-rw-r--r--utils/ypr0tools/cramfs-1.1/mkcramfs.c889
-rw-r--r--utils/ypr0tools/extract_section.c85
-rw-r--r--utils/ypr0tools/files/.rockbox/README1
-rw-r--r--utils/ypr0tools/files/Playlists/README1
-rw-r--r--utils/ypr0tools/files/etc/mods/safe_mode.rawbin0 -> 230400 bytes
-rwxr-xr-xutils/ypr0tools/files/etc/mods/safe_mode.sh111
-rwxr-xr-xutils/ypr0tools/files/etc/profile66
-rwxr-xr-xutils/ypr0tools/pack-firmware.sh132
-rwxr-xr-xutils/ypr0tools/patch-firmware.sh67
-rwxr-xr-xutils/ypr0tools/rockbox.sh47
-rwxr-xr-xutils/ypr0tools/unpack-firmware.sh90
21 files changed, 2939 insertions, 0 deletions
diff --git a/utils/ypr0tools/Makefile b/utils/ypr0tools/Makefile
new file mode 100644
index 0000000000..efc1de63f2
--- /dev/null
+++ b/utils/ypr0tools/Makefile
@@ -0,0 +1,13 @@
1
2.PHONY: all clean
3PROGS = extract_section
4CC = gcc
5CFLAGS = -O1 -g -W -Wall
6
7
8all: $(PROGS)
9 $(MAKE) -C cramfs-1.1
10
11clean:
12 $(MAKE) -C cramfs-1.1 clean
13 rm -f extract_section
diff --git a/utils/ypr0tools/MuonEncrypt b/utils/ypr0tools/MuonEncrypt
new file mode 100755
index 0000000000..b1bc124523
--- /dev/null
+++ b/utils/ypr0tools/MuonEncrypt
Binary files differ
diff --git a/utils/ypr0tools/README b/utils/ypr0tools/README
new file mode 100644
index 0000000000..45777dd8c5
--- /dev/null
+++ b/utils/ypr0tools/README
@@ -0,0 +1,12 @@
1
2To generate a firmware, run (paths may differ):
3
4$ make
5$ ./unpack-firmware.sh R0.ROM /tmp/romfiles
6$ sudo ./patch-firmware.sh files /tmp/romfiles # needs sudo
7$ ./pack-firmware.sh R0.ROM /tmp/romfiles
8
9After that, R0.ROM is patched and can load Rockbox.
10
11rockbox.sh is a script to put into rockbox.zip. It's a small loader script
12that sets stuff up.
diff --git a/utils/ypr0tools/cramfs-1.1/COPYING b/utils/ypr0tools/cramfs-1.1/COPYING
new file mode 100644
index 0000000000..5b6e7c66c2
--- /dev/null
+++ b/utils/ypr0tools/cramfs-1.1/COPYING
@@ -0,0 +1,340 @@
1 GNU GENERAL PUBLIC LICENSE
2 Version 2, June 1991
3
4 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6 Everyone is permitted to copy and distribute verbatim copies
7 of this license document, but changing it is not allowed.
8
9 Preamble
10
11 The licenses for most software are designed to take away your
12freedom to share and change it. By contrast, the GNU General Public
13License is intended to guarantee your freedom to share and change free
14software--to make sure the software is free for all its users. This
15General Public License applies to most of the Free Software
16Foundation's software and to any other program whose authors commit to
17using it. (Some other Free Software Foundation software is covered by
18the GNU Library General Public License instead.) You can apply it to
19your programs, too.
20
21 When we speak of free software, we are referring to freedom, not
22price. Our General Public Licenses are designed to make sure that you
23have the freedom to distribute copies of free software (and charge for
24this service if you wish), that you receive source code or can get it
25if you want it, that you can change the software or use pieces of it
26in new free programs; and that you know you can do these things.
27
28 To protect your rights, we need to make restrictions that forbid
29anyone to deny you these rights or to ask you to surrender the rights.
30These restrictions translate to certain responsibilities for you if you
31distribute copies of the software, or if you modify it.
32
33 For example, if you distribute copies of such a program, whether
34gratis or for a fee, you must give the recipients all the rights that
35you have. You must make sure that they, too, receive or can get the
36source code. And you must show them these terms so they know their
37rights.
38
39 We protect your rights with two steps: (1) copyright the software, and
40(2) offer you this license which gives you legal permission to copy,
41distribute and/or modify the software.
42
43 Also, for each author's protection and ours, we want to make certain
44that everyone understands that there is no warranty for this free
45software. If the software is modified by someone else and passed on, we
46want its recipients to know that what they have is not the original, so
47that any problems introduced by others will not reflect on the original
48authors' reputations.
49
50 Finally, any free program is threatened constantly by software
51patents. We wish to avoid the danger that redistributors of a free
52program will individually obtain patent licenses, in effect making the
53program proprietary. To prevent this, we have made it clear that any
54patent must be licensed for everyone's free use or not licensed at all.
55
56 The precise terms and conditions for copying, distribution and
57modification follow.
58
59 GNU GENERAL PUBLIC LICENSE
60 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
62 0. This License applies to any program or other work which contains
63a notice placed by the copyright holder saying it may be distributed
64under the terms of this General Public License. The "Program", below,
65refers to any such program or work, and a "work based on the Program"
66means either the Program or any derivative work under copyright law:
67that is to say, a work containing the Program or a portion of it,
68either verbatim or with modifications and/or translated into another
69language. (Hereinafter, translation is included without limitation in
70the term "modification".) Each licensee is addressed as "you".
71
72Activities other than copying, distribution and modification are not
73covered by this License; they are outside its scope. The act of
74running the Program is not restricted, and the output from the Program
75is covered only if its contents constitute a work based on the
76Program (independent of having been made by running the Program).
77Whether that is true depends on what the Program does.
78
79 1. You may copy and distribute verbatim copies of the Program's
80source code as you receive it, in any medium, provided that you
81conspicuously and appropriately publish on each copy an appropriate
82copyright notice and disclaimer of warranty; keep intact all the
83notices that refer to this License and to the absence of any warranty;
84and give any other recipients of the Program a copy of this License
85along with the Program.
86
87You may charge a fee for the physical act of transferring a copy, and
88you may at your option offer warranty protection in exchange for a fee.
89
90 2. You may modify your copy or copies of the Program or any portion
91of it, thus forming a work based on the Program, and copy and
92distribute such modifications or work under the terms of Section 1
93above, provided that you also meet all of these conditions:
94
95 a) You must cause the modified files to carry prominent notices
96 stating that you changed the files and the date of any change.
97
98 b) You must cause any work that you distribute or publish, that in
99 whole or in part contains or is derived from the Program or any
100 part thereof, to be licensed as a whole at no charge to all third
101 parties under the terms of this License.
102
103 c) If the modified program normally reads commands interactively
104 when run, you must cause it, when started running for such
105 interactive use in the most ordinary way, to print or display an
106 announcement including an appropriate copyright notice and a
107 notice that there is no warranty (or else, saying that you provide
108 a warranty) and that users may redistribute the program under
109 these conditions, and telling the user how to view a copy of this
110 License. (Exception: if the Program itself is interactive but
111 does not normally print such an announcement, your work based on
112 the Program is not required to print an announcement.)
113
114These requirements apply to the modified work as a whole. If
115identifiable sections of that work are not derived from the Program,
116and can be reasonably considered independent and separate works in
117themselves, then this License, and its terms, do not apply to those
118sections when you distribute them as separate works. But when you
119distribute the same sections as part of a whole which is a work based
120on the Program, the distribution of the whole must be on the terms of
121this License, whose permissions for other licensees extend to the
122entire whole, and thus to each and every part regardless of who wrote it.
123
124Thus, it is not the intent of this section to claim rights or contest
125your rights to work written entirely by you; rather, the intent is to
126exercise the right to control the distribution of derivative or
127collective works based on the Program.
128
129In addition, mere aggregation of another work not based on the Program
130with the Program (or with a work based on the Program) on a volume of
131a storage or distribution medium does not bring the other work under
132the scope of this License.
133
134 3. You may copy and distribute the Program (or a work based on it,
135under Section 2) in object code or executable form under the terms of
136Sections 1 and 2 above provided that you also do one of the following:
137
138 a) Accompany it with the complete corresponding machine-readable
139 source code, which must be distributed under the terms of Sections
140 1 and 2 above on a medium customarily used for software interchange; or,
141
142 b) Accompany it with a written offer, valid for at least three
143 years, to give any third party, for a charge no more than your
144 cost of physically performing source distribution, a complete
145 machine-readable copy of the corresponding source code, to be
146 distributed under the terms of Sections 1 and 2 above on a medium
147 customarily used for software interchange; or,
148
149 c) Accompany it with the information you received as to the offer
150 to distribute corresponding source code. (This alternative is
151 allowed only for noncommercial distribution and only if you
152 received the program in object code or executable form with such
153 an offer, in accord with Subsection b above.)
154
155The source code for a work means the preferred form of the work for
156making modifications to it. For an executable work, complete source
157code means all the source code for all modules it contains, plus any
158associated interface definition files, plus the scripts used to
159control compilation and installation of the executable. However, as a
160special exception, the source code distributed need not include
161anything that is normally distributed (in either source or binary
162form) with the major components (compiler, kernel, and so on) of the
163operating system on which the executable runs, unless that component
164itself accompanies the executable.
165
166If distribution of executable or object code is made by offering
167access to copy from a designated place, then offering equivalent
168access to copy the source code from the same place counts as
169distribution of the source code, even though third parties are not
170compelled to copy the source along with the object code.
171
172 4. You may not copy, modify, sublicense, or distribute the Program
173except as expressly provided under this License. Any attempt
174otherwise to copy, modify, sublicense or distribute the Program is
175void, and will automatically terminate your rights under this License.
176However, parties who have received copies, or rights, from you under
177this License will not have their licenses terminated so long as such
178parties remain in full compliance.
179
180 5. You are not required to accept this License, since you have not
181signed it. However, nothing else grants you permission to modify or
182distribute the Program or its derivative works. These actions are
183prohibited by law if you do not accept this License. Therefore, by
184modifying or distributing the Program (or any work based on the
185Program), you indicate your acceptance of this License to do so, and
186all its terms and conditions for copying, distributing or modifying
187the Program or works based on it.
188
189 6. Each time you redistribute the Program (or any work based on the
190Program), the recipient automatically receives a license from the
191original licensor to copy, distribute or modify the Program subject to
192these terms and conditions. You may not impose any further
193restrictions on the recipients' exercise of the rights granted herein.
194You are not responsible for enforcing compliance by third parties to
195this License.
196
197 7. If, as a consequence of a court judgment or allegation of patent
198infringement or for any other reason (not limited to patent issues),
199conditions are imposed on you (whether by court order, agreement or
200otherwise) that contradict the conditions of this License, they do not
201excuse you from the conditions of this License. If you cannot
202distribute so as to satisfy simultaneously your obligations under this
203License and any other pertinent obligations, then as a consequence you
204may not distribute the Program at all. For example, if a patent
205license would not permit royalty-free redistribution of the Program by
206all those who receive copies directly or indirectly through you, then
207the only way you could satisfy both it and this License would be to
208refrain entirely from distribution of the Program.
209
210If any portion of this section is held invalid or unenforceable under
211any particular circumstance, the balance of the section is intended to
212apply and the section as a whole is intended to apply in other
213circumstances.
214
215It is not the purpose of this section to induce you to infringe any
216patents or other property right claims or to contest validity of any
217such claims; this section has the sole purpose of protecting the
218integrity of the free software distribution system, which is
219implemented by public license practices. Many people have made
220generous contributions to the wide range of software distributed
221through that system in reliance on consistent application of that
222system; it is up to the author/donor to decide if he or she is willing
223to distribute software through any other system and a licensee cannot
224impose that choice.
225
226This section is intended to make thoroughly clear what is believed to
227be a consequence of the rest of this License.
228
229 8. If the distribution and/or use of the Program is restricted in
230certain countries either by patents or by copyrighted interfaces, the
231original copyright holder who places the Program under this License
232may add an explicit geographical distribution limitation excluding
233those countries, so that distribution is permitted only in or among
234countries not thus excluded. In such case, this License incorporates
235the limitation as if written in the body of this License.
236
237 9. The Free Software Foundation may publish revised and/or new versions
238of the General Public License from time to time. Such new versions will
239be similar in spirit to the present version, but may differ in detail to
240address new problems or concerns.
241
242Each version is given a distinguishing version number. If the Program
243specifies a version number of this License which applies to it and "any
244later version", you have the option of following the terms and conditions
245either of that version or of any later version published by the Free
246Software Foundation. If the Program does not specify a version number of
247this License, you may choose any version ever published by the Free Software
248Foundation.
249
250 10. If you wish to incorporate parts of the Program into other free
251programs whose distribution conditions are different, write to the author
252to ask for permission. For software which is copyrighted by the Free
253Software Foundation, write to the Free Software Foundation; we sometimes
254make exceptions for this. Our decision will be guided by the two goals
255of preserving the free status of all derivatives of our free software and
256of promoting the sharing and reuse of software generally.
257
258 NO WARRANTY
259
260 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268REPAIR OR CORRECTION.
269
270 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278POSSIBILITY OF SUCH DAMAGES.
279
280 END OF TERMS AND CONDITIONS
281
282 How to Apply These Terms to Your New Programs
283
284 If you develop a new program, and you want it to be of the greatest
285possible use to the public, the best way to achieve this is to make it
286free software which everyone can redistribute and change under these terms.
287
288 To do so, attach the following notices to the program. It is safest
289to attach them to the start of each source file to most effectively
290convey the exclusion of warranty; and each file should have at least
291the "copyright" line and a pointer to where the full notice is found.
292
293 <one line to give the program's name and a brief idea of what it does.>
294 Copyright (C) <year> <name of author>
295
296 This program is free software; you can redistribute it and/or modify
297 it under the terms of the GNU General Public License as published by
298 the Free Software Foundation; either version 2 of the License, or
299 (at your option) any later version.
300
301 This program is distributed in the hope that it will be useful,
302 but WITHOUT ANY WARRANTY; without even the implied warranty of
303 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 GNU General Public License for more details.
305
306 You should have received a copy of the GNU General Public License
307 along with this program; if not, write to the Free Software
308 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
309
310
311Also add information on how to contact you by electronic and paper mail.
312
313If the program is interactive, make it output a short notice like this
314when it starts in an interactive mode:
315
316 Gnomovision version 69, Copyright (C) year name of author
317 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
318 This is free software, and you are welcome to redistribute it
319 under certain conditions; type `show c' for details.
320
321The hypothetical commands `show w' and `show c' should show the appropriate
322parts of the General Public License. Of course, the commands you use may
323be called something other than `show w' and `show c'; they could even be
324mouse-clicks or menu items--whatever suits your program.
325
326You should also get your employer (if you work as a programmer) or your
327school, if any, to sign a "copyright disclaimer" for the program, if
328necessary. Here is a sample; alter the names:
329
330 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
331 `Gnomovision' (which makes passes at compilers) written by James Hacker.
332
333 <signature of Ty Coon>, 1 April 1989
334 Ty Coon, President of Vice
335
336This General Public License does not permit incorporating your program into
337proprietary programs. If your program is a subroutine library, you may
338consider it more useful to permit linking proprietary applications with the
339library. If this is what you want to do, use the GNU Library General
340Public License instead of this License.
diff --git a/utils/ypr0tools/cramfs-1.1/GNUmakefile b/utils/ypr0tools/cramfs-1.1/GNUmakefile
new file mode 100644
index 0000000000..e15fb22f01
--- /dev/null
+++ b/utils/ypr0tools/cramfs-1.1/GNUmakefile
@@ -0,0 +1,12 @@
1CC = gcc
2CFLAGS = -W -Wall -O2 -g -Wno-pointer-sign
3CPPFLAGS = -I.
4LDLIBS = -lz
5PROGS = mkcramfs cramfsck
6
7all: $(PROGS)
8
9distclean clean:
10 rm -f $(PROGS)
11
12.PHONY: all clean
diff --git a/utils/ypr0tools/cramfs-1.1/NOTES b/utils/ypr0tools/cramfs-1.1/NOTES
new file mode 100644
index 0000000000..445d1c2d76
--- /dev/null
+++ b/utils/ypr0tools/cramfs-1.1/NOTES
@@ -0,0 +1,168 @@
1Notes on Filesystem Layout
2--------------------------
3
4These notes describe what mkcramfs generates. Kernel requirements are
5a bit looser, e.g. it doesn't care if the <file_data> items are
6swapped around (though it does care that directory entries (inodes) in
7a given directory are contiguous, as this is used by readdir).
8
9All data is currently in host-endian format; neither mkcramfs nor the
10kernel ever do swabbing. (See section `Block Size' below.)
11
12<filesystem>:
13 <superblock>
14 <directory_structure>
15 <data>
16
17<superblock>: struct cramfs_super (see cramfs_fs.h).
18
19<directory_structure>:
20 For each file:
21 struct cramfs_inode (see cramfs_fs.h).
22 Filename. Not generally null-terminated, but it is
23 null-padded to a multiple of 4 bytes.
24
25The order of inode traversal is described as "width-first" (not to be
26confused with breadth-first); i.e. like depth-first but listing all of
27a directory's entries before recursing down its subdirectories: the
28same order as `ls -AUR' (but without the /^\..*:$/ directory header
29lines); put another way, the same order as `find -type d -exec
30ls -AU1 {} \;'.
31
32Beginning in 2.4.7, directory entries are sorted. This optimization
33allows cramfs_lookup to return more quickly when a filename does not
34exist, speeds up user-space directory sorts, etc.
35
36<data>:
37 One <file_data> for each file that's either a symlink or a
38 regular file of non-zero st_size.
39
40<file_data>:
41 nblocks * <block_pointer>
42 (where nblocks = (st_size - 1) / blksize + 1)
43 nblocks * <block>
44 padding to multiple of 4 bytes
45
46The i'th <block_pointer> for a file stores the byte offset of the
47*end* of the i'th <block> (i.e. one past the last byte, which is the
48same as the start of the (i+1)'th <block> if there is one). The first
49<block> immediately follows the last <block_pointer> for the file.
50<block_pointer>s are each 32 bits long.
51
52The order of <file_data>'s is a depth-first descent of the directory
53tree, i.e. the same order as `find -size +0 \( -type f -o -type l \)
54-print'.
55
56
57<block>: The i'th <block> is the output of zlib's compress function
58applied to the i'th blksize-sized chunk of the input data.
59(For the last <block> of the file, the input may of course be smaller.)
60Each <block> may be a different size. (See <block_pointer> above.)
61<block>s are merely byte-aligned, not generally u32-aligned.
62
63
64Holes
65-----
66
67This kernel supports cramfs holes (i.e. [efficient representation of]
68blocks in uncompressed data consisting entirely of NUL bytes), but by
69default mkcramfs doesn't test for & create holes, since cramfs in
70kernels up to at least 2.3.39 didn't support holes. Run mkcramfs
71with -z if you want it to create files that can have holes in them.
72
73
74Tools
75-----
76
77The cramfs user-space tools, including mkcramfs and cramfsck, are
78located at <http://sourceforge.net/projects/cramfs/>.
79
80
81Future Development
82==================
83
84Block Size
85----------
86
87(Block size in cramfs refers to the size of input data that is
88compressed at a time. It's intended to be somewhere around
89PAGE_CACHE_SIZE for cramfs_readpage's convenience.)
90
91The superblock ought to indicate the block size that the fs was
92written for, since comments in <linux/pagemap.h> indicate that
93PAGE_CACHE_SIZE may grow in future (if I interpret the comment
94correctly).
95
96Currently, mkcramfs #define's PAGE_CACHE_SIZE as 4096 and uses that
97for blksize, whereas Linux-2.3.39 uses its PAGE_CACHE_SIZE, which in
98turn is defined as PAGE_SIZE (which can be as large as 32KB on arm).
99This discrepancy is a bug, though it's not clear which should be
100changed.
101
102One option is to change mkcramfs to take its PAGE_CACHE_SIZE from
103<asm/page.h>. Personally I don't like this option, but it does
104require the least amount of change: just change `#define
105PAGE_CACHE_SIZE (4096)' to `#include <asm/page.h>'. The disadvantage
106is that the generated cramfs cannot always be shared between different
107kernels, not even necessarily kernels of the same architecture if
108PAGE_CACHE_SIZE is subject to change between kernel versions
109(currently possible with arm and ia64).
110
111The remaining options try to make cramfs more sharable.
112
113One part of that is addressing endianness. The two options here are
114`always use little-endian' (like ext2fs) or `writer chooses
115endianness; kernel adapts at runtime'. Little-endian wins because of
116code simplicity and little CPU overhead even on big-endian machines.
117
118The cost of swabbing is changing the code to use the le32_to_cpu
119etc. macros as used by ext2fs. We don't need to swab the compressed
120data, only the superblock, inodes and block pointers.
121
122
123The other part of making cramfs more sharable is choosing a block
124size. The options are:
125
126 1. Always 4096 bytes.
127
128 2. Writer chooses blocksize; kernel adapts but rejects blocksize >
129 PAGE_CACHE_SIZE.
130
131 3. Writer chooses blocksize; kernel adapts even to blocksize >
132 PAGE_CACHE_SIZE.
133
134It's easy enough to change the kernel to use a smaller value than
135PAGE_CACHE_SIZE: just make cramfs_readpage read multiple blocks.
136
137The cost of option 1 is that kernels with a larger PAGE_CACHE_SIZE
138value don't get as good compression as they can.
139
140The cost of option 2 relative to option 1 is that the code uses
141variables instead of #define'd constants. The gain is that people
142with kernels having larger PAGE_CACHE_SIZE can make use of that if
143they don't mind their cramfs being inaccessible to kernels with
144smaller PAGE_CACHE_SIZE values.
145
146Option 3 is easy to implement if we don't mind being CPU-inefficient:
147e.g. get readpage to decompress to a buffer of size MAX_BLKSIZE (which
148must be no larger than 32KB) and discard what it doesn't need.
149Getting readpage to read into all the covered pages is harder.
150
151The main advantage of option 3 over 1, 2, is better compression. The
152cost is greater complexity. Probably not worth it, but I hope someone
153will disagree. (If it is implemented, then I'll re-use that code in
154e2compr.)
155
156
157Another cost of 2 and 3 over 1 is making mkcramfs use a different
158block size, but that just means adding and parsing a -b option.
159
160
161Inode Size
162----------
163
164Given that cramfs will probably be used for CDs etc. as well as just
165silicon ROMs, it might make sense to expand the inode a little from
166its current 12 bytes. Inodes other than the root inode are followed
167by filename, so the expansion doesn't even have to be a multiple of 4
168bytes.
diff --git a/utils/ypr0tools/cramfs-1.1/README b/utils/ypr0tools/cramfs-1.1/README
new file mode 100644
index 0000000000..31f53f0ab9
--- /dev/null
+++ b/utils/ypr0tools/cramfs-1.1/README
@@ -0,0 +1,76 @@
1
2 Cramfs - cram a filesystem onto a small ROM
3
4cramfs is designed to be simple and small, and to compress things well.
5
6It uses the zlib routines to compress a file one page at a time, and
7allows random page access. The meta-data is not compressed, but is
8expressed in a very terse representation to make it use much less
9diskspace than traditional filesystems.
10
11You can't write to a cramfs filesystem (making it compressible and
12compact also makes it _very_ hard to update on-the-fly), so you have to
13create the disk image with the "mkcramfs" utility.
14
15
16Usage Notes
17-----------
18
19File sizes are limited to less than 16MB.
20
21Maximum filesystem size is a little over 256MB. (The last file on the
22filesystem is allowed to extend past 256MB.)
23
24Only the low 8 bits of gid are stored. The current version of
25mkcramfs simply truncates to 8 bits, which is a potential security
26issue.
27
28Hard links are supported, but hard linked files
29will still have a link count of 1 in the cramfs image.
30
31Cramfs directories have no `.' or `..' entries. Directories (like
32every other file on cramfs) always have a link count of 1. (There's
33no need to use -noleaf in `find', btw.)
34
35No timestamps are stored in a cramfs, so these default to the epoch
36(1970 GMT). Recently-accessed files may have updated timestamps, but
37the update lasts only as long as the inode is cached in memory, after
38which the timestamp reverts to 1970, i.e. moves backwards in time.
39
40Currently, cramfs must be written and read with architectures of the
41same endianness, and can be read only by kernels with PAGE_CACHE_SIZE
42== 4096. At least the latter of these is a bug, but it hasn't been
43decided what the best fix is. For the moment if you have larger pages
44you can just change the #define in mkcramfs.c, so long as you don't
45mind the filesystem becoming unreadable to future kernels.
46
47
48For /usr/share/magic
49--------------------
50
510 ulelong 0x28cd3d45 Linux cramfs offset 0
52>4 ulelong x size %d
53>8 ulelong x flags 0x%x
54>12 ulelong x future 0x%x
55>16 string >\0 signature "%.16s"
56>32 ulelong x fsid.crc 0x%x
57>36 ulelong x fsid.edition %d
58>40 ulelong x fsid.blocks %d
59>44 ulelong x fsid.files %d
60>48 string >\0 name "%.16s"
61512 ulelong 0x28cd3d45 Linux cramfs offset 512
62>516 ulelong x size %d
63>520 ulelong x flags 0x%x
64>524 ulelong x future 0x%x
65>528 string >\0 signature "%.16s"
66>544 ulelong x fsid.crc 0x%x
67>548 ulelong x fsid.edition %d
68>552 ulelong x fsid.blocks %d
69>556 ulelong x fsid.files %d
70>560 string >\0 name "%.16s"
71
72
73Hacker Notes
74------------
75
76See fs/cramfs/README for filesystem layout and implementation notes.
diff --git a/utils/ypr0tools/cramfs-1.1/cramfsck.c b/utils/ypr0tools/cramfs-1.1/cramfsck.c
new file mode 100644
index 0000000000..aef017a4b4
--- /dev/null
+++ b/utils/ypr0tools/cramfs-1.1/cramfsck.c
@@ -0,0 +1,716 @@
1/*
2 * cramfsck - check a cramfs file system
3 *
4 * Copyright (C) 2000-2002 Transmeta Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * 1999/12/03: Linus Torvalds (cramfs tester and unarchive program)
21 * 2000/06/03: Daniel Quinlan (CRC and length checking program)
22 * 2000/06/04: Daniel Quinlan (merged programs, added options, support
23 * for special files, preserve permissions and
24 * ownership, cramfs superblock v2, bogus mode
25 * test, pathname length test, etc.)
26 * 2000/06/06: Daniel Quinlan (support for holes, pretty-printing,
27 * symlink size test)
28 * 2000/07/11: Daniel Quinlan (file length tests, start at offset 0 or 512,
29 * fsck-compatible exit codes)
30 * 2000/07/15: Daniel Quinlan (initial support for block devices)
31 * 2002/01/10: Daniel Quinlan (additional checks, test more return codes,
32 * use read if mmap fails, standardize messages)
33 */
34
35/* compile-time options */
36#define INCLUDE_FS_TESTS /* include cramfs checking and extraction */
37
38#define _GNU_SOURCE
39#include <sys/types.h>
40#include <stdio.h>
41#include <stdarg.h>
42#include <sys/stat.h>
43#include <unistd.h>
44#include <sys/mman.h>
45#include <fcntl.h>
46#include <dirent.h>
47#include <stdlib.h>
48#include <errno.h>
49#include <string.h>
50#include <sys/sysmacros.h>
51#include <utime.h>
52#include <sys/ioctl.h>
53#define _LINUX_STRING_H_
54#include <linux/fs.h>
55#include <linux/cramfs_fs.h>
56#include <zlib.h>
57
58/* Exit codes used by fsck-type programs */
59#define FSCK_OK 0 /* No errors */
60#define FSCK_NONDESTRUCT 1 /* File system errors corrected */
61#define FSCK_REBOOT 2 /* System should be rebooted */
62#define FSCK_UNCORRECTED 4 /* File system errors left uncorrected */
63#define FSCK_ERROR 8 /* Operational error */
64#define FSCK_USAGE 16 /* Usage or syntax error */
65#define FSCK_LIBRARY 128 /* Shared library error */
66
67#define PAD_SIZE 512
68
69#define PAGE_CACHE_SIZE page_size
70
71static const char *progname = "cramfsck";
72
73static int fd; /* ROM image file descriptor */
74static char *filename; /* ROM image filename */
75struct cramfs_super super; /* just find the cramfs superblock once */
76static int opt_verbose = 0; /* 1 = verbose (-v), 2+ = very verbose (-vv) */
77#ifdef INCLUDE_FS_TESTS
78static int opt_extract = 0; /* extract cramfs (-x) */
79static char *extract_dir = "root"; /* extraction directory (-x) */
80static uid_t euid; /* effective UID */
81
82/* (cramfs_super + start) <= start_dir < end_dir <= start_data <= end_data */
83static unsigned long start_dir = ~0UL; /* start of first non-root inode */
84static unsigned long end_dir = 0; /* end of the directory structure */
85static unsigned long start_data = ~0UL; /* start of the data (256 MB = max) */
86static unsigned long end_data = 0; /* end of the data */
87
88/* Guarantee access to at least 8kB at a time */
89#define ROMBUFFER_BITS 13
90#define ROMBUFFERSIZE (1 << ROMBUFFER_BITS)
91#define ROMBUFFERMASK (ROMBUFFERSIZE-1)
92static char read_buffer[ROMBUFFERSIZE * 2];
93static unsigned long read_buffer_block = ~0UL;
94
95/* Uncompressing data structures... */
96static char *outbuffer;
97static z_stream stream;
98
99static size_t page_size;
100
101/* Prototypes */
102static void expand_fs(char *, struct cramfs_inode *);
103#endif /* INCLUDE_FS_TESTS */
104
105/* Input status of 0 to print help and exit without an error. */
106static void usage(int status)
107{
108 FILE *stream = status ? stderr : stdout;
109
110 fprintf(stream, "usage: %s [-hv] [-x dir] file\n"
111 " -h print this help\n"
112 " -x dir extract into dir\n"
113 " -v be more verbose\n"
114 " file file to test\n", progname);
115
116 exit(status);
117}
118
119static void die(int status, int syserr, const char *fmt, ...)
120{
121 va_list arg_ptr;
122 int save = errno;
123
124 fflush(0);
125 va_start(arg_ptr, fmt);
126 fprintf(stderr, "%s: ", progname);
127 vfprintf(stderr, fmt, arg_ptr);
128 if (syserr) {
129 fprintf(stderr, ": %s", strerror(save));
130 }
131 fprintf(stderr, "\n");
132 va_end(arg_ptr);
133 exit(status);
134}
135
136static void test_super(int *start, size_t *length) {
137 struct stat st;
138
139 /* find the physical size of the file or block device */
140 if (stat(filename, &st) < 0) {
141 die(FSCK_ERROR, 1, "stat failed: %s", filename);
142 }
143 fd = open(filename, O_RDONLY);
144 if (fd < 0) {
145 die(FSCK_ERROR, 1, "open failed: %s", filename);
146 }
147 if (S_ISBLK(st.st_mode)) {
148 if (ioctl(fd, BLKGETSIZE, length) < 0) {
149 die(FSCK_ERROR, 1, "ioctl failed: unable to determine device size: %s", filename);
150 }
151 *length = *length * 512;
152 }
153 else if (S_ISREG(st.st_mode)) {
154 *length = st.st_size;
155 }
156 else {
157 die(FSCK_ERROR, 0, "not a block device or file: %s", filename);
158 }
159
160 if (*length < sizeof(struct cramfs_super)) {
161 die(FSCK_UNCORRECTED, 0, "file length too short");
162 }
163
164 /* find superblock */
165 if (read(fd, &super, sizeof(super)) != sizeof(super)) {
166 die(FSCK_ERROR, 1, "read failed: %s", filename);
167 }
168 if (super.magic == CRAMFS_MAGIC) {
169 *start = 0;
170 }
171 else if (*length >= (PAD_SIZE + sizeof(super))) {
172 lseek(fd, PAD_SIZE, SEEK_SET);
173 if (read(fd, &super, sizeof(super)) != sizeof(super)) {
174 die(FSCK_ERROR, 1, "read failed: %s", filename);
175 }
176 if (super.magic == CRAMFS_MAGIC) {
177 *start = PAD_SIZE;
178 }
179 }
180
181 /* superblock tests */
182 if (super.magic != CRAMFS_MAGIC) {
183 die(FSCK_UNCORRECTED, 0, "superblock magic not found");
184 }
185 if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) {
186 die(FSCK_ERROR, 0, "unsupported filesystem features");
187 }
188 if (super.size < PAGE_CACHE_SIZE) {
189 die(FSCK_UNCORRECTED, 0, "superblock size (%d) too small", super.size);
190 }
191 if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) {
192 if (super.fsid.files == 0) {
193 die(FSCK_UNCORRECTED, 0, "zero file count");
194 }
195 if (*length < super.size) {
196 die(FSCK_UNCORRECTED, 0, "file length too short");
197 }
198 else if (*length > super.size) {
199 fprintf(stderr, "warning: file extends past end of filesystem\n");
200 }
201 }
202 else {
203 fprintf(stderr, "warning: old cramfs format\n");
204 }
205}
206
207static void test_crc(int start)
208{
209 void *buf;
210 u32 crc;
211
212 if (!(super.flags & CRAMFS_FLAG_FSID_VERSION_2)) {
213#ifdef INCLUDE_FS_TESTS
214 return;
215#else /* not INCLUDE_FS_TESTS */
216 die(FSCK_USAGE, 0, "unable to test CRC: old cramfs format");
217#endif /* not INCLUDE_FS_TESTS */
218 }
219
220 crc = crc32(0L, Z_NULL, 0);
221
222 buf = mmap(NULL, super.size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
223 if (buf == MAP_FAILED) {
224 buf = mmap(NULL, super.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
225 if (buf != MAP_FAILED) {
226 lseek(fd, 0, SEEK_SET);
227 read(fd, buf, super.size);
228 }
229 }
230 if (buf != MAP_FAILED) {
231 ((struct cramfs_super *) (buf+start))->fsid.crc = crc32(0L, Z_NULL, 0);
232 crc = crc32(crc, buf+start, super.size-start);
233 munmap(buf, super.size);
234 }
235 else {
236 int retval;
237 size_t length = 0;
238
239 buf = malloc(4096);
240 if (!buf) {
241 die(FSCK_ERROR, 1, "malloc failed");
242 }
243 lseek(fd, start, SEEK_SET);
244 for (;;) {
245 retval = read(fd, buf, 4096);
246 if (retval < 0) {
247 die(FSCK_ERROR, 1, "read failed: %s", filename);
248 }
249 else if (retval == 0) {
250 break;
251 }
252 if (length == 0) {
253 ((struct cramfs_super *) buf)->fsid.crc = crc32(0L, Z_NULL, 0);
254 }
255 length += retval;
256 if (length > (super.size-start)) {
257 crc = crc32(crc, buf, retval - (length - (super.size-start)));
258 break;
259 }
260 crc = crc32(crc, buf, retval);
261 }
262 free(buf);
263 }
264
265 if (crc != super.fsid.crc) {
266 die(FSCK_UNCORRECTED, 0, "crc error");
267 }
268}
269
270#ifdef INCLUDE_FS_TESTS
271static void print_node(char type, struct cramfs_inode *i, char *name)
272{
273 char info[10];
274
275 if (S_ISCHR(i->mode) || (S_ISBLK(i->mode))) {
276 /* major/minor numbers can be as high as 2^12 or 4096 */
277 snprintf(info, 10, "%4d,%4d", major(i->size), minor(i->size));
278 }
279 else {
280 /* size be as high as 2^24 or 16777216 */
281 snprintf(info, 10, "%9d", i->size);
282 }
283
284 printf("%c %04o %s %5d:%-3d %s\n",
285 type, i->mode & ~S_IFMT, info, i->uid, i->gid, name);
286}
287
288/*
289 * Create a fake "blocked" access
290 */
291static void *romfs_read(unsigned long offset)
292{
293 unsigned int block = offset >> ROMBUFFER_BITS;
294 if (block != read_buffer_block) {
295 read_buffer_block = block;
296 lseek(fd, block << ROMBUFFER_BITS, SEEK_SET);
297 read(fd, read_buffer, ROMBUFFERSIZE * 2);
298 }
299 return read_buffer + (offset & ROMBUFFERMASK);
300}
301
302static struct cramfs_inode *cramfs_iget(struct cramfs_inode * i)
303{
304 struct cramfs_inode *inode = malloc(sizeof(struct cramfs_inode));
305
306 if (!inode) {
307 die(FSCK_ERROR, 1, "malloc failed");
308 }
309 *inode = *i;
310 return inode;
311}
312
313static struct cramfs_inode *iget(unsigned int ino)
314{
315 return cramfs_iget(romfs_read(ino));
316}
317
318static void iput(struct cramfs_inode *inode)
319{
320 free(inode);
321}
322
323/*
324 * Return the offset of the root directory
325 */
326static struct cramfs_inode *read_super(void)
327{
328 unsigned long offset = super.root.offset << 2;
329
330 if (!S_ISDIR(super.root.mode))
331 die(FSCK_UNCORRECTED, 0, "root inode is not directory");
332 if (!(super.flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) &&
333 ((offset != sizeof(struct cramfs_super)) &&
334 (offset != PAD_SIZE + sizeof(struct cramfs_super))))
335 {
336 die(FSCK_UNCORRECTED, 0, "bad root offset (%lu)", offset);
337 }
338 return cramfs_iget(&super.root);
339}
340
341static int uncompress_block(void *src, int len)
342{
343 int err;
344
345 stream.next_in = src;
346 stream.avail_in = len;
347
348 stream.next_out = (unsigned char *) outbuffer;
349 stream.avail_out = PAGE_CACHE_SIZE*2;
350
351 inflateReset(&stream);
352
353 if (len > PAGE_CACHE_SIZE*2) {
354 die(FSCK_UNCORRECTED, 0, "data block too large");
355 }
356 err = inflate(&stream, Z_FINISH);
357 if (err != Z_STREAM_END) {
358 die(FSCK_UNCORRECTED, 0, "decompression error %p(%d): %s",
359 zError(err), src, len);
360 }
361 return stream.total_out;
362}
363
364static void do_uncompress(char *path, int fd, unsigned long offset, unsigned long size)
365{
366 unsigned long curr = offset + 4 * ((size + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE);
367
368 do {
369 unsigned long out = PAGE_CACHE_SIZE;
370 unsigned long next = *(u32 *) romfs_read(offset);
371
372 if (next > end_data) {
373 end_data = next;
374 }
375
376 offset += 4;
377 if (curr == next) {
378 if (opt_verbose > 1) {
379 printf(" hole at %ld (%d)\n", curr, PAGE_CACHE_SIZE);
380 }
381 if (size < PAGE_CACHE_SIZE)
382 out = size;
383 memset(outbuffer, 0x00, out);
384 }
385 else {
386 if (opt_verbose > 1) {
387 printf(" uncompressing block at %ld to %ld (%ld)\n", curr, next, next - curr);
388 }
389 out = uncompress_block(romfs_read(curr), next - curr);
390 }
391 if (size >= PAGE_CACHE_SIZE) {
392 if (out != PAGE_CACHE_SIZE) {
393 die(FSCK_UNCORRECTED, 0, "non-block (%ld) bytes", out);
394 }
395 } else {
396 if (out != size) {
397 die(FSCK_UNCORRECTED, 0, "non-size (%ld vs %ld) bytes", out, size);
398 }
399 }
400 size -= out;
401 if (opt_extract) {
402 if (write(fd, outbuffer, out) < 0) {
403 die(FSCK_ERROR, 1, "write failed: %s", path);
404 }
405 }
406 curr = next;
407 } while (size);
408}
409
410static void change_file_status(char *path, struct cramfs_inode *i)
411{
412 struct utimbuf epoch = { 0, 0 };
413
414 if (euid == 0) {
415 if (lchown(path, i->uid, i->gid) < 0) {
416 die(FSCK_ERROR, 1, "lchown failed: %s", path);
417 }
418 if (S_ISLNK(i->mode))
419 return;
420 if ((S_ISUID | S_ISGID) & i->mode) {
421 if (chmod(path, i->mode) < 0) {
422 die(FSCK_ERROR, 1, "chown failed: %s", path);
423 }
424 }
425 }
426 if (S_ISLNK(i->mode))
427 return;
428 if (utime(path, &epoch) < 0) {
429 die(FSCK_ERROR, 1, "utime failed: %s", path);
430 }
431}
432
433static void do_directory(char *path, struct cramfs_inode *i)
434{
435 int pathlen = strlen(path);
436 int count = i->size;
437 unsigned long offset = i->offset << 2;
438 char *newpath = malloc(pathlen + 256);
439
440 if (!newpath) {
441 die(FSCK_ERROR, 1, "malloc failed");
442 }
443 if (offset == 0 && count != 0) {
444 die(FSCK_UNCORRECTED, 0, "directory inode has zero offset and non-zero size: %s", path);
445 }
446 if (offset != 0 && offset < start_dir) {
447 start_dir = offset;
448 }
449 /* TODO: Do we need to check end_dir for empty case? */
450 memcpy(newpath, path, pathlen);
451 newpath[pathlen] = '/';
452 pathlen++;
453 if (opt_verbose) {
454 print_node('d', i, path);
455 }
456 if (opt_extract) {
457 if (mkdir(path, i->mode) < 0) {
458 die(FSCK_ERROR, 1, "mkdir failed: %s", path);
459 }
460 change_file_status(path, i);
461 }
462 while (count > 0) {
463 struct cramfs_inode *child = iget(offset);
464 int size;
465 int newlen = child->namelen << 2;
466
467 size = sizeof(struct cramfs_inode) + newlen;
468 count -= size;
469
470 offset += sizeof(struct cramfs_inode);
471
472 memcpy(newpath + pathlen, romfs_read(offset), newlen);
473 newpath[pathlen + newlen] = 0;
474 if (newlen == 0) {
475 die(FSCK_UNCORRECTED, 0, "filename length is zero");
476 }
477 if ((pathlen + newlen) - strlen(newpath) > 3) {
478 die(FSCK_UNCORRECTED, 0, "bad filename length");
479 }
480 expand_fs(newpath, child);
481
482 offset += newlen;
483
484 if (offset <= start_dir) {
485 die(FSCK_UNCORRECTED, 0, "bad inode offset");
486 }
487 if (offset > end_dir) {
488 end_dir = offset;
489 }
490 iput(child); /* free(child) */
491 }
492 free(newpath);
493}
494
495static void do_file(char *path, struct cramfs_inode *i)
496{
497 unsigned long offset = i->offset << 2;
498 int fd = 0;
499
500 if (offset == 0 && i->size != 0) {
501 die(FSCK_UNCORRECTED, 0, "file inode has zero offset and non-zero size");
502 }
503 if (i->size == 0 && offset != 0) {
504 die(FSCK_UNCORRECTED, 0, "file inode has zero size and non-zero offset");
505 }
506 if (offset != 0 && offset < start_data) {
507 start_data = offset;
508 }
509 if (opt_verbose) {
510 print_node('f', i, path);
511 }
512 if (opt_extract) {
513 fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, i->mode);
514 if (fd < 0) {
515 die(FSCK_ERROR, 1, "open failed: %s", path);
516 }
517 }
518 if (i->size) {
519 do_uncompress(path, fd, offset, i->size);
520 }
521 if (opt_extract) {
522 close(fd);
523 change_file_status(path, i);
524 }
525}
526
527static void do_symlink(char *path, struct cramfs_inode *i)
528{
529 unsigned long offset = i->offset << 2;
530 unsigned long curr = offset + 4;
531 unsigned long next = *(u32 *) romfs_read(offset);
532 unsigned long size;
533
534 if (offset == 0) {
535 die(FSCK_UNCORRECTED, 0, "symbolic link has zero offset");
536 }
537 if (i->size == 0) {
538 die(FSCK_UNCORRECTED, 0, "symbolic link has zero size");
539 }
540
541 if (offset < start_data) {
542 start_data = offset;
543 }
544 if (next > end_data) {
545 end_data = next;
546 }
547
548 size = uncompress_block(romfs_read(curr), next - curr);
549 if (size != i->size) {
550 die(FSCK_UNCORRECTED, 0, "size error in symlink: %s", path);
551 }
552 outbuffer[size] = 0;
553 if (opt_verbose) {
554 char *str;
555
556 asprintf(&str, "%s -> %s", path, outbuffer);
557 print_node('l', i, str);
558 if (opt_verbose > 1) {
559 printf(" uncompressing block at %ld to %ld (%ld)\n", curr, next, next - curr);
560 }
561 free(str);
562 }
563 if (opt_extract) {
564 if (symlink(outbuffer, path) < 0) {
565 die(FSCK_ERROR, 1, "symlink failed: %s", path);
566 }
567 change_file_status(path, i);
568 }
569}
570
571static void do_special_inode(char *path, struct cramfs_inode *i)
572{
573 dev_t devtype = 0;
574 char type;
575
576 if (i->offset) { /* no need to shift offset */
577 die(FSCK_UNCORRECTED, 0, "special file has non-zero offset: %s", path);
578 }
579 if (S_ISCHR(i->mode)) {
580 devtype = i->size;
581 type = 'c';
582 }
583 else if (S_ISBLK(i->mode)) {
584 devtype = i->size;
585 type = 'b';
586 }
587 else if (S_ISFIFO(i->mode)) {
588 if (i->size != 0) {
589 die(FSCK_UNCORRECTED, 0, "fifo has non-zero size: %s", path);
590 }
591 type = 'p';
592 }
593 else if (S_ISSOCK(i->mode)) {
594 if (i->size != 0) {
595 die(FSCK_UNCORRECTED, 0, "socket has non-zero size: %s", path);
596 }
597 type = 's';
598 }
599 else {
600 die(FSCK_UNCORRECTED, 0, "bogus mode: %s (%o)", path, i->mode);
601 return; /* not reached */
602 }
603
604 if (opt_verbose) {
605 print_node(type, i, path);
606 }
607
608 if (opt_extract) {
609 if (mknod(path, i->mode, devtype) < 0) {
610 die(FSCK_ERROR, 1, "mknod failed: %s", path);
611 }
612 change_file_status(path, i);
613 }
614}
615
616static void expand_fs(char *path, struct cramfs_inode *inode)
617{
618 if (S_ISDIR(inode->mode)) {
619 do_directory(path, inode);
620 }
621 else if (S_ISREG(inode->mode)) {
622 do_file(path, inode);
623 }
624 else if (S_ISLNK(inode->mode)) {
625 do_symlink(path, inode);
626 }
627 else {
628 do_special_inode(path, inode);
629 }
630}
631
632static void test_fs(int start)
633{
634 struct cramfs_inode *root;
635
636 root = read_super();
637 umask(0);
638 euid = geteuid();
639 stream.next_in = NULL;
640 stream.avail_in = 0;
641 inflateInit(&stream);
642 expand_fs(extract_dir, root);
643 inflateEnd(&stream);
644 if (start_data != ~0UL) {
645 if (start_data < (sizeof(struct cramfs_super) + start)) {
646 die(FSCK_UNCORRECTED, 0, "directory data start (%ld) < sizeof(struct cramfs_super) + start (%ld)", start_data, sizeof(struct cramfs_super) + start);
647 }
648 if (end_dir != start_data) {
649 die(FSCK_UNCORRECTED, 0, "directory data end (%ld) != file data start (%ld)", end_dir, start_data);
650 }
651 }
652 if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) {
653 if (end_data > super.size) {
654 die(FSCK_UNCORRECTED, 0, "invalid file data offset");
655 }
656 }
657 iput(root); /* free(root) */
658}
659#endif /* INCLUDE_FS_TESTS */
660
661int main(int argc, char **argv)
662{
663 int c; /* for getopt */
664 int start = 0;
665 size_t length;
666
667 page_size = sysconf(_SC_PAGESIZE);
668
669 if (argc)
670 progname = argv[0];
671
672 outbuffer = malloc(page_size * 2);
673 if (!outbuffer)
674 die(FSCK_ERROR, 1, "failed to allocate outbuffer");
675
676 /* command line options */
677 while ((c = getopt(argc, argv, "hx:v")) != EOF) {
678 switch (c) {
679 case 'h':
680 usage(FSCK_OK);
681 case 'x':
682#ifdef INCLUDE_FS_TESTS
683 opt_extract = 1;
684 extract_dir = optarg;
685 break;
686#else /* not INCLUDE_FS_TESTS */
687 die(FSCK_USAGE, 0, "compiled without -x support");
688#endif /* not INCLUDE_FS_TESTS */
689 case 'v':
690 opt_verbose++;
691 break;
692 }
693 }
694
695 if ((argc - optind) != 1)
696 usage(FSCK_USAGE);
697 filename = argv[optind];
698
699 test_super(&start, &length);
700 test_crc(start);
701#ifdef INCLUDE_FS_TESTS
702 test_fs(start);
703#endif /* INCLUDE_FS_TESTS */
704
705 if (opt_verbose) {
706 printf("%s: OK\n", filename);
707 }
708
709 exit(FSCK_OK);
710}
711
712/*
713 * Local variables:
714 * c-file-style: "linux"
715 * End:
716 */
diff --git a/utils/ypr0tools/cramfs-1.1/linux/cramfs_fs.h b/utils/ypr0tools/cramfs-1.1/linux/cramfs_fs.h
new file mode 100644
index 0000000000..a8948f34b7
--- /dev/null
+++ b/utils/ypr0tools/cramfs-1.1/linux/cramfs_fs.h
@@ -0,0 +1,98 @@
1#ifndef __CRAMFS_H
2#define __CRAMFS_H
3
4#ifndef __KERNEL__
5
6typedef unsigned char u8;
7typedef unsigned short u16;
8typedef unsigned int u32;
9
10#endif
11
12#define CRAMFS_MAGIC 0x28cd3d45 /* some random number */
13#define CRAMFS_SIGNATURE "Compressed ROMFS"
14
15/*
16 * Width of various bitfields in struct cramfs_inode.
17 * Primarily used to generate warnings in mkcramfs.
18 */
19#define CRAMFS_MODE_WIDTH 16
20#define CRAMFS_UID_WIDTH 16
21#define CRAMFS_SIZE_WIDTH 24
22#define CRAMFS_GID_WIDTH 8
23#define CRAMFS_NAMELEN_WIDTH 6
24#define CRAMFS_OFFSET_WIDTH 26
25
26/*
27 * Since inode.namelen is a unsigned 6-bit number, the maximum cramfs
28 * path length is 63 << 2 = 252.
29 */
30#define CRAMFS_MAXPATHLEN (((1 << CRAMFS_NAMELEN_WIDTH) - 1) << 2)
31
32/*
33 * Reasonably terse representation of the inode data.
34 */
35struct cramfs_inode {
36 u32 mode:CRAMFS_MODE_WIDTH, uid:CRAMFS_UID_WIDTH;
37 /* SIZE for device files is i_rdev */
38 u32 size:CRAMFS_SIZE_WIDTH, gid:CRAMFS_GID_WIDTH;
39 /* NAMELEN is the length of the file name, divided by 4 and
40 rounded up. (cramfs doesn't support hard links.) */
41 /* OFFSET: For symlinks and non-empty regular files, this
42 contains the offset (divided by 4) of the file data in
43 compressed form (starting with an array of block pointers;
44 see README). For non-empty directories it is the offset
45 (divided by 4) of the inode of the first file in that
46 directory. For anything else, offset is zero. */
47 u32 namelen:CRAMFS_NAMELEN_WIDTH, offset:CRAMFS_OFFSET_WIDTH;
48};
49
50struct cramfs_info {
51 u32 crc;
52 u32 edition;
53 u32 blocks;
54 u32 files;
55};
56
57/*
58 * Superblock information at the beginning of the FS.
59 */
60struct cramfs_super {
61 u32 magic; /* 0x28cd3d45 - random number */
62 u32 size; /* length in bytes */
63 u32 flags; /* feature flags */
64 u32 future; /* reserved for future use */
65 u8 signature[16]; /* "Compressed ROMFS" */
66 struct cramfs_info fsid; /* unique filesystem info */
67 u8 name[16]; /* user-defined name */
68 struct cramfs_inode root; /* root inode data */
69};
70
71/*
72 * Feature flags
73 *
74 * 0x00000000 - 0x000000ff: features that work for all past kernels
75 * 0x00000100 - 0xffffffff: features that don't work for past kernels
76 */
77#define CRAMFS_FLAG_FSID_VERSION_2 0x00000001 /* fsid version #2 */
78#define CRAMFS_FLAG_SORTED_DIRS 0x00000002 /* sorted dirs */
79#define CRAMFS_FLAG_HOLES 0x00000100 /* support for holes */
80#define CRAMFS_FLAG_WRONG_SIGNATURE 0x00000200 /* reserved */
81#define CRAMFS_FLAG_SHIFTED_ROOT_OFFSET 0x00000400 /* shifted root fs */
82
83/*
84 * Valid values in super.flags. Currently we refuse to mount
85 * if (flags & ~CRAMFS_SUPPORTED_FLAGS). Maybe that should be
86 * changed to test super.future instead.
87 */
88#define CRAMFS_SUPPORTED_FLAGS ( 0x000000ff \
89 | CRAMFS_FLAG_HOLES \
90 | CRAMFS_FLAG_WRONG_SIGNATURE \
91 | CRAMFS_FLAG_SHIFTED_ROOT_OFFSET )
92
93/* Uncompression interfaces to the underlying zlib */
94int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen);
95int cramfs_uncompress_init(void);
96int cramfs_uncompress_exit(void);
97
98#endif
diff --git a/utils/ypr0tools/cramfs-1.1/linux/cramfs_fs_sb.h b/utils/ypr0tools/cramfs-1.1/linux/cramfs_fs_sb.h
new file mode 100644
index 0000000000..afea368796
--- /dev/null
+++ b/utils/ypr0tools/cramfs-1.1/linux/cramfs_fs_sb.h
@@ -0,0 +1,15 @@
1#ifndef _CRAMFS_FS_SB
2#define _CRAMFS_FS_SB
3
4/*
5 * cramfs super-block data in memory
6 */
7struct cramfs_sb_info {
8 unsigned long magic;
9 unsigned long size;
10 unsigned long blocks;
11 unsigned long files;
12 unsigned long flags;
13};
14
15#endif
diff --git a/utils/ypr0tools/cramfs-1.1/mkcramfs.c b/utils/ypr0tools/cramfs-1.1/mkcramfs.c
new file mode 100644
index 0000000000..2eccb733be
--- /dev/null
+++ b/utils/ypr0tools/cramfs-1.1/mkcramfs.c
@@ -0,0 +1,889 @@
1/*
2 * mkcramfs - make a cramfs file system
3 *
4 * Copyright (C) 1999-2002 Transmeta Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * If you change the disk format of cramfs, please update fs/cramfs/README.
23 */
24
25#include <sys/types.h>
26#include <stdio.h>
27#include <sys/stat.h>
28#include <unistd.h>
29#include <sys/mman.h>
30#include <fcntl.h>
31#include <dirent.h>
32#include <stdlib.h>
33#include <errno.h>
34#include <string.h>
35#include <stdarg.h>
36#include <linux/cramfs_fs.h>
37#include <zlib.h>
38#include <stdint.h>
39
40/* Exit codes used by mkfs-type programs */
41#define MKFS_OK 0 /* No errors */
42#define MKFS_ERROR 8 /* Operational error */
43#define MKFS_USAGE 16 /* Usage or syntax error */
44
45/* The kernel only supports PAD_SIZE of 0 and 512. */
46#define PAD_SIZE 512
47
48/*
49 * The longest filename component to allow for in the input directory tree.
50 * ext2fs (and many others) allow up to 255 bytes. A couple of filesystems
51 * allow longer (e.g. smbfs 1024), but there isn't much use in supporting
52 * >255-byte names in the input directory tree given that such names get
53 * truncated to CRAMFS_MAXPATHLEN (252 bytes) when written to cramfs.
54 *
55 * Old versions of mkcramfs generated corrupted filesystems if any input
56 * filenames exceeded CRAMFS_MAXPATHLEN (252 bytes), however old
57 * versions of cramfsck seem to have been able to detect the corruption.
58 */
59#define MAX_INPUT_NAMELEN 255
60
61/*
62 * Maximum size fs you can create is roughly 256MB. (The last file's
63 * data must begin within 256MB boundary but can extend beyond that.)
64 *
65 * Note that if you want it to fit in a ROM then you're limited to what the
66 * hardware and kernel can support.
67 */
68#define MAXFSLEN ((((1 << CRAMFS_OFFSET_WIDTH) - 1) << 2) /* offset */ \
69 + (1 << CRAMFS_SIZE_WIDTH) - 1 /* filesize */ \
70 + (1 << CRAMFS_SIZE_WIDTH) * 4 / blksize /* block pointers */ )
71
72static const char *progname = "mkcramfs";
73static unsigned int blksize;
74static long total_blocks = 0, total_nodes = 1; /* pre-count the root node */
75static int image_length = 0;
76
77/*
78 * If opt_holes is set, then mkcramfs can create explicit holes in the
79 * data, which saves 26 bytes per hole (which is a lot smaller a
80 * saving than most most filesystems).
81 *
82 * Note that kernels up to at least 2.3.39 don't support cramfs holes,
83 * which is why this is turned off by default.
84 *
85 * If opt_verbose is 1, be verbose. If it is higher, be even more verbose.
86 */
87static u32 opt_edition = 0;
88static int opt_errors = 0;
89static int opt_holes = 0;
90static int opt_pad = 0;
91static int opt_verbose = 0;
92static char *opt_image = NULL;
93static char *opt_name = NULL;
94
95static int warn_dev, warn_gid, warn_namelen, warn_skip, warn_size, warn_uid;
96
97/* In-core version of inode / directory entry. */
98struct entry {
99 /* stats */
100 unsigned char *name;
101 unsigned int mode, size, uid, gid;
102
103 /* these are only used for non-empty files */
104 char *path; /* always null except non-empty files */
105 int fd; /* temporarily open files while mmapped */
106
107 /* FS data */
108 void *uncompressed;
109 /* points to other identical file */
110 struct entry *same;
111 unsigned int offset; /* pointer to compressed data in archive */
112 unsigned int dir_offset; /* Where in the archive is the directory entry? */
113
114 /* organization */
115 struct entry *child; /* null for non-directories and empty directories */
116 struct entry *next;
117};
118
119/* Input status of 0 to print help and exit without an error. */
120static void usage(int status)
121{
122 FILE *stream = status ? stderr : stdout;
123
124 fprintf(stream, "usage: %s [-h] [-b blksize] [-e edition] [-i file] [-n name] dirname outfile\n"
125 " -h print this help\n"
126 " -E make all warnings errors (non-zero exit status)\n"
127 " -b blksize blocksize to use\n"
128 " -e edition set edition number (part of fsid)\n"
129 " -i file insert a file image into the filesystem (requires >= 2.4.0)\n"
130 " -n name set name of cramfs filesystem\n"
131 " -p pad by %d bytes for boot code\n"
132 " -s sort directory entries (old option, ignored)\n"
133 " -v be more verbose\n"
134 " -z make explicit holes (requires >= 2.3.39)\n"
135 " dirname root of the directory tree to be compressed\n"
136 " outfile output file\n", progname, PAD_SIZE);
137
138 exit(status);
139}
140
141static void die(int status, int syserr, const char *fmt, ...)
142{
143 va_list arg_ptr;
144 int save = errno;
145
146 fflush(0);
147 va_start(arg_ptr, fmt);
148 fprintf(stderr, "%s: ", progname);
149 vfprintf(stderr, fmt, arg_ptr);
150 if (syserr) {
151 fprintf(stderr, ": %s", strerror(save));
152 }
153 fprintf(stderr, "\n");
154 va_end(arg_ptr);
155 exit(status);
156}
157
158static void map_entry(struct entry *entry)
159{
160 if (entry->path) {
161 entry->fd = open(entry->path, O_RDONLY);
162 if (entry->fd < 0) {
163 die(MKFS_ERROR, 1, "open failed: %s", entry->path);
164 }
165 entry->uncompressed = mmap(NULL, entry->size, PROT_READ, MAP_PRIVATE, entry->fd, 0);
166 if (entry->uncompressed == MAP_FAILED) {
167 die(MKFS_ERROR, 1, "mmap failed: %s", entry->path);
168 }
169 }
170}
171
172static void unmap_entry(struct entry *entry)
173{
174 if (entry->path) {
175 if (munmap(entry->uncompressed, entry->size) < 0) {
176 die(MKFS_ERROR, 1, "munmap failed: %s", entry->path);
177 }
178 close(entry->fd);
179 }
180}
181
182static int find_identical_file(struct entry *orig, struct entry *newfile)
183{
184 if (orig == newfile)
185 return 1;
186 if (!orig)
187 return 0;
188 if (orig->size == newfile->size && (orig->path || orig->uncompressed))
189 {
190 map_entry(orig);
191 map_entry(newfile);
192 if (!memcmp(orig->uncompressed, newfile->uncompressed, orig->size))
193 {
194 newfile->same = orig;
195 unmap_entry(newfile);
196 unmap_entry(orig);
197 return 1;
198 }
199 unmap_entry(newfile);
200 unmap_entry(orig);
201 }
202 return (find_identical_file(orig->child, newfile) ||
203 find_identical_file(orig->next, newfile));
204}
205
206static void eliminate_doubles(struct entry *root, struct entry *orig) {
207 if (orig) {
208 if (orig->size && (orig->path || orig->uncompressed))
209 find_identical_file(root, orig);
210 eliminate_doubles(root, orig->child);
211 eliminate_doubles(root, orig->next);
212 }
213}
214
215/*
216 * We define our own sorting function instead of using alphasort which
217 * uses strcoll and changes ordering based on locale information.
218 */
219static int cramsort (const void *a, const void *b)
220{
221 return strcmp ((*(const struct dirent **) a)->d_name,
222 (*(const struct dirent **) b)->d_name);
223}
224
225static unsigned int parse_directory(struct entry *root_entry, const char *name, struct entry **prev, loff_t *fslen_ub)
226{
227 struct dirent **dirlist;
228 int totalsize = 0, dircount, dirindex;
229 char *path, *endpath;
230 size_t len = strlen(name);
231
232 /* Set up the path. */
233 /* TODO: Reuse the parent's buffer to save memcpy'ing and duplication. */
234 path = malloc(len + 1 + MAX_INPUT_NAMELEN + 1);
235 if (!path) {
236 die(MKFS_ERROR, 1, "malloc failed");
237 }
238 memcpy(path, name, len);
239 endpath = path + len;
240 *endpath = '/';
241 endpath++;
242
243 /* read in the directory and sort */
244 dircount = scandir(name, &dirlist, 0, cramsort);
245
246 if (dircount < 0) {
247 die(MKFS_ERROR, 1, "scandir failed: %s", name);
248 }
249
250 /* process directory */
251 for (dirindex = 0; dirindex < dircount; dirindex++) {
252 struct dirent *dirent;
253 struct entry *entry;
254 struct stat st;
255 int size;
256 size_t namelen;
257
258 dirent = dirlist[dirindex];
259
260 /* Ignore "." and ".." - we won't be adding them to the archive */
261 if (dirent->d_name[0] == '.') {
262 if (dirent->d_name[1] == '\0')
263 continue;
264 if (dirent->d_name[1] == '.') {
265 if (dirent->d_name[2] == '\0')
266 continue;
267 }
268 }
269 namelen = strlen(dirent->d_name);
270 if (namelen > MAX_INPUT_NAMELEN) {
271 die(MKFS_ERROR, 0,
272 "very long (%u bytes) filename found: %s\n"
273 "please increase MAX_INPUT_NAMELEN in mkcramfs.c and recompile",
274 namelen, dirent->d_name);
275 }
276 memcpy(endpath, dirent->d_name, namelen + 1);
277
278 if (lstat(path, &st) < 0) {
279 warn_skip = 1;
280 continue;
281 }
282 entry = calloc(1, sizeof(struct entry));
283 if (!entry) {
284 die(MKFS_ERROR, 1, "calloc failed");
285 }
286 entry->name = strdup(dirent->d_name);
287 if (!entry->name) {
288 die(MKFS_ERROR, 1, "strdup failed");
289 }
290 /* truncate multi-byte UTF-8 filenames on character boundary */
291 if (namelen > CRAMFS_MAXPATHLEN) {
292 namelen = CRAMFS_MAXPATHLEN;
293 warn_namelen = 1;
294 /* the first lost byte must not be a trail byte */
295 while ((entry->name[namelen] & 0xc0) == 0x80) {
296 namelen--;
297 /* are we reasonably certain it was UTF-8 ? */
298 if (entry->name[namelen] < 0x80 || !namelen) {
299 die(MKFS_ERROR, 0, "cannot truncate filenames not encoded in UTF-8");
300 }
301 }
302 entry->name[namelen] = '\0';
303 }
304 entry->mode = st.st_mode;
305 entry->size = st.st_size;
306 entry->uid = st.st_uid;
307 if (entry->uid >= 1 << CRAMFS_UID_WIDTH)
308 warn_uid = 1;
309 entry->gid = st.st_gid;
310 if (entry->gid >= 1 << CRAMFS_GID_WIDTH)
311 /* TODO: We ought to replace with a default
312 gid instead of truncating; otherwise there
313 are security problems. Maybe mode should
314 be &= ~070. Same goes for uid once Linux
315 supports >16-bit uids. */
316 warn_gid = 1;
317 size = sizeof(struct cramfs_inode) + ((namelen + 3) & ~3);
318 *fslen_ub += size;
319 if (S_ISDIR(st.st_mode)) {
320 entry->size = parse_directory(root_entry, path, &entry->child, fslen_ub);
321 } else if (S_ISREG(st.st_mode)) {
322 if (entry->size) {
323 if (access(path, R_OK) < 0) {
324 warn_skip = 1;
325 continue;
326 }
327 entry->path = strdup(path);
328 if (!entry->path) {
329 die(MKFS_ERROR, 1, "strdup failed");
330 }
331 if ((entry->size >= 1 << CRAMFS_SIZE_WIDTH)) {
332 warn_size = 1;
333 entry->size = (1 << CRAMFS_SIZE_WIDTH) - 1;
334 }
335 }
336 } else if (S_ISLNK(st.st_mode)) {
337 int len;
338 entry->uncompressed = malloc(entry->size);
339 if (!entry->uncompressed) {
340 die(MKFS_ERROR, 1, "malloc failed");
341 }
342 len = readlink(path, entry->uncompressed, entry->size);
343 if (len < 0) {
344 warn_skip = 1;
345 continue;
346 }
347 entry->size = len;
348 } else if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
349 /* maybe we should skip sockets */
350 entry->size = 0;
351 } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
352 entry->size = st.st_rdev;
353 if (entry->size & -(1<<CRAMFS_SIZE_WIDTH))
354 warn_dev = 1;
355 } else {
356 die(MKFS_ERROR, 0, "bogus file type: %s", entry->name);
357 }
358
359 if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
360 int blocks = ((entry->size - 1) / blksize + 1);
361
362 /* block pointers & data expansion allowance + data */
363 if (entry->size)
364 *fslen_ub += (4+26)*blocks + entry->size + 3;
365 }
366
367 /* Link it into the list */
368 *prev = entry;
369 prev = &entry->next;
370 totalsize += size;
371 }
372 free(path);
373 free(dirlist); /* allocated by scandir() with malloc() */
374 return totalsize;
375}
376
377/* Returns sizeof(struct cramfs_super), which includes the root inode. */
378static unsigned int write_superblock(struct entry *root, char *base, int size)
379{
380 struct cramfs_super *super = (struct cramfs_super *) base;
381 unsigned int offset = sizeof(struct cramfs_super) + image_length;
382
383 offset += opt_pad; /* 0 if no padding */
384
385 super->magic = CRAMFS_MAGIC;
386 super->flags = CRAMFS_FLAG_FSID_VERSION_2 | CRAMFS_FLAG_SORTED_DIRS;
387 if (opt_holes)
388 super->flags |= CRAMFS_FLAG_HOLES;
389 if (image_length > 0)
390 super->flags |= CRAMFS_FLAG_SHIFTED_ROOT_OFFSET;
391 super->size = size;
392 memcpy(super->signature, CRAMFS_SIGNATURE, sizeof(super->signature));
393
394 super->fsid.crc = crc32(0L, Z_NULL, 0);
395 super->fsid.edition = opt_edition;
396 super->fsid.blocks = total_blocks;
397 super->fsid.files = total_nodes;
398
399 memset(super->name, 0x00, sizeof(super->name));
400 if (opt_name)
401 strncpy(super->name, opt_name, sizeof(super->name));
402 else
403 strncpy(super->name, "Compressed", sizeof(super->name));
404
405 super->root.mode = root->mode;
406 super->root.uid = root->uid;
407 super->root.gid = root->gid;
408 super->root.size = root->size;
409 super->root.offset = offset >> 2;
410
411 return offset;
412}
413
414static void set_data_offset(struct entry *entry, char *base, unsigned long offset)
415{
416 struct cramfs_inode *inode = (struct cramfs_inode *) (base + entry->dir_offset);
417
418 if ((offset & 3) != 0) {
419 die(MKFS_ERROR, 0, "illegal offset of %lu bytes", offset);
420 }
421 if (offset >= (1 << (2 + CRAMFS_OFFSET_WIDTH))) {
422 die(MKFS_ERROR, 0, "filesystem too big");
423 }
424 inode->offset = (offset >> 2);
425}
426
427/*
428 * TODO: Does this work for chars >= 0x80? Most filesystems use UTF-8
429 * encoding for filenames, whereas the console is a single-byte
430 * character set like iso-latin-1.
431 */
432static void print_node(struct entry *e)
433{
434 char info[10];
435 char type = '?';
436
437 if (S_ISREG(e->mode)) type = 'f';
438 else if (S_ISDIR(e->mode)) type = 'd';
439 else if (S_ISLNK(e->mode)) type = 'l';
440 else if (S_ISCHR(e->mode)) type = 'c';
441 else if (S_ISBLK(e->mode)) type = 'b';
442 else if (S_ISFIFO(e->mode)) type = 'p';
443 else if (S_ISSOCK(e->mode)) type = 's';
444
445 if (S_ISCHR(e->mode) || (S_ISBLK(e->mode))) {
446 /* major/minor numbers can be as high as 2^12 or 4096 */
447 snprintf(info, 10, "%4d,%4d", major(e->size), minor(e->size));
448 }
449 else {
450 /* size be as high as 2^24 or 16777216 */
451 snprintf(info, 10, "%9d", e->size);
452 }
453
454 printf("%c %04o %s %5d:%-3d %s\n",
455 type, e->mode & ~S_IFMT, info, e->uid, e->gid, e->name);
456}
457
458/*
459 * We do a width-first printout of the directory
460 * entries, using a stack to remember the directories
461 * we've seen.
462 */
463static unsigned int write_directory_structure(struct entry *entry, char *base, unsigned int offset)
464{
465 int stack_entries = 0;
466 int stack_size = 64;
467 struct entry **entry_stack;
468
469 entry_stack = malloc(stack_size * sizeof(struct entry *));
470 if (!entry_stack) {
471 die(MKFS_ERROR, 1, "malloc failed");
472 }
473
474 if (opt_verbose) {
475 printf("root:\n");
476 }
477
478 for (;;) {
479 int dir_start = stack_entries;
480 while (entry) {
481 struct cramfs_inode *inode = (struct cramfs_inode *) (base + offset);
482 size_t len = strlen(entry->name);
483
484 entry->dir_offset = offset;
485
486 inode->mode = entry->mode;
487 inode->uid = entry->uid;
488 inode->gid = entry->gid;
489 inode->size = entry->size;
490 inode->offset = 0;
491 /* Non-empty directories, regfiles and symlinks will
492 write over inode->offset later. */
493
494 offset += sizeof(struct cramfs_inode);
495 total_nodes++; /* another node */
496 memcpy(base + offset, entry->name, len);
497 /* Pad up the name to a 4-byte boundary */
498 while (len & 3) {
499 *(base + offset + len) = '\0';
500 len++;
501 }
502 inode->namelen = len >> 2;
503 offset += len;
504
505 if (opt_verbose)
506 print_node(entry);
507
508 if (entry->child) {
509 if (stack_entries >= stack_size) {
510 stack_size *= 2;
511 entry_stack = realloc(entry_stack, stack_size * sizeof(struct entry *));
512 if (!entry_stack) {
513 die(MKFS_ERROR, 1, "realloc failed");
514 }
515 }
516 entry_stack[stack_entries] = entry;
517 stack_entries++;
518 }
519 entry = entry->next;
520 }
521
522 /*
523 * Reverse the order the stack entries pushed during
524 * this directory, for a small optimization of disk
525 * access in the created fs. This change makes things
526 * `ls -UR' order.
527 */
528 {
529 struct entry **lo = entry_stack + dir_start;
530 struct entry **hi = entry_stack + stack_entries;
531 struct entry *tmp;
532
533 while (lo < --hi) {
534 tmp = *lo;
535 *lo++ = *hi;
536 *hi = tmp;
537 }
538 }
539
540 /* Pop a subdirectory entry from the stack, and recurse. */
541 if (!stack_entries)
542 break;
543 stack_entries--;
544 entry = entry_stack[stack_entries];
545
546 set_data_offset(entry, base, offset);
547 if (opt_verbose) {
548 printf("%s:\n", entry->name);
549 }
550 entry = entry->child;
551 }
552 free(entry_stack);
553 return offset;
554}
555
556static int is_zero(char const *begin, unsigned len)
557{
558 /* Returns non-zero iff the first LEN bytes from BEGIN are all NULs. */
559 return (len-- == 0 ||
560 (begin[0] == '\0' &&
561 (len-- == 0 ||
562 (begin[1] == '\0' &&
563 (len-- == 0 ||
564 (begin[2] == '\0' &&
565 (len-- == 0 ||
566 (begin[3] == '\0' &&
567 memcmp(begin, begin + 4, len) == 0))))))));
568}
569
570/*
571 * One 4-byte pointer per block and then the actual blocked
572 * output. The first block does not need an offset pointer,
573 * as it will start immediately after the pointer block;
574 * so the i'th pointer points to the end of the i'th block
575 * (i.e. the start of the (i+1)'th block or past EOF).
576 *
577 * Note that size > 0, as a zero-sized file wouldn't ever
578 * have gotten here in the first place.
579 */
580static unsigned int do_compress(char *base, unsigned int offset, char const *name, char *uncompressed, unsigned int size)
581{
582 unsigned long original_size = size;
583 unsigned long original_offset = offset;
584 unsigned long new_size;
585 unsigned long blocks = (size - 1) / blksize + 1;
586 unsigned long curr = offset + 4 * blocks;
587 int change;
588
589 total_blocks += blocks;
590
591 do {
592 unsigned long len = 2 * blksize;
593 unsigned int input = size;
594 int err;
595
596 if (input > blksize)
597 input = blksize;
598 size -= input;
599 if (!(opt_holes && is_zero (uncompressed, input))) {
600 err = compress2(base + curr, &len, uncompressed, input, Z_BEST_COMPRESSION);
601 if (err != Z_OK) {
602 die(MKFS_ERROR, 0, "compression error: %s", zError(err));
603 }
604 curr += len;
605 }
606 uncompressed += input;
607
608 if (len > blksize*2) {
609 /* (I don't think this can happen with zlib.) */
610 die(MKFS_ERROR, 0, "AIEEE: block \"compressed\" to > 2*blocklength (%ld)", len);
611 }
612
613 *(u32 *) (base + offset) = curr;
614 offset += 4;
615 } while (size);
616
617 curr = (curr + 3) & ~3;
618 new_size = curr - original_offset;
619 /* TODO: Arguably, original_size in these 2 lines should be
620 st_blocks * 512. But if you say that then perhaps
621 administrative data should also be included in both. */
622 change = new_size - original_size;
623 if (opt_verbose > 1) {
624 printf("%6.2f%% (%+d bytes)\t%s\n",
625 (change * 100) / (double) original_size, change, name);
626 }
627
628 return curr;
629}
630
631
632/*
633 * Traverse the entry tree, writing data for every item that has
634 * non-null entry->path (i.e. every non-empty regfile) and non-null
635 * entry->uncompressed (i.e. every symlink).
636 */
637static unsigned int write_data(struct entry *entry, char *base, unsigned int offset)
638{
639 do {
640 if (entry->path || entry->uncompressed) {
641 if (entry->same) {
642 set_data_offset(entry, base, entry->same->offset);
643 entry->offset = entry->same->offset;
644 }
645 else {
646 set_data_offset(entry, base, offset);
647 entry->offset = offset;
648 map_entry(entry);
649 offset = do_compress(base, offset, entry->name, entry->uncompressed, entry->size);
650 unmap_entry(entry);
651 }
652 }
653 else if (entry->child)
654 offset = write_data(entry->child, base, offset);
655 entry=entry->next;
656 } while (entry);
657 return offset;
658}
659
660static unsigned int write_file(char *file, char *base, unsigned int offset)
661{
662 int fd;
663 char *buf;
664
665 fd = open(file, O_RDONLY);
666 if (fd < 0) {
667 die(MKFS_ERROR, 1, "open failed: %s", file);
668 }
669 buf = mmap(NULL, image_length, PROT_READ, MAP_PRIVATE, fd, 0);
670 if (buf == MAP_FAILED) {
671 die(MKFS_ERROR, 1, "mmap failed");
672 }
673 memcpy(base + offset, buf, image_length);
674 munmap(buf, image_length);
675 close (fd);
676 /* Pad up the image_length to a 4-byte boundary */
677 while (image_length & 3) {
678 *(base + offset + image_length) = '\0';
679 image_length++;
680 }
681 return (offset + image_length);
682}
683
684int main(int argc, char **argv)
685{
686 struct stat st; /* used twice... */
687 struct entry *root_entry;
688 char *rom_image;
689 ssize_t offset, written;
690 int fd;
691 /* initial guess (upper-bound) of required filesystem size */
692 loff_t fslen_ub = sizeof(struct cramfs_super);
693 char const *dirname, *outfile;
694 u32 crc;
695 int c; /* for getopt */
696 char *ep; /* for strtoul */
697
698 blksize = sysconf(_SC_PAGESIZE);
699 total_blocks = 0;
700
701 if (argc)
702 progname = argv[0];
703
704 /* command line options */
705 while ((c = getopt(argc, argv, "hEb:e:i:n:psvz")) != EOF) {
706 switch (c) {
707 case 'h':
708 usage(MKFS_OK);
709 case 'E':
710 opt_errors = 1;
711 break;
712 case 'b':
713 errno = 0;
714 blksize = strtoul(optarg, &ep, 10);
715 if (errno || optarg[0] == '\0' || *ep != '\0')
716 usage(MKFS_USAGE);
717 if (blksize < 512 || (blksize & (blksize - 1)))
718 die(MKFS_ERROR, 0, "invalid blocksize: %u", blksize);
719 break;
720 case 'e':
721 errno = 0;
722 opt_edition = strtoul(optarg, &ep, 10);
723 if (errno || optarg[0] == '\0' || *ep != '\0')
724 usage(MKFS_USAGE);
725 break;
726 case 'i':
727 opt_image = optarg;
728 if (lstat(opt_image, &st) < 0) {
729 die(MKFS_ERROR, 1, "lstat failed: %s", opt_image);
730 }
731 image_length = st.st_size; /* may be padded later */
732 fslen_ub += (image_length + 3); /* 3 is for padding */
733 break;
734 case 'n':
735 opt_name = optarg;
736 break;
737 case 'p':
738 opt_pad = PAD_SIZE;
739 fslen_ub += PAD_SIZE;
740 break;
741 case 's':
742 /* old option, ignored */
743 break;
744 case 'v':
745 opt_verbose++;
746 break;
747 case 'z':
748 opt_holes = 1;
749 break;
750 }
751 }
752
753 if ((argc - optind) != 2)
754 usage(MKFS_USAGE);
755 dirname = argv[optind];
756 outfile = argv[optind + 1];
757
758 if (stat(dirname, &st) < 0) {
759 die(MKFS_USAGE, 1, "stat failed: %s", dirname);
760 }
761 fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
762 if (fd < 0) {
763 die(MKFS_USAGE, 1, "open failed: %s", outfile);
764 }
765
766 root_entry = calloc(1, sizeof(struct entry));
767 if (!root_entry) {
768 die(MKFS_ERROR, 1, "calloc failed");
769 }
770 root_entry->mode = st.st_mode;
771 root_entry->uid = st.st_uid;
772 root_entry->gid = st.st_gid;
773
774 root_entry->size = parse_directory(root_entry, dirname, &root_entry->child, &fslen_ub);
775
776 /* always allocate a multiple of blksize bytes because that's
777 what we're going to write later on */
778 fslen_ub = ((fslen_ub - 1) | (blksize - 1)) + 1;
779
780 if (fslen_ub > MAXFSLEN) {
781 fprintf(stderr,
782 "warning: estimate of required size (upper bound) is %jdMB, but maximum image size is %uMB, we might die prematurely\n",
783 (intmax_t) (fslen_ub >> 20),
784 MAXFSLEN >> 20);
785 fslen_ub = MAXFSLEN;
786 }
787
788 /* find duplicate files. TODO: uses the most inefficient algorithm
789 possible. */
790 eliminate_doubles(root_entry, root_entry);
791
792 /* TODO: Why do we use a private/anonymous mapping here
793 followed by a write below, instead of just a shared mapping
794 and a couple of ftruncate calls? Is it just to save us
795 having to deal with removing the file afterwards? If we
796 really need this huge anonymous mapping, we ought to mmap
797 in smaller chunks, so that the user doesn't need nn MB of
798 RAM free. If the reason is to be able to write to
799 un-mmappable block devices, then we could try shared mmap
800 and revert to anonymous mmap if the shared mmap fails. */
801 rom_image = mmap(NULL, fslen_ub?fslen_ub:1, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
802
803 if (rom_image == MAP_FAILED) {
804 die(MKFS_ERROR, 1, "mmap failed");
805 }
806
807 /* Skip the first opt_pad bytes for boot loader code */
808 offset = opt_pad;
809 memset(rom_image, 0x00, opt_pad);
810
811 /* Skip the superblock and come back to write it later. */
812 offset += sizeof(struct cramfs_super);
813
814 /* Insert a file image. */
815 if (opt_image) {
816 printf("Including: %s\n", opt_image);
817 offset = write_file(opt_image, rom_image, offset);
818 }
819
820 offset = write_directory_structure(root_entry->child, rom_image, offset);
821 printf("Directory data: %zd bytes\n", offset);
822
823 offset = write_data(root_entry, rom_image, offset);
824
825 /* We always write a multiple of blksize bytes, so that
826 losetup works. */
827 offset = ((offset - 1) | (blksize - 1)) + 1;
828 printf("Everything: %zd kilobytes\n", offset >> 10);
829
830 /* Write the superblock now that we can fill in all of the fields. */
831 write_superblock(root_entry, rom_image+opt_pad, offset);
832 printf("Super block: %zd bytes\n", sizeof(struct cramfs_super));
833
834 /* Put the checksum in. */
835 crc = crc32(0L, Z_NULL, 0);
836 crc = crc32(crc, (rom_image+opt_pad), (offset-opt_pad));
837 ((struct cramfs_super *) (rom_image+opt_pad))->fsid.crc = crc;
838 printf("CRC: %x\n", crc);
839
840 /* Check to make sure we allocated enough space. */
841 if (fslen_ub < offset) {
842 die(MKFS_ERROR, 0, "not enough space allocated for ROM image (%Ld allocated, %d used)", fslen_ub, offset);
843 }
844
845 written = write(fd, rom_image, offset);
846 if (written < 0) {
847 die(MKFS_ERROR, 1, "write failed");
848 }
849 if (offset != written) {
850 die(MKFS_ERROR, 0, "ROM image write failed (wrote %d of %d bytes): No space left on device?", written, offset);
851 }
852
853 /* (These warnings used to come at the start, but they scroll off the
854 screen too quickly.) */
855 if (warn_namelen)
856 fprintf(stderr, /* bytes, not chars: think UTF-8. */
857 "warning: filenames truncated to %d bytes (possibly less if multi-byte UTF-8)\n",
858 CRAMFS_MAXPATHLEN);
859 if (warn_skip)
860 fprintf(stderr, "warning: files were skipped due to errors\n");
861 if (warn_size)
862 fprintf(stderr,
863 "warning: file sizes truncated to %luMB (minus 1 byte)\n",
864 1L << (CRAMFS_SIZE_WIDTH - 20));
865 if (warn_uid) /* (not possible with current Linux versions) */
866 fprintf(stderr,
867 "warning: uids truncated to %u bits (this may be a security concern)\n",
868 CRAMFS_UID_WIDTH);
869 if (warn_gid)
870 fprintf(stderr,
871 "warning: gids truncated to %u bits (this may be a security concern)\n",
872 CRAMFS_GID_WIDTH);
873 if (warn_dev)
874 fprintf(stderr,
875 "WARNING: device numbers truncated to %u bits (this almost certainly means\n"
876 "that some device files will be wrong)\n",
877 CRAMFS_OFFSET_WIDTH);
878 if (opt_errors &&
879 (warn_namelen||warn_skip||warn_size||warn_uid||warn_gid||warn_dev))
880 exit(MKFS_ERROR);
881
882 exit(MKFS_OK);
883}
884
885/*
886 * Local variables:
887 * c-file-style: "linux"
888 * End:
889 */
diff --git a/utils/ypr0tools/extract_section.c b/utils/ypr0tools/extract_section.c
new file mode 100644
index 0000000000..8ad12bc7df
--- /dev/null
+++ b/utils/ypr0tools/extract_section.c
@@ -0,0 +1,85 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 Thomas Martitz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <unistd.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <stdarg.h>
29
30/* A simple replacement program for (
31 * dd if=$file1 of=$file2 bs=1 skip=$offset count=$size
32 *
33 * Written because byte-size operations with dd are unbearably slow.
34 */
35
36void usage(void)
37{
38 fprintf(stderr, "Usage: extract_section <romfile> <outfile> <offset> <byte count>\n");
39 exit(1);
40}
41
42void die(const char* fmt, ...)
43{
44 va_list ap;
45 va_start(ap, fmt);
46 vfprintf(stderr, fmt, ap);
47 va_end(ap);
48 exit(1);
49}
50
51int main(int argc, const char* argv[])
52{
53 if (argc != 5)
54 usage();
55
56 int ifd, ofd;
57 ssize_t size = atol(argv[4]);
58 long skip = atol(argv[3]);
59
60 if (!size)
61 die("invalid byte count\n");
62
63 ifd = open(argv[1], O_RDONLY);
64 if (ifd < 0)
65 die("Could not open %s for reading!\n", argv[1]);
66
67 ofd = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0666);
68 if (ofd < 0)
69 die("Could not create %s\n", argv[2]);
70
71 void *buf = malloc(size);
72 if (!buf) die("OOM\n");
73
74 lseek(ifd, skip, SEEK_SET);
75 lseek(ofd, 0, SEEK_SET);
76 if (read(ifd, buf, size) != size)
77 die("Read failed\n");
78 if (write(ofd, buf, size) != size)
79 die("write failed\n");
80
81 close(ifd);
82 close(ofd);
83
84 exit(EXIT_SUCCESS);
85}
diff --git a/utils/ypr0tools/files/.rockbox/README b/utils/ypr0tools/files/.rockbox/README
new file mode 100644
index 0000000000..f0e306e196
--- /dev/null
+++ b/utils/ypr0tools/files/.rockbox/README
@@ -0,0 +1 @@
This directory is empty and acts as mount point.
diff --git a/utils/ypr0tools/files/Playlists/README b/utils/ypr0tools/files/Playlists/README
new file mode 100644
index 0000000000..f0e306e196
--- /dev/null
+++ b/utils/ypr0tools/files/Playlists/README
@@ -0,0 +1 @@
This directory is empty and acts as mount point.
diff --git a/utils/ypr0tools/files/etc/mods/safe_mode.raw b/utils/ypr0tools/files/etc/mods/safe_mode.raw
new file mode 100644
index 0000000000..1c1aa61dd1
--- /dev/null
+++ b/utils/ypr0tools/files/etc/mods/safe_mode.raw
Binary files differ
diff --git a/utils/ypr0tools/files/etc/mods/safe_mode.sh b/utils/ypr0tools/files/etc/mods/safe_mode.sh
new file mode 100755
index 0000000000..122b2eabfe
--- /dev/null
+++ b/utils/ypr0tools/files/etc/mods/safe_mode.sh
@@ -0,0 +1,111 @@
1#!/bin/sh
2
3# YP-R0 Safe Mode!!
4# - Part of the "Device Rescue Kit", modded ROM v2.20 and onwards
5# Version: v0.3
6# v0.2 - initial version
7# v0.3 - USB cable check implemented
8# by lorenzo92 aka Memory
9# memoryS60@gmail.com
10
11CustomIMG="/mnt/media1/safe_mode.raw"
12DefIMG="/etc/mods/safe_mode.raw"
13
14timer=0
15# Seconds before turning the device OFF
16timeout=2
17
18shutdown () {
19 sync
20 reboot
21}
22
23cableDaemon () {
24 cd /usr/local/bin
25 while [ 1 ]
26 do
27 if [ $timer -gt $timeout ]
28 then
29 shutdown
30 fi
31
32 if ./minird 0x0a | grep -q 0x00
33 then
34 timer=$(($timer+1))
35 else
36 timer=0
37 fi
38 sleep 1
39 done
40}
41
42# Back button is a \x08\x00\x00\x00 string...
43# ...since bash removes null bytes for us, we must only care the single byte
44var=$(dd if=/dev/r0Btn bs=4 count=1)
45# Here a workaround to detect \x08 byte :S
46var2=$(echo -e -n "\x08")
47if [[ "$var" = "$var2" ]]
48then
49 echo "Safe mode (USB) activated..."
50 # Put the backlight at the minimum level: no energy waste, please ;)
51 # Using low level interface
52
53 cd /usr/local/bin
54 ./afewr 0x1b 0x3 0x8
55
56 # Long press reset time 5 secs
57 [ -e /etc/mods/reset_time_mod.sh ] && /bin/sh /etc/mods/reset_time_mod.sh
58
59 # Clear the screen and show a nice picture :D
60
61 echo -n "1" > /sys/class/graphics/fb0/blank
62 echo -n "0" >> /sys/class/graphics/fb0/blank
63# echo -n "1" > /sys/class/graphics/fb2/blank
64# echo -n "0" >> /sys/class/graphics/fb2/blank
65 if [ -e $CustomIMG ]
66 then
67 cat $CustomIMG > "/dev/fb0"
68 else
69 cat $DefIMG > "/dev/fb0"
70 fi
71
72 # Here the real USB connection stuff
73 # This is slightly modified by me; it was contained in the cramfs shipped with
74 # YP-R0 opensource package...
75
76 lsmod | grep g_file_storage
77 if [ $? == 0 ]
78 then
79 umount /mnt/media1/dev/gadget
80 fi
81 #if [ -d /mnt/media0 ]
82 #then
83 umount /mnt/media1
84 umount /mnt/media0
85 #umount /mnt/mmc
86 #fi
87 lsmod | grep rfs
88 if [ $? == 0 ]
89 then
90 rmmod rfs
91 fi
92 lsmod | grep g_file_storage
93 if [ $? == 0 ]
94 then
95 rmmod gadgetfs
96 rmmod g_file_storage
97 rmmod arcotg_udc
98 fi
99 lsmod | grep g_file_storage
100 if [ $? != 0 ]
101 then
102 modprobe g-file-storage file=/dev/stl3,/dev/stl2,/dev/mmcblk0 removable=1
103 fi
104
105 # Let's implement the check if usb cable is still inserted or not...
106 cableDaemon
107
108 return 1
109else
110 return 0
111fi
diff --git a/utils/ypr0tools/files/etc/profile b/utils/ypr0tools/files/etc/profile
new file mode 100755
index 0000000000..4ba61d7535
--- /dev/null
+++ b/utils/ypr0tools/files/etc/profile
@@ -0,0 +1,66 @@
1export PS1='\u@\h \w$ '
2export PS2='> '
3export PS3='? '
4export PS4='[$LINENO]+'
5
6export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
7export LD_LIBRARY_PATH=/mnt/media1/Lib:/mnt/media1/Lib/ExtraLib:/usr/lib
8export FSL_OMX_COMPONENT_REGISTRY="/Sysdata/OpenMaxIL/ComponentRegistry.txt"
9export FSL_OMX_MAX_INDEX_SIZE=1048576
10export MALLOC_CHECK_=0
11
12ulimit -s unlimited
13hwclock -s
14
15alias ls='ls --color=auto'
16alias ll='ls -l --color=auto'
17
18# Start with lorenzo92's safe mode
19SCRIPT="/etc/mods/safe_mode.sh"
20if [ -f $SCRIPT ]
21then
22 /bin/sh $SCRIPT
23 # it returns 1 if usb was connected
24 if [ "$?" = "1" ]
25 then
26 sync
27 sleep 1
28 reboot
29 fi
30fi
31
32if [ -e "/mnt/media1/r0" ]
33then
34 MAINFILE="/mnt/media1/r0"
35elif [ -f "/mnt/media0/r0" ]
36then
37 # copy to media1 since USB wouldn't work
38 cp /mnt/media0/r0 /mnt/media1/r0_media0
39 if [ "$?" = "0" ]
40 then # perhaps cp failed due to insufficient storage or so
41 MAINFILE="/mnt/media1/r0_media0"
42 else
43 MAINFILE="/usr/local/bin/r0"
44 fi
45else
46 MAINFILE="/usr/local/bin/r0"
47fi
48
49# source the rockbox loader script
50SOURCE="/mnt/media0/.rockbox/rockbox.sh"
51[ -f $SOURCE ] && . $SOURCE
52
53# source user script if available
54SOURCE="/mnt/media0/rc.user"
55[ -f $SOURCE ] && . $SOURCE
56
57# finally call the entry point
58if [ -e $MAINFILE ]
59then
60 chmod 777 $MAINFILE
61 $MAINFILE Application AppMain
62 rm -f /mnt/media1/r0_media0
63 sync
64# sleep 5
65 reboot
66fi
diff --git a/utils/ypr0tools/pack-firmware.sh b/utils/ypr0tools/pack-firmware.sh
new file mode 100755
index 0000000000..f3b55548d9
--- /dev/null
+++ b/utils/ypr0tools/pack-firmware.sh
@@ -0,0 +1,132 @@
1#!/bin/bash
2
3######################################################################
4# __________ __ ___.
5# Open \______ \ ____ ____ | | _\_ |__ _______ ___
6# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
7# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
8# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9# \/ \/ \/ \/ \/
10#
11# * Script to generate a Samsung YP-R0 firmware file (R0.ROM) */
12######################################################################
13#
14# This file was oringally called NewPack.sh, its origin is the R0 open source
15# package from Samsung.
16#
17# Muon Platform
18# Copyright (c) 2004-2009 Samsung Electronics, Inc.
19# All rights reserved.
20#
21# Rom Packaging Script
22# It needs sudoer privilege of rm, mkdir, cp, mkcramfs.
23# You can configure it in the /etc/sudoer file.
24# This script is very dangerous. Be careful to use.
25#
26# SangMan Sim<sangman.sim@samsung.com>
27
28# bail out early
29set -e
30
31DIR=${2:-"."}
32DIR=${DIR%/}
33REVISION="$DIR/RevisionInfo.txt"
34CRAMFS="$DIR/cramfs-fsl.rom"
35SYSDATA="$DIR/SYSDATA.bin"
36MBOOT="$DIR/MBoot.bin"
37MBOOT_TMP="${TMP_DIR:-$DIR}/MBoot.tmp"
38LINUX="$DIR/zImage"
39R0ROM=$1
40
41# some sanity checks
42if [ $# -lt 1 ] || [ $# -gt 2 ]; then
43 echo "Usage $0 <rom file> [path to image files]"
44 exit 1
45fi
46
47if [ ! -f ./MuonEncrypt ]; then
48 echo "Couldn't find MuonEncrypt binary (try 'make')"
49 exit 1
50fi
51
52if [ ! -e $REVISION ]; then
53 cat >$REVISION <<EOF
54Version : V2.30
55Target : KR
56EOF
57fi
58
59
60function WriteImage {
61 echo "Adding $1 to $R0ROM"
62 #HEAD_STR=[`stat -c%s $1`/`md5sum $1 | cut -d " " -f 1`]
63 #HEAD_SIZE=`echo $HEAD_STR | wc -c`
64 #PACK_SIZE=`expr 44 - $HEAD_SIZE`
65
66 #while [ $PACK_SIZE -gt 0 ]
67 #do
68 #PACK_SIZE=`expr $PACK_SIZE - 1`
69 #echo -n 0
70 #done
71
72 ./MuonEncrypt $1 >> $R0ROM
73 #cat $MBOOT >> $R0ROM
74}
75
76function Pack4Byte {
77 FILE_SIZE=`stat -c%s $R0ROM`
78 PACK_SIZE=`expr 4 - $FILE_SIZE % 4`
79
80 if [ $PACK_SIZE != 4 ]
81 then
82 while [ $PACK_SIZE -gt 0 ]
83 do
84 PACK_SIZE=`expr $PACK_SIZE - 1` || true
85 echo -en $1 >> $R0ROM
86 done
87 fi
88
89}
90
91echo Make $R0ROM
92
93cat $REVISION > $R0ROM
94echo User : $USER >> $R0ROM
95echo Dir : $PWD >> $R0ROM
96echo BuildTime : `date "+%y/%m/%d %H:%M:%S"` >> $R0ROM
97echo MBoot : size\(`stat -c%s $MBOOT`\),checksum\(`md5sum $MBOOT | cut -d " " -f 1`\) >> $R0ROM
98echo Linux : size\(`stat -c%s $LINUX`\),checksum\(`md5sum $LINUX | cut -d " " -f 1`\) >> $R0ROM
99echo RootFS : size\(`stat -c%s $CRAMFS`\),checksum\(`md5sum $CRAMFS | cut -d " " -f 1`\) >> $R0ROM
100echo Sysdata : size\(`stat -c%s $SYSDATA`\),checksum\(`md5sum $SYSDATA | cut -d " " -f 1`\) >> $R0ROM
101
102Pack4Byte "\\n"
103
104
105dd if=$MBOOT of=$MBOOT_TMP bs=96 count=1 2> /dev/null
106
107echo `stat -c%s $MBOOT`:`md5sum $MBOOT | cut -d " " -f 1` >> $MBOOT_TMP
108echo `stat -c%s $LINUX`:`md5sum $LINUX | cut -d " " -f 1` >> $MBOOT_TMP
109echo `stat -c%s $CRAMFS`:`md5sum $CRAMFS | cut -d " " -f 1` >> $MBOOT_TMP
110echo `stat -c%s $SYSDATA`:`md5sum $SYSDATA | cut -d " " -f 1` >> $MBOOT_TMP
111
112dd if=$MBOOT of=$MBOOT_TMP bs=1088 skip=1 seek=1 2> /dev/null
113WriteImage $MBOOT_TMP
114
115#rm $MBOOT_TMP
116
117Pack4Byte "0"
118
119WriteImage $LINUX
120
121Pack4Byte "0"
122
123WriteImage $CRAMFS
124
125Pack4Byte "0"
126
127WriteImage $SYSDATA
128
129echo $R0ROM : `stat -c%s $R0ROM`, `md5sum $R0ROM | cut -d " " -f 1`
130#head -9 $R0ROM
131
132echo "Done"
diff --git a/utils/ypr0tools/patch-firmware.sh b/utils/ypr0tools/patch-firmware.sh
new file mode 100755
index 0000000000..879b3f879d
--- /dev/null
+++ b/utils/ypr0tools/patch-firmware.sh
@@ -0,0 +1,67 @@
1#!/bin/sh
2
3
4######################################################################
5# __________ __ ___.
6# Open \______ \ ____ ____ | | _\_ |__ _______ ___
7# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
8# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
9# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10# \/ \/ \/ \/ \/
11#
12# * Script to patch an unpacked Samsung YP-R0 firmware file */
13# Copyright (C) 2011 Thomas Martitz
14######################################################################
15# bail out early
16set -e
17
18if [ $# -lt 1 ] || [ $# -gt 2 ]; then
19 echo "Usage: $0 <files path> [path to unpacked rom]"
20 echo "\t<files path> is expected to have a rootfs layout and to contain"
21 echo "\tonly the files to overwrite (plain cp -r is used)"
22 exit 1
23fi
24
25FILES=${1%/}
26FILES=${FILES:-"/"}
27DIR=${2:-"."}
28DIR=${DIR%/}
29ROOTFS=$DIR/rootfs
30CRAMFS=$DIR/cramfs-fsl.rom
31
32# sanity checks
33
34# this needs to be run as root!
35if [ $(whoami) != "root" ]
36then
37 echo "This needs to be run as root"
38 exit 1
39fi
40
41if [ ! -e $1 ] || [ ! -e $2 ]; then
42 echo "$1 or $2 does not exist"
43 exit 1
44fi
45
46if [ -z $ROOTFS ] || [ -z $FILES ]; then
47 echo "Invalid input directories"
48 exit 1
49fi
50
51if [ ! -e $CRAMFS ]; then
52 echo "Cramfs image not found (did you extract the firmware?)"
53 exit 1
54fi
55
56echo "Extracting cramfs image"
57
58[ ! -e $ROOTFS ] || rmdir -p $ROOTFS
59cramfs-1.1/cramfsck -x $ROOTFS $CRAMFS
60
61echo "Patching rootfs"
62echo "cp -r $FILES/* $ROOTFS/"
63cp -r $FILES/.rockbox $ROOTFS/
64cp -r $FILES/* $ROOTFS/
65
66echo "Packing new cramfs image"
67cramfs-1.1/mkcramfs $ROOTFS $CRAMFS
diff --git a/utils/ypr0tools/rockbox.sh b/utils/ypr0tools/rockbox.sh
new file mode 100755
index 0000000000..cbe54fd223
--- /dev/null
+++ b/utils/ypr0tools/rockbox.sh
@@ -0,0 +1,47 @@
1#!/bin/sh
2######################################################################
3# __________ __ ___.
4# Open \______ \ ____ ____ | | _\_ |__ _______ ___
5# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8# \/ \/ \/ \/ \/
9#
10# * Samsung YP-R0 Rockbox as an application loader *
11# Lorenzo Miori (C) 2011
12######################################################################
13
14# This is expected to be sourced by the shell, which is then
15# expected to run $MAINFILE
16
17# Check for menu button being pressed. Return immediately to launch the OF
18var=$(dd if=/dev/r0Btn bs=4 count=1)
19# Here a workaround to detect the byte
20var2=$(echo -e -n "\x07")
21
22if [[ "$var" = "$var2" ]]
23then
24 return
25fi
26
27
28# Blank-Unblank video to get rid of Samsung BootLogo, but turn off backlight before to hide these things :)
29echo -n "0" > /sys/devices/platform/afe.0/bli
30echo -n "1" > /sys/class/graphics/fb0/blank
31echo -n "0" >> /sys/class/graphics/fb0/blank
32
33amixer sset 'Soft Mute' 0
34amixer sset 'Master' 85%
35
36# We set-up various settings for the cpu governor: default are
37# Every 1,5 s the kernel evaluates if it's the case to down/up clocking the cpu
38echo "ondemand" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
39echo "1" > /sys/devices/system/cpu/cpu0/cpufreq/ondemand/ignore_nice_load
40echo "150000" > /sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate
41echo "95" > /sys/devices/system/cpu/cpu0/cpufreq/ondemand/up_threshold
42
43# bind these two to the root so that they're writable
44mount --bind /mnt/media0/.rockbox /.rockbox
45mount --bind /mnt/media0/Playlists /Playlists
46
47MAINFILE="/mnt/media0/.rockbox/rockbox"
diff --git a/utils/ypr0tools/unpack-firmware.sh b/utils/ypr0tools/unpack-firmware.sh
new file mode 100755
index 0000000000..ab80670c79
--- /dev/null
+++ b/utils/ypr0tools/unpack-firmware.sh
@@ -0,0 +1,90 @@
1#!/bin/bash
2
3######################################################################
4# __________ __ ___.
5# Open \______ \ ____ ____ | | _\_ |__ _______ ___
6# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
7# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
8# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9# \/ \/ \/ \/ \/
10#
11# * Script to unpack a Samsung YP-R0 firmware file (R0.ROM) */
12######################################################################
13
14# The file was originally called MuonDecrypt.sh
15#
16# I'm not sure about the original author of this file, as it wasn't included in Samsung package.
17# But I guess it was done by JeanLouis, an Italian user of the Hardware Upgrade Forum. If needed, we should search throug old posts for that...
18#
19
20
21# bail out early
22set -e
23
24# some sanity checks
25if [ $# -lt 1 ] || [ $# -gt 2 ]; then
26 echo "Usage $0 <rom file> [out dir]"
27 exit 1
28fi
29
30
31ROM=$1
32DIR=${2:-"."}
33DIR=${DIR%/}
34MBOOT="$DIR/MBoot.bin"
35MBOOT_TMP="${TMP_DIR:-$DIR}/MBoot.tmp"
36LINUX="$DIR/zImage"
37CRAMFS="$DIR/cramfs-fsl.rom"
38SYSDATA="$DIR/SYSDATA.bin"
39MD5SUMS="$DIR/MD5SUMS"
40TMP="${TMP_DIR:-$DIR}/_$$.tmp"
41
42
43if [ ! -f ./extract_section ]; then
44 echo "Couldn't find extract_section binary (try 'make')"
45 exit 1
46fi
47
48if [ ! -f ./MuonEncrypt ]; then
49 echo "Couldn't find MuonEncrypt binary (try 'make')"
50 exit 1
51fi
52
53mkdir -p $DIR
54
55if [ ! -w $DIR ]; then
56 echo "Target dir not writable"
57 exit 1
58fi
59
60ExtractAndDecrypt() {
61 START=$(expr $START - $2)
62 echo "Extracting $1..."
63 ./extract_section $ROM $TMP $START $2
64 echo "Decrypt $1..."
65 ./MuonEncrypt $TMP > $1
66}
67
68size=( `head -n 9 $ROM | tail -n 4 | while read LINE; do echo $LINE | cut -d\( -f 2 | cut -d\) -f 1; done`)
69checksum=( `head -n 9 $ROM | tail -n 4 | while read LINE; do echo $LINE | cut -d\( -f 3 | cut -d\) -f 1; done`)
70
71echo "${checksum[0]} $MBOOT" > $MD5SUMS
72echo "${checksum[1]} $LINUX" >> $MD5SUMS
73echo "${checksum[2]} $CRAMFS" >> $MD5SUMS
74echo "${checksum[3]} $SYSDATA" >> $MD5SUMS
75
76START=`stat -c%s $ROM`
77
78ExtractAndDecrypt $SYSDATA ${size[3]}
79ExtractAndDecrypt $CRAMFS ${size[2]}
80ExtractAndDecrypt $LINUX ${size[1]}
81ExtractAndDecrypt $MBOOT_TMP ${size[0]}
82
83rm $TMP
84echo "Create $MBOOT..."
85dd if=$MBOOT_TMP of=$MBOOT bs=96 count=1 2>/dev/null
86dd if=$MBOOT_TMP of=$MBOOT bs=1088 skip=1 seek=1 2>/dev/null
87rm $MBOOT_TMP
88
89echo "Check integrity:"
90md5sum -c $MD5SUMS