Skip to main content

Build an embedded Linux distro from scratch

Peter Seebach, Freelance author, Plethora.net
Peter Seebach
Peter Seebach has been collecting video game consoles for years, but has only been running Linux on them recently. He is still not sure whether this is a Linux machine that plays video games, or a game machine that runs Linux.

Summary:  Learn how to build a custom Linux® distribution to use in an embedded environment, in this case to drive a Technologic Systems TS-7800 single-board computer. In this tutorial, you learn about cross-compiling, the boot loader, file systems, the root file system, disk images, and the boot process, all with respect to the decisions you make as you're building the system and creating the distribution.

Date:  12 Aug 2008
Level:  Intermediate PDF:  A4 and Letter (86 KB | 21 pages)Get Adobe® Reader®

Comments:  

Boot loaders

What is a boot loader?

A boot loader (or bootstrap loader) is a program that loads another program. The boot loader is a small and specialized hunk of code, specific to a target system, that has just enough complexity to find the kernel and load it without being a full-featured kernel. Different systems use a variety of different boot loaders, from the huge and complicated BIOS programs common on desktop PCs, to very small and simple programs more common on embedded systems.

A simple boot loader

The TS-7800 uses an unusually simple boot loader, which simply picks up the kernel from a predetermined partition of the SD card or on-board flash. A jumper determines whether the board looks first at the on-board flash, or at the SD cards. There are no other configuration settings. More complicated boot loaders (such as grub, commonly used on desktop PCs) have options for configuring kernel options and so on at boot time. On this system, the kernel's default options must be compiled in, as described previously.

The decision to compile in kernel options is a typical example of a choice that makes some sense in an embedded system, but would be uncomfortably limiting on a desktop.

Kernel formats

There are a variety of formats in which kernels are stored. The initial Linux kernel binary, named vmlinux, is rarely the file that a boot loader will work with. On the TS-7800, the boot loader can use two files, either Image (uncompressed) or zImage (compressed). These files are created in the arch/arm/boot directory within the kernel tree.

People often describe the zImage kernel as a compressed kernel, and so expect the boot loader to need to provide decompression. In fact, it's rather more clever. The zImage kernel is an uncompressed executable, which contains a particularly large static data object which is a compressed kernel image. When the boot loader loads and runs the zImage executable, that executable then unpacks the kernel image and executes it. This way, you get most of the benefit of compression without imposing additional effort on the boot loader.

Setting up the SD card

The SD card needs an MBR table containing DOS-style partition information. A sample MBR table is available for download from Technologic's site; this is for a 512MB card, but it is easy to edit the fourth partition to a size suiting whatever size card you want to use. The first three partitions are 4MB each; the first is unused on smaller cards, and the second and third hold the kernel and initial ramdisk image respectively.

For my purposes, I used the sfdisk utility, which is not always recommended but has the desirable trait of trusting me when I ask it to create a partition that does not align on a partition boundary.

Installing the initial kernel

The kernel for the TS-7800 is dumped directly into the second partition of the SD card. The exact path to the card depends on how you are accessing it; typically, if you have the card on a USB card reader, it will be detected as a SCSI device. Note that there is no file system access involved; the raw kernel is just dumped into the partition. The dd command copies raw data from one source to another, as in this example:

$ dd if=zImage of=/dev/sdd2 bs=16k
93+1 records in
93+1 records out
1536688 bytes (1.5 MB) copied, 0.847047 s, 1.8 MB/s

This command dumps raw data from the zImage file to the second partition of /dev/sdd, using 16KB blocks.

A bit about block sizes

The output of this command is a little cryptic (as are its inputs, honestly). When dd runs, it copies data in "records," which are by default 512-byte blocks; this command specifies a block size of 16k (which dd understands to mean 16*1024).

The dd command reports the amount of data copied first in blocks; the number after the plus sign is the number of partial blocks copied. In this case, because 1,536,688 is not an exact multiple of the block size, the remaining bytes of the file are read (and written) separately as a partial block. This information is harmless for most modern devices but crucial to diagnosing problems with some older ones.

The ability to control block sizes (and reblock data when transferring it) was exceptionally useful for working with tape devices and other specialized media that required writes to be of particular fixed sizes, and also helps for performance and reliability reasons with flash devices.

While the kernel device representing flash media can often take writes of arbitrary sizes, it is common for the underlying device to work only in full blocks, often of somewhat larger sizes (4KB or larger). To do a partial write, the flash device must extract the current contents of the full block, modify them with the input data, and flash the whole block back. If a device uses 4KB blocks, and you write to it in 512-byte blocks, each device block gets rewritten eight times for a single copy. This is bad for the device's longevity, and also bad for performance. (A 512-byte write of the same file was half as fast on the flash card I used.)

Booting the kernel

Booting the kernel is simple enough. Set the jumper for an SD boot, put the card in the system, and power it up. If you started with a blank card, this produces a predictable result:

Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)

This cryptic message indicates that the kernel has been unable to find its root filesystem. That means it's about time to create one.

5 of 12 | Previous | Next

Comments



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Linux
ArticleID=330452
TutorialTitle=Build an embedded Linux distro from scratch
publish-date=08122008
author1-email=developerworks@seebs.plethora.net
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).