• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html><head><title>toybox FAQ</title>
2<!--#include file="header.html" -->
3
4<h1>Frequently Asked Questions</h1>
5
6<h2>General Questions</h2>
7
8<ul>
9<li><h2><a href="#why_toybox">Why toybox? (What was wrong with busybox?)</a></h2></li>
10<li><h2><a href="#capitalize">Do you capitalize toybox?</a></h2></li>
11<li><h2><a href="#support_horizon">Why a 7 year support horizon?</a></h2></li>
12<li><h2><a href="#releases">Why time based releases?</a></h2></li>
13<li><h2><a href="#code">Where do I start understanding the toybox source code?</a></h2></li>
14<li><h2><a href="#when">When were historical toybox versions released?</a></h2></li>
15<li><h2><a href="#bugs">Where do I report bugs?</a></h2></li>
16<li><h2><a href="#b_links">What are those /b/number links in the git log?</a></h2></li>
17<li><h2><a href="#opensource">What is the relationship between toybox and android?</a></h2></li>
18<li><h2><a href="#backporting">Will you backport fixes to old versions?</a></h2></li>
19<li><h2><a href="#dotslash">What's this ./ on the front of commands in your examples?</a></h2></li>
20
21</ul>
22
23<h2>Using toybox</h2>
24
25<ul>
26<!-- get binaries -->
27<li><h2><a href="#install">How do I install toybox?</h2></li>
28<li><h2><a href="#cross">How do I cross compile toybox?</h2></li>
29<li><h2><a href="#system">What part of Linux/Android does toybox provide?</h2></li>
30<li><h2><a href="#mkroot">How do I build a working Linux system with toybox?</a></h2></li>
31</ul>
32
33<hr /><h2><a name="why_toybox" />Q: "Why is there toybox? What was wrong with busybox?"</h2>
34
35<p>A: Toybox started back in 2006 when I (Rob Landley)
36<a href=https://lwn.net/Articles/202106/>handed off BusyBox maintainership</a>
37and <a href=http://landley.net/notes-2006.html#28-09-2006>started over from
38scratch</a> on a new codebase after a
39<a href=http://lists.busybox.net/pipermail/busybox/2006-September/058617.html>protracted licensing argument</a> took all the fun out of working on BusyBox.</p>
40
41<p>Toybox was just a personal project until it got
42<a href=http://landley.net/notes-2011.html#13-11-2011>relaunched</a>
43in November 2011 with a new goal to make Android
44<a href=http://landley.net/aboriginal/about.html#selfhost>self-hosting</a>.
45This involved me relicensing my own
46code, which made people who had never used or participated in the project
47<a href=https://lwn.net/Articles/478308/>loudly angry</a>. The switch came
48after a lot of thinking <a href=http://landley.net/talks/ohio-2013.txt>about
49licenses</a> and <a href=http://landley.net/notes-2011.html#21-03-2011>the
50transition to smartphones</a>, which led to a
51<a href=https://www.youtube.com/watch?v=SGmtP5Lg_t0>2013 talk</a> laying
52out a
53<a href=http://landley.net/talks/celf-2013.txt>strategy</a>
54to make Android self-hosting using toybox. This helped
55<a href=https://code.google.com/p/android/issues/detail?id=76861>bring
56it to Android's attention</a>, and they
57<a href=https://lwn.net/Articles/629362/>merged it</a> into Android M.</p>
58
59<p>The unfixable problem with busybox was licensing: BusyBox predates Android
60by almost a decade, but Android still doesn't ship with it because GPLv3 came
61out around the same time Android did and caused many people to throw
62out the GPLv2 baby with the GPLv3 bathwater.
63Android <a href=https://source.android.com/source/licenses.html>explicitly
64discourages</a> use of GPL and LGPL licenses in its products, and has gradually
65reimplemented historical GPL components (such as its bluetooth stack) under the
66Apache license. Apple's
67<a href=http://meta.ath0.com/2012/02/05/apples-great-gpl-purge/>less subtle</a> response was to freeze xcode at the last GPLv2 releases
68(GCC 4.2.1 with binutils 2.17) for over 5 years while sponsoring the
69development of new projects (clang/llvm/lld) to replace them,
70implementing a
71<a href=https://www.osnews.com/story/24572/apple-ditches-samba-in-favour-of-homegrown-replacement/>new SMB server</a> from scratch to
72<a href=https://archive.org/details/copyleftconf2020-allison>replace samba</a>,
73switching <a href=https://www.theverge.com/2019/6/4/18651872/apple-macos-catalina-zsh-bash-shell-replacement-features>bash with zsh</a>, and so on.
74Toybox itself exists because somebody with in a legacy position
75just wouldn't shut up about GPLv3, otherwise I would probably
76still happily be maintaining BusyBox. (For more on how I wound
77up working on busybox in the first place,
78<a href=http://landley.net/aboriginal/history.html>see here</a>.)</p>
79
80<hr /><h2><a name="capitalize" />Q: Do you capitalize toybox?</h2>
81
82<p>A: Only at the start of a sentence. The command name is all lower case so
83it seems silly to capitalize the project name, but not capitalizing the
84start of sentences is awkward, so... compromise. (It is _not_ "ToyBox".)</p>
85
86<hr /><h2><a name="support_horizon">Q: Why a 7 year support horizon?</a></h2>
87
88<p>A: Our <a href=http://lists.busybox.net/pipermail/busybox/2006-September/058440.html>longstanding rule of thumb</a> is to try to run and build on
89hardware and distributions released up to 7 years ago, and feel ok dropping
90support for stuff older than that. (This is a little longer than Ubuntu's
91Long Term Support, but not by much.)</p>
92
93<p>My original theory was "4 to 5 of the 18-month cycles of moore's law should cover
94the vast majority of the installed base of PC hardware", loosely based on some
95research I did <a href=http://www.catb.org/esr/halloween/halloween9.html#id2867629>back in 2003</a>
96and <a href=http://catb.org/esr/writings/world-domination/world-domination-201.html#id248066>updated in 2006</a>
97which said that low end systems were 2 iterations of moore's
98law below the high end systems, and that another 2-3 iterations should cover
99the useful lifetime of most systems no longer being sold but still in use and
100potentially being upgraded to new software releases.</p>
101
102<p>That analysis missed <a href=http://landley.net/notes-2011.html#26-06-2011>industry
103changes</a> in the 1990's that stretched the gap
104from low end to high end from 2 cycles to 4 cycles, and ignored
105<a href=https://landley.net/notes-2010.html#09-10-2010>the switch</a> from PC to smartphone cutting off the R&D air supply of the
106laptop market. Meanwhile the Moore's Law <a href=https://en.wikipedia.org/wiki/Logistic_function>s-curve</a> started bending back down (as they
107<a href=https://en.wikipedia.org/wiki/Diffusion_of_innovations>always do</a>)
108back in 2000, and these days is pretty flat: the drive for faster clock
109speeds <a href=http://www.anandtech.com/show/613>stumbled</a>
110and <a href=http://www.pcworld.com/article/118603/article.html>died</a>, with
111the subsequent drive to go "wide" maxing out for most applications
112around 4x SMP with maybe 2 megabyte caches. These days the switch from exponential to
113linear growth in hardware capabilities is
114<a href=https://www.cnet.com/news/end-of-moores-law-its-not-just-about-physics/>common knowledge</a> and
115<a href=http://www.acm.org/articles/people-of-acm/2016/david-patterson>widely
116accepted</a>.</p>
117
118<p>But the 7 year rule of thumb stuck around anyway: if a kernel or libc
119feature is less than 7 years old, I try to have a build-time configure test
120for it to let the functionality cleanly drop out. I also keep old Ubuntu
121images around in VMs to perform the occasional defconfig build there to
122see what breaks. (I'm not perfect about this, but I accept bug reports.)</p>
123
124<hr /><h2><a name="releases" />Q: Why time based releases?</h2>
125<p>A: Toybox targets quarterly releases (a similar schedule to the Linux
126kernel) because Martin Michlmayr's excellent
127<a href=http://www.youtube.com/watch?v=IKsQsxubuAA>talk on the
128subject</a> was convincing. This is actually two questions, "why have
129releases" and "why schedule them".</p>
130
131<p>Releases provide synchronization points where the developers certify
132"it worked for me". Each release is a known version with predictable behavior,
133and right or wrong at least everyone should be seeing
134similar results so might be able to google an unexpected outcome.
135Releases focus end-user testing on specific versions
136where issues can be reproduced, diagnosed, and fixed.
137Releases also force the developers to do periodic tidying, packaging,
138documentation review, finish up partially implemented features languishing
139in their private trees, and give regular checkpoints to measure progress.</p>
140
141<p>Changes accumulate over time: different feature sets, data formats,
142control knobs... Toybox's switch from "ls -q" to "ls -b" as the default output
143format was not-a-bug-it's-a "design improvement", but the
144difference is academic if the change breaks somebody's script.
145Releases give you the option to schedule upgrades as maintenance, not to rock
146the boat just now, and use a known working release version until later.</p>
147
148<p>The counter-argument is that "continuous integration"
149can be made robust with sufficient automated testing. But like the
150<a href=https://web.archive.org/web/20131123071427/http://www.shirky.com/weblog/2013/11/healthcare-gov-and-the-gulf-between-planning-and-reality/>waterfall method</a>, this places insufficent
151emphasis on end-user feedback and learning from real world experience.
152Developer testing is either testing that the code does what the developers
153expect given known inputs running in an established environment, or it's
154regression testing against bugs previously found in the field. No plan
155survives contact with the enemy, and technology always breaks once it
156leaves the lab and encounters real world data and use cases in new
157runtime and build environments.</p>
158
159<p>The best way to give new users a reasonable first experience is to point
160them at specific stable versions where development quiesced and
161extra testing occurred. There will still be teething troubles, but multiple
162people experiencing the _same_ teething troubles can potentially
163help each other out.</p>
164
165<p>Releases on a schedule are better than releases "when it's ready" for
166the same reason a regularly scheduled bus beats one that leaves when it's
167"full enough": the schedule lets its users make plans. Even if the bus leaves
168empty you know when the next one arrives so missing this one isn't a disaster.
169and starting the engine to leave doesn't provoke a last-minute rush of nearby
170not-quite-ready passengers racing to catch it causing further delay and
171repeated start/stop cycles as it ALMOST leaves.
172(The video in the first paragraph goes into much greater detail.)</p>
173
174<hr /><h2><a name="code" />Q: Where do I start understanding the source code?</h2>
175
176<p>A: Toybox is written in C. There are longer writeups of the
177<a href=design.html>design ideas</a> and a <a href=code.html>code walkthrough</a>,
178and the <a href=about.html>about page</a> summarizes what we're trying to
179accomplish, but here's a quick start:</p>
180
181<p>Toybox uses the standard three stage configure/make/install
182<a href=code.html#building>build</a>, in this case "<b>make defconfig;
183make; make install</b>". Type "<b>make help</b>" to
184see available make targets.</p>
185
186<p><u>The configure stage</u> is copied from the Linux kernel (in the "kconfig"
187directory), and saves your selections in the file ".config" at the top
188level. The "<b>make defconfig</b>" target selects the
189maximum sane configuration (enabling all the commands and features that
190aren't unfinished, or only intended as examples, or debug code...) and is
191probably what you want. You can use "<b>make menuconfig</b>" to manually select
192specific commands to include, through an interactive menu (cursor up and
193down, enter to descend into a sub-menu, space to select an entry, ? to see
194an entry's help text, esc to exit). The menuconfig help text is the
195same as the command's "<b>--help</b>" output.</p>
196
197<p><u>The "make" stage</u> creates a toybox binary (which is stripped, look in
198generated/unstripped for the debug versions), and "<b>make install</b>" adds a bunch of
199symlinks to toybox under the various command names. Toybox determines which
200command to run based on the filename, or you can use the "toybox" name in which case the first
201argument is the command to run (ala "toybox ls -l").</p>
202
203<p><u>You can also build
204individual commands as standalone executables</u>, ala "make sed cat ls".
205The "make change" target builds all of them, as in "change for a $20".</p>
206
207<p><u>The main() function is in main.c</u> at the top level,
208along with setup plumbing and selecting which command to run this time.
209The function toybox_main() in the same file implements the "toybox"
210multiplexer command that lists and selects the other commands.</p>
211
212<p><u>The individual command implementations are under "toys"</u>, and are grouped
213into categories (mostly based on which standard they come from, posix, lsb,
214android...) The "pending" directory contains unfinished commands, and the
215"examples" directory contains example code that aren't really useful commands.
216Commands in those two directories
217are _not_ selected by defconfig. (Most of the files in the pending directory
218are third party submissions that have not yet undergone
219<a href=cleanup.html>proper code review</a>.)</p>
220
221<p><u>Common infrastructure shared between commands is under "lib"</u>. Most
222commands call lib/args.c to parse their command line arguments before calling
223the command's own main() function, which uses the option string in
224the command's NEWTOY() macro. This is similar to the libc function getopt(),
225but more powerful, and is documented at the top of lib/args.c. A NULL option
226string prevents this code from being called for that command.</p>
227
228<p><u>The build/install infrastructure is shell scripts under
229"scripts"</u> (starting with scripts/make.sh and scripts/install.sh).
230<u>These populate the "generated" directory</u> with headers
231created from other files, which are <a href=code.html#generated>described</a>
232in the code walkthrough. All the
233build's temporary files live under generated, including the .o files built
234from the .c files (in generated/obj). The "make clean" target deletes that
235directory. ("make distclean" also deletes your .config and deletes the
236kconfig binaries that process .config.)</p>
237
238<p><u>Each command's .c file contains all the information for that command</u>, so
239adding a command to toybox means adding a single file under "toys".
240Usually you <a href=code.html#adding>start a new command</a> by copying an
241existing command file to a new filename
242(toys/examples/hello.c, toys/examples/skeleton.c, toys/posix/cat.c,
243and toys/posix/true.c have all been used for this purpose) and then replacing
244all instances of its old name with the new name (which should match the
245new filename), and modifying the help text, argument string, and what the
246code does. You might have to "make distclean" before your new command
247shows up in defconfig or menuconfig.</p>
248
249<p><u>The toybox test suite lives in the "tests" directory</u>, and is
250driven by scripts/test.sh and scripts/runtest.sh. From the top
251level you can "make tests" to test everything, or "make test_sed" to test a
252single command's standalone version (which should behave identically,
253but that's why we test). You can set TEST_HOST=1 to test the host version
254instead of the toybox version (in theory they should work the same),
255and VERBOSE=1 to see diffs of the expected and actual output when a
256test fails. Set VERBOSE=fail to stop at the first such failure.</p>
257
258<hr /><h2><a name="when" />Q: When were historical toybox versions released?</h2>
259
260<p>A: For vanilla releases, check the
261<a href=https://github.com/landley/toybox/tags>date on the commit tag</a>
262or <a href=https://landley.net/toybox/downloads/binaries/>the
263example binaries</a> against the output of "toybox --version".
264Between releases the --version
265information is in "git describe --tags" format with "tag-count-hash" showing the
266most recent commit tag, the number of commits since that tag, and
267the hash of the current commit.</p>
268
269<p>Android makes its own releases on its own
270<a href=https://en.wikipedia.org/wiki/Android_version_history>schedule</a>
271using its own version tags, but lists corresponding upstream toybox release
272versions <a href=https://android.googlesource.com/platform/system/core/+/master/shell_and_utilities/README.md>here</a>. For more detail you can look up
273<a href=https://android.googlesource.com/platform/external/toybox/+refs>AOSP's
274git tags</a>. (The <a href=https://source.android.com/setup/start>Android Open Source Project</a> is the "upstream" android vendors
275start form when making their own releases. Google's phones run AOSP versions
276verbatim, other vendors tend to take those releases as starting points to
277modify.)</p>
278
279<p>If you want to find the vanilla toybox commit corresponding to an AOSP
280toybox version, find the most recent commit in the android log that isn't from a
281@google or @android address and search for it in the vanilla commit log.
282(The timestamp should match but the hash will differ,
283because each git hash includes the previous
284git hash in the data used to generate it so all later commits have a different
285hash if any of the tree's history differs; yes Linus Torvalds published 3 years
286before Satoshi Nakamoto.) Once you've identified the vanilla commit's hash,
287"git describe --tags $HASH" in the vanilla tree should give you the --version
288info for that one.</p>
289
290<hr /><h2><a name="bugs" />Q: Where do I report bugs?</h2>
291
292<p>A: Ideally on the <a href=http://lists.landley.net/listinfo.cgi/toybox-landley.net>mailing list</a>, although <a href=mailto:rob@landley.net>emailing the
293maintainer</a> is a popular if slightly less reliable alternative.
294Issues submitted to <a href=https://github.com/landley/toybox>github</a>
295are generally dealt with less promptly, but mostly get done eventually.
296AOSP has its <a href=https://source.android.com/setup/contribute/report-bugs>own bug reporting mechanism</a> (although for toybox they usually forward them
297to the mailing list) and Android vendors usually forward them to AOSP which
298forwards them to the list.</p>
299
300<p>Note that if we can't reproduce a bug, we probably can't fix it.
301Not only does this mean providing enough information for us to see the
302behavior ourselves, but ideally doing so in a reasonably current version.
303The older it is the greater the chance somebody else found and fixed it
304already, so the more out of date the version you're reporting a bug against
305the less effort we're going to put into reproducing the problem.</p>
306
307<hr /><h2><a name="b_links" />Q: What are those /b/number bug report
308links in the git log?</h2>
309
310<p>A: It's a Google thing. Replace /b/$NUMBER with
311https://issuetracker.google.com/$NUMBER to read it outside the googleplex.</p>
312
313<hr /><a name="opensource" /><h2>Q: What is the relationship between toybox and android?</h2>
314
315<p>A: The <a href=about.html>about page</a> tries to explain that,
316and Linux Weekly News has covered toybox's history a
317<a href=https://lwn.net/Articles/202106/>little</a>
318<a href=https://lwn.net/Articles/478308/>over</a>
319<a href=https://lwn.net/Articles/616272/>the</a>
320<a href=https://lwn.net/Articles/629362/>years</a>.</p>
321
322<p>Toybox is a traditional open source project created and maintained
323by hobbyist (volunteer) developers, originally for Linux but these days
324also running on Android, BSD, and MacOS. The project started in 2006
325and its original author (Rob Landley)
326continues to maintain the open source project.</p>
327
328<p>Android's base OS maintainer (Elliott Hughes, I.E. enh)
329<a href=https://github.com/landley/toybox/commit/69a9f257234a>ported</a>
330<a href=https://github.com/landley/toybox/commit/6a29bb1ebe62>toybox</a>
331to Android in 2014, merged it into Android M (Marshmallow), and remains
332Android's toybox maintainer. (He explained it in his own words in
333<a href=http://androidbackstage.blogspot.com/2016/07/episode-53-adb-on-adb.html>this podcast</a>, starting either 18 or 20 minutes in depending how
334much backstory you want.)</p>
335
336<p>Android's policy for toybox development is to push patches to the
337open source project (submitting them via the mailing list) then
338"git pull" the public tree into Android's tree. To avoid merge conflicts, Android's
339tree doesn't change any of the existing toybox files but instead adds <a href=https://android.googlesource.com/platform/external/toybox/+/refs/heads/master/Android.bp>parallel
340build infrastructure</a> off to one side. (Toybox uses a make wrapper around bash
341scripts, AOSP builds with soong/ninja instead and checks in a snapshot of the
342generated/ directory to avoid running kconfig each build).
343Android's changes to toybox going into the open source tree first
344and being pulled from there into Android keeps the two trees in
345sync, and makes sure each change undergoes full open source design review
346and discussion.</p>
347
348<p>Rob acknowledges Android is by far the largest userbase for the project,
349but develops on a standard 64-bit Linux+glibc distro while building embedded
35032-bit big-endian nommu musl systems requiring proper data alignment for work,
351and is not a Google employee so does not have access
352to the Google build cluster of powerful machines capable of running the full
353AOSP build in a reasonable amount of time. Rob is working to get android
354building under android (the list of
355toybox tools Android's build uses is
356<a href=https://android.googlesource.com/platform/prebuilts/build-tools/+/refs/heads/master/path/linux-x86/>here</a>,
357and what else it needs from its build environment is
358<a href=https://android.googlesource.com/platform/build/soong/+/refs/heads/master/ui/build/paths/config.go>here</a>), and he hopes someday to not only make a usable development
359environment out of it but also nudge the base OS towards a more granular
360package management system allowing you to upgrade things like toybox without
361a complete reinstall and reboot, plus the introduction of a "posix container"
362within which you can not only run builds, but selinux lets you run binaries
363you've just built). In the meantime, Rob tests static bionic
364builds via the Android NDK when he remembers, but has limited time to work
365on toybox because it's not his day job. (The products his company makes ship
366toybox and they do sponsor the project's development, but it's one of many
367responsibilities at work.)</p>
368
369<p>Elliott is the Android base OS maintainer, in which role he manages
370a team of engineers. He also has limited time for toybox, both because it's one
371of many packages he's responsible for (he maintains bionic, used to maintain
372dalvik...) and because he allowed himself to be promoted into management
373and thus spends less time coding than he does sitting in meetings where testers
374talk to security people about vendor issues.</p>
375
376<p>Android has many other coders and security people who submit the occasional
377toybox patch, but of the last 1000 commits at the <a href=https://github.com/landley/toybox/commit/88b34c4bd3f8>time
378of writing</a> this FAQ entry, Elliott submitted 276 and all other google.com
379or android.com addresses combined totaled 17. (Rob submitted 591, leaving
380116 from other sources, but for both Rob and Elliott there's a lot of "somebody
381else pointed out an issue, and then we wrote a patch". A lot of patches
382from both "Author:" lines thank someone else for the suggestion in the
383commit comment.)</p>
384
385<hr /><a name="backporting" /><h2>Q: Will you backport fixes to old versions?</h2>
386
387<p>A: Probably not. The easiest thing to do is get your issue fixed upstream
388in the current release, then get the newest version of the
389project built and running in the old environment.</p>
390
391<p>Backporting fixes generally isn't something open source projects run by
392volunteer developers do because the goal of the project's development community
393is to extend and improve the project. We're happy to respond to our users'
394needs, but if you're coming to the us for free tech support we're going
395to ask you to upgrade to a current version before we try to diagnose your
396problem.</p>
397
398<p>The volunteers are happy to fix any bugs you point out in the current
399versions because doing so helps everybody and makes the project better. We
400want to make the current version work for you. But diagnosing, debugging, and
401backporting fixes to old versions doesn't help anybody but you, so isn't
402something we do for free. The cost of volunteer tech support is using a
403reasonably current version of the project.</p>
404
405<p>If you're using an old version built with an old
406compiler on an old OS (kernel and libc), there's a fairly large chance
407whatever problem you're
408seeing already got fixed, and to get that fix all you have to do is upgrade
409to a newer version. Diagnosing a problem that wasn't our bug means we spent
410time that only helps you, without improving the project.
411If you don't at least _try_ a current version, you're asking us for free
412personalized tech support.</p>
413
414<p>Reproducing bugs in current versions also makes our job easier.
415The further back in time
416you are, the more work it is for us digging back in the history to figure
417out what we hadn't done yet in your version. If spot a problem in a git
418build pulled 3 days ago, it's obvious what changed and easy to fix or back out.
419If you ask about the current release version 3 months after it came out,
420we may have to think a while to remember what we did and there are a number of
421possible culprits, but it's still tractable. If you ask about 3 year old
422code, we have to reconstruct the history and the problem could be anything,
423there's a lot more ground to cover and we haven't seen it in a while.</p>
424
425<p>As a rule of thumb, volunteers will generally answer polite questions about
426a given version for about three years after its release before it's so old
427we don't remember the answer off the top of our head. And if you want us to
428put any _effort_ into tracking it down, we want you to put in a little effort
429of your own by confirming it's still a problem with the current version
430(I.E. we didn't fix it already). It's
431also hard for us to fix a problem of yours if we can't reproduce it because
432we don't have any systems running an environment that old.</p>
433
434<p>If you don't want to upgrade, you have the complete source code and thus
435the ability to fix it yourself, or can hire a consultant to do it for you. If
436you got your version from a vendor who still supports the older version, they
437can help you. But there are limits as to what volunteers will feel obliged to
438do for you.</p>
439
440<p>Commercial companies have different incentives. Your OS vendor, or
441hardware vendor for preinstalled systems, may have their own bug reporting
442mechanism and update channel providing backported fixes. And a paid consultant
443will happily set up a special environment just to reproduce your problem.</p>
444
445<hr /><h2><a name="install" />Q: How do I install toybox?</h2>
446
447<p>A:
448Multicall binaries like toybox behave differently based on the filename
449used to call them, so if you "mv toybox ls; ./ls -l" it acts like ls. Creating
450symlinks or hardlinks and adding them to the $PATH lets you run the
451commands normally by name, so that's probably what you want to do.</p>
452
453<p>If you already have a <a href=https://landley.net/toybox/downloads/binaries/>toybox binary</a>
454you can install a tree of command symlinks to
455<a href=http://git.musl-libc.org/cgit/musl/tree/include/paths.h>the
456standard path</a>
457locations (<b>export PATH=/bin:/usr/bin:/sbin:/usr/sbin</b>) by doing:</p>
458
459<blockquote><p><b>for i in $(/bin/toybox --long); do ln -s /bin/toybox $i; done</b></p></blockquote>
460
461<p>Or you can install all the symlinks in the same directory as the toybox binary
462(<b>export PATH="$PWD:$PATH"</b>) via:</p>
463
464<blockquote><p><b>for i in $(./toybox); do ln -s toybox $i; done</b></p></blockquote></p>
465
466<p>When building from source, use the "<b>make install</b>" and
467"<b>make install_flat</b>"
468targets with an appropriate <b>PREFIX=/target/path</b> either
469exported or on the make command line. When cross compiling,
470"<b>make list</b>" outputs the command names enabled by defconfig.
471For more information, see "<b>make help</b>".</p>
472
473<p>The command name "toybox" takes the second argument as the name of the
474command to run, so "./toybox ls -l" also behaves like ls. The "toybox"
475name is special in that it can have a suffix (toybox-i686 or toybox-1.2.3)
476and still be recognized, so you can have multiple versions of toybox in the
477same directory.</p>
478
479<p>When toybox doesn't recognize its
480filename as a command, it dereferences one
481level of symlink. So if your script needs "gsed" you can "ln -s sed gsed",
482then when you run "gsed" toybox knows how to be "sed".</p>
483
484<hr /><h2><a name="dotslash" />Q: What's this ./ on the front of commands in your examples?</h2>
485
486<p>A: When you don't give a path to a command's executable file,
487linux command shells search the directories listed in the $PATH envionment
488variable (in order), which usually doesn't include the current directory
489for security reasons. The
490magic name "." indicates the current directory (the same way ".." means
491the parent directory and starting with "/" means the root directory)
492so "./file" gives a path to the executable file, and thus runs a command
493out of the current directory where just typing "file" won't find it.
494For historical reasons PATH is colon-separated, and treats an
495empty entry (including leading/trailing colon) as "check the current
496directory", so if you WANT to add the current directory to PATH you
497can PATH="$PATH:" but doing so is a TERRIBLE idea.</p>
498
499<p>Toybox's shell (toysh) checks for built-in commands before looking at the
500$PATH (using the standard "bash builtin" logic just with lots more builtins),
501so "ls" doesn't have to exist in your filesystem for toybox to find it. When
502you give a path to a command the shell won't run the built-in version
503but will run the file at that location. (But the multiplexer command
504won't: "toybox /bin/ls" runs the built-in ls, you can't point it at an
505arbitrary file out of the filesystem and have it run that. You could
506"toybox nice /bin/ls" though.)</p>
507
508<hr /><h2><a name="standalone" />Q: How do I make individual/standalone toybox command binaries?</h2>
509
510<p>After running the configure step (generally "make defconfig")
511you can "make list" to see available command names you can use as build
512targets to build just that command
513(ala "make sed"). Commands built this way do not contain a multiplexer and
514don't care what the command filename is.</p>
515
516<p>The "make change" target (as in change for a $20) builds every command
517standalone (in the "change" subdirectory). Note that this is collectively
518about 10 times as large as the multiplexer version, both in disk space and
519runtime memory. (Even more when statically linked.)</p>
520
521<hr /><h2><a name="cross" />Q: How do I cross compile toybox?</h2>
522
523<p>A: You need a compiler "toolchain" capable of producing binaries that
524run on your target. A toolchain is an
525integrated suite of compiler, assembler, and linker, plus the standard
526headers and
527libraries necessary to build C programs. (And a few miscellaneous binaries like
528nm and objdump.)</p>
529
530<p>Toybox is tested against two compilers (llvm, gcc) and three C libraries
531(bionic, musl, glibc) in the following combinations:</p>
532
533<a name="cross1" />
534<p><a href="#cross1">1) gcc+glibc = host toolchain</a></p>
535
536<p>Most Linux distros come with that as a host compiler, which is used by
537default when you build normally
538(<b>make distclean defconfig toybox</b>, or <b>make menuconfig</b> followed
539by <b>make</b>).</p>
540
541<p>You can use LDFLAGS=--static if you want static binaries, but static
542glibc is hugely inefficient ("hello world" is 810k on x86-64) and throws a
543zillion linker warnings because one of its previous maintainers
544<a href=https://www.akkadia.org/drepper/no_static_linking.html>was insane</a>
545(which meant at the time he refused to fix
546<a href=https://elinux.org/images/2/2d/ELC2010-gc-sections_Denys_Vlasenko.pdf>obvious bugs</a>), plus it uses dlopen() at runtime to implement basic things like
547<a href=https://stackoverflow.com/questions/15165306/compile-a-static-binary-which-code-there-a-function-gethostbyname>DNS lookup</a> (which is almost impossible
548to support properly from a static binary because you wind up with two
549instances of malloc() managing two heaps which corrupt as soon as a malloc()
550from one is free()d into the other, although glibc added
551<a href=https://stackoverflow.com/questions/14289488/use-dlsym-on-a-static-binary>improper support</a> which still requires the shared libraries to be
552installed on the system alongside the static binary:
553<a href=https://www.youtube.com/watch?v=Ih-3vK2qLls>in brief, avoid</a>).
554These days glibc is <a href=https://blog.aurel32.net/175>maintained
555by a committee</a> instead of a single
556maintainer, if that's an improvement. (As with Windows and
557Cobol, most people deal with it and get on with their lives.)</p>
558
559<a name="cross2" />
560<p><a href="#cross2">2) gcc+musl = musl-cross-make</a></p>
561
562<p>The cross compilers I test this with are built from the
563<a href=http://musl.libc.org/>musl-libc</a> maintainer's
564<a href=https://github.com/richfelker/musl-cross-make>musl-cross-make</a>
565project, built by running toybox's scripts/mcm-buildall.sh in that directory,
566and then symlink the resulting "ccc" subdirectory into toybox where
567"make root CROSS=" can find them, ala:</p>
568
569<blockquote><b><pre>
570cd ~
571git clone https://github.com/landley/toybox
572git clone https://github.com/richfelker/musl-cross-make
573cd musl-cross-make
574../toybox/scripts/mcm-buildall.sh # this takes a while
575ln -s $(realpath ccc) ../toybox/ccc
576</pre></b></blockquote>
577
578<p>Instead of symlinking ccc, you can specify a CROSS_COMPILE= prefix
579in the same format the Linux kernel build uses. You can either provide a
580full path in the CROSS_COMPILE string, or add the appropriate bin directory
581to your $PATH. I.E:</p>
582
583<blockquote>
584<b><p>make LDFLAGS=--static CROSS_COMPILE=~/musl-cross-make/ccc/m68k-linux-musl-cross/bin/m68k-linux-musl- distclean defconfig toybox</p></b>
585</blockquote>
586
587<p>Is equivalent to:</p>
588
589<blockquote><b><p>
590export "PATH=~/musl-cross-make/ccc/m68k-linux-musl-cross/bin:$PATH"<br />
591LDFLAGS=--static make distclean defconfig toybox CROSS=m68k-linux-musl-
592</p></b></blockquote>
593
594<p>Note: these examples use static linking becausae a dynamic musl binary
595won't run on your host unless you install musl's libc.so into the system
596libraries (which is an accident waiting to happen adding a second C library
597to most glibc linux distribution) or play with $LD_LIBRARY_PATH.
598In theory you could "make root" a dynamic root filesystem with musl by copying
599the shared libraries out of the toolchain, but I haven't bothered implementing
600that in mkroot yet because a static linked musl hello world is 10k on x86
601(5k if stripped).</p>
602
603<a name="cross3" />
604<p><a href="#cross3">3) llvm+bionic = Android NDK</a></p>
605
606<p>The <a href=https://developer.android.com/ndk/downloads>Android
607Native Development Kit</a> provides an llvm toolchain with the bionic
608libc used by Android. To turn it into something toybox can use, you
609just have to add an appropriately prefixed "cc" symlink to the other
610prefixed tools, ala:</p>
611
612<blockquote><b><pre>
613unzip android-ndk-r21b-linux-x86_64.zip
614cd android-ndk-21b/toolchains/llvm/prebuilt/linux-x86_64/bin
615ln -s x86_64-linux-android29-clang x86_64-linux-android-cc
616PATH="$PWD:$PATH"
617cd ~/toybox
618make distclean
619make LDFLAGS=--static CROSS_COMPILE=x86_64-linux-android- defconfig toybox
620</pre></b></blockquote>
621
622<p>Again, you need to static link unless you want to install bionic on your
623host. Binaries statically linked against bionic are almost as big as with
624glibc, but at least it doesn't have the dlopen() issues. (You still can't
625sanely use dlopen() from a static binary, but bionic doesn't use dlopen()
626internally to implement basic features.)</p>
627
628<p>Note: although the resulting toybox will run in a standard
629Linux system, even "hello world"
630statically linked against bionic segfaults before calling main()
631when /dev/null isn't present. This presents mkroot with a chicken and
632egg problem for both chroot and qemu cases, because mkroot's init script
633has to mount devtmpfs on /dev to provide /dev/null before the shell binary
634can run mkroot's init script.
635Since mkroot runs as a normal user, we can't "mknod dev/null" at build
636time to create a "null" device in the filesystem we're packaging up so
637initramfs doesn't start with an empty /dev, and the
638<a href=https://lkml.org/lkml/2016/6/22/686>kernel</a>
639<a href=https://lkml.org/lkml/2017/5/14/180>developers</a>
640<a href=https://lkml.org/lkml/2017/9/13/651>repeatedly</a>
641<a href=https://lkml.org/lkml/2020/5/14/1584>rejected</a> a patch to
642make the Linux kernel honor DEVTMPFS_MOUNT in initramfs. Teaching toybox
643cpio to accept synthetic filesystem metadata,
644presumably in <a href=https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt>get_init_cpio</a> format, remains a todo item.</p>
645
646<hr /><h2><a name="system" />Q: What part of Linux/Android does toybox provide?</h2>
647
648<p>A:
649Toybox is one of three packages (linux, libc, command line) which together provide a bootable unix-style command line operating system.
650Toybox provides the "command line" part, with a
651<a href=https://en.wikipedia.org/wiki/Bash_(Unix_shell)>bash</a> compatible
652<a href=https://en.wikipedia.org/wiki/Unix_shell>command line interpreter</a>
653and over two hundred <a href=https://landley.net/toybox/help.html>commands</a>
654to call from it, as documented in
655<a href=https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/>posix</a>,
656the <a href=https://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/cmdbehav.html>Linux Standard Base</a>, and the
657<a href=https://man7.org/linux/man-pages/dir_section_1.html>Linux Manual
658Pages</a>.</p>
659
660<p>Toybox is not by itself a complete operating system, it's a set of standard command line utilities that run in an operating system.
661Booting a simple system to a shell prompt requires a kernel to drive the hardware (such as Linux, or BSD with a Linux emulation layer), programs for the system to run (such as toybox's commands), and a C library ("libc") to connect them together.</p>
662
663<p>Toybox has a policy of requiring no external dependencies other than the
664kernel and C library (at least for defconfig builds). You can optionally enable support for
665additional libraries in menuconfig (such as openssl, zlib, or selinux),
666but toybox either provides its own built-in versions of such functionality
667(which the libraries provide larger, more complex, often assembly optimized
668alternatives to), or allows things like selinux support to cleanly drop
669out.</p>
670
671<p>Static linking (with the --static option) copies library contents
672into the resulting binary, creating larger but more portable programs which
673can run even if they're the only file in the filesystem. Otherwise,
674the "dynamically" linked programs require each shared library file to be
675present on the target system, either copied out of the toolchain or built
676again from source (with potential version skew if they don't match the toolchain
677versions exactly), plus a dynamic linker executable installed at a specific
678absolute path. See the
679<a href=https://www.man7.org/linux/man-pages/man1/ldd.1.html>ldd</a>,
680<a href=https://www.man7.org/linux/man-pages/man8/ld.so.8.html>ld.so</a>,
681and <a href=https://www.man7.org/linux/man-pages/man7/libc.7.html>libc</a>
682man pages for details.</p>
683
684<p>Most embedded systems will add another package to the kernel/libc/cmdline
685above containing the dedicated "application" that the embedded system exists to
686run, plus any other packages that application depends on.
687Build systems add a native version of the toolchain packages so
688they can compile additional software on the resulting system. Desktop systems
689add a GUI and additional application packages like web browsers
690and video players. A linux distro like Debian adds hundreds of packages.
691Android adds around a thousand.</p>
692
693<p>But all of these systems conceptually sit on a common three-package
694"kernel/libc/cmdline" base (often inefficiently implemented and broken up
695into more packages), and toybox aims to provide a simple, reproducible,
696auditable version of the cmdline portion of that base.</p>
697
698<hr /><h2><a name="mkroot" />Q: How do you build a working Linux system with toybox?</h2>
699
700<p>A: Toybox has a built-in <a href=https://github.com/landley/toybox/blob/master/scripts/mkroot.sh>system builder</a>, with the Makefile target "<b>make
701root</b>". To enter the resulting root filesystem, "<b>sudo chroot
702root/host/fs /init</b>". Type "exit" to get back out.</p>
703
704<p>You can cross compile simple three package (toybox+libc+linux)
705systems configured to boot to a shell prompt under the emulator
706<a href=https://qemu.org>qemu</a>
707by specifying a target type with CROSS=
708(or by setting CROSS_COMPILE= to a <a href=#cross>cross compiler</a> prefix with optional absolute
709path), and pointing the build at a Linux kernel source directory, ala:</p>
710
711<blockquote><p><b>make root CROSS=sh4 LINUX=~/linux</b></p></blockquote>
712
713<p>Then you can <b>cd root/sh4; ./qemu-sh4.sh</b> to launch the emulator.
714(You'll need the appropriate qemu-system-* emulator binary installed.)
715Type "exit" when done and it should shut down the emulator on the way out,
716similar to exiting the chroot version. (Except this is more like you ssh'd
717to a remote machine: the emulator created its own CPU with its own memory
718and I/O devices, and booted a kernel in it.)</p>
719
720<p>The build finds the <a href=#system>three packages</a> needed to produce
721this system because 1) you're in a toybox source directory, 2) your cross
722compiler has a libc built into it, 3) you tell it where to find a Linux kernel
723source directory with LINUX= on the command line. If you don't say LINUX=,
724it skips that part of the build and just produces a root filesystem directory
725ala the first example in this FAQ answer.</p>
726
727<p>The CROSS= shortcut expects a "ccc" symlink in the toybox source directory
728pointing at a directory full of cross compilers. The ones I test this with are built from the musl-libc
729maintainer's
730<a href=https://github.com/richfelker/musl-cross-make>musl-cross-make</a>
731project, built by running toybox's scripts/mcm-buildall.sh in that directory,
732and then symlink the resulting "ccc" subdirectory into toybox where CROSS=
733can find them:</p>
734
735<blockquote><b><pre>
736cd ~
737git clone https://github.com/landley/toybox
738git clone https://github.com/richfelker/musl-cross-make
739cd musl-cross-make
740../toybox/scripts/mcm-buildall.sh # this takes a while
741ln -s $(realpath ccc) ../toybox/ccc
742</pre></b></blockquote>
743
744<p>If you don't want to do that, you can download <a href=http://mkroot.musl.cc/latest/>prebuilt binary versions</a> from Zach van Rijn's site and
745just extract them into a "ccc" subdirectory under the toybox source.</p>
746
747<p>Once you've installed the cross compilers, "<b>make root CROSS=help</b>"
748should list all the available cross compilers it recognizes under ccc,
749something like:</p>
750
751<blockquote><b><p>
752aarch64 armv4l armv5l armv7l armv7m armv7r i486 i686 m68k microblaze mips mips64 mipsel powerpc powerpc64 powerpc64le s390x sh2eb sh4 x32 x86_64
753</p></b></blockquote>
754
755<p>(A long time ago I
756<a href=http://landley.net/aboriginal/architectures.html>tried to explain</a>
757what some of these architectures were.)</p>
758
759<p>You can build all the targets at once, and can add additonal packages
760to the build, by calling the script directly and listing packages on
761the command line:</p>
762
763<blockquote>
764<p><b>scripts/mkroot.sh CROSS=all LINUX=~/linux dropbear</b></p>
765</blockquote>
766
767<p>An example package build script (building the dropbear ssh server, adding a
768port forward from 127.0.0.1:2222 to the qemu command line, and providing a
769ssh2dropbear.sh convenience script to the output directory) is provided
770in the scripts/root directory. If you add your own scripts elsewhere, just
771give a path to them on the command line. (No, I'm not merging more package build
772scripts, I <a href=https://speakerdeck.com/landley/developing-for-non-x86-targets-using-qemu?slide=78>learned that lesson</a> long ago. But if you
773want to write your own, feel free.)</p>
774
775<p>(Note: currently mkroot.sh cheats. If you don't have a .config it'll
776make defconfig and add CONFIG_SH and CONFIG_ROUTE to it, because the new
777root filesystem kinda needs those commands to function properly. If you already
778have a .config that
779_doesn't_ have CONFIG_SH in it, you won't get a shell prompt or be able to run
780the init script without a shell. This is currently a problem because sh
781and route are still in pending and thus not in defconfig, so "make root"
782cheats and adds them. I'm working on it. tl;dr if make root doesn't work
783"rm .config" and run it again, and all this should be fixed up in future when
784those two commands are promoted out of pending so "make defconfig" would have
785what you need anyway. It's designed to let yout tweak your config, which is
786why it uses the .config that's there when there is one, but the default is
787currently wrong because it's not quite finished yet. All this should be
788cleaned up in a future release, before 1.0.)</p>
789
790
791
792<!--#include file="footer.html" -->
793