10010.Building Tiny Linux Systems with Busybox

ELJ Issue 0: Building Tiny Linux Systems with Busybox--Part I
Posted on Tuesday, November 20, 2001 by Bruce Perens
Printer Friendly Page  Send this Article to a Friend

Embedded Create a Busybox single-floppy Linux system that includes a kernel, command-line environment and your application.

Because Linux is small and easy to customize, it's a fine kernel for embedded systems. But what about all of the other programs that are needed for a minimum functional GNU/Linux system? The minimum system installed by the Debian or Red Hat set-up disks, exclusive of the kernel, is about 40 megabytes in size. Busybox replaces the GNU/Linux distribution with a large set of command-line tools--all that are needed to boot and run a practical Linux system with networking--in a very small package.

The typical compiled size of Busybox on the i386 architecture is 256 to 500K total for all tools, depending on the C library used and how it is linked. This makes it easily possible to create a single-floppy Linux systems with a full-featured kernel, a command-line environment, plus your application.

I originally wrote Busybox in 1996 for the Debian GNU/Linux setup disk. The goal was to put a complete bootable system on a single floppy that would be both a rescue disk and an installer for the Debian system. A rescue disk is used to repair a Linux system when that system has become unbootable. Thus, a rescue disk needs to be able to boot the system and mount the hard disk file systems, and it must provide the command-line tools needed to bring the hard-disk root file system back to a bootable state. The Debian installer at the time I wrote Busybox was a Bourne shell script using dialogto provide a simple graphical interface on an ANSI terminal or the Linux console.

Since its creation, many people have added to and maintained Busybox, including members of the Debian Boot-Floppies team, the Linux Router Project and Lineo Corporation, where Eric Anderson maintains Busybox today. In the tradition of Free Software projects, contributions by other authors now make up the majority of the project. Busybox is a part of almost every commercial embedded Linux offerings, and is found in such diverse projects as the Kerbango Internet Radio and the IBM Wristwatch that runs Linux.

The name Busybox comes from a child's toy box with a telephone dial and anumber of knobs, buttons and other devices, all of which make noises when operated. This was called a busy boxin the past and is today commonly referred to as an activity center.

The Busybox source code can be found at www.busybox.lineo.com. By default, the Makefile provided builds a dynamic-link executable using the default libc library on your system. However, it is easily adapted to cross-compilation, and one can select static linking and other, specialized libc libraries by editing Makefile variables. Before you exercise the Makefile options or embed Busybox, you should build and run it on your host system just so that you can get familiar with it. If you are on a Linux system with the development tools installed, simply typing make should build it.

Once you build Busybox, it's time to learn about multi-call executable files. This is a trick we use to make Busybox small. There is one executable called busybox that is linked to 107 different names and provides the functions of 107 different programs. To illustrate this, run the following shell commands:

ln busybox ls
ln busybox uptime
ln busybox whoami

Now, run these commands:

./ls
./uptime
./whoami

Be sure to type the leading "./" as illustrated above, or you will get the system version of these commands rather than the Busybox version.

The lncommand is used to apply another name to a file. It does not copy the file. The only space it uses in the file system is the small amount that is necessary to store a name in a directory. You can illustrate this using the following ls command:

ls -il busybox ls uptime whoami

Be sure to use the -il argument to ls as above. This causes ls to print the inode number, a unique number identifying each file in a file system, along with the usual long listing provided by the -l argument. Linux allows the same file to have more than one name, but a file only has one inode number. You should see something similar to Listing 1.

1849054	-rwxrwxr-x	4	bruce	bruce	252956	Sep	7	08:22	busybox
1849054	-rwxrwxr-x      4       bruce   bruce   252956  Sep     7	08:22	ls
1849054 -rwxrwxr-x      4       bruce   bruce   252956  Sep     7	08:22	uptime
1849054 -rwxrwxr-x      4       bruce   bruce   252956  Sep     7	08:22	whoami

Note that this is not a listing of four files. It is a listing of one file with four names, as indicated by the inode number in the first column and the link count in the third column. The link count reports how many names a file has. You'll notice that directories in the common Linux file systems always have a link count of two, because they have two names: "." and "..". Most files, however, only have one name and their link count will be 1.

Because there is a fixed overhead of several kilobytes for every executable program, compressing 107 commands into one file saves a significant amount of space. So, just as we have linked Busybox to four different names, we can link it to 107. This provides us with a complete, bootable, runnable Linux system in a very small space. Even static-linking with GNU LIBC 6, which has become the standard for Linux systems, Busybox occupies only half a megabgyte.

If you don't need the internationalization of LIBC 6, the old LIBC 5 is significantly smaller. A new library intended for embedded use, uC-Libc (www.opensource.lineo.com), is even smaller, but use caution if your application is proprietary. Like Busybox, uC-Libc is covered by the GNU GPL (General Public License), and can't be linked to proprietary software. GNU LIBC 5 and 6, in contrast, are under the LGPL (the Lesser General Public License) and can be linked to proprietary applications. So, don't use uC-Libc for the libc library of a non-free program. At this writing, uC-Libc doesn't quite provide all of the functions required by Busybox, but it's only short a few and these may be provided by the time you read this article.

Table 1. Tools Provided

On the Debian install floppy, I linked Busybox dynamicaly, and then stripped down the shared libc library so that it only provided the functions necessary to support Busybox and the other executables on the floppy. This was the best way to provide a library shared by several different executables, since the floppy contained other programs besides Busybox. Stripping libc down to only the functions that actually were used cut its size by half. Rather than strip it by hand, I wrote a script that finds all of the library functions referenced by a set of dynamic executables, and then creates a library subset providing those functions (and the functions they depend on). This script has since been completely replaced by a version written by Marcus Brinkmann, which can be found in the Debian boot-floppies package under scripts/rootdisk/mklibs.sh. The script and how it works are properly the subject of another article the size of this one however, until that article is written, one can puzzle out how mklibs.sh works by installing the boot-floppies package on a Debian system, building the floppies and then reading the script carefully. Warning: mklibs.sh is probably the most complex shell script you will ever examine.

So, now that you know how to build and run Busybox, how do you make a small Linux system containing it? You'll need a few pieces: a static-linked Busybox executable, a skeleton root file system and /dev directory populated with the proper special files, and a Linux kernel with the features you need plus two features that will be used to boot and run a small Linux system: RAM disks and the compressed ROM file system. [Look for the details on how to build a small Linux system containing Busybox in a future issue--Ed.]


------------------------------------------------------------------------------------------------

ELJ Issue 1: Building Tiny Linux Systems with Busybox, Part 2: Building the Kernel
Posted on Saturday, January 20, 2001 by Bruce Perens
Printer Friendly Page  Send this Article to a Friend

Embedded Let Bruce help you put the BusyBox to work.

For this example I use Linux kernel version 2.2.17. The 2.4.0-test8 kernel that I tried did not size the RAM disk for the root file system properly, leading to a ``not enough memory'' message at boot time. That bug will probably be repaired in the 2.4 series of kernels by the time you read this.

We will build our example to run on an i386-architecture PC-compatible system with PC keyboard and VGA display, booting from a floppy disk and running the root file system entirely in RAM once the system is booted. This example should also boot from IDE disks and from FLASH EEPROM devices that masquerade as IDE disks. It can also be configured to boot from a CD-ROM.

Build a bzImage-style kernel with all of the facilities needed for the application, plus these three:

  • RAM disk support (in the Block Devices menu)
  • Initial RAM disk (initrd) support (also in the Block Devices menu)
  • ROM file system support (in the File Systems menu)
Don't use kernel modules, because this example system doesn't support them. Don't put any facilities in the kernel that you don't need, as they will use up space that you need on the floppy disk. A kernel with the facilities you need should be around half a megabyte in size and should fit easily on a floppy along with the ROM root file system. A kernel with many unnecessary bells and whistles will be a megabyte or more and won't leave sufficient room for your ROM root file system.

If you're not familiar with building and installing kernels on a normal Linux PC, you'll need to study up on that. In short, I placed the kernel sources in /usr/src/linux and ran:

xhost +localhost
su
make xconfig
make dep
make bzImage
This created a compiled Linux kernel in /usr/src/linux/arch/i386/boot/bzImage.

Building a Static-Linked Busybox

In the busybox source directory, edit the Makefile, changing the variable DOSTATIC from false to true. Then run make. That will create a static-linked version of busybox. Confirm that it is static-linked by running this command:

ldd busybox
This should print something like:

statically linked (ELF)
It's important to get this right; if you install a dynamic-linked version of Busybox, your system won't run because we aren't installing the runtime dynamic linker and its libraries on the floppy disk for this example.

Creating a ROM Root File System

We're going to go through all of the steps for creating a minimal root file system by hand so that you will understand just how little is necessary to boot your system rather than copying all of the files from the root of your Linux distribution and then being afraid to remove anything because you don't know whether it's necessary. You will need to become root (the superuser) to perform the following steps because the mknod command requires superuser privilege.

Create the tiny-linux directory and change directory into it:

mkdir tiny-linux
cd tiny-linux
Create the standard directories in it:

mkdir dev etc etc/init.d bin proc mnt tmp var var/shm
chmod 755 . dev etc etc/init.d bin proc mnt tmp var var/shm
Enter the tiny-linux/dev directory:

cd dev
Create the generic terminal devices:

mknod tty c 5 0
mknod console c 5 1
chmod 666 tty console
#Allow anyone to open and write terminals.
Create the virtual terminal device for the VGA display:

mknod tty0 c 4 0
chmod 666 tty0
Create the RAM disk device:

mknod ram0 b 1 0
chmod 600 ram0
Create the null device, used to discard unwanted output:

mknod null c 1 3
chmod 666 null
Change directory to tiny-linux/etc/init.d, where startup scripts are stored:

cd ../etc/init.d
Use an editor to create this shell script in tiny-linux/etc/init.d/rcS. It will be executed when the system boots:

#! /bin/sh
mount -a # Mount the default file systems mentioned in /etc/fstab.
Make the script executable:

chmod 744 rcS
Change directory to tiny-linux/etc:

cd ..
Use an editor to create the file tiny-linux/etc/fstab, which says what file systems should be mounted at boot time:

proc  /proc      proc    defaults     0      0
none  /var/shm   shm     defaults     0      0
Set the mode of tiny-linx/etc/fstab:

chmod 644 fstab
Use an editor to create the file tiny-linux/etc/inittab, which tells /bin/init, the system startup program, what processes to start:

::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
The above example runs the script /etc/init.d/rcS at boot time and runs an interactive shell on the console device.

Set the modes of tiny-linux/etc/inittab:

chmod 644 inittab
That's everything necessary to create your root file system, except for the installation of the programs. Change directory to tiny-linux/bin:

cd ../bin
Copy your static-linked version of Busybox from wherever you built it into tiny-linux/bin/busybox with a command similar to this one:

cp ~/busybox-0.46/busybox busybox
Add another command name ls to Busybox using the ln command:

ln busybox ls
Run ls, and the result should look like this:

-rwxr-xr-x    2 root     root       580424 Sep 12 15:17 busybox
-rwxr-xr-x    2 root     root       580424 Sep 12 15:17 ls
Repeat the above ln command for all of these names:

[, ar, basename, cat, chgrp, chmod, chown,
chroot, chvt, clear, cp, cut, date, dc, dd,
deallocvtdf, dirname, dmesg, du, dumpkmap dutmp,
echo, false, fbset, fdflush, find, free,
freeramdisk, fsck.minix, grep, gunzip, gzip, halt,
head, hostid, hostname, id, init, insmod, kill,
killall, length, linuxrc, ln, loadacm, loadfont,
loadkmap, logger, logname, lsmod, makedevs, md5sum,
mkdir, mkfifo, mkfs.minix, mknod, mkswap, mktemp,
more, mount, mt, mv, nc, nslookup, ping, poweroff,
printf, ps, pwd, reboot, rm, rmdir, rmmod, sed,
setkeycodes, sh, sleep, sort, swapoff, swapon, syn, c
syslogd, tail, tar, tee, telnet, test, touch, tri,
true, tty, umount, uname, uniq, update, uptime,
usleep, uudecode, uuencode, wc, which, whoami, yes,
zcat
Are you tired yet? Well, now is a good time to take a break--you've finished creating your ROM root file system.

Generate the ROM Root File System Image

You'll need the genromfs program to generate the ROM file system image. If you are using Debian or Red Hat, it's already packaged for you as part of the standard system; you'll just need to run the command to install it. If your Linux distribution doesn't include a prepackaged version, at this writing the program can be found at ftp://ibiblio.org/pub/Linux/system/recovery/genromfs-0.3.tar.gz. Install the program, change directory to the directory that contains tiny-linux and run these commands:

genromfs -d tiny-linux -f fs
This creates the ROM file system image in the file fs. Now, compress the file system image using the gzip command:

gzip -9 fs
That will create the file fs.gz, which is about half the size of the uncompressed version.

Build the Floppy

We'll need one more program to build our floppy: syslinux. This is an i386 bootstrap program that will load a kernel and a compressed root file system image from a floppy, hard disk or CD. Again, it's prepackaged with Debian or Red Hat and can be found, at this writing, at ftp://ibiblio.org/pub/Linux/system/boot/loaders/syslinux-1.48.tar.gz.

Create an MS-DOS file system on a floppy by using the Linux mformat command (or by another means). Put the floppy in your drive but don't mount it, and install the syslinux bootstrap with this command:

syslinux /dev/fd0
That will copy a first-stage bootstrap onto the first block of the floppy and a second-stage bootstrap into the file LDLINUX.SYS in the MS-DOS file system of the floppy. I'm assuming you have a directory called /mnt; substitute whatever directory you usually use for mounting floppy disks in the shell commands below. Now, it's time to copy our kernel and root file system onto the floppy:

mount -t msdos /dev/fd0 /mnt
cp fs.gz /mnt
cp /usr/src/linux/arch/i386/boot/bzImage /mnt/linux
Create the configuration file /mnt/syslinux.cfg with an editor:

TIMEOUT 20
DEFAULT linux

LABEL linux
    KERNEL linux
    APPEND root=/dev/ram0 initrd=fs.gz
This tells syslinux to wait for two seconds and then boot the default system. You can interrupt the default boot during those two seconds by pressing the shift key. Typing linux at the prompt will do the same thing as the default.

The kernel is booted with the arguments root=/dev/ram0 and initrd=fs.gz. These arguments tell the kernel that the root is a RAM disk, and that the RAM disk is loaded from the compressed ROM file system image fs.gz. Although the ``ROM'' root file system is actually in RAM, it will not be writable because the Linux ROM file system driver used in this example is meant to work with real ROMs and thus doesn't support writing.

The Smoke Test

Configure an i386 PC to boot from the floppy. Note that this is a setting in the BIOS preferences of most new PCs, and they are often configured to boot from the hard disk without first looking for a bootstrap on the floppy. Place the floppy in the first floppy drive, and restart the system. You should see something like the following:

SYSLINUX 1.48 1999-09-26
Copyright (C) 1994-1999 H. Peter Anvin

loading fs.gz.........
loading linux...............
Uncompressing linux, OK, booting the kernel
Tons of cybercrud about every device driver and facility in the kernel race by too rapidly to read...

RAMDISK: Compressed image found at block 0.
VFS: Mounted root (romfs file system)

Please press Enter to activate this console.
You've done it! Press Enter and you should see something like this:

Busybox v0.46 (2000-09-12-22:16+0000) built-in shell
Enter 'help' for a list of built-in commands.

/ # _
Pop out the floppy disk; it's not being used any longer. The root file system is entirely in RAM. You should be able to look around the system and try out commands, but you won't have any writable storage. This is the simplest, bootable-system, running busybox that I could think of, and thus I've left out the files in /dev that you'd need to mount writable RAM disks, floppies and hard disks. You now should be able to figure out what those devices are, add them and build a tiny Linux system specialized to your application.



-----------------------------------------------------------------------------------------

ELJ Issue 2: Building Tiny Linux Systems with BusyBox, Part 3
Posted on Tuesday, March 20, 2001 by Bruce Perens
Printer Friendly Page  Send this Article to a Friend

Embedded Let's get smaller, writable and multiuser! A new library, new kernel and other bells and whistles gives us more practice building a highly functional Linux system with a tiny footprint.

This is the third article in the series ``Building Tiny Linux Systems with BusyBox''. You'll need to refer to my last article (part 2) on kernel building in the January/February 2001 issue of ELJ if you don't have a paper copy of the previous issue on hand, you can refer to the on-line magazine archive at http://embedded.linuxjournal.com/magazine/issue01/4395/ [Part 1 appeared in the ELJ supplement (November 2000) and is available at http://embedded.linuxjournal.com/magazine/issue00/4335/.]

In this article, we'll add writable storage and a multiuser capability to your tiny Linux system, and when we're done the system will be much smaller than when we started.

Time Marches On

Progress on BusyBox and its friends has continued since I wrote the first two articles, largely due to the efforts of Erik Andersen, whose name I so horribly misspelled in the first article. Erik's work on BusyBox and associated programs is supported by Lineo and benefits the entire Embedded Linux community. Erik and his colleagues have continued to contribute to BusyBox using the original license I chose, the GPL, and they have made great contributions to other embedded programs under the GPL and LGPL.

In my last article, we used the 2.2 kernel, due to a bug in 2.4. That has now been repaired, and since the 2.4 kernel has been released, let's try it. syslinux has also been updated to cope with the new kernel.

Software to Download

We'll be using some new software: TinyLogin and uClibc, and new versions of BusyBox and syslinux. Create a directory where you will work on this example, and change to that directory. Download the 2.4 kernel source from http://www.kernel.org or any of its mirrors. Download all of the files from ftp://ftp.perens.com/ELJ/3/. Read the README.txt file. Extract the compressed tar archives you've just downloaded. Don't run the shell script as_in_episode_2.sh yet. Build and install syslinux from the downloaded sources, replacing the old version if you've installed it on your system. Build BusyBox from the downloaded sources.

Getting Comfortable with the 2.4 Kernel

Take the time to install the 2.4 kernel on a BusyBox floppy, just to get comfortable with configuring and running it. We'll use some scripts in the elj-3 directory to spare you most of the typing you did in the kernel article.

If you still have the tiny Linux directory that we used in the second article, move it out of the way. We're about to create a new one.

Extract the kernel source and configure it as we configured the kernel in my last article under the subhead ``Build the Kernel'', but add two new features to the kernel if they are not already in it: the DOS FAT filesystem and the VFAT (Windows 95) filesystem. These are in the filesystems menu of the kernel configuration. You will need to use these filesystems on both your development system and your tiny Linux system, so you may end up building and installing two kernels. Remember, you need to keep the kernel on your tiny Linux system small, so it probably won't be the same kernel you run on your development system.

Go to the BusyBox source directory and edit the Makefile, setting DOSTATIC to true to build a statically linked version of BusyBox. Build BusyBox with the make command, and then run:

make PREFIX=../tiny-linux install-hardlinks
This will create the tiny Linux directory in the directory above the BusyBox directory and will create the bin, sbin and /usr/sbin directories within the tiny Linux directory. The Makefile will install BusyBox in that directory tree and will create all of the links for the various command names, automatically doing much of the work we performed manually in Part 2. It won't install scripts and files and won't create the /dev directory. One of the scripts you downloaded will do that. Change directory to ../elj-3 and run:

sh -x as_in_episode_2.sh ../tiny-linux
That will create the contents of the /dev and /etc directories and anything else you need to make a ROM filesystem.

Now, follow the instructions in my January/February 2001 article under the subheadings ``Generate the ROM Root Filesystem Image'' and ``Build the Floppy''. Finally, boot the floppy to test it.

Let's Get Small

Another good thing Erik and others have been working on is uClibc, the free embedded C library. I had previously identified this library as being under the GPL license, but I was mistaken. uClibc is under the LGPL and is thus fine for linking with proprietary applications. You can now make BusyBox statically linked to run with uClibc rather than libc5 or libc6. The result is less than 300K in size, and of course, it gets even smaller when the ROM filesystem is compressed. In the uClibc source directory, edit the configuration file and change HAS_MMU to true, HAS_FLOATS to true and KERNEL_SOURCE to the location of your kernel source. Change the definition of the CC to be $(CROSS)gcc -Os to optimize for smaller code size. If your version of gcc does not support the -Os flag, use -O2 instead. Run make to build the libc.a library. In this article, uClib supports only static linking, but dynamic linking has just started to work. We'll give it a little time to stabilize and will cover it in the next issue.

Now, go back to the BusyBox source, edit the Makefile and look for the lines that say ``to compile vs. an alternative libc, you may need to use/adjust the following lines of source to meet your needs''. Below that section are lines that define LIBCDIR, LDFLAGS, LIBRARIES, CROSS_CFLAGS and GCCINCDIR. Most or all of these definitions are commented out. Uncomment the definitions to enable linking with uClibc. Change the definition of LIBCDIR to be the location of your uClibc source. Edit Config.h, and comment out the BB_GETOPT and BB_FEATURE_NFSMOUNT definitions to disable the getopt command and the ability to mount remote NFS filesystems with the mount command. As I write this, there's a bug preventing the BusyBox getopt command from working with uClibc, but that might be fixed by the time you read this article. uClibc does not currently include network support, although I'm sure that someone will add it eventually.

Now, rebuild all of BusyBox with the make clean and make commands. On my system, the result is a statically linked executable of 297,620 bytes in size.

Remove the file tiny-linux/bin/getopt. That file won't be generated this time because we turned off the definition of BB_GETOPT. If we don't remove it, we'll end up with two versions of BusyBox and a lot of wasted space.

Use the instructions above under ``Getting Comfortable with the 2.4 Kernel'', starting with the command:

make PREFIX=../tiny-linux install-hardlinks
This generates another floppy. Boot the floppy to test it.

Add Writable Storage

Probably the biggest missing feature in your tiny Linux system so far is the lack of writable storage. Let's fix that now. We'll use a VFAT filesystem for the writable storage. This is an extension of the old DOS FAT filesystem to handle long and mixed-case filenames, introduced for Windows 95. Since your floppy already uses a DOS filesystem to hold the kernel and the compressed ROM image file, it's easiest to use VFAT to extend that filesystem for this example. Become root. Create a tiny var directory. This directory tree will hold files that will be writable on your tiny Linux system. You will copy it to the floppy later on, and it will be mounted on /floppy/var when your tiny Linux system boots.

Move your entire tiny-linux/etc directory to tiny-var/etc using the command:

mv tiny-linux/etc tiny-var
Create two other directories: tiny-var/shm and tiny-var/home. The first directory is used by the mount command as a placeholder when providing shared memory, and the second is used to hold home directories for users.

Now we'll create symbolic links in tiny Linux to redirect some directories to /var so that you will have access to your writable storage and then redirect /var to /floppy/var. We do the symbolic links in two levels here so that the location of all of the writable storage can be changed by replacing only one link:

cd tiny-linux
rm -f -r var
mkdir floppy
ln -s floppy/var var
ln -s var/etc etc
ln -s var/home home
Create the shell script startup.sh as shown below:

#! /bin/sh
/bin/mount -t vfat /dev/fd0 /floppy
exec /sbin/init
This script will run when the system starts, instead of init, because we'll provide a special command-line argument to the kernel. It will mount the floppy so that the contents of /etc are correct before init starts. Note that exec/sbin/init is different from simply running /sbin/init. The exec command says to replace the shell with the given program, rather than run the program as a subprocess of the shell. Thus, init will run in the same process-ID as the shell, which in this case will be process-ID 1. This is important as the kernel gives process-ID 1 some special properties, and init will not run properly unless it's in process-ID 1.

Change the mode of the script so that it is executable:

chmod 744 startup.sh
Change directory up one level (cd ..):

Use an editor to modify the file tiny-var/etc/inittab, which tells /bin/init, the system startup program, which processes to start. The entire contents of the file should look like this:

::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
::ctrlaltdel:/sbin/swapoff -a
::ctrlaltdel:/bin/umount -a
We're adding lines here to cleanly unmount filesystems at shutdown time, so that the floppy filesystem containing the writable files will be unmounted. Tasks on lines that start with ::ctrlaltdel: will be executed just before the system halts. We also turn off any swap partitions that are activated, just in case they live on a mounted filesystem.

Create the special device file necessary to mount the floppy:

mknod tiny-linux/dev/fd0 b 2 0
chmod 644 tiny-linux/dev/fd0
Now, regenerate the ROM filesystem from the tiny Linux directory, using genromfs as before, and compress it using gzip to create a new fs.gz.

Mount your floppy with this command:

mount -t vfat /dev/fd0 /mnt
and copy the new fs.gz to your tiny Linux floppy, replacing the old ROM filesystem.

Copy the tiny var directory tree to your floppy with the commands:

mkdir /mnt/var
cp -R tiny-var/* /mnt/var
Tell the kernel to run /startup.sh instead of /sbin/init by editing the file /mnt/syslinux.cfg. Change the line that says

APPEND root=/dev/ram0 initrd=fs.gz
to say

APPEND root=/dev/ram0 initrd=fs.gz init=startup.sh
Change directory to /, and unmount the floppy with this command

umount /dev/fd0
You should now be able to boot the floppy, and the directories /var, /etc and /home should be writable.

A Multiuser System on One Floppy

Your tiny Linux system currently just logs you in as root. Let's make a more versatile system that supports user and group names, the login command, support for logins via the console, a modem or a serial line, and utilities to add and delete users. Let's also make the disk writable, unlike the system we made in the second article. Let's fit all of this, and our BusyBox toolkit of more than 100 general-purpose UNIX commands, on one floppy with room to spare!

Go into the TinyLogin source directory and edit the Makefile. We'll be using uClibc to build TinyLogin, so set DOSTATIC to true, comment out the -lcrypt in the definition of LIBRARIES, and set USE_SYSTEM_PWD_GRP to true. Look in the Makefile for the lines that say ``To compile vs. an alternative libc, you may need to use/adjust the following lines to meet your needs.'' Change the lines below that in the same way that you changed the BusyBox Makefile to enable building with uClibc.

Warning: if you ever link TinyLogin with a C library that uses the Name Service Switch (NSS), including GNU LIBC and probably the default libc on your development system, you must set USE_SYSTEM_PWD_GRP to false in the Makefile. That will replace the functions that read the /etc/passwd and /etc/group files, etc., with a version that does not use NSS. Our tiny Linux system doesn't provide the files and other facilities needed for NSS to work, and thus TinyLogin will fail when built with it. This is the most-often-reported ``bug'' for TinyLogin, and its author is rather weary of explaining how NSS works to everyone who reports this ``bug''.

Build TinyLogin with the make command. The result should be about 58K in size.

Install TinyLogin in your tiny Linux directory using

make PREFIX=../tiny-linux install-hardlinks
Change directory up one level (cd ..).

Use an editor to modify the file tiny-var/etc/inittab, which tells /bin/init, the system startup program, which processes to start. The entire contents of the file should look like this:

::sysinit:/etc/init.d/rcS
tty1::askfirst:/bin/login
tty2::askfirst:/bin/login
tty3::askfirst:/bin/login
tty4::askfirst:/bin/login
::respawn:/sbin/getty -L ttyS0 9600
::respawn:/sbin/getty -L ttyS1 9600
::ctrlaltdel:/sbin/swapoff -a
::ctrlaltdel:/sbin/umount -a
This configures the system to offer a login on the first four console virtual terminals and on the first two serial ports at 9,600 baud. Create the file tiny-var/etc/passwd containing this line:

root::0:0:Super User:/:/bin/sh
Create tiny-var/etc/group containing this line:

root:x:0:
Create the terminal devices:

cd tiny-linux/dev
mknod tty0 c 4 0
mknod tty1 c 4 1
mknod tty2 c 4 2
mknod tty3 c 4 3
mknod tty4 c 4 4
mknod ttyS0 c 4 64
mknod ttyS1 c 4 65
chmod 600 tty0 tty1 tty2 tty3 tty4 ttyS0 ttyS1
Change directory up two levels (cd ../..).

Regenerate the compressed ROM filesystem, and install it on the floppy, as you have done before. Copy the new tiny var to the floppy using this command:

cp -R tiny-var/* /mnt/var
Unmount the floppy disk. Boot the floppy to test it. When the floppy boots, you will get a login prompt. Use root as your login--there's no password (yet). You'll see some complaints about missing files. Now, you can experiment with the adduser and passwd commands. You should be able to add users and set their passwords. Once you've added some users, you can log them in. To visit one of the other console virtual terminals, type Ctrl+Alt+F2 through Ctrl+Alt+F4. Ctrl+Alt+F1 will get you back to the first virtual console. You should be able to log in a different user to each virtual terminal. If you can, connect two serial terminals, set to 9,600 baud, to the first two serial ports on the system. You should be able to have users on each terminal too.

Feel free to add the missing files and test the other programs in the TinyLogin package. To have a fully functional system, you'll need /etc/shadow, /etc/gshadow, /etc/securetty and the utmp file. The location of the utmp file is defined in /usr/include/paths.h on your development system.

Security will be nonexistent because the VFAT filesystem doesn't support the ownership and mode information needed to provide security. You'll have to replace VFAT with another filesystem if you actually need this system to be secure. The USMSDOS filesystem is a good replacement for VFAT. Other filesystems are just a bit more complicated because they aren't compatible with the MS-DOS FAT filesystem used by syslinux to load the kernel and the ROM filesystem image. You could replace the FAT filesystem entirely with the MINIX or EXT2 filesystems, but you'd have to switch your boot loader from syslinux to LILO or grub. You could also mount the writable filesystem from another disk drive.

Coming Up

In the next issue, we'll work on security, and we'll provide the remaining facilities used by TinyLogin. Don't let that keep you from experimenting between now and then--you'll understand how the system works much better if you figure it out by yourself. We'll add dynamic linking and shared libraries and some other exciting new facilities. So, stay tuned!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值