Normally, Linux has only a single root filesystem. However, during boot, it is common to use a temporary root filesystem to load and configure device drivers and the like, and then obtain the real root filesystem and switch to it. The TS-7800 uses this temporary filesystem (called an initial ramdisk, or initrd) for the SD driver and for a variety of configuration options. In fact, the ramdisk is used for many of the things (such as determining the final root filesystem to use) that might be handled by the boot loader on another system.
A general caveat applies: most filesystem operations require root
privileges. There are some exceptions and some workarounds. The most
notable is the
which allows you to build applications with "fakeroot support." This
allows the manipulation of a virtual root filesystem with control over
ownership, permissions, and so on. However, the permissions and
related material are maintained in a separate database, and no actual
privileged operations are needed. This allows a non-root user to
manipulate directory hierarchies with virtual root privileges, and
ultimately create archives or filesystem images containing files that
the user hasn't got the privileges to create. For this tutorial,
however, I assume root privileges.
chroot command, while certainly part of
the story, is not sufficient to change the root filesystem. The tool
for this is
pivot_root, which makes one
named directory the new root directory, and "moves" (really, changes
the mount point of) the old root directory to another name.
For the purposes of this tutorial, I'm assuming that the default initrd image provided with the board is adequate. Linux kernel distributions have some support for generating suitable initrd images, and the details of this one are not crucial to an understanding of building an actual distribution. I'll just introduce the key things needed to get the system moving, then focus on what goes on the real root filesystem.
Most Linux users are familiar with files containing images of ISO
CD-ROM or DVD filesystems. Linux supports the creation and use of
images of other types of filesystems. In fact, any file can be treated
as though it were a disk partition, using the
loop option to
mount. For instance, while researching
this, I made a copy of the initrd image used by the TS-7800:
$ dd if=/dev/sdd3 of=initrd.dist bs=16k
$ cp initrd.dist initrd.local
With this file available, it's possible to mount the filesystem to have
a look at it. The copy named
is the local version to edit; the copy named
initrd.dist is a safe pristine copy in case
something gets broken later.
$ mount -o loop initrd.local /mnt
The initrd provides a very basic initial filesystem used to bootstrap
the device by finding and mounting the real root filesystem. The
default kernel configuration is hard-wired to use an initrd
/dev/ram0) as root, and run the
linuxrc script on startup. There are
several provided variants of this script for different root file
systems. The obvious choice is to look at the
linuxrc-sdroot program tries to
configure the system to use an SD card as root. Assuming a correctly
configured SD card with an ext3 filesystem on the fourth fdisk
partition, the script mounts that filesystem and runs
/sbin/init on it. This looks like a good
strategy. So, a couple of small changes are needed to the initrd
image. The first is to change the
symlink to point to
second is to update the script to work with the uClibc build instead
of the Debian build it was configured for.
The SD driver for the TS-7800 includes a proprietary module, so the
tssdcard.ko file simply has to be manually
copied in, and loaded at runtime. The file on the distribution initrd
works fine with the new kernel, so no change is needed.
The kernel simply runs the program called
linuxrc. By default, this is a symbolic
link to the program
comes up quickly to the initrd root filesystem. Removing the link, and
linuxrc instead to
linuxrc-sdroot, causes the system to try to
boot from the last partition on the SD once the drivers are loaded.
The script checks for errors, and if it finds any, mounts from the
internal flash. If it does not, it mounts the filesystem from the SD
card and then tries to change to it. The bootstrap routine actually
has a small quirk that affects this build; it tries to use its own
mount utility, rather than the rootfs one,
for the last cleanup work after calling
pivot_root. This works well with the
provided Debian install, but fails with the minimalist uClibc install.
The solution is to change the lines following the
pivot_root command at the end of the file
else clause) as follows:
pivot_root . ./initrd
/bin/mount -n --move ./initrd/dev ./dev
/bin/mount -n --move ./initrd/sys ./sys
/bin/mount -n --move ./initrd/proc ./proc
exec /sbin/init < $CONSOLE > $CONSOLE 2>&1
This causes the script to run the new (uClibc, statically linked) executables that you are about to create, instead of trying to run dynamically linked executables from another system. (If you were doing this without a tutorial, you probably wouldn't know this until after you'd set everything else up and started getting cryptic error messages).
Unmount the initrd disk image like so:
$ umount /mnt