---
title: '[Embedded System] Deploy Linux v5.13 onto qemu vexpress-a9'
disqus: hackmd
---
[Embedded System] Deploy Linux v5.13 onto qemu vexpress-a9
===
## Table of Contents
[TOC]
## Beginners Guide
Given the fact the the tutorials are mostly focused on Linux v4, and you will find that it doesnt work out by simply follow these tutorials to deploy v5.13, this blog aims to cover the latest Linux version of the time (2021/10/29), v5.13.
If you are a total beginner to this, start here!
1. Visit [The Linux Kernel Archives](https://www.kernel.org/)
2. Visit [BUSYBOX v1.34.1](https://busybox.net/)
3. See [奔跑吧-linux內核-qemu調試內核-软件开发平台及语言笔记大全(超详细)](https://cntofu.com/book/46/qemu/ben_pao_5427-_linux_nei_6838-_qemu_diao_shi_nei_he.md)
4. See [QEMU搭建arm Linux開發環境](https://www.twblogs.net/a/5b8ed4692b71771883481169)
5. See [ubuntu-16.04 qemu 嵌入式arm模拟](https://www.jianshu.com/p/cd7d9a753433)
6. See [qemu参数大全](https://www.zhaixue.cc/qemu/qemu-param.html)
7. See [嵌入式 C語言自我修養 — 從芯片、編譯器到操作系統](https://www.tenlong.com.tw/products/9787121408564)
8. See [/etc/inittab,/etc/init.d/rcS和/etc/profile分析](https://www.itread01.com/content/1547140746.html)
9. install related library and tools
10. Start
Install library and tools
---
```bash=
sudo apt-get install qemu qemu-system-arm libncurses5-dev gcc-arm-linux-gnueabi build-essential flex bison
```
Linux v5.14.14 (stable)
---
Download it
```bash=
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.14.14.tar.xz
```
> and untar it [name=ztex]
```bash=
$> cd linux-5.14.14
linux-5.14.14> CROSS_COMPILE=arm-linux-gnueabi-
linux-5.14.14> ARCH=arm
linux-5.14.14> make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm vexpress_defconfig
linux-5.14.14> make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm dtbs
linux-5.14.14> make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm
```
> After this, you can get, dtb file (describe hardware configuration of vexpress-a9), zImage (kernel image)
BUSYBOX v1.34.1
---
```bash=
$> wget https://busybox.net/downloads/busybox-1.34.1.tar.bz2
```
> and untar it [name=ztex]
```bash=
$> cd busybox-1.34.1
busybox-1.34.1> CROSS_COMPILE=arm-linux-gnueabi-
busybox-1.34.1> ARCH=arm
busybox-1.34.1> make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm menuconfig
Settings —>
— Build Options
[ ] Build static binary (no shared libs)
```


```bash=
busybox-1.34.1> CROSS_COMPILE=arm-linux-gnueabi-
busybox-1.34.1> ARCH=arm
busybox-1.34.1> make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm
busybox-1.34.1> make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm install
```
> You will see there is a `_install` directory, we are gonna use this to make our ramfs. [name=ztex]
```bash=
busybox-1.34.1> mkdir rootfs
busybox-1.34.1> cp -r _install/* rootfs
busybox-1.34.1> mkdir rootfs/lib
busybox-1.34.1> mkdir rootfs/dev
busybox-1.34.1> cp -p /usr/arm-linux-gnueabi/lib/* rootfs/lib
(cuz we need arm library to execute on the arm platform)
busybox-1.34.1> sudo mknod -m 666 rootfs/dev/tty1 c 4 1
busybox-1.34.1> sudo mknod -m 666 rootfs/dev/tty2 c 4 2
busybox-1.34.1> sudo mknod -m 666 rootfs/dev/tty3 c 4 3
busybox-1.34.1> sudo mknod -m 666 rootfs/dev/tty4 c 4 4
(create serial devices)
busybox-1.34.1> sudo mknod -m 666 rootfs/dev/console c 5 1
(create console)
busybox-1.34.1> sudo mknod -m 666 rootfs/dev/null c 1 3
(create null)
```
> Now, we have created the rootfs, let's make our image file. based on a ext4 file system format![name=ztex]
```bash=
➜ rootfs ls
bin dev etc lib linuxrc proc sbin sys usr
➜ rootfs file linuxrc
linuxrc: symbolic link to bin/busybox
```
> note that this first thing been executed is `linuxrc`, which is a symbolic link to `bin/busybox`[name=ztex]
```bash=
busybox-1.34.1> dd if=/dev/zero of=a9rootfs.ext4 bs=1M count=64
busybox-1.34.1> mkfs.ext4 a9rootfs.ext4
busybox-1.34.1> mount -t ext4 a9rootfs.ext4 /mnt/ -o loop
busybox-1.34.1> cp -r rootfs/* /mnt
busybox-1.34.1> umount /mnt
```
> while the other tutorials use 32M. I found that 32M gives no enough space, so I adjust it to 64M[name=ztex]
Mount `proc` `sys` fs
---
```bash=
mkdir rootfs/proc
mkdir rootfs/sys
mkdir rootfs/etc
mkdir rootfs/etc/init.d
touch rootfs/etc/init.d/rcS
touch rootfs/etc/inittab
chmod -R 777 rootfs/etc
```
```bash=
rootfs
├── bin
├── dev
├── etc
├── lib
├── linuxrc -> bin/busybox
├── proc
├── sbin
├── sys
└── usr
➜ busybox-1.34.1 tree rootfs/etc -L 2
rootfs/etc
├── init.d
│ └── rcS
└── inittab
```
- [ ] `inittab`
```bash=
#first:run the system script file
::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
::ctrlaltdel:-/sbin/reboot
#umount all filesystem
::shutdown:/bin/umount -a -r
#restart init process
::restart:/sbin/init
```
- [ ] `init.d/rcS`
```bash=
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
mount -o remount,rw /
/sbin/mdev -s
#/sbin/umount -a
#/sbin/mount -a
#/sbin/mount -t ext4 remount rw /
```
see [[Linux筆記] 利用 mount 指令解決 Read-only file system 問題](https://blog.wu-boy.com/2008/05/linux%E7%AD%86%E8%A8%98-%E5%88%A9%E7%94%A8-mount-%E6%8C%87%E4%BB%A4%E8%A7%A3%E6%B1%BA-read-only-file-system-%E5%95%8F%E9%A1%8C/)
see [用busybox制作文件系统](https://www.cnblogs.com/asulove/p/6043200.html)
see [移植Linux操作系統時候遇到的問題](https://www.twblogs.net/a/5f00709e0b1faa371958bfa5)
```bash=
➜ busybox-1.34.1 cat mkrootfs.sh
mkdir rootfs
cd rootfs
mkdir -pv proc sys dev etc etc/init.d
touch etc/inittab
touch etc/init.d/rcS
chmod -R 777 etc
cd ..
cp -r _install/* rootfs
mknod -m 666 rootfs/dev/tty1 c 4 1
mknod -m 666 rootfs/dev/tty2 c 4 2
mknod -m 666 rootfs/dev/tty3 c 4 3
mknod -m 666 rootfs/dev/tty4 c 4 4
mknod -m 666 rootfs/dev/console c 5 1
mknod -m 666 rootfs/dev/null c 1 3
dd if=/dev/zero of=a9rootfs.ext4 bs=1M count=64
mkfs.ext4 a9rootfs.ext4
mount -t ext4 a9rootfs.ext4 /mnt/ -o loop
cp -r rootfs/* /mnt
umount /mnt
```
Fire QEMU
---
```bash=
$> qemu-system-arm -M vexpress-a9 -m 512M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -append "root=/dev/mmcblk0 console=ttyAMA0" -sd a9rootfs.ext4
```

What's next
---
Now we can develop and modify linux kernel and test&debug on qemu!!
## Appendix and FAQ
:::info
**Find this document incomplete?** Leave a comment!
:::
###### tags: `QEMU` `Linux` `Busybox`