yoctoでNano Pi NEO 2用イメージをビルドする
公式イメージもいいですが,meta-allwinner-hxレイヤーというものがあるのでyoctoでNano Pi NEO 2用イメージをビルドすることができます。
環境
以下の環境を使いました。
- ホストPC:ubuntu 18.04 LTS
- poky warrior 2.7.1
- meta-allwinner-hx (warrior)
- meta-openembedded(warrior)
ビルド環境のセットアップ
meta-allwinner-hxのREADMEを見ながら ホームディレクトリの下に以下のような構成のbuild_nanopiディレクトリを作っていきます。(名前は何でもいいです)
build_nanopi/ ├── flash_sd.sh ├── setup-environment.sh └── sources ├── meta-allwinner-hx ├── meta-openembedded └── poky
yocto環境は通常~/poky-warriorなどに作成されているかと思います。上記のようなフォルダ構成を実現するためにまた同じものをダウンロードしてくるのも無駄なので,sourcesディレクトリ以下はシンボリックリンクを作成します。
以下コマンドを実行していきます。
$ mkdir ~/build_nanopi $ cd ~/build_nanopi $ mkdir sources $ cd sources $ ln -s ~/poky-warrior/meta-allwinner-hx meta-allwinner-hx $ ln -s ~/poky-warrior poky $ ln -s ~/poky-warrior/meta-openembedded meta-openembedded
セットアップスクリプトをコピーします。
$ cd ~build_nanopi $ cp sources/meta-allwinner-hx/scripts/setup-environment.sh . $ cp sources/meta-allwinner-hx/scripts/flash_sd.sh .
環境変数MACHINEにnanopi-neo2を設定します。
$ export MACHINE=nanopi-neo2
setup-environment.shを実行します。
$ source ./setup-environment.sh build
以下のようにsetup-environment-append.shが見つからないというメッセージが表示されますが,buildディレクトリは正常に生成されます。
Configuring for nanopi-neo2 Searching for append setup scripts... ls: '/home/***/build_nanopi/sources/*/setup-environment-append.sh' にアクセスできません: そのようなファイルやディレクトリはありません These are the default supported images: allwinner-image You can now build your image. To build the allwinner-image then run this: $ bitbake allwinner-image
buildディレクトリが生成され,confディレクトリ内にlocal.confとbblayers.confが自動生成されます。
私の環境ではbitbakeのdo_fetchでダウンロードするファイルが~/poky-warrior/downloadsに入っているのでlocal.confのDL_DIRは以下のように変更しました。
DL_DIR = "${HOME}/poky-warrior/downloads"
local.confを設定したら以下のコマンドを実行するとNano Pi NEO 2用のイメージを作成できます。(bitbakeへのパスが通っている必要があります)
$ bitbake allwinner-image
microSDカードへの書き込み
イメージが作成できたらmicroSDカードへ書き込みます。
~/build_nanopiにあるflash_sd.shを使用します。flasah_sd.shからbmaptoolが呼ばれるので,まずは必要なパッケージをインストールします。
$ sudo apt-get install bmap-tools
MACHINEと書き込み先を指定して./flash_sd.shを実行します。
デフォルトでは13.8GBのイメージを書き込むようになっているため,16GB以上のmicroSDカードを用意する必要があります。
$ sudo MACHINE=nanopi-neo2 ./flash_sd.sh /dev/sdb
meta-allwinner-hxのREADMEには「デフォルトだと13.8GBのイメージを作るが,本当に必要なのは60MB弱だから中身スカスカで,bmaptoolを使えば14GBを数秒で書き込めるんだ」みたいなことが書いてありますが,ならばもっと低容量のSDに入るようにしたいですね。
作成されるイメージを小さくするにはmeta-allwinner-hx/classes/allwinner-wks-defs.inc
を編集し,ROOT_EXTRA_SPACEを変更してルートディレクトリの領域を小さくします。デフォルトでは10240となっていますが,1024に変更すると1.2GBくらいのイメージが作成されます。
meta-allwinner-hx/classes/allwinner-wks-defs.inc
のROOT_EXTRA_SPACEを以下のように変更します。
ROOT_EXTRA_SPACE ?= "1024"
起動確認
イメージを書き込んだmicroSDをNano Pi NEO 2に挿入し,LANケーブルも接続して電源を入れます。
シリアルコンソールを繋いでいない場合,Nano Pi NEO 2のIPアドレスを知るにはNmapを使ってスキャンする必要があります。
IPアドレスがわかったらSSHで接続します。
$ sudo nmap -sP 192.168.0.* ・・・ Nmap scan report for nanopi-neo2 (192.168.0.32) ・・・ $ ssh root@192.168.0.32
なんとパスワード無しでログインできました。
早めにパスワードを変えておきましょう。
Raspberry Piに増設したSDカードの速度を測る 1bitモードと4bitモードの比較
Raspberry Piに増設したSDカードのパフォーマンスをfioで測ってみました。
増設方法は以下で紹介しています。
tshell.hatenablog.com
実は前の記事のようにdtboファイルを作らなくても以下の設定を/boot/config.txtに追記するだけで使えました。
dtoverlay=sdio,poll_once=off,sdio_overclock=50
前回はbus_width=1
を指定して動作させ,とりあえず動いて喜んでいましたがこれを指定すると1bitモードで動作するようです。せっかくDAT0〜3まで結線しているのにDAT0しか使っていません。
今回はbus_width=1の指定を外してデフォルトの4bitモードで動作させ,どれくらい速度が違うのか測ってみます。
環境
以下のものを使用しました。
- Raspberry Pi Compute Module 3+(8GBモデル)
- Compute Module IO
- Raspbian Buster Lite
- MicroSDカード(SDSDQAF3-008G-I) datasheet
測り方
SDカードをマウントしたあと,fioを使用してSDカードへの書き込み速度を測ってみます。
以下のコマンドを実行します。
$ sudo mount -t ext4 /dev/mmcblk1 /mnt/sdcard $ fio -filename=/mnt/sdcard/test1g -direct=1 -rw=write -bs=4k -size=1G -name=file1
/mnt/sdcardに1GBのファイルをブロックサイズ4kBで書き込んでアクセス速度を測ります。
1bitモード
まずは/boot/config.txtへの追記内容を以下のようにしたときの速度を測ってみます。
dtoverlay=sdio,poll_once=off,bus_width=1,sdio_overclock=50
結果は以下のようになりました。
file1: (g=0): rw=write, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=psync, iodepth=1 fio-3.12 Starting 1 process file1: Laying out IO file (1 file / 1024MiB) Jobs: 1 (f=1): [W(1)][100.0%][w=1628KiB/s][w=407 IOPS][eta 00m:00s] file1: (groupid=0, jobs=1): err= 0: pid=667: Mon Dec 2 04:37:06 2019 write: IOPS=406, BW=1626KiB/s (1665kB/s)(1024MiB/644787msec); 0 zone resets clat (usec): min=1602, max=20014, avg=2442.16, stdev=763.70 lat (usec): min=1603, max=20019, avg=2444.70, stdev=763.72 clat percentiles (usec): | 1.00th=[ 1926], 5.00th=[ 1975], 10.00th=[ 2040], 20.00th=[ 2073], | 30.00th=[ 2089], 40.00th=[ 2114], 50.00th=[ 2147], 60.00th=[ 2311], | 70.00th=[ 2507], 80.00th=[ 2900], 90.00th=[ 3064], 95.00th=[ 3294], | 99.00th=[ 3851], 99.50th=[ 9110], 99.90th=[10814], 99.95th=[11338], | 99.99th=[13042] bw ( KiB/s): min= 1552, max= 1736, per=100.00%, avg=1626.02, stdev=20.09, samples=1289 iops : min= 388, max= 434, avg=406.50, stdev= 5.02, samples=1289 lat (msec) : 2=8.00%, 4=91.17%, 10=0.61%, 20=0.22%, 50=0.01% cpu : usr=0.59%, sys=7.93%, ctx=265811, majf=0, minf=23 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued rwts: total=0,262144,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1 Run status group 0 (all jobs): WRITE: bw=1626KiB/s (1665kB/s), 1626KiB/s-1626KiB/s (1665kB/s-1665kB/s), io=1024MiB (1074MB), run=644787-644787msec Disk stats (read/write): mmcblk1: ios=0/262310, merge=0/279, ticks=0/592877, in_queue=592690, util=91.91%
IOPS(1秒あたりのIO数)が406,アクセス速度は1665kB/sでした。
4bitモード
次に/boot/config.txtの追記内容を以下のようにして4bitモードでの速度を測ってみます。
dtoverlay=sdio,poll_once=off,sdio_overclock=50
結果は以下のようになりました。
file1: (g=0): rw=write, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=psync, iodepth=1 fio-3.12 Starting 1 process Jobs: 1 (f=1): [W(1)][100.0%][w=2312KiB/s][w=578 IOPS][eta 00m:00s] file1: (groupid=0, jobs=1): err= 0: pid=530: Mon Dec 2 04:47:50 2019 write: IOPS=577, BW=2310KiB/s (2366kB/s)(1024MiB/453837msec); 0 zone resets clat (usec): min=921, max=21609, avg=1715.19, stdev=743.28 lat (usec): min=922, max=21611, avg=1717.64, stdev=743.29 clat percentiles (usec): | 1.00th=[ 1205], 5.00th=[ 1254], 10.00th=[ 1319], 20.00th=[ 1352], | 30.00th=[ 1369], 40.00th=[ 1385], 50.00th=[ 1418], 60.00th=[ 1582], | 70.00th=[ 1795], 80.00th=[ 2114], 90.00th=[ 2311], 95.00th=[ 2376], | 99.00th=[ 3228], 99.50th=[ 8029], 99.90th=[ 9503], 99.95th=[10159], | 99.99th=[11207] bw ( KiB/s): min= 2160, max= 2504, per=100.00%, avg=2310.03, stdev=34.79, samples=907 iops : min= 540, max= 626, avg=577.46, stdev= 8.71, samples=907 lat (usec) : 1000=0.01% lat (msec) : 2=75.77%, 4=23.49%, 10=0.68%, 20=0.06%, 50=0.01% cpu : usr=0.77%, sys=3.67%, ctx=263680, majf=0, minf=26 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued rwts: total=0,262144,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1 Run status group 0 (all jobs): WRITE: bw=2310KiB/s (2366kB/s), 2310KiB/s-2310KiB/s (2366kB/s-2366kB/s), io=1024MiB (1074MB), run=453837-453837msec Disk stats (read/write): mmcblk1: ios=1/262264, merge=0/91, ticks=1/435935, in_queue=435340, util=95.99%
IOPSは577,アクセス速度は2366kB/sです。
まとめ
アクセス速度を比較すると1bitモードのとき1665kB/s,4bitモードのとき2366kB/sで,4bitモードにすると1.4倍ほど速くなります。
データシートにはシーケンシャル書き込みは最大50MB/sと書いてありますが,ブロックサイズを大きくすればこれくらい出るということかもしれません。
Fuegoにテストを追加する(スクリプト編)
前回はホストPCにFuegoをインストールし,サンプルを実行しました。 tshell.hatenablog.com
今回はシェルスクリプトとして記述したテストを追加する方法です。
環境
前回と同様以下の環境を使用しました。
- ホストPC : ubuntu 18.04 LTS
- ターゲット : Raspberry Pi 3(Raspbian Buster Lite)
- fuego (Commit eeb3c08c...)
作業手順
以下の作業を行ってテストを追加します。
今回はmytestという名前のテストを作成します。
ディレクトリ作成
Fuegoのインストールディレクトリにテストを作成します。Fuegoは/home/ユーザー名/fuegoにインストールされているとします。
ホストPCのターミナルで以下のコマンドを実行します。
cd /home/ユーザー名/fuego/fuego-core/tests mkdir Functional.mytest cd Functional.mytest
テストスクリプトの作成
作成したFunctional.mytest
ディレクトリの中にmytest-target.sh
を以下の内容で作成します。
与えられた引数をそのまま表示するスクリプトです。
#!/bin/bash echo $1
spec.jsonの作成
以下の内容でテストスペックを設定するファイルspec.json
を作成します。このファイルは必ずspec.jsonという名称で作成する必要があります。
{ "testName": "Functional.mytest", "specs":{ "fail":{ "ARG":"FAIL" }, "success":{ "ARG":"SUCCESS" }, "default":{ "ARG":"SUCCESS" } } }
ここで設定したARGはあとで述べるfuego_test.sh
の中でFUNCTIONAL_MYTEST_ARGとして使用できます。spec.jsonの中でARGとだけ記述したものに自動的にテスト名が付加されます。
fuego_test.shの作成
以下の内容でfuego_test.sh
を作成します。このファイルもfuego_test.shという名前で作成する必要があります。
function test_deploy { put $TEST_HOME/mytest-target.sh $BOARD_TESTDIR/fuego.$TESTDIR/ } function test_run { report "cd $BOARD_TESTDIR/fuego.$TESTDIR; \ ./mytest-target.sh $FUNCTIONAL_MYTEST_ARG" } function test_processing { log_compare "$TESTDIR" "1" "SUCCESS" "p" }
function test_deploy
ではテスト実行前にターゲットに対して何を転送するか記述しています。
function test_run
ではテストを実行する際に何をするか記述しています。
Fuegoのreportコマンドは引数で指定されたコマンドを実行して結果をファイルに保存するコマンドです。
test_runの中で,spec.jsonで設定したARGを$FUNCTIONAL_MYTEST_ARGとして使っています。
function test_processing
はテスト結果を判定する設定です。log_compareコマンドで結果を判定します。
Fuego wiki - function log_compare
各引数の意味は以下のようになっています。
$1 = reflog_prefix = prefix of reference parsed log filename
$2 = match_count = number of matching results
$3 = results_expression
$4 = results_category (either 'p', 'n', or something else)
log_compare "$TESTDIR" "1" "SUCCESS" "p"
と記述した場合は,$TESTDIRからログを読み取ってSUCCESSが含まれれば成功とする,という意味になります。
テストの登録
前回のサンプルと同様にFuegoコンテナのコンソールで以下のコマンドを実行して,作成したテストを登録します。
ftc add-jobs -b myboard -t Functional.mytest
上記のコマンドで登録するとspec.jsonのdefaultに記述した内容が有効になります。別のspecを指定したい場合は以下のようにコマンドを実行します。
ftc add-jobs -b mytest -t Functional.mytest -s fail
以上のようにしてシェルスクリプトで作成したテストをFuegoで実行することができます。
FuegoでRaspberry Piをテストする
Fuegoとは
Fuegoとは組み込みLinux用テストフレームワークです。ターゲットにSSH接続してターゲット上でテストを実行し,Jenkinsでテストを管理することができます。
ターゲット上で動作するソフトの単体テストを実行するものではなく,組み込みシステムとしてのテストを実行するものです。
スペイン語で炎という意味です。(炎上しそうですね)
Fuego wikiのArchitectureのページに詳しく載っていますが,
Fuego = (Jenkins + abstraction scripts + pre-packed tests) inside a container
ということでJenkinsとテスト実行のためのスクリプト群,よく使いそうなテストの記述がDockerコンテナとして提供されています。
今回はFuegoのインストールとサンプルのテストの実行までやってみます。
構成
Fuegoの構成は上のような感じになっています。ホストPCからターゲット(ここではRaspberry Pi)に対してSSH接続できるようになっている必要があります。
ホストPCではJenkinsとFuegoのスクリプトが含まれるDockerコンテナが起動し,Jenkinsからテストを実行できます。
テストプログラムはホストPC上でクロスコンパイルされ,Raspberry Piに転送されます。Raspberry Pi上で実行されたテストが標準出力上に結果を返し,この結果によってテストの成功・失敗を判定します。なにをもって成功とするかはテストの設定ファイルに記述します。
テストの設定ファイルはFuegoのインストールディレクトリ内に含まれ,Fuegoのコンテナが起動するときにReadOnlyでコンテナにマウントされます。
開発時には以下のものを操作しながら作業することになります。
- JenkinsのWebUI操作
- Fuegoコンテナのコンソール操作
- Fuegoインストールディレクトリ内のファイル編集
参考情報
公式のWikiを読むとだいたい使えるようになります。
環境
以下の環境を使いました。
- ホストPC : ubuntu 18.04 LTS
- ターゲット : Raspberry Pi 3 (Raspbian Buster Lite)
- Fuego (Commit eeb3c08c...)
Fuegoのインストールとテスト実行
Quick Start Guideに記載されているコマンドを実行していきます。
大まかに以下のような流れです。
- ホストPCにFuegoをインストールする
- Raspberry Piの設定をする
- ホストPCでJenkinsにジョブを登録する
Fuegoのインストール
ホストPC上で以下のコマンドを実行し,必要なパッケージをインストールする。
sudo apt-get update sudo apt-get install git docker.io
ホストPCで以下のコマンドを実行し,Fuegoのリポジトリをクローンする。
git clone https://bitbucket.org/fuegotest/fuego.git
fuegoディレクトリに移動し,インストール用スクリプトを実行する。
(数十分かかります)
cd fuego ./install.sh
インストールが終了したら以下のコマンドを実行する。
./start.sh
start.sh
を実行すると以下のように,Fuegoコンテナのコンソールにアタッチされる。
http://localhost:8090/fuegoを開き,以下のような画面が表示されればOK
Raspberry Pi側の準備
既存のユーザー(piなど)でテストを実行しても良いと思いますが,ここでは以下のコマンドを実行し,ユーザーfuegoを作成します。
sudo su mkdir /home/fuego adduser fuego (fuegoのパスワード等設定)
rootでの接続が必要な場合
テストによってはrootでの実行が必要かもしれません。
rootでのSSH接続が必要な場合は/etc/ssh/sshd_configのPermitRootLogin
をyesに変更し,SSHサーバーを再起動します。
sudo vi /etc/ssh/sshd_config (PermitRootLogin をyesに変更) sudo systemctl restart sshd
ボードファイルの作成
テストの実行対象を設定するボードファイルを作成します。 fuego/fuego-ro/boards内にraspberrypi3.boardがすでにあるので,これをmyboard.boardにコピーして編集します。
cd fuego/fuego-ro/boards cp raspberrypi3.board myboard.board
myboard.boardは以下のように修正しました。(修正箇所のみ載せています)
IPADDRはRaspberry PiのIPアドレス,SRV_IPはホストPCのIPアドレスを設定します。また,PASSWORDはRaspberry Piに作成したユーザーfuegoのパスワードを指定します。
IPADDR="192.168.0.10 SSH_PORT="22" SRV_IP="192.168.0.11" LOGIN="fuego" BOARD_TESTDIR="/home/fuego/" PASSWORD="****" TOOLCHAIN="debian-armhf" #TARGET_SETUP_LINK="fuego-lava-target-setup" #TARGET_TEARDOWN_LINK="fuego-lava-target-teardown"
クロス開発用ツールチェインのインストール
Fuegoコンテナのコンソールで以下のコマンドを実行します。
cd /fuego-ro/toolchains ./install_cross_toolchain.sh
Jenkinsにジョブを登録
Fuegoコンテナのコンソールで以下のコマンドを実行し,Jenkinsにノードを登録します。上で作成したmyboard.boardの内容が登録されます。
ftc add-nodes -b myboard
Fuegoコンテナのコンソールで以下のコマンドを実行し,ジョブを登録します。
ftc add-jobs -b myboard -t Functional.hello_world
テストの実行
Jenkinsでビルドの実行をクリックするとテストがビルドされ,Raspberry Piに転送されたあと実行されます。
Functional.hello_worldはデフォルトでは常に成功します。
FuegoからRaspberry Pi上でテストを実行させることができました。次回はテストの記述方法です。
Raspbian buster-liteでCM3+のeMMCをROM化
前回はRaspberry Pi Compute Module 3+(CM3+)にSDカードを増設しました。 tshell.hatenablog.com
産業用途で使う場合であってもなくても,予期しない電源断によってファイルシステムが飛んで二度と起動しなくなるというのは避けたいところです。
CM3+はeMMCからOSが起動するようになっていますが,今回はeMMCをリードオンリーに設定してみます。
環境
- Raspberry Pi Compute Module 3+
- Compute Module IO Board v3.0
- Raspbian Buster-lite
スワップ領域をSDカードに変更する
メモリが1GBもあるのでスワップなしでもよさそうですが一応スワップありの構成で進めます。以降の作業でeMMCへの書き込みがRAMに保持されるようになるのでスワップファイルがデフォルトの/var/swapのままではスワップの意味をなさなくなります。
前回の記事で増設したSDカード上にスワップファイルを作成し,こちらを使用するようにします。
まずはSDカードをフォーマットして,起動時に/mnt/sdcardにマウントされるようにします。
フォーマット
sudo mkfs -t ext4 /dev/mmcblk1
マウントポイントを作成する
sudo mkdir /mnt/sdcard
UUIDを含む行をfstabに追加しておく
sudo bash lsblk -f | grep mmcblk1 >> /etc/fstab
fstabを編集する
sudo vi /etc/fstab
以下の行を追加する。(あらかじめUUIDを含む行を追加しているのでそのまま利用する。)
UUID=... /mnt/sdcard ext4 defaults 0 2
再起動して/mnt/sdcardにlost+foundがあることを確認します。
スワップファイルの作成とdphys-swapfileの設定
SDカード上に256MBのスワップファイルを作成します。
sudo dd if=/dev/zero of=/mnt/sdcard/swap/swap bs=1M count=256 sudo chmod 600 /mnt/sdcard/swap/swap sudo mkswap /mnt/sdcard/swap/swap
作成したスワップファイルが使えるかテストする
sudo swapoff --all sudo swapon /mnt/sdcard/swap/swap
free -h
を実行してswapのサイズが256MBになっていることを確認します。
/etc/dphys-swapfileを以下のようにコメントアウトを解除して編集します。
CONF_SWAPFILE=/mnt/sdcard/swap/swap CONF_SWAPSIZE=256
再起動後にfree -h
を実行し,swapのサイズが256MBであることを確認します。
以上でスワップファイルを増設したSDカードに移すことができました。
fsprotectをインストールする
続いてeMMCをリードオンリー化していきます。
まずはfsprotectをインストールします。
sudo apt-get install fsprotect
aufs-dkmsのセットアップでエラーが出た場合は,以下のようにpsotinstとpreermを削除してから再度セットアップします。
sudo rm /var/lib/dpkg/info/aufs-dkms.postinst sudo rm /var/lib/dpkg/info/aufs-dkms.prerm sudo apt-get install fsprotect
initramfsイメージの作成
以降のステップで編集するhook-functionsなどのファイルを生成するため,update-initramfsを実行します。
sudo update-initramfs -c -k `uname -r`
上記を実行すると/usr/share/initramfs-tools/hooks/fsprotect
の処理でコケます。
/usr/bin/touchを読みに行くところで失敗しており,/usr/bin/touchは/bin/touchへのシンボリックリンクなので,/usr/share/initramfs-tools/hooks/fsprotectの最終行を以下のように変更します。
copy_exec /bin/touch "/bin"
再度update-initramfsを実行します。
sudo update-initramfs -c -k `uname -r`
hook-functionsの修正
以下のページを参考に,hook-functionsを修正します。
https://www.raspberrypi.org/forums/viewtopic.php?t=161416
/usr/share/initramfs-tools/hook-functionsの524行目付近を以下のように編集します。
(modulesの最後にoverlayを追加する)
for arg in "$@" ; do case "$arg" in base) modules="$modules btrfs ext2 ext3 ext4 ext4dev overlay"
新しいbootスクリプトを作成する
既存のスクリプトをコピーしてoverlayファイルシステムを使用するように変更します。
cd /usr/share/initramfs-tools/scripts sudo cp local overlay sudo cp -rp local-premount overlay-premount sudo cp -rp local-bottom overlay-bottom
/usr/share/initramfs-tools/scripts/overlayのlocal_mount_root()の中を以下のように修正します。
ここに示した行でlocal_mount_root()が終わるようにします。
# if [ "${readonly}" = "y" ]; then roflag=-r # else # roflag=-w # fi # FIXME This has no error checking modprobe ${FSTYPE} checkfs ${ROOT} root # FIXME This has no error checking # Mount root mkdir /upper /lower if [ "${FSTYPE}" != "unknown" ]; then mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} /lower else mount ${roflag} ${ROOTFLAGS} ${ROOT} /lower fi modprobe overlay mount -t tmpfs tmpfs /upper mkdir /upper/data /upper/work mount -t overlay \ -olowerdir=/lower,upperdir=/upper/data,workdir=/upper/work \ overlay ${rootmnt}
initramfsの作成
以下のコマンドを実行し,initramfsを作成してリネームします。
sudo update-initramfs -c -k `uname -r` sudo mv /boot/initrd.img-4.19.66-v7+ /boot/initrd7.img
/boot/config.txt,/boot/cmdline.txtの編集
/boot/config.txtに以下を追記します。
kernel=kernel7.img initramfs initrd7.img
/boot/cmdline.txtの先頭にboot=overlay
を追加して再起動します。
動作確認
再起動後,mount
を実行し,overlay on / type overlay
のような行があればルートファイルシステムがoverlay fs でマウントされています。
適当なファイルを作成して,再起動すると消えることを見てみましょう。
参考にしたページはRaspbian Pixelを使っていましたが,Raspbian busterでも以前と同様にして実現できるようです。
Raspberry Pi にSDカードスロットを増設する
Raspberry Pi Compute Module 3+(CM3+)にSDカードスロットを増設しました。
CM3+の開発ボード,Compute Module IOにはMicroSDカードスロットが実装されていますが,付近にSD CARD ONLY FOR MODULES WITHOUT ON-BOARD FLASHと書いてあり,eMMCが搭載されているCM3+ではこのスロットが使えません。
CM3+を使うにあたってOSの起動はeMMCから,データの記録はSDカードへ,ということがしたい場合にはGPIOにSDカードを接続して使うことができます。
CM3+と開発ボードを使いましたが,ほかのRaspberry Piでも可能だと思います。
環境
以下のものを使いました。
- Raspberry Pi Compute Module 3+
- Compute Module IO rev 3
- Raspbian Buster-lite
配線
Raspberry PiではGPIO22-27またはGPIO34-39にSDカードを接続するとセカンダリSDとして使用することができます。今回はGPIO22-27に接続しました。
SDカードのピンアサインは以下のようになっています。
CM3+のGPIO22-27には後述する設定により,以下機能を割り当てることができるので,SDカードのピンの対応するものを接続します。
なお,VCCには3.3Vを,VSSはGNDに接続します。
GPIO | 機能 | SD |
---|---|---|
22 | SD1_CLK | CLK |
23 | SD1_CMD | CMD |
24 | SD1_DAT0 | DAT0 |
25 | SD1_DAT1 | DAT1 |
26 | SD1_DAT2 | DAT2 |
27 | SD1_DAT3 | DAT3 |
設定
ここのソースをダウンロードします。sdio22-overlay.dtsに名前を変えて,以下のコマンドを実行します。
sudo dtc -@ -I dts -O dtb -o sdio22.dtbo sdio22-overlay.dts
作成されたsdio22.dtboを/boot/overlaysに移動します。
sudo mv sdio22.dtbo /boot/overlays/
/boot/config.txtに以下を追記して再起動します。
dtoverlay=sdio22,poll_once=off,bus_width=1,sdio_overclock=50
接続確認
dmesg | grep mmc
を実行し,以下のような表示があれば増設したSDがmmc1として認識されています。mmc0はCM3+に実装されているeMMCです。
[ 2.554010] mmc1: host does not support reading read-only switch, assuming write-enable [ 2.573205] mmc1: new high speed SDHC card at address aaaa [ 2.616025] mmcblk1: mmc1:aaaa SA08G 7.40 GiB [ 2.705981] mmcblk1: p1
Raspberry PiにSDカードを増設したかったらUSBに接続してしまうのが手っ取り早いと思いますが,CM3+を使って自分で基板を起こすとかRaspberry Pi Zeroを使うという場合には以上のような方法が使えると思います。
Nano Pi NEO 2のセットアップ
Frendly ArmのNano Pi NEO 2 WikiのInstall OSの項を参照
nanopi-neo2_sd_friendlycore-xenial_4.14_arm64_20190430.img.zipをダウンロード
Nano Pi NEOでは書き込むイメージが違うので注意
Frendly ArmのNano Pi NEO Wiki
Win32DiskImagerで書き込む。
イメージを指定して,下部のWriteボタンを押す。
確認ダイアログが表示されるので,Yesを選択する。
書き込み中
終了するとダイアログが出る。
書き込み済みのマイクロSDをマウントしようとするが,Windowsが対応していないファイルシステムのため,フォーマットするか聞かれる。キャンセルを選択して,マイクロSDをPCから取り出す。
マイクロSDカードを本体に挿入して起動する。
IPアドレスはDHCPで設定されるが,何に設定されたかわからない場合はシリアルコンソールで接続して調査する。
シリアルコンソール用のピンはUSB端子の近く,2.54mmピンヘッダ,外側からGND,5V,RX, TX(RX,TXはNano Pi NEO 2側,シリアルケーブルはクロスになるようにつなぐ)
ボーレートは115200bps
ifconfigでipアドレスを調べる。
ssh接続する。ユーザー名,パスワードともにpi
ログインすると以下のような画面が表示される。
固定IPの設定
公式Wikiの以下ページを参考に固定IPの設定を行う。
Use NetworkManager to configure network settings
NetworkManagerで設定する。
nmcli connection show
で現在の設定を見る。
nmcli connection modify
で設定し,再起動する。
あとは自由に使えます。