使用 Busybox 构建微型 Linux 系统,第 2 部分:构建内核

作者:Bruce Perens

在本例中,我使用 Linux 内核版本 2.2.17。我尝试过的 2.4.0-test8 内核没有正确调整根文件系统的 RAM 磁盘大小,导致启动时出现“内存不足”的消息。到您阅读本文时,该错误可能已在 2.4 系列内核中修复。

我们将构建我们的示例,使其在 i386 架构的 PC 兼容系统上运行,该系统配备 PC 键盘和 VGA 显示器,从软盘启动,并在系统启动后完全在 RAM 中运行根文件系统。此示例也应该可以从 IDE 磁盘和伪装成 IDE 磁盘的 FLASH EEPROM 设备启动。它也可以配置为从 CD-ROM 启动。

构建一个 bzImage 样式的内核,其中包含应用程序所需的所有功能,以及以下三个功能

  • RAM 磁盘支持(在“块设备”菜单中)

  • 初始 RAM 磁盘 (initrd) 支持(也在“块设备”菜单中)

  • ROM 文件系统支持(在“文件系统”菜单中)

不要使用内核模块,因为此示例系统不支持它们。不要在内核中放置任何您不需要的功能,因为它们会占用您在软盘上需要的空间。具有您所需功能的内核应该大约为半兆字节大小,并且应该可以轻松地与 ROM 根文件系统一起安装在软盘上。具有许多不必要的附加功能的内核将超过一兆字节,并且不会为您的 ROM 根文件系统留下足够的空间。

如果您不熟悉在普通 Linux PC 上构建和安装内核,则需要学习一下。简而言之,我将内核源代码放在 /usr/src/linux 中并运行了

xhost +localhost
su
make xconfig
make dep
make bzImage

这在 /usr/src/linux/arch/i386/boot/bzImage 中创建了一个编译后的 Linux 内核。

构建静态链接的 Busybox

在 busybox 源代码目录中,编辑 Makefile,将变量 DOSTATIC 从 false 更改为 true。然后运行 make。这将创建一个静态链接版本的 busybox。通过运行以下命令确认它是静态链接的

ldd busybox

这应该打印出类似以下内容

statically linked (ELF)
正确完成此操作非常重要;如果您安装动态链接版本的 Busybox,您的系统将无法运行,因为我们没有在此示例的软盘上安装运行时动态链接器及其库。
创建 ROM 根文件系统

我们将手动完成创建最小根文件系统的所有步骤,以便您了解启动系统所需的最小内容,而不是从 Linux 发行版的根目录复制所有文件,然后因为不知道是否需要删除任何文件而害怕删除。您将需要成为 root 用户(超级用户)才能执行以下步骤,因为 mknod 命令需要超级用户权限。

创建 tiny-linux 目录并更改目录到其中

mkdir tiny-linux
cd tiny-linux

在其中创建标准目录

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
进入 tiny-linux/dev 目录
cd dev
创建通用终端设备
mknod tty c 5 0
mknod console c 5 1
chmod 666 tty console
#Allow anyone to open and write terminals.
为 VGA 显示器创建虚拟终端设备
mknod tty0 c 4 0
chmod 666 tty0
创建 RAM 磁盘设备
mknod ram0 b 1 0
chmod 600 ram0
创建 null 设备,用于丢弃不需要的输出
mknod null c 1 3
chmod 666 null
更改目录到 tiny-linux/etc/init.d,启动脚本存储在此处
cd ../etc/init.d
使用编辑器在 tiny-linux/etc/init.d/rcS 中创建此 shell 脚本。它将在系统启动时执行
#! /bin/sh
mount -a # Mount the default file systems mentioned in /etc/fstab.
使脚本可执行
chmod 744 rcS
更改目录到 tiny-linux/etc
cd ..
使用编辑器创建文件 tiny-linux/etc/fstab,该文件说明在启动时应挂载哪些文件系统
proc  /proc      proc    defaults     0      0
none  /var/shm   shm     defaults     0      0
设置 tiny-linx/etc/fstab 的模式
chmod 644 fstab
使用编辑器创建文件 tiny-linux/etc/inittab,该文件告诉系统启动程序 /bin/init 启动哪些进程
::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
上面的示例在启动时运行脚本 /etc/init.d/rcS,并在控制台设备上运行交互式 shell。

设置 tiny-linux/etc/inittab 的模式

chmod 644 inittab

这就是创建根文件系统所需的一切,除了安装程序。更改目录到 tiny-linux/bin

cd ../bin
从您构建它的任何位置将静态链接版本的 Busybox 复制到 tiny-linux/bin/busybox 中,命令类似于此命令
cp ~/busybox-0.46/busybox busybox
使用 ln 命令向 Busybox 添加另一个命令名称 ls
ln busybox ls
运行 ls,结果应如下所示
-rwxr-xr-x    2 root     root       580424 Sep 12 15:17 busybox
-rwxr-xr-x    2 root     root       580424 Sep 12 15:17 ls
为所有这些名称重复上述 ln 命令
[, 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
您累了吗?好吧,现在是休息的好时机——您已经完成了创建 ROM 根文件系统。
生成 ROM 根文件系统镜像

您将需要 genromfs 程序来生成 ROM 文件系统镜像。如果您使用的是 Debian 或 Red Hat,它已经作为标准系统的一部分为您打包;您只需要运行命令来安装它。如果您的 Linux 发行版不包含预打包版本,则在撰写本文时,可以在 ftp://ibiblio.org/pub/Linux/system/recovery/genromfs-0.3.tar.gz 找到该程序。安装程序,更改目录到包含 tiny-linux 的目录并运行以下命令

genromfs -d tiny-linux -f fs

这将在文件 fs 中创建 ROM 文件系统镜像。现在,使用 gzip 命令压缩文件系统镜像

gzip -9 fs
这将创建文件 fs.gz,它大约是未压缩版本的一半大小。
构建软盘

我们需要另一个程序来构建我们的软盘:syslinux。这是一个 i386 引导程序,它将从软盘、硬盘或 CD 加载内核和压缩的根文件系统镜像。同样,它与 Debian 或 Red Hat 预先打包在一起,并且在撰写本文时,可以在 ftp://ibiblio.org/pub/Linux/system/boot/loaders/syslinux-1.48.tar.gz. 找到。

通过使用 Linux mformat 命令(或通过其他方式)在软盘上创建 MS-DOS 文件系统。将软盘放入驱动器,但不要挂载它,并使用以下命令安装 syslinux 引导程序

syslinux /dev/fd0

这会将第一阶段引导程序复制到软盘的第一个块,并将第二阶段引导程序复制到软盘的 MS-DOS 文件系统中的文件 LDLINUX.SYS 中。我假设您有一个名为 /mnt 的目录;在下面的 shell 命令中替换您通常用于挂载软盘的任何目录。现在,是将我们的内核和根文件系统复制到软盘的时候了

mount -t msdos /dev/fd0 /mnt
cp fs.gz /mnt
cp /usr/src/linux/arch/i386/boot/bzImage /mnt/linux
使用编辑器创建配置文件 /mnt/syslinux.cfg
TIMEOUT 20
DEFAULT linux
LABEL linux
    KERNEL linux
    APPEND root=/dev/ram0 initrd=fs.gz
这告诉 syslinux 等待两秒钟,然后启动默认系统。您可以在这两秒钟内按下 Shift 键来中断默认启动。在提示符下键入 linux 将执行与默认操作相同的操作。

内核使用参数 root=/dev/ram0initrd=fs.gz 启动。这些参数告诉内核根目录是 RAM 磁盘,并且 RAM 磁盘是从压缩的 ROM 文件系统 镜像 fs.gz 加载的。虽然“ROM”根文件系统实际上在 RAM 中,但它将不可写,因为此示例中使用的 Linux ROM 文件系统驱动程序旨在与真正的 ROM 一起使用,因此不支持写入。

冒烟测试

配置 i386 PC 以从软盘启动。请注意,这是大多数新 PC 的 BIOS 首选项中的设置,它们通常配置为从硬盘启动,而不会首先在软盘上查找引导程序。将软盘放入第一个软盘驱动器,然后重新启动系统。您应该看到类似以下内容

SYSLINUX 1.48 1999-09-26
Copyright (C) 1994-1999 H. Peter Anvin
loading fs.gz.........
loading linux...............
Uncompressing linux, OK, booting the kernel

大量关于内核中每个设备驱动程序和功能的网络垃圾飞速而过,来不及阅读...

RAMDISK: Compressed image found at block 0.
VFS: Mounted root (romfs file system)
Please press Enter to activate this console.
您成功了!按 Enter 键,您应该看到类似以下内容
Busybox v0.46 (2000-09-12-22:16+0000) built-in shell
Enter 'help' for a list of built-in commands.
/ # _
弹出软盘;它不再被使用。根文件系统完全在 RAM 中。您应该能够查看系统并尝试命令,但您不会有任何可写存储。这是我能想到的最简单的可启动系统,运行 busybox,因此我省略了 /dev 中的文件,您需要这些文件来挂载可写 RAM 磁盘、软盘和硬盘。您现在应该能够弄清楚这些设备是什么,添加它们并构建一个专门用于您的应用程序的微型 Linux 系统。

电子邮件:bruce@perens.com

加载 Disqus 评论