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