
I have written a number of scripts to create Debian foreign architecture
(mostly armel and armhf) rootfs images for SD cards or NAND flashing. I started
with putting Debian on my
Openmoko gta01 and gta02 and continued with
devices like the qi nanonote, a
marvel kirkwood based device, the Always
Innovating Touchbook (close to the Beagleboard), the
Notion Ink Adam and
most recently the
Golden Delicious gta04. Once it has been manufactured, I
will surely also get my hands dirty with the
Neo900 whose creators are
currently
looking for potential donors/customers to increase the size of
the first batch and get the price per unit further down.
Creating a Debian rootfs disk image for all these devices basically follows the
same steps:
- create an disk image file, partition it, format the partitions and mount the
/ partition into a directory
- use
debootstrap or multistrap to extract a selection of armel or armhf packages into the directory
- copy over
/usr/bin/qemu-arm-static for qemu user mode emulation
- chroot into the directory to execute package maintainer scripts with
dpkg --configure -a
- copy the disk image onto the sd card
It was not long until I started wondering why I had to run all of the above
steps with superuser privileges even though everything except the final step
(which I will not cover here) was in principle nothing else than writing some
magic bytes to files I had write access to (the disk image file) in some more
or less fancy ways.
So I tried using
fakeroot+
fakechroot and after some
initial troubles I
managed to build a foreign architecture rootfs
without needing root
priviliges for steps two, three and four. I wrote about my solution which
still included some workarounds in
another article here.
These
workarounds were soon not needed anymore as upstream fixed the outstanding
issues. As a result I wrote the
polystrap tool which combines
multistrap,
fakeroot,
fakechroot and qemu user mode emulation. Recently
I managed to integrate
proot support
in a separate branch of
polystrap.
Last year I got the LEGO ev3 robot for christmas and since it runs Linux I also
wanted to put Debian on it by following the instructions given by the
ev3dev
project. Even though ev3dev calls itself a "distribution" it only deviates
from pure Debian by its kernel, some configuration options and its initial
package selection. Otherwise it's vanilla Debian. The project also supplies
some
multistrap based scripts which create the rootfs and then
partition and populate an SD card. All of this is of course done as the
superuser.
While the creation of the file/directory structure of the foreign Debian armel
rootfs can by now easily be done without superuser priviliges by running
multistrap under
fakeroot/
fakechroot/
proot, creating the SD card image
still seems to be a bit more tricky. While it is no problem to write a
partition table to a regular file, it turned out to be tricky to mount these
partition because tools like
kpartx and
losetup require superuser
permissions. Tools like
mkfs.ext3 and
fuse-ext2 which otherwise would be
able to work on a regular file without superuser privileges do not seem to
allow to specify the required offsets that the partitions have within the disk
image. With
fuseloop there exists a tool which allows to "loop-mount"
parts of a file in userspace to a new file and thus allows tools like
mkfs.ext3 and
fuse-ext2 to work as they normally do. But
fuseloop is not
packaged for Debian yet and thus also not in the current Debian stable. An
obvious workaround would be to create and fill each partition in a separate
file and concatenate them together. But why do I have to write my data twice
just because I do not want to become the superuser? Even worse: because
parted refuses to write a partition table to a file which is too small to
hold the specified partitions, one spends twice the disk space of the final
image: the image with the partition table plus the image with the main
partition's content.
So lets summarize: a bootable foreign architecture SD card disk image is
nothing else than a regular file representing the contents of the SD card as a
block device. This disk image is created in my home directory and given enough
free disk space there is nothing stopping me from writing any possible
permutation of bits to that file. Obviously I'm interested in a permutation
representing a valid partition table and file systems with sensible content.
Why do I need superuser privileges to generate such a sensible permutation of
bits?
Gladly it seems that the (at least in my opinion) hardest part of faking chroot
and executing foreign architecture package maintainer scripts is already
possible without superuser privileges by using
fakeroot and
fakechroot or
proot together with qemu user mode emulation. But then there is still the
blocker of creating the disk image itself through some user mode loop mounting
of a filesystem occupying a virtual "partition" in the disk image.
Why has all this only become available so very recently and still requires a
number of workarounds to fully work in userspace? There exists a surprising
amount of scripts which wrap
debootstrap/
multistrap. Most of them require
superuser privileges. Does everybody just accept that they have to put a
sudo
in front of every invocation and hope for the best? While this might be okay
for well tested code like
debootstrap and
multistrap the countless wrapper
scripts might accidentally (be it a bug in the code or a typo in the given
command line arguments) write to your primary hard disk instead of your SD
card. Such behavior can easily be mitigated by not executing any such script
with superuser privileges in the first place.
Operations like loop mounting affect the whole system. Why do I have to touch
anything outside of my home directory (
/dev/loop in this case) to populate a
file in it with some meaningful bits? Virtualization is no option because every
virtualization solution again requires root privileges.
One might argue that a number of solutions just require some initial setup by
root to then later be used by a regular user (for example
/etc/fstab
configuration or the
schroot approach). But then again: why do I have to
write anything outside of my home directory (even if it is only once) to be
able to write something meaningful to a file in it?
The latter approach also does not work if one cannot become root in the first
place or is limited by a virtualized environment. Imagine you are trying to
build a Debian rootfs on a machine where you just have a regular user account.
Or a situation I was recently in: I had a virtual server which denied me
operations like loop mounting.
Given all these downsides, why is it still so common to just assume that one is
able and willing to use
sudo and be done with it in most cases?
I really wonder why technologies like
fakeroot and
fakechroot have only
been developed this late. Has this problem not been around since the earliest
days of Linux/Unix?
Am I missing something and rambling around for nothing? Is this idea a lost
cause or something that is worth spending time and energy on to extend and fix
the required tools?