Skip to content

Instantly share code, notes, and snippets.

@philipz
Last active September 30, 2015 19:01
Show Gist options
  • Save philipz/9f41498837baeae23cd6 to your computer and use it in GitHub Desktop.
Save philipz/9f41498837baeae23cd6 to your computer and use it in GitHub Desktop.
Docker on Qemu

How to build a Qemu environment to run Docker

Qemu

sudo apt-get install qemu-user-static qemu-system-arm debootstrap
mkdir vexpress
cd vexpress
mkdir qemu-img
dd if=/dev/zero of=./vexpress-4G.img bs=4M count=1024
sudo losetup -f ./vexpress-4G.img
sudo mkfs.ext4 /dev/loop0
sudo mount /dev/loop0 qemu-img
sudo qemu-debootstrap --arch=armhf utopic qemu-img
sudo cp `which qemu-arm-static` qemu-img/usr/bin/

準備 serial console, apt repositories, network

sudo cp -f /etc/init/tty1.conf qemu-img/etc/init/
sudo chroot qemu-img
sed 's/tty1/ttyAMA0/g' /etc/init/tty1.conf > /etc/init/ttyAMA0.conf
echo -e "\nauto eth0\niface eth0 inet dhcp" >> /etc/network/interfaces

設定 root password passwd 抓取必要的 kernel image

echo "deb  http://ports.ubuntu.com saucy main restricted multiverse universe" > /etc/apt/sources.list
apt-get update
apt-get install wget ca-certificates
wget --no-check-certificate https://launchpad.net/ubuntu/+archive/primary/+files/linux-image-3.16.0-23-generic_3.16.0-23.31_armhf.deb

準備安裝 kernel image (保持耐心),如果無法apt-get安裝,請檢查/etc/apt/sources.list

apt-get install busybox initramfs-tools klibc-utils libklibc module-init-tools
dpkg -i linux-image-3.16.0-23-generic_3.16.0-23.31_armhf.deb

按下 Ctrl-D 離開 chroot 複製 kernel 相關檔案到 QEMU 可存取之處

sudo cp qemu-img/boot/vmlinuz-3.16.0-23-generic .
sudo cp qemu-img/boot/initrd.img-3.16.0-23-generic .
cp qemu-img/lib/firmware/3.16.0-23-generic/device-tree/vexpress-v2p-ca9.dtb .

將檔案擁有者改為一般使用者,以利後續操作:

sudo chown $USER.$USER vmlinuz-3.16.0-23-generic initrd.img-3.16.0-23-generic

尾聲,卸載 loop 裝置

sudo umount qemu-img
sudo losetup -d /dev/loop0

使用 qemu-system-arm 來啟動,建議寫個簡單的 shell script,如 run.sh

#!/bin/bash
KERN_VER=3.16.0-23-generic
qemu-system-arm \
    -kernel vmlinuz-$KERN_VER \
    -initrd initrd.img-$KERN_VER \
    -M vexpress-a9 -serial stdio -m 1024 -append \
    'root=/dev/mmcblk0 rw mem=1024M raid=noautodetect rootwait console=ttyAMA0,38400n8 devtmpfs.mount=0' \
    -sd vexpress-4G.img \
    -dtb vexpress-v2p-ca9.dtb -display none

設定 SSH 以允許遠端連線

修改 RUN.sh,將 Host 端的 port 2200 重新導向到 Guest/QEMU 的 port 22 (ssh)

#!/bin/bash
KERN_VER=3.16.0-23-generic
qemu-system-arm \
    -kernel vmlinuz-$KERN_VER \
    -initrd initrd.img-$KERN_VER \
    -M vexpress-a9 -serial stdio -m 1024 -append \
    'root=/dev/mmcblk0 rw mem=1024M raid=noautodetect rootwait console=ttyAMA0,38400n8 devtmpfs.mount=0' \
    -dtb vexpress-v2p-ca9.dtb -display none \
    -redir tcp:2200::22 \
    -drive file=vexpress-4G.img,if=sd,cache=writeback

用 scp/sshfs 建構便利的 Go 開發環境

以下指令都在 Host 端執行,事先準備好 hello.go 檔案

ssh -p2200 root@localhost ln -s /go/ /usr/local

複製 hello.go 到 ARM 環境

scp -P 2200 hello.go root@localhost:/root

編譯 hello.go 為 ARM 執行檔,保持耐心

ssh -p2200 root@localhost /go/bin/go build hello.go

執行輸出的 ARM 執行檔

ssh -p2200 root@localhost /root/hello
hello world

要一直用 scp 複製檔案到 QEMU 環境很麻煩,而且又會佔用 QEMU image 的空間,這時候就可以透過 sshfs。以下示範將 QEMU/ARM 環境的 /tmp 掛載在 host 端的 target 目錄:

mkdir -p target
sudo apt-get install sshfs
sshfs root@localhost:/tmp target -p 2200

接著將 hello.go 複製到 target 目錄並且編譯執行,顯然就快多了:

ssh -p2200 root@localhost "cd /tmp; /go/bin/go build /tmp/hello.go"
ssh -p2200 root@localhost /tmp/hello

在關閉 ARM 之前,記得要 umount

fusermount -u target

Reference

JServ Qemu hackpad

https://wiki.debian.org/QEMU

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment