Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sonkm3/9b044d9791f31637939a649838472adf to your computer and use it in GitHub Desktop.
Save sonkm3/9b044d9791f31637939a649838472adf to your computer and use it in GitHub Desktop.

Docker multi platformでraspberrypi osを実行する

Dockerのmultiarch機能を使うとホストとは別のアーキテクチャのコンテナを実行できます

ここではarmhf用のraspberrypi osをDockerコンテナにすることでx86_64などのシステム上で実行してみます
Leverage multi-CPU architecture support

  • システム全体のエミュレーションとは違い、この仕組みではCPUとメモリ、ファイルシステムまでが提供されます。Raspberry Pi特有の機能(GPUやGPIO、Wifi、Bluetoothなど)は提供されません。

raspberrypi osをDockerコンテナ化する手順

  1. rootfsをダウンロード、もしくはSDカード用イメージから抽出してDocker imageを作る

    1. rootfsを直接ダウンロードする

      wget https://downloads.raspberrypi.org/raspios_lite_armhf/root.tar.xz
      
    2. SDカードへ書き込む用のイメージからrootfsを取り出す(以下の手順はWindowsやmacosでの手順になります。linuxで作業している場合はunzipした後そのままlosetupでrootfsを作業環境の任意のディレクトリにマウントして作業を進められます)

      1. SDカード用のイメージをダウンロードして展開する
      unzip 2021-03-04-raspios-buster-armhf-lite
      
      1. SDカード用イメージをマウントして作業するためDocker上でdebianを起動する
      docker container run -it --rm --privileged  -v $(pwd):/work debian
      
      1. losetupを使って二つ目のパーティションを/mntにマウントする
      losetup --show -f -P /work/2021-03-04-raspios-buster-armhf-lite.img 
      mount /dev/loop0p2 /mnt
      
      1. /mntをアーカイブとして保存する
      tar cfvz /work/2021-03-04-raspios-buster-armhf-lite.tar.gz -C /mnt .
      
  2. Dockerfileを作る

    FROM scratch
    ADD root.tar.xz .
    CMD /bin/bash

    SDカード用イメージからrootfsのアーカイブを作った場合はroot.tar.gzの箇所を2021-03-04-raspios-buster-armhf-lite.tar.gzに変更する

  3. Dockerイメージをビルドする

    docker build --platform linux/arm32v6 -t raspios:2021-03-04 .
  4. raspberrypi osがエミュレーションされたコンテナとして実行できるようになりました

    1. コンテナの起動
    docker run --platform linux/arm32v6 --rm -it  raspios:2021-03-04 
    
    1. unameで確認

      docker run --platform linux/arm32v6 --rm -it  raspios:2021-03-04 uname -a
      Linux 5e29992ae623 5.10.25-linuxkit #1 SMP PREEMPT Tue Mar 23 09:24:45 UTC 2021 armv7l GNU/Linux
    2. fileコマンドで確認

      docker run --platform linux/arm32v6 --rm -it  raspios:2021-03-04 file /bin/ls
      /bin/ls: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=67a394390830ea3ab4e83b5811c66fea9784ee69, stripped
    3. cpuinfoを確認

      $ docker run --platform linux/arm32v6 --rm -it  raspios:2021-03-04 cat /proc/cpuinfo
      processor	: 0
      BogoMIPS	: 48.00
      Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32 fphp asimdhp cpuid dit
      CPU implementer	: 0x41
      CPU architecture: 8
      CPU variant	: 0x1
      CPU part	: 0xd07
      CPU revision	: 0
      
      processor	: 1
      BogoMIPS	: 48.00
      Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32 fphp asimdhp cpuid dit
      CPU implementer	: 0x41
      CPU architecture: 8
      CPU variant	: 0x1
      CPU part	: 0xd07
      CPU revision	: 0
    • arm32v6用のバイナリは実行できていますが気になる箇所は残っています
      • raspberrypi osからはarmv7lとして見えているようです
      • cpuinfoもarm32v6相当ではない値のように見えます
  5. エミュレーション下でコンパイルしたプログラムを実機に移して実行できることの確認

    この環境でコンパイルしたプログラムを実機に持っていけるか確認をしてみたところccIllegal instructionエラーが出ました。ほかにもaptコマンドなどで同様にIllegal instructionエラーが出ます

    ここまでmacos(Apple)上のDockerで作業を進めていたので、試しにWindows(x86_64)上のDockerに移り、hello worldをコンパイルしてみたところ、コンパイルから実行まで確認できました

    root@873c732f951d:/# cat hello.c
    #include <stdio.h>    
    
    int main(void){       
    printf("Hello world");
    }
    
    root@873c732f951d:/# cc hello.c
    root@873c732f951d:/# ./a.out
    Hello worldroot@873c732f951d:/# 
    

    a.outを実機にコピーして確認します

    pi@pi:~ $ uname -a
    Linux pi 5.4.79+ #1373 Mon Nov 23 13:18:15 GMT 2020 armv6l GNU/Linux
    pi@tokyopi:~ $ file a.out
    a.out: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=1575879d031273ff78ed00ac22df31b1175db976, not stripped
    pi@pi:~ $ ./a.out
    Hello worldpi@pi:~ $
    

    期待通り動きました

  6. 実機のuname、file、cpuinfo

    $ uname -a
    Linux raspberrypi 5.10.17-v7+ #1403 SMP Mon Feb 22 11:29:51 GMT 2021 armv7l GNU/Linux
    $ cat /proc/cpuinfo
    processor	: 0
    model name	: ARMv7 Processor rev 4 (v7l)
    BogoMIPS	: 38.40
    Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
    CPU implementer	: 0x41
    CPU architecture: 7
    CPU variant	: 0x0
    CPU part	: 0xd03
    CPU revision	: 4
    
    processor	: 1
    model name	: ARMv7 Processor rev 4 (v7l)
    BogoMIPS	: 38.40
    Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
    CPU implementer	: 0x41
    CPU architecture: 7
    CPU variant	: 0x0
    CPU part	: 0xd03
    CPU revision	: 4
    
    processor	: 2
    model name	: ARMv7 Processor rev 4 (v7l)
    BogoMIPS	: 38.40
    Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
    CPU implementer	: 0x41
    CPU architecture: 7
    CPU variant	: 0x0
    CPU part	: 0xd03
    CPU revision	: 4
    
    processor	: 3
    model name	: ARMv7 Processor rev 4 (v7l)
    BogoMIPS	: 38.40
    Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
    CPU implementer	: 0x41
    CPU architecture: 7
    CPU variant	: 0x0
    CPU part	: 0xd03
    CPU revision	: 4
    
    Hardware	: BCM2835
    Revision	: a22042
    Serial		: 000000005bbfb286
    Model		: Raspberry Pi 2 Model B Rev 1.2

How to run raspberrypi os inside Docker

with Multi-Platform Docker Builds, we can run armhf raspberry pi os image as Docker container on your x86_64 or other system.
Leverage multi-CPU architecture support

how to build and run raspberry pi os on Docker

  1. download root fs or extract rootfs from raspberry pi os image file.

    1. just download raspberry pi os rootfs archive.

      wget https://downloads.raspberrypi.org/raspios_lite_armhf/root.tar.xz
      
    2. download raspberry pi os image, then extract rootfs.

      1. download os image.
      unzip 2021-03-04-raspios-buster-armhf-lite
      
      1. use debian to mount image file.
      docker container run -it --rm --privileged  -v $(pwd):/work debian
      
      1. use losetup to mount second partition to /mnt.
      losetup --show -f -P /work/2021-03-04-raspios-buster-armhf-lite.img 
      mount /dev/loop0p2 /mnt
      
    3. save /mnt as an archive.

      tar cfvz /work/2021-03-04-raspios-buster-armhf-lite.tar.gz -C /mnt .
      
  2. create Dockerfile.

    FROM scratch
    ADD root.tar.xz .
    CMD /bin/bash

    root.tar.gz should be 2021-03-04-raspios-buster-armhf-lite.tar.gz if you extract rootfs from os image.

  3. build docker image.

    docker build --platform linux/arm32v6 -t raspios:2021-03-04 .
  4. now you can run raspberry pi os container on your x86_64 or other system.

    docker run --platform linux/arm32v6 --rm -it  raspios:2021-03-04 
    
    1. check uname

      docker run --platform linux/arm32v6 --rm -it  raspios:2021-03-04 uname -a
      Linux 5e29992ae623 5.10.25-linuxkit #1 SMP PREEMPT Tue Mar 23 09:24:45 UTC 2021 armv7l GNU/Linux
    2. check bin file architecuture

      docker run --platform linux/arm32v6 --rm -it  raspios:2021-03-04 file /bin/ls
      /bin/ls: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=67a394390830ea3ab4e83b5811c66fea9784ee69, stripped
    3. check cpuinfo

      $ docker run --platform linux/arm32v6 --rm -it  raspios:2021-03-04 cat /proc/cpuinfo
      processor	: 0
      BogoMIPS	: 48.00
      Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32 fphp asimdhp cpuid dit
      CPU implementer	: 0x41
      CPU architecture: 8
      CPU variant	: 0x1
      CPU part	: 0xd07
      CPU revision	: 0
      
      processor	: 1
      BogoMIPS	: 48.00
      Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32 fphp asimdhp cpuid dit
      CPU implementer	: 0x41
      CPU architecture: 8
      CPU variant	: 0x1
      CPU part	: 0xd07
      CPU revision	: 0
  5. FYI uname and cpuinfo for raspberry pi2 itself

    $ uname -a
    Linux raspberrypi 5.10.17-v7+ #1403 SMP Mon Feb 22 11:29:51 GMT 2021 armv7l GNU/Linux
    $ cat /proc/cpuinfo
    processor	: 0
    model name	: ARMv7 Processor rev 4 (v7l)
    BogoMIPS	: 38.40
    Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
    CPU implementer	: 0x41
    CPU architecture: 7
    CPU variant	: 0x0
    CPU part	: 0xd03
    CPU revision	: 4
    
    processor	: 1
    model name	: ARMv7 Processor rev 4 (v7l)
    BogoMIPS	: 38.40
    Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
    CPU implementer	: 0x41
    CPU architecture: 7
    CPU variant	: 0x0
    CPU part	: 0xd03
    CPU revision	: 4
    
    processor	: 2
    model name	: ARMv7 Processor rev 4 (v7l)
    BogoMIPS	: 38.40
    Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
    CPU implementer	: 0x41
    CPU architecture: 7
    CPU variant	: 0x0
    CPU part	: 0xd03
    CPU revision	: 4
    
    processor	: 3
    model name	: ARMv7 Processor rev 4 (v7l)
    BogoMIPS	: 38.40
    Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
    CPU implementer	: 0x41
    CPU architecture: 7
    CPU variant	: 0x0
    CPU part	: 0xd03
    CPU revision	: 4
    
    Hardware	: BCM2835
    Revision	: a22042
    Serial		: 000000005bbfb286
    Model		: Raspberry Pi 2 Model B Rev 1.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment