Embedded Linux Howto Sebastien Huet, Version 0.302, March 3th, 2000 This document describes how to create a small linux system to be used as embedded purpose from your desktop linux and some additional specialized packages. Introduction Subject

I made the distro (aka Linux EMbedded) in February 1999. It is a tiny linux distribution i used with some x86 hardware to make a touch panel Graphical User Interface to audio, video, conferencing and polling hardware for . It is not hard to make a small linux from scratch. However, i made this document to spare people losing time wrestling with many (usefull) . This document describes how the distro has been made.

New Versions

The latest version of the document may be found at


This document is started for a while but has never been published before v0.3 because lacking a good structure. Recently, i have discovered 's , and decided to rewrite this document using the structure from the . Luc Herman's and Paul Moody also granted me to use their jobs to improve this document.


...At least a todo section...


Copyright © 1999,2000 by Sebastien Huet. This document may be distributed under the terms set forth in the Linux Documentation Project License at This is free documentation. It is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.


Feel free to send me your informations and comments at .

Dependencies A Desktop Linux

You will need a full linux distribution to build your own embedded linux OS. It will contains everything you need (utilities, sources, compiler, debugger, documentation....).

Some software packages

This is a list of the software i used to make LEM. Other specialized software for embedded purpose may be foud at


TinyLogin is a suite of tiny Unix utilities for handling logging into, being authenticated by, changing one's password for, and otherwise maintaining users and groups on an embedded system. It also provides shadow password support to enhance system security. TinyLogin is, as the name implies, very small, and makes an excellent complement to BusyBox on an embedded System. TinyLogin is being maintained by TinyLogin is available at


Busybox is a multicall binary used to provide a minimal subset of POSIX style commands and specialized functions.It is geared toward the very small, i.e. boot floppies, embedded-systems, etc. Specifically it is used in the (which caused the original busybox to be made), the , , and others. Busybox is being maintained by Busybox is available at


Ash is a very small Bourne shell available at


Sysvinit is the most used init package for Linux. We will use init and the C version of the start-stop-deamon. Sysvinit is available at

The boot process.

This section is for the most based on the Bootdisk-HOWTO.


All PC systems start the boot process by executing code in ROM (specifically, the BIOS) to load the sector from sector 0, cylinder 0 of the boot drive. The boot drive is usually the first floppy drive (designated A: in DOS and /dev/fd0 in Linux). The BIOS then tries to execute this sector. On most bootable disks, sector 0, cylinder 0 contains either: Code from a boot loader such as LILO, which locates the kernel, loads it and executes it to start the boot proper. he start of an operating system kernel, such as Linux. If a Linux kernel has been raw-copied to a diskette, a hard drive or another media, the first sector of the disk will be the first sector of the Linux kernel itself. This first sector will continue the boot process by loading the rest of the kernel from the boot device.

The boot loader

We will use a boot loader like lilo to operate our boot process. It permits to have the dev and production platforms on the same hardware and to switch from one to the other by only rebooting. The lilo boot loader is loaded by the bios. Then, it loads kernels or the boot sectors of other operating systems. It also provides a simple command-line interface to interactively select the item to boot with its options. More may be found in the Lilo documentation at .

The Kernel

The kernel checks the hardware and mounts the Init



The file /etc/inittab/ refers to scripts named /etc/rc... to do the system setup. It also has entries for the The login process

There is one getty available in the inittab file for each console you allow for the users. Getty will launch /bin/login to verify the user password.

More info about the boot process may be found at and in the init and inittab man pages.

Creating a root file system Creating a new partition

Quoted from the LFS-HOWTO at Before we can build our new Linux system, we need to have an empty Linux partition on which we can build our new system. If you already have a Linux Native partition available, you can skip this subsection and the following one.

Start the Creating an ext2 file system on the new partition

Quoted from the LFS-HOWTO at To create a new ext2 file system we use the mke2fs command. Give $LFS as the only option and the file system will be created. From now on I'll refer to this newly created partition as $EMBPART. $EMBPART should be substituted with the partition you have created.

Mounting the partition

To access the newly created filesystem, you have to mount it. For this create a /mnt/hda? directory and type at shell prompt: mkdir /mnt/hda? mount $EMBPART /mnt/hda? If you created your partition on /dev/hda4, and you mounted it on /mnt/hda4, when this document will tell you to copy a file to $dollar;EMBPART/usr/bin then you will need to copy that file to /mnt/hda4/usr/bin.

Populating the filesystem

The root filesystem must contain everything needed to support a full Linux system. We will build a directory structure not that far from the


Directories are made by using the /proc

Directory stub required by the proc filesystem.


System configuration file


Critical System binaries


Basic binaries considered part of the system


Shared Libraries to provide run time support


Mount point for maintenance


Additional utilities and applications

cd /mnt/hda? mkdir bin dev home proc sbin usr boot etc liv mnt root tmp var mkdir -p usr/bin usr/sbin usr/share usr/lib mkdir -p etc/config etc/default etc/init.d etc/rc.boot mkdir -p etc/rc0.d etc/rc1.d etc/rc2.d etc/rc3.d etc/rc4.d etc/rc5.d etc/rc6.d etc/rcS.d

the /dev directory

The dev directory is the stub required to perform devices input / output. Each file in this directory may be created using the mknod function. You may avoid losing time by directly copying the required dev entries from your desktop Linux. cp -av /dev/???? /mnt/hda?

Installing TinyLogin & login dependencies

TinyLogin is available at . It will give us the following tools in less than 35Ko : /bin/addgroup, /bin/adduser, /bin/delgroup, /bin/deluser, /bin/login, /bin/su, /sbin/getty, /sbin/sulogin, /usr/bin/passwd Please refers to your main distribution doc or man pages to have a full description of those commands.

Configuring TinyLogin

[... part of TinyLogin README ...] TinyLogin is modularized to easily allow you to build only the components you need, thereby reducing binary size. To turn off unwanted TinyLogin components, simply edit the file tinylogin.def.h and comment out the parts you do not want using C++ style (//) comments.

Installing TinyLogin

After the build is complete a tinylogin.links file is generated which is then used by 'make install' to create symlinks to the tinylogin binary for all compiled in functions. By default, 'make install' will place a symlink forest into `pwd`/_install unless you have defined the PREFIX environment variable.

Installing Sysvinit & start-stop-daemon

After the kernel is done loading it attempts to run the init program to finalize the boot process. Unpack the Sysvinit archive. Go to the src directory Compile the package by running make Copy the init executable in $EMBPART/sbin The Sysvinit package also offers a C version of the start-stop-deamon in the contrib directory. Compile it. Copy the file in $EMBPART/usr/sbin

Configuring Sysvinit

Sysvinit needs a configuration file named inittab and placed in $EMBPART/etc. The following is the one used in the LEM distro: # /etc/inittab: init(8) configuration. # $Id: inittab,v 1.6 1997/01/30 15:03:55 miquels Exp $ # Modified for LEM 2/99 by Sebastien HUET # default rl. id:2:initdefault: # first except in emergency (-b) mode. si::sysinit:/etc/init.d/rcS # single-user mode. ~~:S:wait:/sbin/sulogin # /etc/init.d executes the S and K scripts upon change # 0:halt 1:single-user 2-5:multi-user (5 may be X with xdm or other) 6:reboot. l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 l3:3:wait:/etc/init.d/rc 3 l4:4:wait:/etc/init.d/rc 4 l5:5:wait:/etc/init.d/rc 5 l6:6:wait:/etc/init.d/rc 6 # CTRL-ALT-DEL pressed. ca:12345:ctrlaltdel:/sbin/shutdown -t1 -r now # Action on special keypress (ALT-UpArrow). kb::kbrequest:/bin/echo "Keyboard Request--edit /etc/inittab to let this work." # /sbin/mingetty invocations for runlevels. 1:2345:respawn:/sbin/getty 9600 tty1 2:23:respawn:/sbin/getty 9600 tty2 #3:23:respawn:/sbin/getty tty3 #you may add console there #4:23:respawn:/sbin/getty tty4

Creating initial boot scripts

As seen in the inittab file, Sysvinit needs additional scripts in their own directories.

Creating the necessary directories and base files

cd $EMBPART/etc mkdir rc0.d rc1.d rc2.d rc3.d rc4.d rc5.d rc6.d init.d rcS.d rc.boot Go to the unpacked Sysvinit source directory. Copy the debian/etc/init.d/rc to:$EMBART/etc/init.d Go to the $EMBPART/etc/init.d/ Create a new file rcS like those in LEM: #!/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin runlevel=S prevlevel=N umask 022 export PATH runlevel prevlevel ./etc/default/rcS export VERBOSE # Trap CTRL-C &c only in this shell so we can interrupt subprocesses. trap ":" 2 3 20 # Call all parts in order. for i in /etc/rcS.d/S??* do [ ! -f "$i" ] && continue case "$i" in *.sh) ( trap - 2 3 20 . $i start ) ;; *) $i start ;; esac done # run the files in /etc/rc.boot [ -d /etc/rc.boot ] && run-parts /etc/rc.boot Copy run-parts from your distro to $EMBPART/bin

Adding base scripts

Create a new file reboot containing the following: #!/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin echo -n "Rebooting... " reboot -d -f -i Create a new file halt containing the following: #!/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin halt -d -f -i -p Create a new file mountfs containing the following:

Creating initial scripts

Copying passwd & group files

Not finished: Installing the ash root shell Preparing ash

Configuring ash

Not finished: Installing BusyBox Preparing BusyBox

Deploying BusyBox

Not finished: Installing required libraries Which ones ?