利用 buildroot 與 Qemu 建構簡易 Embedded Linux 環境
===
###### tags: `twlkh`, `qemu`, `buildroot`
# Embedded Linux development
[Building Embedded Linux Full Tutorial for ARM](http://www.slideshare.net/sherif_mosa/building-embedded-linux-full-tutorial-for-arm)
{%slideshare sherif_mosa/building-embedded-linux-full-tutorial-for-arm %}
## Components
* cross toolchain
* libc: glibc / uclibc / musl
* bootloader
* uboot / barebox
* kernel
* rootfs
* busybox
* applications
* development toolkits
## Some limitations
* Different sources download path
* url
* local
* ... and so on, one for each package
* Different download tools
* tar ball / zip
* git/svn/mercurial
* copy (for local)
* Some patches might required for embedded environment
* non-glibc
* busybox
* rootfs path
* and so on
* Package dependency
# builtroot
* (wiki) A set of Makefiles and patches that simplifies and automates the process of building a complete and bootable Linux environment for an embedded system
* menuconfig to select alternatives and versions of
* board
* bootloaders
* compiler, binutils and libc
* kernel version
* supported packages
* How to support one package, e.g. foo
* foo.mk (Makefile DSL). Commands for
* download
* configure
* build
* install
* Config.in (menuconfig selection)
![buildroot](http://free-electrons.com/wp-content/uploads/2011/02/buildroot-diagram.png)
* Example mk for customized package, e.g. bpftest.mk
~~~
BPFTEST_VERSION = 1.0
BPFTEST_SITE = $(TOPDIR)/../bpftest
BPFTEST_SOURCE = "apps modules"
BPFTEST_SITE_METHOD = local
BPFTEST_LICENSE = GPLv3+
BPFTEST_LICENSE_FILES = COPYING
BPFTEST_MODULE_SUBDIRS = modules
BPF_MODULE_MAKE_OPTS = KVERSION=$(LINUX_VERSION_PROBED) KERNEL_DIR=$(LINUX_DIR)
define BPFTEST_EXTRACT_CMDS
cp -a $(TOPDIR)/$(BPFTEST_SOURCE) $(@D)
endef
define BPFTEST_BUILD_CMDS
$(MAKE) CC="$(TARGET_CC)" LD="$(TARGET_LD)" -C $(@D)/apps all
endef
define BPFTEST_INSTALL_TARGET_CMDS
$(INSTALL) -D -m 0755 $(@D)/apps/hello $(TARGET_DIR)/usr/bin
endef
$(eval $(kernel-module))
$(eval $(generic-package))
~~~
## 簡單的操作流程 - 以 qemu for ARM vexpress-a9 為例
```shell=
git clone https://git.busybox.net/buildroot
cd buildroot
make qemu_arm_vexpress_defconfig
#這會跑很久,要下載新的 cross-toolchain, kernel, ... 並且把他全部 build起來
make
#接下來就可用 qemu跑了歐,簡單吧
# Ref:https://github.com/buildroot/buildroot/tree/master/board/qemu/arm-vexpress
qemu-system-arm -M vexpress-a9 -smp 1 -m 256 -kernel output/images/zImage -dtb output/images/vexpress-v2p-ca9.dtb -drive file=output/images/rootfs.ext2,if=sd,format=raw -append "console=ttyAMA0,115200 root=/dev/mmcblk0" -serial stdio -net nic,model=lan9118 -net user
```
參考資料:
[Build Your ARM Image for QEMU](https://medicineyeh.wordpress.com/2016/03/29/buildup-your-arm-image-for-qemu/)
[FicHugh blog - buildRoot study - 建立自己的作業系統](http://fichugh.blogspot.tw/2016/02/buildroot-study.html)
# Qemu
* My target: arm vexpress
* Supported by vanilla kernel
* Supported by Qemu
## Steps
* Build
~~~ sh
$ configure --prefix=/path/to/install --target-list=arm-softmmu
$ make
$ make install
~~~
* Run
* https://wiki.linaro.org/PeterMaydell/QemuVersatileExpress
* target: `-M vexpress-a15`
(Feedback) Can try virtio (?)
* images:
* kernel: `-kernel /path/to/zImage`
* dtb: `-dtb /path/to/dtb`
* disk: `-drive ...`
* serial output to tty: `-serial stdio`
* virtual NAT and port forwarding:`-net nic,vlan=1 -net user,vlan=1,hostfwd=udp:127.0.0.1:6669-:69`
(Feedback) Can try tap
* boot args: `-append "root=/dev/mmcblk0 console=ttyAMA0,115200n8"`
* debug:`-s` or `-gdb tcp::1234` / `-S`
* CPU logging: `-d op -D /path/to/qemu.log`
* example command
~~~ sh
$ /path/to/install/bin/qemu-system-arm \
-M vexpress-a15 \
-kernel buildroot/output/images/zImage \
-dtb buildroot/output/images/vexpress-v2p-ca15_a7.dtb \
-drive file=buildroot/output/images/rootfs.ext2,if=sd \
-smp 2 \
-s \
-serial stdio \
-append "root=/dev/mmcblk0 console=ttyAMA0,115200n8" \
-net nic,vlan=1 -net user,vlan=1,hostfwd=udp:127.0.0.1:6669-:69
~~~