組込みLinuxを動かしてみよう

ルネサス エレクトロニクスからRZ/GシリーズのRZ/G2Lが2021年にリリースされました。このCPUはArmの64ビットコアCortex-A55を2個と、Cortex-M33を搭載したハイエンドチップですが、RZ/Gシリーズの中ではエントリクラスに位置付けられています。

「エントリクラスだったら簡単では?」と思いますが、Linuxを搭載して動作確認するとなると、それなりのハードルがありそうです。それではまず、組込みLinuxが動作するところまでやってみましょう。

機材と環境

RZ/G2Lのボードはルネサスから販売されている「RZG2L Evaluation Board Kit」を使用します。ルネサスから提供されている情報やサンプルプログラムなどは、このボードを使用しているため、なるべく道を外さずに資料の通りやっていきます。「それではつまらん」と思われる方もおられますが、まずは一度レールに乗っかってやってみるのが近道だと実感しています。

RZ/G2L評価ボード

以下に今回使用した機材とソフトウェアを列挙します。

  • ボード: RZG2L Evaluation Board Kit
  • パソコン: なるべく速いもの
  • SDカード: 8GBマイクロSD
  • ターミナルソフト:TeraTerm 4.84
  • 仮想環境: VirtualBox 7.0
  • ホストLinux: Ubuntu 20.04.4 LTS
  • 組込みLinux: RZ/G Verified Linux Package V3.0.3

今回はLinuxのカーネルビルドも必要になりますので、Windowsパソコンに仮想環境を作ってUbuntuをインストールしました。この時、仮想環境のリソースをケチると、カーネルのビルドに影響します。ちなみに私の環境ではCPUコア4個、メモリ8GB、ディスク100GBを確保しています。

専用のLinuxパソコンを作ればビルドも速いし、全行程をクローズすることも可能ですが、メイン業務がWindowsなので仮想環境で動かすことにしました。そうすると、LinuxとWindows間でファイルを共有する必要が出てきますのでSambaをインストールしました。

Cortex-A55でLinuxを動かす

最初にCortex-A55側で組込みLinuxを動かします。まずはルネサスのWebサイトから「RZ/G Verified Linux Package」をダウンロードします。このファイルの中にLinuxをビルドするための手順書がありますので、その通りやってみます。ただし「Linux知ってたら当然でしょ」的なところは書かれていないので、行間、文字間を読み解く必要があります。

ちなみに今日時点でダウンロードしたファイルは「RTK0EF0045Z0021AZJ-v3.0.3.zip」というファイル名となっていました。このzipファイルは以下のように5つのファイルに展開されます。

r01us0553ej0106-rz-g(Release Note).pdf
r01us0554ej0105-rz-g(Component List).pdf
r01us0555ej0101-rz-g(Board_StartUp_Guide_RZG2H,M,N,E).pdf
r01us0556ej0102-rz-g(Board_StartUp_Guide_smarcEVK).pdf
rzg_bsp_v3.0.3.tar.gz

ここで一番上のPDFが組込みLinuxを動かすための手順書で、一番下のtar.gzファイルがビルドするために必要なファイルです。今回はとりあえずLinuxを動かすところまでをシンプルに遂行します。よって、グラフィックライブラリやビデオコーデックなどの追加はしません。

組込みLinuxのビルド

では、手順書に従ってやっていきましょう。まずは組込みLinuxのビルドに必要なツールをインストールするところから始めます。パソコンのLinuxのターミナルを開いて、apt-getコマンドを実行します。このコマンドを実行するには管理者権限が必要ですので、sudoを付けて実行します。緑色の文字が入力文字です。

$ sudo apt-get update
[sudo] password for ubuntu: ******
 :(中略)
Fetched 336 kB in 3s (121 kB/s) 
Reading package lists... Done
$ sudo apt-get install gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential chrpath socat cpio python python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping libsdl1.2-dev xterm p7zip-full libyaml-dev
Reading package lists... Done
Building dependency tree 
Reading state information... Done
 :(中略)
Setting up python-is-python2 (2.7.17-4) ...
Setting up p7zip-full (16.02+dfsg-7build1) ...
Processing triggers for man-db (2.9.1-1) ...

この段階で失敗する場合はプロキシの設定を確認してください。ネットワークの構成によってプロキシの設定が必要になることがあります。

次はgitの設定を行います。gitコマンドでメールアドレスと名前を設定します。

$ git config --global user.email "****@computex.co.jp"
$ git config --global user.name "****"

ここでの設定をどこまで正直に行わなければならないか分かりませんが、後々問題にならないようにリアルメールアドレスを設定しました。現在、組込みLinuxのビルドはYoctoというシステムが主流となっています。Yoctoとは、私のざっくりとした理解ではLinuxカーネルをはじめとして、ライブラリ、ユーザランド、ブートローダなどをビルドして、最終的にSDカードやフラッシュに書き込めるバイナリイメージまで作るもの、と認識しています。そして、Yoctoの初回のビルドは恐ろしく時間がかかります。これはレシピに書かれたあちこちのサイトから、gitを使ってソースファイルを取得するためです。

では、実際にLinux上で作業を行っていきます。最初にWindowsでダウンロードしてzipを展開してしまったので、「rzg_bsp_v3.0.3.tar.gz」をLinuxにコピーして展開します。Sambaをインストールしていれば、LinuxのファイルシステムをWindowsのフォルダとして開くことができるのでコピーも簡単です(というか手順書通りLinux側でダウンロードした方が簡単かもしれません)。

$ mkdir ~/rzg_vlp_v3.0.3
$ chmod +x ~/rzg_vlp_v3.0.3
(Windowsからrzg_bsp_v3.0.3.tar.gzをコピー)
$ cd ~/rzg_vlp_v3.0.3
$ tar zxvf rzg_bsp_v3.0.3.tar.gz
 :(ファイル展開)
$ ls
extra       meta-openembedded  meta-renesas         poky
meta-gplv2  meta-qt5           meta-virtualization  rzg_bsp_v3.0.3.tar.gz

sourceコマンドでスクリプトを実行してビルド環境の設定を行い、その後bitbakeを使ってビルドを行います。コマンド直前にTEMPLATECONFやMACHINEの環境変数を設定して、その値をコマンドに渡しています。

$ TEMPLATECONF=$PWD/meta-renesas/meta-rzg2l/docs/template/conf/ source poky/oe-init-build-env build
:(中略)
$ MACHINE=smarc-rzg2l bitbake core-image-minimal
:(中略)
NOTE: Tasks Summary: Attempted 2817 tasks of which 8 didn't need to be rerun and all succeeded.

bitbakeのパラメータとしてcore-image-minimalを選択していますが、これは最小構成のビルドとなります。それでもビルドの完了まで私の環境で1時間以上かかりました。

SDカードの準備

次はビルドしたバイナリをSDカードに書き込んで、RZ/G2LのボードでLinuxの起動を確認します。SDへの書き込み手順は「r01us0556ej0102-rz-g(Board_StartUp_Guide_smarcEVK).pdf」に書かれています。

では早速書き込んでみましょう。まず、マイクロSDカードをパソコンに接続します。パソコンにSDカードスロットがないのでSD→USB変換アダプタを使用しました。Windowsがデバイスを認識しますが無視して、仮想環境側のLinuxで認識させます。VirtualBoxでは[デバイス]メニューの[USB][Generic USB2.0-CRW]を選択します。すべての環境でこの方法で行けるのかは謎ですが、私のパソコンではこの方法でSDカードを認識しました。

lsblkで接続を確認すると以下のようにディスク系のデバイスが表示されます。sdbがSDカードを表します。

$ lsblk
sda      8:0    0   200G  0 disk 
├─sda1   8:1    0   512M  0 part /boot/efi
├─sda2   8:2    0     1K  0 part 
└─sda5   8:5    0 199.5G  0 part /
sdb      8:16   1   7.2G  0 disk 
└─sdb1   8:17   1   7.2G  0 part /media/ubuntu/ボリューム
sr0     11:0    1  1024M  0 rom  

パーティションの作成

手順書に従ってSDカードをアンマウントして初期化します。まず、FAT32とext4の二つのパーティションを割り当てます。

$ sudo umount /media/ubuntu/ボリューム
$ sudo fdisk /dev/sdb
[sudo] password for ubuntu: ****
 :(中略)
Command (m for help): o
Created a new DOS disklabel with disk identifier 0xeff59bf8.

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): [ENTER]
First sector (2048-15130623, default 2048): [ENTER]
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-15130623, default 15130623): +500M

Created a new partition 1 of type 'Linux' and of size 500 MiB.

ここまででFAT32のパーティションが500MB割り当てられました。引き続き残りのパーティションをext4に割り当てます。

Command (m for help): n
Partition type
   p   primary (1 primary, 0 extended, 3 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (2-4, default 2): [ENTER]
First sector (1026048-15130623, default 1026048): [ENTER]
Last sector, +/-sectors or +/-size{K,M,G,T,P} (1026048-15130623, default 15130623): [ENTER]
Created a new partition 2 of type 'Linux' and of size 6.7 GiB.
Partition #2 contains a ext4 signature.

Do you want to remove the signature? [Y]es/[N]o: n

ext4のパーティションを割り当てました。割り当てたパーティションを確認します。

Command (m for help): p

Disk /dev/sdb: 7.22 GiB, 7746879488 bytes, 15130624 sectors
Disk model: SD/MMC
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xeff59bf8

Device     Boot   Start      End  Sectors  Size Id Type
/dev/sdb1          2048  1026047  1024000  500M 83 Linux
/dev/sdb2       1026048 15130623 14104576  6.7G 83 Linux

一つ目のパーティションがLinuxになっていますのでW95 FAT32に変更し、書き込みを行って終了します。

Command (m for help): t
Partition number (1,2, default 2): 1
Hex code (type L to list all codes): b

Changed type of partition 'Linux' to 'W95 FAT32'.

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

パーティションを最終確認します。

$ sudo partprobe
$ sudo fdisk -l /dev/sdb
Disk /dev/sdb: 7.22 GiB, 7746879488 bytes, 15130624 sectors
Disk model: SD/MMC
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xeff59bf8

Device     Boot   Start      End  Sectors  Size Id Type
/dev/sdb1          2048  1026047  1024000  500M  b W95 FAT32
/dev/sdb2       1026048 15130623 14104576  6.7G 83 Linux

ちゃんと1つ目のパーティションがW95 FAT32となりましたが、まだ終わりません。次はフォーマットを行います。

SDカードのフォーマット

まずはFAT32のフォーマットです。

$ sudo mkfs.vfat -v -c -F 32 /dev/sdb1
mkfs.fat 4.1 (2017-01-24)
/dev/sdb1 has 239 heads and 62 sectors per track,
 :(中略)
Volume ID is 0548ca76, no volume label.
Searching for bad blocks 21712... 44880... 67536... 89680... 111952... 134224... 156496... 178896... 201552... 224464... 247376... 269648... 291920... 314064... 337360... 359632... 382032... 405328... 428368... 451024... 473296... 495568...

次はext4のフォーマットを行います。

$ sudo mkfs.ext4 -L rootfs /dev/sdb2
mke2fs 1.45.5 (07-Jan-2020)
 :(中略)
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done 

これでフォーマットが完了しました。再マウントするために、SDカードを取り外して、再度取り付けます。そしてdfコマンドで正しく認識されているか確認します。

$ df
 :(中略)
/dev/sdb1         510984        4    510980   1% /media/ubuntu/0548-CA76
/dev/sdb2        6844912       24   6475892   1% /media/ubuntu/rootfs

sdb1とsdb2の二つのパーティションが/media/ubuntu/以下にマウントされています。

SDカードにイメージをコピー

マウントした「/media/ubuntu/0548-CA76」に、ビルド生成物のカーネルイメージとデバイスツリーファイルをコピーします。ビルド生成物は「rzg_vlp_v3.0.3/build/tmp/deploy/images」にありますので、以下のコマンドを実行します。

$ cp ~/rzg_vlp_v3.0.3/build/tmp/deploy/images/smarc-rzg2l/Image-smarc-rzg2l.bin  /media/ubuntu/0548-CA76
$ cp ~/rzg_vlp_v3.0.3/build/tmp/deploy/images/smarc-rzg2l/Image-*.dtb /media/ubuntu/0548-CA76

次はルートファイルシステムのイメージを展開します。Yoctoがビルド生成物のファイルをtar.bz2の形式にしてくれているんですね。

$ cd /media/ubuntu/rootfs
$ sudo tar jxvf ~/rzg_vlp_v3.0.3/build/tmp/deploy/images/smarc-rzg2l/core-image-minimal-smarc-rzg2l-*.rootfs.tar.bz2
./
./bin/
./bin/ash
 :(中略)
./var/tmp
./var/volatile/

これでSDカードへの処理は終わりです。SDカードをRZ/G2Lのボードに差し込んで電源を入れます。ただし、そのままでは何が起こっているのかわからないので、ターミナルを開いてブートの状態を確認します。

Linuxのブート確認

RZ/G2Lのボードにはターミナル用のUSBコネクタが用意されていますので、パソコンに接続してターミナルソフト(TeraTerm)を開きます。ボードの電源を入れないとCOMポートが有効になりませんのでご注意ください。また、有効になるCOMポートは環境によって変化します。私のパソコンではCOM4が有効になりました。

COMポートの設定としてはボーレートを115200に設定すればあとはデフォルトでOKのはずです。Linuxが無事に起動すれば以下のようなブート画面が表示されます。

Workbench

ブート画面が何も表示されない場合は、すでにブートが終わっているかもしれませんので、試しにEnterキーを押してみてください。login:と表示されればちゃんと動いています。

Linuxのビルド構成でcore-image-minimalを指定しましたので、特に面白いことができるわけではありませんが、まあ、lsコマンドでどんなファイルがあるのかぐらいは確認できます。

とりあえず、ここまででLinuxのブートまでの手順を行いました。次からこれをベースにいろいろ試してみたいと思います。