
For embedded systems based on MIPS and ARM architectures, specialized GNU / Linux distribution generators are often used: buildroot, openwrt, and other Yocto.
But sometimes it is interesting to run a universal Debian OS on such a system. Installing Debian on a computer with an x86 / amd64 architecture processor is simple, but with embedded systems,
believe me, everything is not so simple ...In this publication, I will tell you how to install using debootstrap, and then how to use Debian for running a Debian operating system for computers with MIPS and ARM processors using QEMU.
Introduction
GNU / Linux operating systems most often consist of at least two components: the OS kernel (kernel) and the user programs (userspace). The Linux kernel (yes, yes, this is exactly the kernel called Linux!) Directly interacts with the hardware and provides user programs access to computer hardware resources using abstract interfaces.
While the kernel is strongly tied to a specific SoC family or even to a specific board, user applications are much more “loose” components; their executable files are tied only to a specific version of the processor command system (for example, MIPS-I or MIPS32r2), and to the version of the kernel programming interfaces.
This state of affairs turns out to be the following: it becomes possible to run the same applications on completely different SoCs, on completely different boards, the main thing is to ensure that the program interfaces of the kernel are the same.
Such a “lag” of applications can be very useful in practice. For example, the
Raspbian and QEMU publication describes the launch of the Raspbian OS for the Raspberry Pi on an ARM Versatile card emulated with QEMU.
Action plan
From the above, it is clear that to run Debian on an emulated MIPS (or ARM) board we need:
- Linux kernel that runs on QEMU;
- image of the Debian root filesystem (i.e. the applications mentioned above).
We will build the Linux kernel using cross-development tools on our own, and we will entrust the creation of an image of the root file system of Debian to the debootstrap program.
We will use a computer with an x86_64 processor running the Debian Linux testing version as an instrumental computer (a computer on which we will cross-compile and run the QEMU emulator).
Why choose Debian testing?Because out-of-the-box Debian testing supports a comparatively recent version of QEMU and cross-compilers for both MIPS and ARM.
All actions to build the kernel and form an image of the root file system are performed from the command line, do not require operator intervention, and can easily be placed inside a script.
Commands to be executed as root are preceded by a
#
character, commands that do not need superuser privileges are preceded by a
$
character.
For example:
- The command for installing the software is executed as the root user:
# aptitude install -y binfmt-support qemu qemu-user-static debootstrap
- The linux kernel build command can be executed on behalf of an unprivileged user:
$ make
How to quickly build the required tool computer?The required tool computer is easy to build with virtualization software (VMWare, VirtualBox or QEMU / KVM).
For this:
- Download the debian-8.3.0-amd64-netinst.iso network installation disk image ,
- Create a virtual computer with the following minimum parameters: RAM: 1 GB, HDD: 8 GB; connect the Debian installation boot disk to the virtual computer;
- start the virtual computer with the download of the Debian installer from the installation disk;
- Install the Debian virtual computer OS on an almost minimal configuration (for example, to launch QEMU there is no need to install the components of a web server and a graphical user interface):

- Download the newly installed Debian OS, and log in as root;
- enable the ability to install Debian packages of the testing version, to do this in the command line
# echo "deb http://ftp.ru.debian.org/debian/ testing main non-free contrib" \
>> /etc/apt/sources.list
# apt-get update
Note: in a good way, it would be better to do apt-get dist-upgrade
after apt-get update
, but if you want to use a virtual machine only to start Debian MIPS / ARM, then this is not necessary at all.
')
Debian for MIPS
Debian for MIPS under QEMU will be demonstrated on a MIPS Malta virtual board with a MIPS32R2 architecture processor in big-endian mode.
Linux kernel build for QEMU Malta
First, let's take care of getting the source code for the kernel - download it from kernel.org:
$ wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.3.tar.xz
Unpack the archive and go to the
linux-4.4.3
directory:
$ tar fx linux-4.4.3.tar.xz
$ cd linux-4.4.3
Install the toolchain for MIPS:
# aptitude install -y gcc-mips-linux-gnu
In addition to the toolchain for MIPS, additional tools will be needed to build the Linux kernel:
# aptitude install -y make gcc gawk
Prepare for assembly under MIPS:
$ export ARCH = mips
$ export CROSS_COMPILE = mips-linux-gnu-
The
ARCH
variable explains to the kernel build system (Kbuild) that all platform-specific kernel components are taken in the
arch/mips
directory, and the
CROSS_COMPILE
variable explicitly tells Kbuild which compiler (or rather toolchain) to use - they can be several on the machine, and Kbuild likes accuracy.
A note about ARCH and CROSS_COMPILEIn principle, you can not do this, and each time you can set the ARCH
and CROSS_COMPILE
on the make command line, but then the make line will look somewhat cumbersome.
Note about out of tree buildThe Linux kernel build order described below is called
in tree build , i.e. compiled object files fall into the same directories as the source files. Kbuild allows you to use the
out of tree build order, in which the object files fall into a separate directory, which allows you to collect several different kernel variants from the same source code, while the object files of different kernel variants will not conflict. For details, see, for example,
here .
Now select the configuration for the core based on the pre-configured configuration for the Malta board.
The preparation of the configuration file for the Malta
arch/mips/configs/malta_defconfig
that ships in linux-4.4.3 does not work for two reasons:
- The configuration is designed for Malta in little-endian mode, and I would like to use big-endian mode.
- in the
malta_defconfig
configuration, the options ( CONFIG_FHANDLE
and CONFIG_CGROUPS
) are not enabled, without which Debian 8 simply will not boot.
Based on the
malta_defconfig
we will create the necessary
malta_defconfig
configuration file
malta-big_defconfig
, which will not have these disadvantages:
$ sed "s / CONFIG_CPU_LITTLE_ENDIAN = y / CONFIG_CPU_BIG_ENDIAN = y /" \
<arch / mips / configs / malta_defconfig \
> arch / mips / configs / malta-big_defconfig
$ echo "CONFIG_FHANDLE = y" >> arch / mips / configs / malta-big_defconfig
$ echo "CONFIG_CGROUPS = y" >> arch / mips / configs / malta-big_defconfig
Now, from the workpiece, we will generate the kernel configuration file
.config
:
$ make malta-big_defconfig
And run the build process:
$ make
Note: If your tool computer has more than one processor core, you should use them. In order to parallelize the make operation, the -j option is used, the argument of which is the number of tasks (commands) that make will try to run at the same time. So on a 4-processor instrumental computer, it makes sense to run make like this: $ make -j 4
As a result, we get the
vmlinux
kernel
vmlinux
. Check its performance under QEMU!
Install QEMU:
# aptitude install -y qemu-system
Run the newly compiled kernel under QEMU, after leaving the linux-4.4.3 directory:
$ cd ..
$ qemu-system-mips -nodefaults -nographic -kernel linux-4.4.3 / vmlinux -serial stdio
Linux version 4.4.3 (user @ debian) (gcc version 5.3.1 20160205 (Debian 5.3.1-8))
earlycon console serial ix port 0x3f8 (options '38400n8')
bootconsole [uart0] enabled
Config serial console: console = ttyS0,38400n8r
CPU0 revision is: 00019300 (MIPS 24Kc)
FPU revision is: 00739300
MIPS: machine is mti, malta
...
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block (0,0)
As you can see, the kernel successfully passed the initialization and tried to mount the root file system, which, however, did not work.
Create the necessary root filesystem!
Creating a root file system for MIPS
Creating the Debian root filesystem will therefore begin with the installation of debootstrap and the components necessary for it to work:
# aptitude install -y binfmt-support qemu qemu-user-static debootstrap
Now run the first stage of debootstrap:
# debootstrap --foreign --arch = mips jessie debian-jessie-mips / \
http://ftp.ru.debian.org/debian/
At the first stage, debootstrap will download the jessie version (stable) Debian packages required for the minimal root filesystem from
ftp.ru.debian.org/debian (the official Russian Debian mirror) for the 32-bit MIPS big-endian architecture (options
--foreign
and
--arch=mips
), and unpack them into the
debian-jessie-mips/
directory.
According to the results of the first stage of debootstrap, a file system will be formed in the
debian-jessie-mips/
directory, very similar to the real one, you can even try to use it for downloading. However, the root filesystem components (Debian packages) are not yet configured at this stage.
To perform the setup, you must run the second stage of debootstrap. At this stage, you need to run programs for MIPS, so you have to use a special version of QEMU, the so-called usermode qemu, which ensures the launch of separate programs for Linux MIPS under Linux amd64.
We will put a statically assembled system emulator with a MIPS architecture processor inside the root file system and run debootstrap inside the root file system using chroot:
# cp / usr / bin / qemu-mips-static debian-jessie-mips / usr / bin /
# DEBIAN_FRONTEND = noninteractive DEBCONF_NONINTERACTIVE_SEEN = true \
LC_ALL = C LANGUAGE = C LANG = C \
PATH = / usr / local / bin: / usr / bin: / bin: / usr / local / sbin: / usr / sbin: / sbin \
chroot debian-jessie-mips / / debootstrap / debootstrap - second-stage
When the second stage of debootstrap is finished, the components of the Debian root filesystem are configured, and it remains to put the final touches (for example, fix some files in
/etc
, say, configure the host and network, add users, etc.).
But for this demo, we will limit ourselves to installing the trivial password 123 for the root user:
# echo 'root: 123' | chroot debian-jessie-mips / chpasswd
Now the root file system can be considered configured - it's time to cover up the tracks. For safekeeping, archive the root file system:
# rm debian-jessie-mips / usr / bin / qemu-mips-static
# tar czf debian-jessie-mips.tar.gz -C debian-jessie-mips.
To run under the emulator, the root file system will have to be placed on a virtual drive (in the case of Malta it is a virtual IDE disk).
Let us estimate the size of the disk we will have to create:
# du -sh debian-jessie-mips /
284M debian-jessie-mips /
Once the root file system is less than 300 MB, it is quite possible to allocate a virtual disk of 512 MB for its storage. Create a virtual disk file, create an ext2 file system on it, and copy our root file system to it:
$ dd if = / dev / zero bs = 1M count = 512 of = debian-jessie-mips.ext2
$ / sbin / mke2fs -F debian-jessie-mips.ext2
# mkdir ext2
# mount debian-jessie-mips.ext2 ext2 /
# tar xf debian-jessie-mips.tar.gz -C ext2 /
# umount ext2 /
# rmdir ext2 /
Now we will start Debian Linux under QEMU:
$ qemu-system-mips -nodefaults -nographic -kernel linux-4.4.3 / vmlinux \
-serial stdio -hda debian-jessie-mips.ext2 -append "root = / dev / sda"
After the
login:
prompt appears
login:
you can log in as root (the password is 123) and check the processor type:

Debian for ARM
Debian for ARM under QEMU will be demonstrated on the ARM Versatile PB virtual board.
The steps to build a Linux kernel and create a root filesystem are almost completely similar to those for MIPS, so I’ll only give a sequence of commands to achieve a result with minimal comments.
We will assume that we are starting to work on a “clean” instrumental computer.
Build Linux kernel for ARM Versatile PB
$ wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.3.tar.xz
$ tar fx linux-4.4.3.tar.xz
$ cd linux-4.4.3
# aptitude install -y gcc-arm-linux-gnueabi
# aptitude install -y make gcc gawk
$ export ARCH = arm
$ export CROSS_COMPILE = arm-linux-gnueabi-
With the preparation of the kernel configuration for Versatile, you will have to tinker, since the built-in ROM Versatile PB emulated by QEMU is quite small (64 MB). Fortunately, the emulated Versatile PB has a PCI controller to which you can connect a virtual SCSI controller. However, support for this hardware will have to be enabled in the kernel:
$ cp arch / arm / configs / versatile_defconfig arch / arm / configs / versatile-debian_defconfig
$ echo "CONFIG_FHANDLE = y" >> arch / arm / configs / versatile-debian_defconfig
$ echo "CONFIG_CGROUPS = y" >> arch / arm / configs / versatile-debian_defconfig
$ echo "CONFIG_DEVTMPFS = y" >> arch / arm / configs / versatile-debian_defconfig
$ echo "CONFIG_TMPFS = y" >> arch / arm / configs / versatile-debian_defconfig
$ echo "CONFIG_PCI = y" >> arch / arm / configs / versatile-debian_defconfig
$ echo "CONFIG_SCSI = y" >> arch / arm / configs / versatile-debian_defconfig
$ echo "CONFIG_BLK_DEV_SD = y" >> arch / arm / configs / versatile-debian_defconfig
$ echo "CONFIG_SCSI_SYM53C8XX_2 = y" >> arch / arm / configs / versatile-debian_defconfig
$ make versatile-debian_defconfig
$ make
# aptitude install -y qemu-system
Unlike the MIPS Malta board,
vmlinux
download
vmlinux
for Versatile PB is not implemented,
zImage
images are
zImage
:
$ cd ..
$ qemu-system-arm -nodefaults -nographic -M versatilepb \
-kernel linux-4.4.3 / arch / arm / boot / zImage \
-append "console = ttyAMA0" -serial stdio
...
Uncompressing Linux ... done, booting the kernel.
Booting Linux on physical CPU 0x0
Linux version 4.4.3 (antony @ debian) (gcc version 5.3.1 20160205 (Debian 5.3.1-8))
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr = 00093177
CPU: VIVT data cache, VIVT instruction cache
Machine: ARM-Versatile PB
...
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block (0,0)
Creating a root file system for ARM
# aptitude install -y binfmt-support qemu qemu-user-static debootstrap
# debootstrap --foreign --arch = armel jessie debian-jessie-armel \
http://ftp.ru.debian.org/debian/
# cp / usr / bin / qemu-arm-static debian-jessie-armel / usr / bin /
# DEBIAN_FRONTEND = noninteractive DEBCONF_NONINTERACTIVE_SEEN = true \
LC_ALL = C LANGUAGE = C LANG = C \
PATH = / usr / local / bin: / usr / bin: / bin: / usr / local / sbin: / usr / sbin: / sbin \
chroot debian-jessie-armel / / debootstrap / debootstrap --second-stage
# echo 'root: 123' | chroot debian-jessie-armel / chpasswd
# rm debian-jessie-armel / usr / bin / qemu-arm-static
# tar czf debian-jessie-armel.tar.gz -C debian-jessie-armel.
# du -sh debian-jessie-armel /
270M debian-jessie-armel /
$ dd if = / dev / zero bs = 1M count = 512 of = debian-jessie-armel.ext2
$ / sbin / mke2fs -F debian-jessie-armel.ext2
# mkdir ext2
# mount debian-jessie-armel.ext2 ext2 /
# tar xf debian-jessie-armel.tar.gz -C ext2 /
# umount ext2 /
# rmdir ext2 /
$ qemu-system-arm -nodefaults -nographic -M versatilepb \
-kernel linux-4.4.3 / arch / arm / boot / zImage \
-append "console = ttyAMA0 root = / dev / sda" \
-serial stdio -hda debian-jessie-armel.ext2
The results of checking the type of processor (remember, the password is 123):

Conclusion
As you can see, installing and running Debian for MIPS and ARM is not that difficult.
Running Debian on a real motherboard with a MIPS or ARM processor is usually more troublesome and is worthy of a separate publication.
Links