LeavaTailの日記

LeavaTailの日記

Linuxエンジニアを目指した技術者の備忘録

組込みLinuxディストリビューションを構築する(BuildRoot編)

はじめに

前回の記事で、QEMUx86_64アーキテクチャ上でARM64用にビルドしたLinuxカーネルを起動させることに成功した。

leavatail.hatenablog.com

しかし、前回作成した環境はLinuxカーネルを起動してシェルから最低限の操作ができるものだった。 ここから、Linuxシステムとして利用できるようにするためには、uClibcなどを利用してツールチェーンを生成したり、必要に応じてブートローダをビルドする必要がある。 上記の手順を一から手動で構築するには手間がかかり、依存関係の乱れによるケアレスミスなど発生する恐れがある。

BuildRootは、上記のような問題を解決することができるLinuxシステムを構築するツールである。 BuildRootを使用することで、下記のものを構築することができる。

今回はBuildRootを使用して、組込みLinuxディストリビューションを構築する。

変更履歴

  • 2020/2/11: 記事公開
  • 2020/12/18: 投稿画像のアップデート

環境構成

前回の記事で作成した環境を利用する。

f:id:LeavaTail:20200209234103p:plain
実行環境

仮想マシンの構築にはVagrantVirtualBox、BoxイメージにはUbuntu /bionic64を利用する。

TargetBoardにはARM仮想ボードの「virt-2.11」を使用する。 このTargetBoardに、ルートファイルシステムLinuxカールの入ったディスクを接続し、フラッシュメモリブートローダをロードする。

今回使用するTargetBoardの抽象図を下記に示す。

f:id:LeavaTail:20201218214326p:plain
QEMUでエミュレートするボードの抽象図

依存パッケージ

公式サイト(The Buildroot user manual)より、下記のコマンドを必要とする。

  • sed
  • make (version 3.81 or any later)
  • binutils
  • build-essential (only for Debian based systems)
  • gcc (version 4.8 or any later)
  • g++ (version 4.8 or any later)
  • bash
  • patch
  • gzip
  • bzip2
  • perl (version 5.8.7 or any later)
  • tar
  • cpio
  • unzip
  • rsync
  • file (must be in /usr/bin/file)
  • bc
  • wget

システム構築の手順

1. BuildRootに必要としているパッケージをインストールする。(そのほかのコマンドは、Vagrantのイメージでもインストール済み)

vagrant@ubuntu-bionic:~$ libncurses-dev unzip

2. BuildRootを入手する。(執筆時点の安定版である2019.11.1を使用する)

vagrant@ubuntu-bionic:~$ git clone git://git.buildroot.net/buildroot
vagrant@ubuntu-bionic:~/buildroot$ cd buildroot
vagrant@ubuntu-bionic:~/buildroot$ git checkout -b 2019.11.1 2019.11.1

3. QEMU用のARM64アーキテクチャqemu_aarch64_virt_defconfigのconfigファイルを生成する。1

vagrant@ubuntu-bionic:~/buildroot$ make qemu_aarch64_virt_defconfig

4. ブートローダU-Bootのビルドを有効化する

vagrant@ubuntu-bionic:~/buildroot$ make menuconfig

Bootloadersを選択する。

f:id:LeavaTail:20200204231834p:plain
U-Bootを選択、Board defconfigに(qemu_arm64)を入力する。
f:id:LeavaTail:20200204230354p:plain

5. 生成したconfigをもとにビルドする。(一般権限で実行すること)

vagrant@ubuntu-bionic:~/buildroot$ make

Linuxの起動

1. カーネルを格納するイメージ2を生成する。

vagrant@ubuntu-bionic:~$ dd if=/dev/zero of=boot.img bs=512 count=65536
vagrant@ubuntu-bionic:~$ mkfs.vfat boot.img 
mkfs.fat 4.1 (2017-01-24)

2. 作成したイメージにカーネルを格納する。

vagrant@ubuntu-bionic:~$ sudo mount -o loop boot.img /mnt/
vagrant@ubuntu-bionic:~$ sudo cp buildroot/output/images/Image /mnt/
vagrant@ubuntu-bionic:~/buildroot$ sudo umount /mnt 

3. 作成したカーネルを格納したイメージとルートファイルシステムイメージを接続、ファームウェアにU-Bootのイメージをロードし、QEMUを起動させる。

vagrant@ubuntu-bionic:~$ qemu-system-aarch64 \
  -M virt \
  -cpu cortex-a53 \
  -bios ~/buildroot/output/images/u-boot.bin \
  -drive file=~/boot.img,if=none,format=raw,id=hd0 \
  -device virtio-blk-device,drive=hd0 \
  -drive file=~/buildroot/output/images/rootfs.ext4,if=none,format=raw,id=hd1 \
  -device virtio-blk-device,drive=hd1 \
  -nographic

4. U-Bootのデフォルト設定では今回の環境を動作させることができないので、設定を変更する。
4-1: virtioの2つ目(未確認だが、オプションの指定から逆順)のデバイスからカーネルイメージをロードする。

=> load virtio 1 ${kernel_addr_r} /Image

4-2: ルートファイルシステムと、initプロセスを指定する。

=> setenv bootargs root=/dev/vda rdinit=/bin/sh

4-3: カーネルイメージをロードした範囲を指定する。

=> booti ${kernel_addr_r} - ${fdt_addr}

f:id:LeavaTail:20200211151740p:plain
Linuxの起動画面

BuildRootではユーザ名root、パスワードなしでログインすることができる。

ツールチェインの取得

生成したツールチェインはoutput/host/以下に格納されている。

vagrant@ubuntu-bionic:~$ ls -l buildroot/output/host/
total 48
drwxr-xr-x  6 vagrant vagrant  4096 Feb  4 15:33 aarch64-buildroot-linux-uclibc
drwxr-xr-x  2 vagrant vagrant 12288 Feb  9 16:03 bin
drwxr-xr-x  4 vagrant vagrant  4096 Feb  9 15:52 etc
drwxr-xr-x 23 vagrant vagrant  4096 Feb  9 15:52 include
drwxr-xr-x  8 vagrant vagrant  4096 Feb  9 15:52 lib
lrwxrwxrwx  1 vagrant vagrant     3 Feb  4 15:10 lib64 -> lib
drwxr-xr-x  3 vagrant vagrant  4096 Feb  4 15:44 libexec
drwxr-xr-x  3 vagrant vagrant  4096 Feb  9 15:49 man
drwxr-xr-x  2 vagrant vagrant  4096 Feb  9 15:51 sbin
drwxr-xr-x 21 vagrant vagrant  4096 Feb  4 15:44 share
lrwxrwxrwx  1 vagrant vagrant     1 Feb  4 15:10 usr -> .
drwxr-xr-x  3 vagrant vagrant  4096 Feb  4 15:44 var

おわりに

Linuxシステムを構築するツールBuildRootを使用して、組込みLinuxディストリビューションを構築した。 BuildRootでは、BusyBoxやuClibcなどを組み込んで構築してくれるので、依存関係の意識せずとも構築することができる。 しかし、BuildRootに頼りすぎてしまうと内部構造がブラックボックス化してしまうのであまりよくないと考えられる。 legal-infomakeターゲットを指定することでライセンスの一覧を取得することはできるが、これだけでは不十分だろう。

次回は、そのほかのLinux構築ツールyoctoなどを使用して同様の環境を構築してみたいと思う。

参考


  1. 指定可能なターゲットはlist-defconfigsで確認することができる。

  2. 現状はカーネルのみ格納できれば良いので32Mで作成する。