提交 9893c331 编写于 作者: ZHJ0125's avatar ZHJ0125 🐢

Upload RootFS

上级 4b0d9c43

要显示的变更太多。

To preserve performance only 1000 of 1000+ files are displayed.
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
CC = gcc
CFLAGS = -W -Wall -O2 -g
CPPFLAGS = -I.
LDLIBS = -lz
PROGS = mkcramfs cramfsck
all: $(PROGS)
distclean clean:
rm -f $(PROGS)
.PHONY: all clean
Notes on Filesystem Layout
--------------------------
These notes describe what mkcramfs generates. Kernel requirements are
a bit looser, e.g. it doesn't care if the <file_data> items are
swapped around (though it does care that directory entries (inodes) in
a given directory are contiguous, as this is used by readdir).
All data is currently in host-endian format; neither mkcramfs nor the
kernel ever do swabbing. (See section `Block Size' below.)
<filesystem>:
<superblock>
<directory_structure>
<data>
<superblock>: struct cramfs_super (see cramfs_fs.h).
<directory_structure>:
For each file:
struct cramfs_inode (see cramfs_fs.h).
Filename. Not generally null-terminated, but it is
null-padded to a multiple of 4 bytes.
The order of inode traversal is described as "width-first" (not to be
confused with breadth-first); i.e. like depth-first but listing all of
a directory's entries before recursing down its subdirectories: the
same order as `ls -AUR' (but without the /^\..*:$/ directory header
lines); put another way, the same order as `find -type d -exec
ls -AU1 {} \;'.
Beginning in 2.4.7, directory entries are sorted. This optimization
allows cramfs_lookup to return more quickly when a filename does not
exist, speeds up user-space directory sorts, etc.
<data>:
One <file_data> for each file that's either a symlink or a
regular file of non-zero st_size.
<file_data>:
nblocks * <block_pointer>
(where nblocks = (st_size - 1) / blksize + 1)
nblocks * <block>
padding to multiple of 4 bytes
The i'th <block_pointer> for a file stores the byte offset of the
*end* of the i'th <block> (i.e. one past the last byte, which is the
same as the start of the (i+1)'th <block> if there is one). The first
<block> immediately follows the last <block_pointer> for the file.
<block_pointer>s are each 32 bits long.
The order of <file_data>'s is a depth-first descent of the directory
tree, i.e. the same order as `find -size +0 \( -type f -o -type l \)
-print'.
<block>: The i'th <block> is the output of zlib's compress function
applied to the i'th blksize-sized chunk of the input data.
(For the last <block> of the file, the input may of course be smaller.)
Each <block> may be a different size. (See <block_pointer> above.)
<block>s are merely byte-aligned, not generally u32-aligned.
Holes
-----
This kernel supports cramfs holes (i.e. [efficient representation of]
blocks in uncompressed data consisting entirely of NUL bytes), but by
default mkcramfs doesn't test for & create holes, since cramfs in
kernels up to at least 2.3.39 didn't support holes. Run mkcramfs
with -z if you want it to create files that can have holes in them.
Tools
-----
The cramfs user-space tools, including mkcramfs and cramfsck, are
located at <http://sourceforge.net/projects/cramfs/>.
Future Development
==================
Block Size
----------
(Block size in cramfs refers to the size of input data that is
compressed at a time. It's intended to be somewhere around
PAGE_CACHE_SIZE for cramfs_readpage's convenience.)
The superblock ought to indicate the block size that the fs was
written for, since comments in <linux/pagemap.h> indicate that
PAGE_CACHE_SIZE may grow in future (if I interpret the comment
correctly).
Currently, mkcramfs #define's PAGE_CACHE_SIZE as 4096 and uses that
for blksize, whereas Linux-2.3.39 uses its PAGE_CACHE_SIZE, which in
turn is defined as PAGE_SIZE (which can be as large as 32KB on arm).
This discrepancy is a bug, though it's not clear which should be
changed.
One option is to change mkcramfs to take its PAGE_CACHE_SIZE from
<asm/page.h>. Personally I don't like this option, but it does
require the least amount of change: just change `#define
PAGE_CACHE_SIZE (4096)' to `#include <asm/page.h>'. The disadvantage
is that the generated cramfs cannot always be shared between different
kernels, not even necessarily kernels of the same architecture if
PAGE_CACHE_SIZE is subject to change between kernel versions
(currently possible with arm and ia64).
The remaining options try to make cramfs more sharable.
One part of that is addressing endianness. The two options here are
`always use little-endian' (like ext2fs) or `writer chooses
endianness; kernel adapts at runtime'. Little-endian wins because of
code simplicity and little CPU overhead even on big-endian machines.
The cost of swabbing is changing the code to use the le32_to_cpu
etc. macros as used by ext2fs. We don't need to swab the compressed
data, only the superblock, inodes and block pointers.
The other part of making cramfs more sharable is choosing a block
size. The options are:
1. Always 4096 bytes.
2. Writer chooses blocksize; kernel adapts but rejects blocksize >
PAGE_CACHE_SIZE.
3. Writer chooses blocksize; kernel adapts even to blocksize >
PAGE_CACHE_SIZE.
It's easy enough to change the kernel to use a smaller value than
PAGE_CACHE_SIZE: just make cramfs_readpage read multiple blocks.
The cost of option 1 is that kernels with a larger PAGE_CACHE_SIZE
value don't get as good compression as they can.
The cost of option 2 relative to option 1 is that the code uses
variables instead of #define'd constants. The gain is that people
with kernels having larger PAGE_CACHE_SIZE can make use of that if
they don't mind their cramfs being inaccessible to kernels with
smaller PAGE_CACHE_SIZE values.
Option 3 is easy to implement if we don't mind being CPU-inefficient:
e.g. get readpage to decompress to a buffer of size MAX_BLKSIZE (which
must be no larger than 32KB) and discard what it doesn't need.
Getting readpage to read into all the covered pages is harder.
The main advantage of option 3 over 1, 2, is better compression. The
cost is greater complexity. Probably not worth it, but I hope someone
will disagree. (If it is implemented, then I'll re-use that code in
e2compr.)
Another cost of 2 and 3 over 1 is making mkcramfs use a different
block size, but that just means adding and parsing a -b option.
Inode Size
----------
Given that cramfs will probably be used for CDs etc. as well as just
silicon ROMs, it might make sense to expand the inode a little from
its current 12 bytes. Inodes other than the root inode are followed
by filename, so the expansion doesn't even have to be a multiple of 4
bytes.
Cramfs - cram a filesystem onto a small ROM
cramfs is designed to be simple and small, and to compress things well.
It uses the zlib routines to compress a file one page at a time, and
allows random page access. The meta-data is not compressed, but is
expressed in a very terse representation to make it use much less
diskspace than traditional filesystems.
You can't write to a cramfs filesystem (making it compressible and
compact also makes it _very_ hard to update on-the-fly), so you have to
create the disk image with the "mkcramfs" utility.
Usage Notes
-----------
File sizes are limited to less than 16MB.
Maximum filesystem size is a little over 256MB. (The last file on the
filesystem is allowed to extend past 256MB.)
Only the low 8 bits of gid are stored. The current version of
mkcramfs simply truncates to 8 bits, which is a potential security
issue.
Hard links are supported, but hard linked files
will still have a link count of 1 in the cramfs image.
Cramfs directories have no `.' or `..' entries. Directories (like
every other file on cramfs) always have a link count of 1. (There's
no need to use -noleaf in `find', btw.)
No timestamps are stored in a cramfs, so these default to the epoch
(1970 GMT). Recently-accessed files may have updated timestamps, but
the update lasts only as long as the inode is cached in memory, after
which the timestamp reverts to 1970, i.e. moves backwards in time.
Currently, cramfs must be written and read with architectures of the
same endianness, and can be read only by kernels with PAGE_CACHE_SIZE
== 4096. At least the latter of these is a bug, but it hasn't been
decided what the best fix is. For the moment if you have larger pages
you can just change the #define in mkcramfs.c, so long as you don't
mind the filesystem becoming unreadable to future kernels.
For /usr/share/magic
--------------------
0 ulelong 0x28cd3d45 Linux cramfs offset 0
>4 ulelong x size %d
>8 ulelong x flags 0x%x
>12 ulelong x future 0x%x
>16 string >\0 signature "%.16s"
>32 ulelong x fsid.crc 0x%x
>36 ulelong x fsid.edition %d
>40 ulelong x fsid.blocks %d
>44 ulelong x fsid.files %d
>48 string >\0 name "%.16s"
512 ulelong 0x28cd3d45 Linux cramfs offset 512
>516 ulelong x size %d
>520 ulelong x flags 0x%x
>524 ulelong x future 0x%x
>528 string >\0 signature "%.16s"
>544 ulelong x fsid.crc 0x%x
>548 ulelong x fsid.edition %d
>552 ulelong x fsid.blocks %d
>556 ulelong x fsid.files %d
>560 string >\0 name "%.16s"
Hacker Notes
------------
See fs/cramfs/README for filesystem layout and implementation notes.
文件已添加
/*
* cramfsck - check a cramfs file system
*
* Copyright (C) 2000-2002 Transmeta Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* 1999/12/03: Linus Torvalds (cramfs tester and unarchive program)
* 2000/06/03: Daniel Quinlan (CRC and length checking program)
* 2000/06/04: Daniel Quinlan (merged programs, added options, support
* for special files, preserve permissions and
* ownership, cramfs superblock v2, bogus mode
* test, pathname length test, etc.)
* 2000/06/06: Daniel Quinlan (support for holes, pretty-printing,
* symlink size test)
* 2000/07/11: Daniel Quinlan (file length tests, start at offset 0 or 512,
* fsck-compatible exit codes)
* 2000/07/15: Daniel Quinlan (initial support for block devices)
* 2002/01/10: Daniel Quinlan (additional checks, test more return codes,
* use read if mmap fails, standardize messages)
*/
/* compile-time options */
#define INCLUDE_FS_TESTS /* include cramfs checking and extraction */
#define _GNU_SOURCE
#include <sys/types.h>
#include <stdio.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/sysmacros.h>
#include <utime.h>
#include <sys/ioctl.h>
#define _LINUX_STRING_H_
#include <linux/fs.h>
#include <linux/cramfs_fs.h>
#include <zlib.h>
/* Exit codes used by fsck-type programs */
#define FSCK_OK 0 /* No errors */
#define FSCK_NONDESTRUCT 1 /* File system errors corrected */
#define FSCK_REBOOT 2 /* System should be rebooted */
#define FSCK_UNCORRECTED 4 /* File system errors left uncorrected */
#define FSCK_ERROR 8 /* Operational error */
#define FSCK_USAGE 16 /* Usage or syntax error */
#define FSCK_LIBRARY 128 /* Shared library error */
#define PAD_SIZE 512
#define PAGE_CACHE_SIZE (4096)
static const char *progname = "cramfsck";
static int fd; /* ROM image file descriptor */
static char *filename; /* ROM image filename */
struct cramfs_super super; /* just find the cramfs superblock once */
static int opt_verbose = 0; /* 1 = verbose (-v), 2+ = very verbose (-vv) */
#ifdef INCLUDE_FS_TESTS
static int opt_extract = 0; /* extract cramfs (-x) */
static char *extract_dir = "root"; /* extraction directory (-x) */
static uid_t euid; /* effective UID */
/* (cramfs_super + start) <= start_dir < end_dir <= start_data <= end_data */
static unsigned long start_dir = ~0UL; /* start of first non-root inode */
static unsigned long end_dir = 0; /* end of the directory structure */
static unsigned long start_data = ~0UL; /* start of the data (256 MB = max) */
static unsigned long end_data = 0; /* end of the data */
/* Guarantee access to at least 8kB at a time */
#define ROMBUFFER_BITS 13
#define ROMBUFFERSIZE (1 << ROMBUFFER_BITS)
#define ROMBUFFERMASK (ROMBUFFERSIZE-1)
static char read_buffer[ROMBUFFERSIZE * 2];
static unsigned long read_buffer_block = ~0UL;
/* Uncompressing data structures... */
static char outbuffer[PAGE_CACHE_SIZE*2];
static z_stream stream;
/* Prototypes */
static void expand_fs(char *, struct cramfs_inode *);
#endif /* INCLUDE_FS_TESTS */
/* Input status of 0 to print help and exit without an error. */
static void usage(int status)
{
FILE *stream = status ? stderr : stdout;
fprintf(stream, "usage: %s [-hv] [-x dir] file\n"
" -h print this help\n"
" -x dir extract into dir\n"
" -v be more verbose\n"
" file file to test\n", progname);
exit(status);
}
static void die(int status, int syserr, const char *fmt, ...)
{
va_list arg_ptr;
int save = errno;
fflush(0);
va_start(arg_ptr, fmt);
fprintf(stderr, "%s: ", progname);
vfprintf(stderr, fmt, arg_ptr);
if (syserr) {
fprintf(stderr, ": %s", strerror(save));
}
fprintf(stderr, "\n");
va_end(arg_ptr);
exit(status);
}
static void test_super(int *start, size_t *length) {
struct stat st;
/* find the physical size of the file or block device */
if (stat(filename, &st) < 0) {
die(FSCK_ERROR, 1, "stat failed: %s", filename);
}
fd = open(filename, O_RDONLY);
if (fd < 0) {
die(FSCK_ERROR, 1, "open failed: %s", filename);
}
if (S_ISBLK(st.st_mode)) {
if (ioctl(fd, BLKGETSIZE, length) < 0) {
die(FSCK_ERROR, 1, "ioctl failed: unable to determine device size: %s", filename);
}
*length = *length * 512;
}
else if (S_ISREG(st.st_mode)) {
*length = st.st_size;
}
else {
die(FSCK_ERROR, 0, "not a block device or file: %s", filename);
}
if (*length < sizeof(struct cramfs_super)) {
die(FSCK_UNCORRECTED, 0, "file length too short");
}
/* find superblock */
if (read(fd, &super, sizeof(super)) != sizeof(super)) {
die(FSCK_ERROR, 1, "read failed: %s", filename);
}
if (super.magic == CRAMFS_MAGIC) {
*start = 0;
}
else if (*length >= (PAD_SIZE + sizeof(super))) {
lseek(fd, PAD_SIZE, SEEK_SET);
if (read(fd, &super, sizeof(super)) != sizeof(super)) {
die(FSCK_ERROR, 1, "read failed: %s", filename);
}
if (super.magic == CRAMFS_MAGIC) {
*start = PAD_SIZE;
}
}
/* superblock tests */
if (super.magic != CRAMFS_MAGIC) {
die(FSCK_UNCORRECTED, 0, "superblock magic not found");
}
if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) {
die(FSCK_ERROR, 0, "unsupported filesystem features");
}
if (super.size < PAGE_CACHE_SIZE) {
die(FSCK_UNCORRECTED, 0, "superblock size (%d) too small", super.size);
}
if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) {
if (super.fsid.files == 0) {
die(FSCK_UNCORRECTED, 0, "zero file count");
}
if (*length < super.size) {
die(FSCK_UNCORRECTED, 0, "file length too short");
}
else if (*length > super.size) {
fprintf(stderr, "warning: file extends past end of filesystem\n");
}
}
else {
fprintf(stderr, "warning: old cramfs format\n");
}
}
static void test_crc(int start)
{
void *buf;
u32 crc;
if (!(super.flags & CRAMFS_FLAG_FSID_VERSION_2)) {
#ifdef INCLUDE_FS_TESTS
return;
#else /* not INCLUDE_FS_TESTS */
die(FSCK_USAGE, 0, "unable to test CRC: old cramfs format");
#endif /* not INCLUDE_FS_TESTS */
}
crc = crc32(0L, Z_NULL, 0);
buf = mmap(NULL, super.size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (buf == MAP_FAILED) {
buf = mmap(NULL, super.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (buf != MAP_FAILED) {
lseek(fd, 0, SEEK_SET);
read(fd, buf, super.size);
}
}
if (buf != MAP_FAILED) {
((struct cramfs_super *) (buf+start))->fsid.crc = crc32(0L, Z_NULL, 0);
crc = crc32(crc, buf+start, super.size-start);
munmap(buf, super.size);
}
else {
int retval;
size_t length = 0;
buf = malloc(4096);
if (!buf) {
die(FSCK_ERROR, 1, "malloc failed");
}
lseek(fd, start, SEEK_SET);
for (;;) {
retval = read(fd, buf, 4096);
if (retval < 0) {
die(FSCK_ERROR, 1, "read failed: %s", filename);
}
else if (retval == 0) {
break;
}
if (length == 0) {
((struct cramfs_super *) buf)->fsid.crc = crc32(0L, Z_NULL, 0);
}
length += retval;
if (length > (super.size-start)) {
crc = crc32(crc, buf, retval - (length - (super.size-start)));
break;
}
crc = crc32(crc, buf, retval);
}
free(buf);
}
if (crc != super.fsid.crc) {
die(FSCK_UNCORRECTED, 0, "crc error");
}
}
#ifdef INCLUDE_FS_TESTS
static void print_node(char type, struct cramfs_inode *i, char *name)
{
char info[10];
if (S_ISCHR(i->mode) || (S_ISBLK(i->mode))) {
/* major/minor numbers can be as high as 2^12 or 4096 */
snprintf(info, 10, "%4d,%4d", major(i->size), minor(i->size));
}
else {
/* size be as high as 2^24 or 16777216 */
snprintf(info, 10, "%9d", i->size);
}
printf("%c %04o %s %5d:%-3d %s\n",
type, i->mode & ~S_IFMT, info, i->uid, i->gid, name);
}
/*
* Create a fake "blocked" access
*/
static void *romfs_read(unsigned long offset)
{
unsigned int block = offset >> ROMBUFFER_BITS;
if (block != read_buffer_block) {
read_buffer_block = block;
lseek(fd, block << ROMBUFFER_BITS, SEEK_SET);
read(fd, read_buffer, ROMBUFFERSIZE * 2);
}
return read_buffer + (offset & ROMBUFFERMASK);
}
static struct cramfs_inode *cramfs_iget(struct cramfs_inode * i)
{
struct cramfs_inode *inode = malloc(sizeof(struct cramfs_inode));
if (!inode) {
die(FSCK_ERROR, 1, "malloc failed");
}
*inode = *i;
return inode;
}
static struct cramfs_inode *iget(unsigned int ino)
{
return cramfs_iget(romfs_read(ino));
}
static void iput(struct cramfs_inode *inode)
{
free(inode);
}
/*
* Return the offset of the root directory
*/
static struct cramfs_inode *read_super(void)
{
unsigned long offset = super.root.offset << 2;
if (!S_ISDIR(super.root.mode))
die(FSCK_UNCORRECTED, 0, "root inode is not directory");
if (!(super.flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) &&
((offset != sizeof(struct cramfs_super)) &&
(offset != PAD_SIZE + sizeof(struct cramfs_super))))
{
die(FSCK_UNCORRECTED, 0, "bad root offset (%lu)", offset);
}
return cramfs_iget(&super.root);
}
static int uncompress_block(void *src, int len)
{
int err;
stream.next_in = src;
stream.avail_in = len;
stream.next_out = (unsigned char *) outbuffer;
stream.avail_out = PAGE_CACHE_SIZE*2;
inflateReset(&stream);
if (len > PAGE_CACHE_SIZE*2) {
die(FSCK_UNCORRECTED, 0, "data block too large");
}
err = inflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
die(FSCK_UNCORRECTED, 0, "decompression error %p(%d): %s",
zError(err), src, len);
}
return stream.total_out;
}
static void do_uncompress(char *path, int fd, unsigned long offset, unsigned long size)
{
unsigned long curr = offset + 4 * ((size + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE);
do {
unsigned long out = PAGE_CACHE_SIZE;
unsigned long next = *(u32 *) romfs_read(offset);
if (next > end_data) {
end_data = next;
}
offset += 4;
if (curr == next) {
if (opt_verbose > 1) {
printf(" hole at %ld (%d)\n", curr, PAGE_CACHE_SIZE);
}
if (size < PAGE_CACHE_SIZE)
out = size;
memset(outbuffer, 0x00, out);
}
else {
if (opt_verbose > 1) {
printf(" uncompressing block at %ld to %ld (%ld)\n", curr, next, next - curr);
}
out = uncompress_block(romfs_read(curr), next - curr);
}
if (size >= PAGE_CACHE_SIZE) {
if (out != PAGE_CACHE_SIZE) {
die(FSCK_UNCORRECTED, 0, "non-block (%ld) bytes", out);
}
} else {
if (out != size) {
die(FSCK_UNCORRECTED, 0, "non-size (%ld vs %ld) bytes", out, size);
}
}
size -= out;
if (opt_extract) {
if (write(fd, outbuffer, out) < 0) {
die(FSCK_ERROR, 1, "write failed: %s", path);
}
}
curr = next;
} while (size);
}
static void change_file_status(char *path, struct cramfs_inode *i)
{
struct utimbuf epoch = { 0, 0 };
if (euid == 0) {
if (lchown(path, i->uid, i->gid) < 0) {
die(FSCK_ERROR, 1, "lchown failed: %s", path);
}
if (S_ISLNK(i->mode))
return;
if ((S_ISUID | S_ISGID) & i->mode) {
if (chmod(path, i->mode) < 0) {
die(FSCK_ERROR, 1, "chown failed: %s", path);
}
}
}
if (S_ISLNK(i->mode))
return;
if (utime(path, &epoch) < 0) {
die(FSCK_ERROR, 1, "utime failed: %s", path);
}
}
static void do_directory(char *path, struct cramfs_inode *i)
{
int pathlen = strlen(path);
int count = i->size;
unsigned long offset = i->offset << 2;
char *newpath = malloc(pathlen + 256);
if (!newpath) {
die(FSCK_ERROR, 1, "malloc failed");
}
if (offset == 0 && count != 0) {
die(FSCK_UNCORRECTED, 0, "directory inode has zero offset and non-zero size: %s", path);
}
if (offset != 0 && offset < start_dir) {
start_dir = offset;
}
/* TODO: Do we need to check end_dir for empty case? */
memcpy(newpath, path, pathlen);
newpath[pathlen] = '/';
pathlen++;
if (opt_verbose) {
print_node('d', i, path);
}
if (opt_extract) {
if (mkdir(path, i->mode) < 0) {
die(FSCK_ERROR, 1, "mkdir failed: %s", path);
}
change_file_status(path, i);
}
while (count > 0) {
struct cramfs_inode *child = iget(offset);
int size;
int newlen = child->namelen << 2;
size = sizeof(struct cramfs_inode) + newlen;
count -= size;
offset += sizeof(struct cramfs_inode);
memcpy(newpath + pathlen, romfs_read(offset), newlen);
newpath[pathlen + newlen] = 0;
if (newlen == 0) {
die(FSCK_UNCORRECTED, 0, "filename length is zero");
}
if ((pathlen + newlen) - strlen(newpath) > 3) {
die(FSCK_UNCORRECTED, 0, "bad filename length");
}
expand_fs(newpath, child);
offset += newlen;
if (offset <= start_dir) {
die(FSCK_UNCORRECTED, 0, "bad inode offset");
}
if (offset > end_dir) {
end_dir = offset;
}
iput(child); /* free(child) */
}
free(newpath);
}
static void do_file(char *path, struct cramfs_inode *i)
{
unsigned long offset = i->offset << 2;
int fd = 0;
if (offset == 0 && i->size != 0) {
die(FSCK_UNCORRECTED, 0, "file inode has zero offset and non-zero size");
}
if (i->size == 0 && offset != 0) {
die(FSCK_UNCORRECTED, 0, "file inode has zero size and non-zero offset");
}
if (offset != 0 && offset < start_data) {
start_data = offset;
}
if (opt_verbose) {
print_node('f', i, path);
}
if (opt_extract) {
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, i->mode);
if (fd < 0) {
die(FSCK_ERROR, 1, "open failed: %s", path);
}
}
if (i->size) {
do_uncompress(path, fd, offset, i->size);
}
if (opt_extract) {
close(fd);
change_file_status(path, i);
}
}
static void do_symlink(char *path, struct cramfs_inode *i)
{
unsigned long offset = i->offset << 2;
unsigned long curr = offset + 4;
unsigned long next = *(u32 *) romfs_read(offset);
unsigned long size;
if (offset == 0) {
die(FSCK_UNCORRECTED, 0, "symbolic link has zero offset");
}
if (i->size == 0) {
die(FSCK_UNCORRECTED, 0, "symbolic link has zero size");
}
if (offset < start_data) {
start_data = offset;
}
if (next > end_data) {
end_data = next;
}
size = uncompress_block(romfs_read(curr), next - curr);
if (size != i->size) {
die(FSCK_UNCORRECTED, 0, "size error in symlink: %s", path);
}
outbuffer[size] = 0;
if (opt_verbose) {
char *str;
asprintf(&str, "%s -> %s", path, outbuffer);
print_node('l', i, str);
if (opt_verbose > 1) {
printf(" uncompressing block at %ld to %ld (%ld)\n", curr, next, next - curr);
}
free(str);
}
if (opt_extract) {
if (symlink(outbuffer, path) < 0) {
die(FSCK_ERROR, 1, "symlink failed: %s", path);
}
change_file_status(path, i);
}
}
static void do_special_inode(char *path, struct cramfs_inode *i)
{
dev_t devtype = 0;
char type;
if (i->offset) { /* no need to shift offset */
die(FSCK_UNCORRECTED, 0, "special file has non-zero offset: %s", path);
}
if (S_ISCHR(i->mode)) {
devtype = i->size;
type = 'c';
}
else if (S_ISBLK(i->mode)) {
devtype = i->size;
type = 'b';
}
else if (S_ISFIFO(i->mode)) {
if (i->size != 0) {
die(FSCK_UNCORRECTED, 0, "fifo has non-zero size: %s", path);
}
type = 'p';
}
else if (S_ISSOCK(i->mode)) {
if (i->size != 0) {
die(FSCK_UNCORRECTED, 0, "socket has non-zero size: %s", path);
}
type = 's';
}
else {
die(FSCK_UNCORRECTED, 0, "bogus mode: %s (%o)", path, i->mode);
return; /* not reached */
}
if (opt_verbose) {
print_node(type, i, path);
}
if (opt_extract) {
if (mknod(path, i->mode, devtype) < 0) {
die(FSCK_ERROR, 1, "mknod failed: %s", path);
}
change_file_status(path, i);
}
}
static void expand_fs(char *path, struct cramfs_inode *inode)
{
if (S_ISDIR(inode->mode)) {
do_directory(path, inode);
}
else if (S_ISREG(inode->mode)) {
do_file(path, inode);
}
else if (S_ISLNK(inode->mode)) {
do_symlink(path, inode);
}
else {
do_special_inode(path, inode);
}
}
static void test_fs(int start)
{
struct cramfs_inode *root;
root = read_super();
umask(0);
euid = geteuid();
stream.next_in = NULL;
stream.avail_in = 0;
inflateInit(&stream);
expand_fs(extract_dir, root);
inflateEnd(&stream);
if (start_data != ~0UL) {
if (start_data < (sizeof(struct cramfs_super) + start)) {
die(FSCK_UNCORRECTED, 0, "directory data start (%ld) < sizeof(struct cramfs_super) + start (%ld)", start_data, sizeof(struct cramfs_super) + start);
}
if (end_dir != start_data) {
die(FSCK_UNCORRECTED, 0, "directory data end (%ld) != file data start (%ld)", end_dir, start_data);
}
}
if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) {
if (end_data > super.size) {
die(FSCK_UNCORRECTED, 0, "invalid file data offset");
}
}
iput(root); /* free(root) */
}
#endif /* INCLUDE_FS_TESTS */
int main(int argc, char **argv)
{
int c; /* for getopt */
int start = 0;
size_t length;
if (argc)
progname = argv[0];
/* command line options */
while ((c = getopt(argc, argv, "hx:v")) != EOF) {
switch (c) {
case 'h':
usage(FSCK_OK);
case 'x':
#ifdef INCLUDE_FS_TESTS
opt_extract = 1;
extract_dir = optarg;
break;
#else /* not INCLUDE_FS_TESTS */
die(FSCK_USAGE, 0, "compiled without -x support");
#endif /* not INCLUDE_FS_TESTS */
case 'v':
opt_verbose++;
break;
}
}
if ((argc - optind) != 1)
usage(FSCK_USAGE);
filename = argv[optind];
test_super(&start, &length);
test_crc(start);
#ifdef INCLUDE_FS_TESTS
test_fs(start);
#endif /* INCLUDE_FS_TESTS */
if (opt_verbose) {
printf("%s: OK\n", filename);
}
exit(FSCK_OK);
}
/*
* Local variables:
* c-file-style: "linux"
* End:
*/
#ifndef __CRAMFS_H
#define __CRAMFS_H
#ifndef __KERNEL__
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#endif
#define CRAMFS_MAGIC 0x28cd3d45 /* some random number */
#define CRAMFS_SIGNATURE "Compressed ROMFS"
/*
* Width of various bitfields in struct cramfs_inode.
* Primarily used to generate warnings in mkcramfs.
*/
#define CRAMFS_MODE_WIDTH 16
#define CRAMFS_UID_WIDTH 16
#define CRAMFS_SIZE_WIDTH 24
#define CRAMFS_GID_WIDTH 8
#define CRAMFS_NAMELEN_WIDTH 6
#define CRAMFS_OFFSET_WIDTH 26
/*
* Since inode.namelen is a unsigned 6-bit number, the maximum cramfs
* path length is 63 << 2 = 252.
*/
#define CRAMFS_MAXPATHLEN (((1 << CRAMFS_NAMELEN_WIDTH) - 1) << 2)
/*
* Reasonably terse representation of the inode data.
*/
struct cramfs_inode {
u32 mode:CRAMFS_MODE_WIDTH, uid:CRAMFS_UID_WIDTH;
/* SIZE for device files is i_rdev */
u32 size:CRAMFS_SIZE_WIDTH, gid:CRAMFS_GID_WIDTH;
/* NAMELEN is the length of the file name, divided by 4 and
rounded up. (cramfs doesn't support hard links.) */
/* OFFSET: For symlinks and non-empty regular files, this
contains the offset (divided by 4) of the file data in
compressed form (starting with an array of block pointers;
see README). For non-empty directories it is the offset
(divided by 4) of the inode of the first file in that
directory. For anything else, offset is zero. */
u32 namelen:CRAMFS_NAMELEN_WIDTH, offset:CRAMFS_OFFSET_WIDTH;
};
struct cramfs_info {
u32 crc;
u32 edition;
u32 blocks;
u32 files;
};
/*
* Superblock information at the beginning of the FS.
*/
struct cramfs_super {
u32 magic; /* 0x28cd3d45 - random number */
u32 size; /* length in bytes */
u32 flags; /* feature flags */
u32 future; /* reserved for future use */
u8 signature[16]; /* "Compressed ROMFS" */
struct cramfs_info fsid; /* unique filesystem info */
u8 name[16]; /* user-defined name */
struct cramfs_inode root; /* root inode data */
};
/*
* Feature flags
*
* 0x00000000 - 0x000000ff: features that work for all past kernels
* 0x00000100 - 0xffffffff: features that don't work for past kernels
*/
#define CRAMFS_FLAG_FSID_VERSION_2 0x00000001 /* fsid version #2 */
#define CRAMFS_FLAG_SORTED_DIRS 0x00000002 /* sorted dirs */
#define CRAMFS_FLAG_HOLES 0x00000100 /* support for holes */
#define CRAMFS_FLAG_WRONG_SIGNATURE 0x00000200 /* reserved */
#define CRAMFS_FLAG_SHIFTED_ROOT_OFFSET 0x00000400 /* shifted root fs */
/*
* Valid values in super.flags. Currently we refuse to mount
* if (flags & ~CRAMFS_SUPPORTED_FLAGS). Maybe that should be
* changed to test super.future instead.
*/
#define CRAMFS_SUPPORTED_FLAGS ( 0x000000ff \
| CRAMFS_FLAG_HOLES \
| CRAMFS_FLAG_WRONG_SIGNATURE \
| CRAMFS_FLAG_SHIFTED_ROOT_OFFSET )
/* Uncompression interfaces to the underlying zlib */
int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen);
int cramfs_uncompress_init(void);
int cramfs_uncompress_exit(void);
#endif
#ifndef _CRAMFS_FS_SB
#define _CRAMFS_FS_SB
/*
* cramfs super-block data in memory
*/
struct cramfs_sb_info {
unsigned long magic;
unsigned long size;
unsigned long blocks;
unsigned long files;
unsigned long flags;
};
#endif
文件已添加
此差异已折叠。
cmd_busybox_unstripped := /home/zhj/ARMTraining/rootfs/busybox-1.12.2/scripts/trylink "busybox_unstripped" "arm-linux-gcc" " -Wall -Wshadow -Wwrite-strings -Wundef -Wstrict-prototypes -Wunused -Wunused-parameter -Wmissing-prototypes -Wmissing-declarations -Wdeclaration-after-statement -Wold-style-definition -fno-builtin-strlen -finline-limit=0 -fomit-frame-pointer -ffunction-sections -fdata-sections -fno-guess-branch-probability -funsigned-char -static-libgcc -falign-functions=1 -falign-jumps=1 -falign-labels=1 -falign-loops=1 -Os -static" " " " applets/built-in.o" " archival/lib.a archival/libunarchive/lib.a console-tools/lib.a coreutils/lib.a coreutils/libcoreutils/lib.a debianutils/lib.a e2fsprogs/lib.a editors/lib.a findutils/lib.a init/lib.a libbb/lib.a libpwdgrp/lib.a loginutils/lib.a miscutils/lib.a modutils/lib.a networking/lib.a networking/libiproute/lib.a networking/udhcp/lib.a printutils/lib.a procps/lib.a runit/lib.a selinux/lib.a shell/lib.a sysklogd/lib.a util-linux/lib.a util-linux/volume_id/lib.a archival/built-in.o archival/libunarchive/built-in.o console-tools/built-in.o coreutils/built-in.o coreutils/libcoreutils/built-in.o debianutils/built-in.o e2fsprogs/built-in.o editors/built-in.o findutils/built-in.o init/built-in.o libbb/built-in.o libpwdgrp/built-in.o loginutils/built-in.o miscutils/built-in.o modutils/built-in.o networking/built-in.o networking/libiproute/built-in.o networking/udhcp/built-in.o printutils/built-in.o procps/built-in.o runit/built-in.o selinux/built-in.o shell/built-in.o sysklogd/built-in.o util-linux/built-in.o util-linux/volume_id/built-in.o" " m crypt"
此差异已折叠。
此差异已折叠。
--blank-lines-after-declarations
--blank-lines-after-procedures
--break-before-boolean-operator
--no-blank-lines-after-commas
--braces-on-if-line
--braces-on-struct-decl-line
--comment-indentation25
--declaration-comment-column25
--no-comment-delimiters-on-blank-lines
--cuddle-else
--continuation-indentation4
--case-indentation0
--else-endif-column33
--space-after-cast
--line-comments-indentation0
--declaration-indentation1
--dont-format-first-column-comments
--dont-format-comments
--honour-newlines
--indent-level4
/* changed from 0 to 4 */
--parameter-indentation4
--line-length78 /* changed from 75 */
--continue-at-parentheses
--no-space-after-function-call-names
--dont-break-procedure-type
--dont-star-comments
--leave-optional-blank-lines
--dont-space-special-semicolon
--tab-size4
/* additions by Mark */
--case-brace-indentation0
--leave-preprocessor-space
deps_config := \
printutils/Config.in \
selinux/Config.in \
runit/Config.in \
sysklogd/Config.in \
shell/Config.in \
procps/Config.in \
networking/udhcp/Config.in \
networking/Config.in \
miscutils/Config.in \
util-linux/Config.in \
modutils/Config.in \
e2fsprogs/Config.in \
loginutils/Config.in \
init/Config.in \
findutils/Config.in \
editors/Config.in \
debianutils/Config.in \
console-tools/Config.in \
coreutils/Config.in \
archival/Config.in \
libbb/Config.in \
Config.in
.config include/autoconf.h: $(deps_config)
$(deps_config):
List of the authors of code contained in BusyBox.
If you have code in BusyBox, you should be listed here. If you should be
listed, or the description of what you have done needs more detail, or is
incorrect, _please_ let me know.
-Erik
-----------
Peter Willis <psyphreak@phreaker.net>
eject
Emanuele Aina <emanuele.aina@tiscali.it>
run-parts
Erik Andersen <andersen@codepoet.org>
Tons of new stuff, major rewrite of most of the
core apps, tons of new apps as noted in header files.
Lots of tedious effort writing these boring docs that
nobody is going to actually read.
Laurence Anderson <l.d.anderson@warwick.ac.uk>
rpm2cpio, unzip, get_header_cpio, read_gz interface, rpm
Jeff Angielski <jeff@theptrgroup.com>
ftpput, ftpget
Enrik Berkhan <Enrik.Berkhan@inka.de>
setconsole
Jim Bauer <jfbauer@nfr.com>
modprobe shell dependency
Edward Betts <edward@debian.org>
expr, hostid, logname, whoami
John Beppu <beppu@codepoet.org>
du, nslookup, sort
David Brownell <dbrownell@users.sourceforge.net>
zcip
Brian Candler <B.Candler@pobox.com>
tiny-ls(ls)
Randolph Chung <tausq@debian.org>
fbset, ping, hostname
Dave Cinege <dcinege@psychosis.com>
more(v2), makedevs, dutmp, modularization, auto links file,
various fixes, Linux Router Project maintenance
Jordan Crouse <jordan@cosmicpenguin.net>
ipcalc
Magnus Damm <damm@opensource.se>
tftp client
insmod powerpc support
Larry Doolittle <ldoolitt@recycle.lbl.gov>
pristine source directory compilation, lots of patches and fixes.
Glenn Engel <glenne@engel.org>
httpd
Gennady Feldman <gfeldman@gena01.com>
Sysklogd (single threaded syslogd, IPC Circular buffer support,
logread), various fixes.
Robert Griebl <sandman@handhelds.org>
modprobe, hwclock, suid/sgid handling, tinylogin integration
many bugfixes and enhancements
Karl M. Hegbloom <karlheg@debian.org>
cp_mv.c, the test suite, various fixes to utility.c, &c.
Daniel Jacobowitz <dan@debian.org>
mktemp.c
Matt Kraai <kraai@alumni.cmu.edu>
documentation, bugfixes, test suite
Rob Landley <rob@landley.net>
Became busybox maintainer in 2006.
sed (major rewrite in 2003, and I now maintain the thing)
bunzip2 (complete from-scratch rewrite, then mjn3 optimized the result)
sort (more or less from scratch rewrite in 2004, I now maintain it)
mount (rewrite in 2005, I maintain the new one)
Stephan Linz <linz@li-pro.net>
ipcalc, Red Hat equivalence
John Lombardo <john@deltanet.com>
tr
Glenn McGrath <glenn.l.mcgrath@gmail.com>
Common unarchiving code and unarchiving applets, ifupdown, ftpgetput,
nameif, sed, patch, fold, install, uudecode.
Various bugfixes, review and apply numerous patches.
Manuel Novoa III <mjn3@codepoet.org>
cat, head, mkfifo, mknod, rmdir, sleep, tee, tty, uniq, usleep, wc, yes,
mesg, vconfig, nice, renice,
make_directory, parse_mode, dirname, mode_string,
get_last_path_component, simplify_path, and a number trivial libbb routines
also bug fixes, partial rewrites, and size optimizations in
ash, basename, cal, cmp, cp, df, du, echo, env, ln, logname, md5sum, mkdir,
mv, realpath, rm, sort, tail, touch, uname, watch, arith, human_readable,
interface, dutmp, ifconfig, route
Vladimir Oleynik <dzo@simtreas.ru>
cmdedit; bb_mkdep, xargs(current), httpd(current);
ports: ash, crond, fdisk (initial, unmaintained now), inetd, stty, traceroute,
top;
locale, various fixes
and irreconcilable critic of everything not perfect.
Bruce Perens <bruce@pixar.com>
Original author of BusyBox in 1995, 1996. Some of his code can
still be found hiding here and there...
Rodney Radford <rradford@mindspring.com>
ipcs, ipcrm
Tim Riker <Tim@Rikers.org>
bug fixes, member of fan club
Kent Robotti <robotti@metconnect.com>
reset, tons and tons of bug reports and patches.
Chip Rosenthal <chip@unicom.com>, <crosenth@covad.com>
wget - Contributed by permission of Covad Communications
Pavel Roskin <proski@gnu.org>
Lots of bugs fixes and patches.
Gyepi Sam <gyepi@praxis-sw.com>
Remote logging feature for syslogd
Rob Sullivan <cogito.ergo.cogito@gmail.com>
comm
Linus Torvalds
mkswap, fsck.minix, mkfs.minix
Mark Whitley <markw@codepoet.org>
grep, sed, cut, xargs(previous),
style-guide, new-applet-HOWTO, bug fixes, etc.
Charles P. Wright <cpwright@villagenet.com>
gzip, mini-netcat(nc)
Enrique Zanardi <ezanardi@ull.es>
tarcat (since removed), loadkmap, various fixes, Debian maintenance
Tito Ragusa <farmatito@tiscali.it>
devfsd and size optimizations in strings, openvt, chvt, deallocvt, hdparm,
fdformat, lsattr, chattr, id and eject.
Paul Fox <pgf@foxharp.boston.ma.us>
vi editing mode for ash, various other patches/fixes
Roberto A. Foglietta <me@roberto.foglietta.name>
port: dnsd
Bernhard Fischer <rep.nop@aon.at>
misc
Mike Frysinger <vapier@gentoo.org>
initial e2fsprogs, printenv, setarch, sum, misc
#
# For a description of the syntax of this configuration file,
# see scripts/kbuild/config-language.txt.
#
mainmenu "BusyBox Configuration"
config HAVE_DOT_CONFIG
bool
default y
menu "Busybox Settings"
menu "General Configuration"
config DESKTOP
bool "Enable options for full-blown desktop systems"
default n
help
Enable options and features which are not essential.
Select this only if you plan to use busybox on full-blown
desktop machine with common Linux distro, not on an embedded box.
config EXTRA_COMPAT
bool "Provide compatible behavior for rare corner cases (bigger code)"
default n
help
This option makes grep, sed etc handle rare corner cases
(embedded NUL bytes and such). This makes code bigger and uses
some GNU extensions in libc. You probably only need this option
if you plan to run busybox on desktop.
config FEATURE_ASSUME_UNICODE
bool "Assume that 1:1 char/glyph correspondence is not true"
default n
help
This makes various applets aware that one byte is not
one character on screen.
Busybox aims to eventually work correctly with Unicode displays.
Any older encodings are not guaranteed to work.
Probably by the time when busybox will be fully Unicode-clean,
other encodings will be mainly of historic interest.
choice
prompt "Buffer allocation policy"
default FEATURE_BUFFERS_USE_MALLOC
help
There are 3 ways BusyBox can handle buffer allocations:
- Use malloc. This costs code size for the call to xmalloc.
- Put them on stack. For some very small machines with limited stack
space, this can be deadly. For most folks, this works just fine.
- Put them in BSS. This works beautifully for computers with a real
MMU (and OS support), but wastes runtime RAM for uCLinux. This
behavior was the only one available for BusyBox versions 0.48 and
earlier.
config FEATURE_BUFFERS_USE_MALLOC
bool "Allocate with Malloc"
config FEATURE_BUFFERS_GO_ON_STACK
bool "Allocate on the Stack"
config FEATURE_BUFFERS_GO_IN_BSS
bool "Allocate in the .bss section"
endchoice
config SHOW_USAGE
bool "Show terse applet usage messages"
default y
help
All BusyBox applets will show help messages when invoked with
wrong arguments. You can turn off printing these terse usage
messages if you say no here.
This will save you up to 7k.
config FEATURE_VERBOSE_USAGE
bool "Show verbose applet usage messages"
default n
select SHOW_USAGE
help
All BusyBox applets will show more verbose help messages when
busybox is invoked with --help. This will add a lot of text to the
busybox binary. In the default configuration, this will add about
13k, but it can add much more depending on your configuration.
config FEATURE_COMPRESS_USAGE
bool "Store applet usage messages in compressed form"
default y
depends on SHOW_USAGE
help
Store usage messages in compressed form, uncompress them on-the-fly
when <applet> --help is called.
If you have a really tiny busybox with few applets enabled (and
bunzip2 isn't one of them), the overhead of the decompressor might
be noticeable. Also, if you run executables directly from ROM
and have very little memory, this might not be a win. Otherwise,
you probably want this.
config FEATURE_INSTALLER
bool "Support --install [-s] to install applet links at runtime"
default n
help
Enable 'busybox --install [-s]' support. This will allow you to use
busybox at runtime to create hard links or symlinks for all the
applets that are compiled into busybox.
config LOCALE_SUPPORT
bool "Enable locale support (system needs locale for this to work)"
default n
help
Enable this if your system has locale support and you would like
busybox to support locale settings.
config GETOPT_LONG
bool "Support for --long-options"
default y
help
Enable this if you want busybox applets to use the gnu --long-option
style, in addition to single character -a -b -c style options.
config FEATURE_DEVPTS
bool "Use the devpts filesystem for Unix98 PTYs"
default y
help
Enable if you want BusyBox to use Unix98 PTY support. If enabled,
busybox will use /dev/ptmx for the master side of the pseudoterminal
and /dev/pts/<number> for the slave side. Otherwise, BSD style
/dev/ttyp<number> will be used. To use this option, you should have
devpts mounted.
config FEATURE_CLEAN_UP
bool "Clean up all memory before exiting (usually not needed)"
default n
help
As a size optimization, busybox normally exits without explicitly
freeing dynamically allocated memory or closing files. This saves
space since the OS will clean up for us, but it can confuse debuggers
like valgrind, which report tons of memory and resource leaks.
Don't enable this unless you have a really good reason to clean
things up manually.
config FEATURE_PIDFILE
bool "Support writing pidfiles"
default n
help
This option makes some applets (e.g. crond, syslogd, inetd) write
a pidfile in /var/run. Some applications rely on them.
config FEATURE_SUID
bool "Support for SUID/SGID handling"
default n
help
With this option you can install the busybox binary belonging
to root with the suid bit set, and it'll and it'll automatically drop
priviledges for applets that don't need root access.
If you're really paranoid and don't want to do this, build two
busybox binaries with different applets in them (and the appropriate
symlinks pointing to each binary), and only set the suid bit on the
one that needs it. The applets currently marked to need the suid bit
are login, passwd, su, ping, traceroute, crontab, dnsd, ipcrm, ipcs,
and vlock.
config FEATURE_SUID_CONFIG
bool "Runtime SUID/SGID configuration via /etc/busybox.conf"
default n if FEATURE_SUID
depends on FEATURE_SUID
help
Allow the SUID / SGID state of an applet to be determined at runtime
by checking /etc/busybox.conf. (This is sort of a poor man's sudo.)
The format of this file is as follows:
<applet> = [Ssx-][Ssx-][x-] (<username>|<uid>).(<groupname>|<gid>)
An example might help:
[SUID]
su = ssx root.0 # applet su can be run by anyone and runs with
# euid=0/egid=0
su = ssx # exactly the same
mount = sx- root.disk # applet mount can be run by root and members
# of group disk and runs with euid=0
cp = --- # disable applet cp for everyone
The file has to be owned by user root, group root and has to be
writeable only by root:
(chown 0.0 /etc/busybox.conf; chmod 600 /etc/busybox.conf)
The busybox executable has to be owned by user root, group
root and has to be setuid root for this to work:
(chown 0.0 /bin/busybox; chmod 4755 /bin/busybox)
Robert 'sandman' Griebl has more information here:
<url: http://www.softforge.de/bb/suid.html >.
config FEATURE_SUID_CONFIG_QUIET
bool "Suppress warning message if /etc/busybox.conf is not readable"
default y
depends on FEATURE_SUID_CONFIG
help
/etc/busybox.conf should be readable by the user needing the SUID,
check this option to avoid users to be notified about missing
permissions.
config SELINUX
bool "Support NSA Security Enhanced Linux"
default n
help
Enable support for SELinux in applets ls, ps, and id. Also provide
the option of compiling in SELinux applets.
If you do not have a complete SELinux userland installed, this stuff
will not compile. Go visit
http://www.nsa.gov/selinux/index.html
to download the necessary stuff to allow busybox to compile with
this option enabled. Specifially, libselinux 1.28 or better is
directly required by busybox. If the installation is located in a
non-standard directory, provide it by invoking make as follows:
CFLAGS=-I<libselinux-include-path> \
LDFLAGS=-L<libselinux-lib-path> \
make
Most people will leave this set to 'N'.
config FEATURE_PREFER_APPLETS
bool "exec prefers applets"
default n
help
This is an experimental option which directs applets about to
call 'exec' to try and find an applicable busybox applet before
searching the PATH. This is typically done by exec'ing
/proc/self/exe.
This may affect shell, find -exec, xargs and similar applets.
They will use applets even if /bin/<applet> -> busybox link
is missing (or is not a link to busybox). However, this causes
problems in chroot jails without mounted /proc and with ps/top
(command name can be shown as 'exe' for applets started this way).
config BUSYBOX_EXEC_PATH
string "Path to BusyBox executable"
default "/proc/self/exe"
help
When Busybox applets need to run other busybox applets, BusyBox
sometimes needs to exec() itself. When the /proc filesystem is
mounted, /proc/self/exe always points to the currently running
executable. If you haven't got /proc, set this to wherever you
want to run BusyBox from.
# These are auto-selected by other options
config FEATURE_SYSLOG
bool "Support for logging to syslog"
default n
help
This option is auto-selected when you select any applet which may
send its output to syslog. You do not need to select it manually.
config FEATURE_HAVE_RPC
bool "RPC support"
default n
help
This is automatically selected if any of enabled applets need it.
You do not need to select it manually.
endmenu
menu 'Build Options'
config STATIC
bool "Build BusyBox as a static binary (no shared libs)"
default n
help
If you want to build a static BusyBox binary, which does not
use or require any shared libraries, then enable this option.
This can cause BusyBox to be considerably larger, so you should
leave this option false unless you have a good reason (i.e.
your target platform does not support shared libraries, or
you are building an initrd which doesn't need anything but
BusyBox, etc).
Most people will leave this set to 'N'.
config PIE
bool "Build BusyBox as a position independent executable"
default n
depends on !STATIC
help
(TODO: what is it and why/when is it useful?)
Most people will leave this set to 'N'.
config NOMMU
bool "Force NOMMU build"
default n
help
Busybox tries to detect whether architecture it is being
built against supports MMU or not. If this detection fails,
or if you want to build NOMMU version of busybox for testing,
you may force NOMMU build here.
Most people will leave this set to 'N'.
# PIE can be made to work with BUILD_LIBBUSYBOX, but currently
# build system does not support that
config BUILD_LIBBUSYBOX
bool "Build shared libbusybox"
default n
depends on !FEATURE_PREFER_APPLETS && !PIE && !STATIC
help
Build a shared library libbusybox.so.N.N.N which contains all
busybox code.
This feature allows every applet to be built as a tiny
separate executable. Enabling it for "one big busybox binary"
approach serves no purpose and increases code size.
You should almost certainly say "no" to this.
### config FEATURE_FULL_LIBBUSYBOX
### bool "Feature-complete libbusybox"
### default n if !FEATURE_SHARED_BUSYBOX
### depends on BUILD_LIBBUSYBOX
### help
### Build a libbusybox with the complete feature-set, disregarding
### the actually selected config.
###
### Normally, libbusybox will only contain the features which are
### used by busybox itself. If you plan to write a separate
### standalone application which uses libbusybox say 'Y'.
###
### Note: libbusybox is GPL, not LGPL, and exports no stable API that
### might act as a copyright barrier. We can and will modify the
### exported function set between releases (even minor version number
### changes), and happily break out-of-tree features.
###
### Say 'N' if in doubt.
config FEATURE_INDIVIDUAL
bool "Produce a binary for each applet, linked against libbusybox"
default y
depends on BUILD_LIBBUSYBOX
help
If your CPU architecture doesn't allow for sharing text/rodata
sections of running binaries, but allows for runtime dynamic
libraries, this option will allow you to reduce memory footprint
when you have many different applets running at once.
If your CPU architecture allows for sharing text/rodata,
having single binary is more optimal.
Each applet will be a tiny program, dynamically linked
against libbusybox.so.N.N.N.
You need to have a working dynamic linker.
config FEATURE_SHARED_BUSYBOX
bool "Produce additional busybox binary linked against libbusybox"
default y
depends on BUILD_LIBBUSYBOX
help
Build busybox, dynamically linked against libbusybox.so.N.N.N.
You need to have a working dynamic linker.
### config BUILD_AT_ONCE
### bool "Compile all sources at once"
### default n
### help
### Normally each source-file is compiled with one invocation of
### the compiler.
### If you set this option, all sources are compiled at once.
### This gives the compiler more opportunities to optimize which can
### result in smaller and/or faster binaries.
###
### Setting this option will consume alot of memory, e.g. if you
### enable all applets with all features, gcc uses more than 300MB
### RAM during compilation of busybox.
###
### This option is most likely only beneficial for newer compilers
### such as gcc-4.1 and above.
###
### Say 'N' unless you know what you are doing.
config LFS
bool "Build with Large File Support (for accessing files > 2 GB)"
default n
select FDISK_SUPPORT_LARGE_DISKS
help
If you want to build BusyBox with large file support, then enable
this option. This will have no effect if your kernel or your C
library lacks large file support for large files. Some of the
programs that can benefit from large file support include dd, gzip,
cp, mount, tar, and many others. If you want to access files larger
than 2 Gigabytes, enable this option. Otherwise, leave it set to 'N'.
config CROSS_COMPILER_PREFIX
string "Cross Compiler prefix"
default ""
help
If you want to build BusyBox with a cross compiler, then you
will need to set this to the cross-compiler prefix, for example,
"i386-uclibc-". Note that CROSS_COMPILE environment variable
or "make CROSS_COMPILE=xxx ..." will override this selection.
For native build leave it empty.
endmenu
menu 'Debugging Options'
config DEBUG
bool "Build BusyBox with extra Debugging symbols"
default n
help
Say Y here if you wish to examine BusyBox internals while applets are
running. This increases the size of the binary considerably, and
should only be used when doing development. If you are doing
development and want to debug BusyBox, answer Y.
Most people should answer N.
config DEBUG_PESSIMIZE
bool "Disable compiler optimizations"
default n
depends on DEBUG
help
The compiler's optimization of source code can eliminate and reorder
code, resulting in an executable that's hard to understand when
stepping through it with a debugger. This switches it off, resulting
in a much bigger executable that more closely matches the source
code.
config WERROR
bool "Abort compilation on any warning"
default n
help
Selecting this will add -Werror to gcc command line.
Most people should answer N.
choice
prompt "Additional debugging library"
default NO_DEBUG_LIB
help
Using an additional debugging library will make BusyBox become
considerable larger and will cause it to run more slowly. You
should always leave this option disabled for production use.
dmalloc support:
----------------
This enables compiling with dmalloc ( http://dmalloc.com/ )
which is an excellent public domain mem leak and malloc problem
detector. To enable dmalloc, before running busybox you will
want to properly set your environment, for example:
export DMALLOC_OPTIONS=debug=0x34f47d83,inter=100,log=logfile
The 'debug=' value is generated using the following command
dmalloc -p log-stats -p log-non-free -p log-bad-space \
-p log-elapsed-time -p check-fence -p check-heap \
-p check-lists -p check-blank -p check-funcs -p realloc-copy \
-p allow-free-null
Electric-fence support:
-----------------------
This enables compiling with Electric-fence support. Electric
fence is another very useful malloc debugging library which uses
your computer's virtual memory hardware to detect illegal memory
accesses. This support will make BusyBox be considerable larger
and run slower, so you should leave this option disabled unless
you are hunting a hard to find memory problem.
config NO_DEBUG_LIB
bool "None"
config DMALLOC
bool "Dmalloc"
config EFENCE
bool "Electric-fence"
endchoice
config INCLUDE_SUSv2
bool "Enable obsolete features removed before SUSv3?"
default y
help
This option will enable backwards compatibility with SuSv2,
specifically, old-style numeric options ('command -1 <file>')
will be supported in head, tail, and fold. (Note: should
affect renice too.)
config PARSE
bool "Uniform config file parser debugging applet: parse"
endmenu
menu 'Installation Options'
config INSTALL_NO_USR
bool "Don't use /usr"
default n
help
Disable use of /usr. Don't activate this option if you don't know
that you really want this behaviour.
choice
prompt "Applets links"
default INSTALL_APPLET_SYMLINKS
help
Choose how you install applets links.
config INSTALL_APPLET_SYMLINKS
bool "as soft-links"
help
Install applets as soft-links to the busybox binary. This needs some
free inodes on the filesystem, but might help with filesystem
generators that can't cope with hard-links.
config INSTALL_APPLET_HARDLINKS
bool "as hard-links"
help
Install applets as hard-links to the busybox binary. This might
count on a filesystem with few inodes.
config INSTALL_APPLET_SCRIPT_WRAPPERS
bool "as script wrappers"
help
Install applets as script wrappers that call the busybox binary.
config INSTALL_APPLET_DONT
bool "not installed"
depends on FEATURE_INSTALLER || FEATURE_SH_STANDALONE || FEATURE_PREFER_APPLETS
help
Do not install applet links. Useful when using the -install feature
or a standalone shell for rescue purposes.
endchoice
choice
prompt "/bin/sh applet link"
default INSTALL_SH_APPLET_SYMLINK
depends on INSTALL_APPLET_SCRIPT_WRAPPERS
help
Choose how you install /bin/sh applet link.
config INSTALL_SH_APPLET_SYMLINK
bool "as soft-link"
help
Install /bin/sh applet as soft-link to the busybox binary.
config INSTALL_SH_APPLET_HARDLINK
bool "as hard-link"
help
Install /bin/sh applet as hard-link to the busybox binary.
config INSTALL_SH_APPLET_SCRIPT_WRAPPER
bool "as script wrapper"
help
Install /bin/sh applet as script wrapper that call the busybox
binary.
endchoice
config PREFIX
string "BusyBox installation prefix"
default "./_install"
help
Define your directory to install BusyBox files/subdirs in.
endmenu
source libbb/Config.in
endmenu
comment "Applets"
source archival/Config.in
source coreutils/Config.in
source console-tools/Config.in
source debianutils/Config.in
source editors/Config.in
source findutils/Config.in
source init/Config.in
source loginutils/Config.in
source e2fsprogs/Config.in
source modutils/Config.in
source util-linux/Config.in
source miscutils/Config.in
source networking/Config.in
source procps/Config.in
source shell/Config.in
source sysklogd/Config.in
source runit/Config.in
source selinux/Config.in
source printutils/Config.in
Building:
=========
The BusyBox build process is similar to the Linux kernel build:
make menuconfig # This creates a file called ".config"
make # This creates the "busybox" executable
make install # or make CONFIG_PREFIX=/path/from/root install
The full list of configuration and install options is available by typing:
make help
Quick Start:
============
The easy way to try out BusyBox for the first time, without having to install
it, is to enable all features and then use "standalone shell" mode with a
blank command $PATH.
To enable all features, use "make defconfig", which produces the largest
general-purpose configuration. (It's allyesconfig minus debugging options,
optional packaging choices, and a few special-purpose features requiring
extra configuration to use.)
make defconfig
make
PATH= ./busybox ash
Standalone shell mode causes busybox's built-in command shell to run
any built-in busybox applets directly, without looking for external
programs by that name. Supplying an empty command path (as above) means
the only commands busybox can find are the built-in ones.
Note that the standalone shell requires CONFIG_BUSYBOX_EXEC_PATH
to be set appropriately, depending on whether or not /proc/self/exe is
available or not. If you do not have /proc, then point that config option
to the location of your busybox binary, usually /bin/busybox.
Configuring Busybox:
====================
Busybox is optimized for size, but enabling the full set of functionality
still results in a fairly large executable -- more than 1 megabyte when
statically linked. To save space, busybox can be configured with only the
set of applets needed for each environment. The minimal configuration, with
all applets disabled, produces a 4k executable. (It's useless, but very small.)
The manual configurator "make menuconfig" modifies the existing configuration.
(For systems without ncurses, try "make config" instead.) The two most
interesting starting configurations are "make allnoconfig" (to start with
everything disabled and add just what you need), and "make defconfig" (to
start with everything enabled and remove what you don't need). If menuconfig
is run without an existing configuration, make defconfig will run first to
create a known starting point.
Other starting configurations (mostly used for testing purposes) include
"make allbareconfig" (enables all applets but disables all optional features),
"make allyesconfig" (enables absolutely everything including debug features),
and "make randconfig" (produce a random configuration).
Configuring BusyBox produces a file ".config", which can be saved for future
use. Run "make oldconfig" to bring a .config file from an older version of
busybox up to date.
Installing Busybox:
===================
Busybox is a single executable that can behave like many different commands,
and BusyBox uses the name it was invoked under to determine the desired
behavior. (Try "mv busybox ls" and then "./ls -l".)
Installing busybox consists of creating symlinks (or hardlinks) to the busybox
binary for each applet enabled in busybox, and making sure these symlinks are
in the shell's command $PATH. Running "make install" creates these symlinks,
or "make install-hardlinks" creates hardlinks instead (useful on systems with
a limited number of inodes). This install process uses the file
"busybox.links" (created by make), which contains the list of enabled applets
and the path at which to install them.
Installing links to busybox is not always necessary. The special applet name
"busybox" (or with any optional suffix, such as "busybox-static") uses the
first argument to determine which applet to behave as, for example
"./busybox cat LICENSE". (Running the busybox applet with no arguments gives
a list of all enabled applets.) The standalone shell can also call busybox
applets without links to busybox under other names in the filesystem. You can
also configure a standaone install capability into the busybox base applet,
and then install such links at runtime with one of "busybox --install" (for
hardlinks) or "busybox --install -s" (for symlinks).
If you enabled the busybox shared library feature (libbusybox.so) and want
to run tests without installing, set your LD_LIBRARY_PATH accordingly when
running the executable:
LD_LIBRARY_PATH=`pwd` ./busybox
Building out-of-tree:
=====================
By default, the BusyBox build puts its temporary files in the source tree.
Building from a read-only source tree, or building multiple configurations from
the same source directory, requires the ability to put the temporary files
somewhere else.
To build out of tree, cd to an empty directory and configure busybox from there:
make -f /path/to/source/Makefile defconfig
make
make install
Alternately, use the O=$BUILDPATH option (with an absolute path) during the
configuration step, as in:
make O=/some/empty/directory allyesconfig
cd /some/empty/directory
make
make CONFIG_PREFIX=. install
More Information:
=================
Se also the busybox FAQ, under the questions "How can I get started using
BusyBox" and "How do I build a BusyBox-based system?" The BusyBox FAQ is
available from http://www.busybox.net/FAQ.html or as the file
docs/busybox.net/FAQ.html in this tarball.
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
busybox
\ No newline at end of file
busybox
\ No newline at end of file
busybox
\ No newline at end of file
busybox
\ No newline at end of file
busybox
\ No newline at end of file
busybox
\ No newline at end of file
busybox
\ No newline at end of file
busybox
\ No newline at end of file
busybox
\ No newline at end of file
busybox
\ No newline at end of file
busybox
\ No newline at end of file
busybox
\ No newline at end of file
busybox
\ No newline at end of file
busybox
\ No newline at end of file
busybox
\ No newline at end of file
busybox
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册