びぼうろく

北海道の人。適当にもっさりまったり書きます。さくら荘のましろが好きです。アニメとかパソコンとか

Raspberry Pi Zero向けのデバイスドライバを作る(本編)

デバイスドライバ作成

はじめに

この記事は前回の続きになります。
gari30.hatenablog.com

仕事が忙しく、あまり作業時間が取れない状況でしたが、
やっとこさ出来上がったので、ここにまとめておきます。

ターゲットデバイスRaspberry Pi Zero WHになります。

参考にさせていただいたサイト様

(前回同様)RaspberryPi2上でデバイスドライバを作成する記事です。
リンクのページから連載されています。
組み込みLinuxデバイスドライバの作り方 (1) - Qiita

(前回同様)RaspbianとRaspbian Kernelについて説明がある記事です。
大変参考になりました。
Raspberry Pi でドライバ開発したい(基礎編) | なたで日記


出来たもの

github.com

詰まったところメモ

1. 環境変数設定スクリプト

参考にさせていただいたサイト様に記載のこちらのサイト を参考に、
ロスコンパイル環境の環境変数設定シェルスクリプトを作成しました。
deviceDriver/env.sh at master · Kyokko-OB-Team/deviceDriver · GitHub

. ./env.sh

のように、ドット(.)コマンドを使うと、

source ./env.sh

と同じ効果があるとのことを初めて知りました。
ドットコマンドを使うと、現在のコマンド実行環境で実行してくれるようです。

2. printk

躓いた、というか寝ぼけて間違えただけですが、念の為書いておきます。

kernel moduleではprintfは使えないです。
代わりにprintkが使えます。

3. __aeabi_uldivmod 未定義エラー
ERROR: "__aeabi_uldivmod" [/home/xxxx/deviceDriver/hc-sr04/hc-sr04.ko] undefined!

kernel module内で浮動小数点を使用するとこのエラーが出るらしい。

ソースコードではこの箇所

distance = ((falling_timestamp - rising_timestamp) / 58) * 1000;

Cキャストをするようにした。

distance = ((unsigned int)(falling_timestamp - rising_timestamp) / 58) * 1000;
4. 認識されないコマンドラインオプション '-fstack-protector-strong'
arm-linux-gnueabihf-gcc: エラー: unrecognized command line option ‘-fstack-protector-strong’

raspberry pi toolchainのgccのバージョンが古いことで発生するらしい。
使用しているコンパイラのバージョンはこれ。

$ /mnt/4tb/raspberrypi_kernel/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc -v
組み込み spec を使用しています。
COLLECT_GCC=/mnt/4tb/raspberrypi_kernel/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/mnt/4tb/raspberrypi_kernel/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/../libexec/gcc/arm-linux-gnueabihf/4.8.3/lto-wrapper
ターゲット: arm-linux-gnueabihf
configure 設定: /home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/.build/src/gcc-linaro-4.8-2014.03/configure --build=x86_64-build_unknown-linux-gnu --host=x86_64-build_unknown-linux-gnu --target=arm-linux-gnueabihf --prefix=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/install --with-sysroot=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/install/arm-linux-gnueabihf/libc --enable-languages=c,c++,fortran --disable-multilib --enable-multiarch --with-arch=armv6 --with-tune=arm1176jz-s --with-fpu=vfp --with-float=hard --with-pkgversion='crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03' --with-bugurl=https://bugs.launchpad.net/gcc-linaro --enable-__cxa_atexit --enable-libmudflap --enable-libgomp --enable-libssp --with-gmp=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-mpfr=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-mpc=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-isl=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-cloog=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-libelf=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --enable-threads=posix --disable-libstdcxx-pch --enable-linker-build-id --enable-plugin --enable-gold --with-local-prefix=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/install/arm-linux-gnueabihf/libc --enable-c99 --enable-long-long --with-float=hard
スレッドモデル: posix
gcc バージョン 4.8.3 20140303 (prerelease) (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03)

回避策をggるとgccをアップデートしろ、と言われるが
raspberry pi用のクロスコンパイラはこれが最新版なのでアップデートできない。
csdnのこのページを参考に、kernelのMakefileを変更してエラーがでなくなった。

動作確認

カーネルモジュールをロードして、
テストアプリを実行して、
カーネルモールをアンロードして、
dmesgでログを確認

$ sudo insmod ./hc-sr04/hc-sr04.ko
$ sudo ./test_hc-sr04/test_hc-sr04
./test_hc-sr04/test_hc-sr04 ver.0.1
exec measure distance.
exec get distance.
distance: 6310000mm
$ dmesg
(省略)
[  223.047133] hc_sr04: loading out-of-tree module taints kernel.
[  223.058371] hc_sr04 init. ver.0.1.
[  418.259926] hc_sr04 module exit.

特にエラーが出ないのでOK

デバイスドライバの動作環境をまとめる

デバイスドライバを動作させるカーネルセットも保存しておきたいので、
動作環境をまとめておきます。

// kernelディレクトリに移動
$ cd linux/

// 一時コピー先ディレクトリ作成
$ mkdir -p device_tree/overlays

// デバイスツリーファイル群をコピー
$ cp ./arch/arm/boot/dts/*.dtb ./device_tree/.
$ cp ./arch/arm/boot/dts/overlays/*.dtb* ./device_tree/overlays/.

// デバイスツリーファイル群をアーカイブにする
$ cd device_tree/
$ tar -cvzf ../dtb.tar.gz *

// モジュールファイルをビルド
$ sudo make ARCH=arm INSTALL_MOD_PATH=./modules/ modules_install

// モジュールファイル群をアーカイブにする
$ cd modules/
$ tar -cvjf ../modules.tar.bz2 *

Raspberry Piで展開

まとめた動作環境ファイルをRaspberry Pi上にコピーしてから以下の様に
ファイルを展開する。

// カーネルイメージのバックアップ
$ sudo cp /boot/kernel.img /boot/kernel-bk.img

// カーネルイメージを更新
$ sudo cp ./kernel.img /boot/.

// デバイスツリーファイルを展開
// 所有者を変更できません。とエラーが出るので、--no-same-ownerオプションをつける
$ sudo tar --no-same-owner -xzvf ./dtb.tar.gz -C /boot/

// モジュールファイルを展開
$ sudo tar -xvjf ./modules.tar.bz2 -C /

// 再起動して起動確認
$ sync
$ sudo shutdown -r now

起動確認

まとめたデバイスドライバの動作環境をRaspberry Pi上で展開して
作成したカーネルモジュールとテストアプリでの動作確認をした。
OKだったので完璧!
以上

デキる人は知っているgnuplotの使い方

gnuplotを初めて使ったのでそのログ

はじめに

最近、おすすめの記事とかに「ショートカットを使いこなして仕事爆速!」とか
「デキる人は使ってる仕事術!」みたいなのがあって
記事を呼んでみると

Windowsはショートカットキーを使って時短!

とか

Excel、wordでおすすめのショートカットはこちら!ctrl+v!!

みたいなのばっかりで面白いので
似たタイトルにしてみた。

仕事だとデータ解析とかその結果はExcelが好まれるので
仕事で使う機会はあまりなかったけど
使えるようになりたいので勉強してみた。

やりたいこと

温度と湿度のデータがあるので、それを1つのグラフにしたい。
データはここに無限に上がってくるこれを使う。

1. 入力データの整理

入力データの形式はJSONもどきで、文字列が含まれるため
このままプロットできない。

ワンライナーを書いた。

cat ./202105_Temp_Humidi_Sensor_Data.json | sed -e 's/: /,/g' | sed -e 's/ /,/g' | sed -e 's/[\{\|\}\|"\]//g' | awk -F "," ' $2 == "2021/05/28" { print $3","$5","$6 }' > temp.log

ワンライナーでやってること
sed -e 's/: /,/g'
keyとvalueの区切りが: になっているので,にする。

sed -e 's/ /,/g'
日時データの日付と時間の間のスペースを,にする。

sed -e 's/[\{\|\}\|"\]//g'
行の両端の{}を消す。

awk -F "," ' $2 == "2021/05/28" { print $3","$5","$6 }'
区切り記号を,として、
日付を指定して時刻、温度、湿度のデータだけ抽出する。

2. gnuplotでグラフ作成

gnuplotがなければインストールする。

$ sudo apt install gnuplot

gnuplotで設定して、グラフを作る。

$ gnuplot
gnuplot> set timefmt "%H:%M:%S"  // 入力データの時間のフォーマット設定
gnuplot> set datafile separator ","    // 入力データの区切り記号を設定
gnuplot> set title "2021/05/29"        // グラフのタイトル設定
gnuplot> set xdata time                    // x軸を時間に設定
gnuplot> set format x "%H"              // x軸のフォーマット設定
gnuplot> set xlabel "time"                // x軸のラベル設定
gnuplot> set yrange [0:40]                // y軸のレンジ設定(0~40)
gnuplot> set ylabel "temp"               // y軸のラベル設定
gnuplot> set ytics nomirror              // y軸のメモリを片側表示に設定
gnuplot> set y2label "humidi"         // y2軸のラベル設定
gnuplot> set y2range [0:100]          // y2軸のレンジ設定(0~100)
gnuplot> set y2tics nomirror          // y2軸のメモリを片側表示に設定
gnuplot> set my2tics 10                 // y2軸のメモリの数を設定(10)
gnuplot> set terminal png             // グラフの出力設定(png)
// 出力ファイルの名前設定
gnuplot> set output "20210528_plot.png"
// グラフの作成(グラフ1の指定、グラフ2の指定)
// グラフ1: 入力ファイル、使うデータ、出力グラフ、グラフのプロット方法
// グラフ2: 入力ファイル、使うデータ、出力グラフ、グラフのプロット方法
gnuplot> plot "./temp.log" using 1:2 axis x1y1 with line title "temp", "./temp.log" using 1:3 axis x1y2 with line title "humidi"

これで出力したファイルがこれ
f:id:gari30:20210530010416p:plain

3. シェル化

作った。
measurementData/graph-make.sh at master · Kyokko-OB-Team/measurementData · GitHub

使い方

./graph-make.sh <任意の日付>_Temp_Humidi_Sensor_Data.json YYYY/MM/DD

Raspberry Pi Zero向けのデバイスドライバを作る(環境構築)

ラズパイゼロのデバイスドライバ開発環境構築

はじめに

Raspberry Pi ZeroでHC-SR04を使いやすくするために、
デバイスドライバを作成するので、
やったことをメモしておく。
とりあえず環境構築まで<2021/08/16修正>
再度環境構築し直したときに、記載ミスに気付いたのでコマンドを修正しました。

HC-SR04について

akizukidenshi.com

超音波をつかった距離センサです。
超音波パルスを送出して、
反射した超音波を受信するまでの時間で距離を求める仕組みです。
2cm~400cmまで、0.3cmの分解能で距離を測定できる仕様となっています。
お勉強がてらこいつのデバイスドライバを作ります。

参考にさせていただいたサイト

RaspberryPi2上でデバイスドライバを作成する記事です。
組み込みLinuxデバイスドライバの作り方 (1) - Qiita

今回の私と同じく、RaspberryPiZeroのデバイスドライバを別のLinuxPCで作成する記事です。
Raspberry Pi でドライバ開発したい(基礎編) | なたで日記

RaspbianとRaspbian Kernelについて説明がある記事です。
Raspberry Pi でカーネルモジュールビルドの準備 - Qiita

開発環境作成

1. 必要なものを集める

必要なパッケージをインストール

$ sudo apt install git bc bison flex libssl-dev make


カーネルとクロスコンパイラをclone

$ git clone https://github.com/raspberrypi/linux
$ git clone https://github.com/raspberrypi/tools
2. ラズパイのカーネルバージョンのソースにする

カーネルモジュール(*.ko)を作成する場合、
ターゲット環境のカーネルバージョンを合わせておくと面倒が無い。

ターゲットのカーネルバージョンの確認する。
今回は 5.4.51+ だった。

$ uname -r
5.4.51+

同じバージョン番号のコミットをここから探す。
Commits · Hexxeh/rpi-firmware · GitHub
今回はこのコミットだった。

同じバージョン番号のコミットのハッシュ値をコピーする。
今回は、8382ece2b30be0beb87cac7f3b36824f194d01e9だった。

コミットのハッシュ値githubに投げるとカーネルのリビジョンが取得できる。
(仕組みはわからん)
今回は、ff68b68ffe3e8f1759fd17532b6fe8dc4e211a2dだった。

$ export FIRM_REV=8382ece2b30be0beb87cac7f3b36824f194d01e9
$ curl -L https://github.com/Hexxeh/rpi-firmware/raw/${FIRM_REV}/git_hash

これで、現在ターゲットのRaspbianのカーネルのリビジョンがわかったので、
先程クローンしたカーネルを、先程取得したカーネルのリビジョンでチェックアウトする。
今回はこんな感じでブランチを切った。

$ git checkout -b raspbian-5.4.51_kernel ff68b68ffe3e8f1759fd17532b6fe8dc4e211a2d
3. カーネルのビルド

ターゲットによってビルド時に設定する環境変数が異なる。
今回は、Raspberry Pi Zeroなので以下のようにビルドする。

$ export ARCH=arm
$ export KERNEL=kernel
$ make bcmrpi_defconfig
#
# configuration written to .config
#
$ export CROSS_COMPILE=/mnt/4tb/raspberrypi_kernel/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-
$ make zImage modules dtbs
4. カーネルの書き込み

事前にRaspbianをmicroSDに焼いておく。
microSDをPCに接続して、ビルドしたカーネルを更新する。
今回は以下のようにした。

// マウント先ディレクトリの作成
$ sudo mkdir raspbian-boot
$ sudo mkdir raspbian

// マウント
$ sudo mount /dev/sdc1 /mnt/raspbian-boot
$ sudo mount /dev/sdc2 /mnt/raspbian

// カーネルモジュールの書き込み
$ sudo make ARCH=arm INSTALL_MOD_PATH=/mnt/raspbian/ modules_install

// カーネルのバックアップ
$ sudo cp /mnt/raspbian-boot/kernel.img /mnt/raspbian-boot/kernel_bk.img

// カーネルのコピー
$ sudo cp ./arch/arm/boot/zImage /mnt/raspbian-boot/kernel.img

// デバイスツリーのコピー
$ sudo cp ./arch/arm/boot/dts/*.dtb /mnt/raspbian-boot/.
$ sudo cp ./arch/arm/boot/dts/overlays/*.dtb* /mnt/raspbian-boot/overlays/.

// マウント解除
$ sudo umount /mnt/raspbian*

// マウント先ディレクトリの削除
$ sudo rm -rf ./raspbian*
5. 起動確認

ラズパイにmicroSDを戻して、通常通り起動するか確認する。
今回はコードに変更を加えなかったので、起動したらOKということにする

組み込みLinuxでスクリーンショットを撮影する

組み込みでスクリーンショット

はじめに

組み込みLinuxはデスクトップ環境が無いので
スクリーンショットを取るアプリも無い。
でも操作画面(LCD)はあるからドキュメントを作るのにスクリーンショットが欲しい!

という上司からの要望があった。
半日でスクリーンショット撮影するツールを作らされたのでここにメモっておく。

こちらのサイトを参考にさせていただきました。
非常に助かりました。ありがとうございます。
ラズパイでフレームバッファ(/dev/fb0)を使用して、直接ディスプレイ画像を入出力する - Qiita
Bitmapファイルフォーマット

結論

フレームバッファを読みだしたRawファイルに、
ビットマップのヘッダをつけたらビットマップファイルとして開けた。

作ったものはgithubに置いてあります。
github.com

内容

結論までの経緯とやったことを書いておく。

フレームバッファとは

Linuxフレームバッファにデータを書き込むとカーネルがいい感じに勝手に描画してくれる。
つまりディスプレイの情報はフレームバッファに入っている。
カーネルが書き込んだフレームバッファをどう処理しているのかはわからない(そのうち理解したい)。

手元のUbuntuマシンでは/dev/fb0があった。

フレームバッファの情報は以下のコマンドで確認できるらしい。

$ cat /sys/class/graphics/fb0/bits_per_pixel
32

$ cat /sys/class/graphics/fb0/virtual_size 
1920,1080
フレームバッファを取得して見てみる

以下のコマンドでフレームバッファを取得する。

$ cat /dev/fb0 > temp.raw

IrfanViewでrawファイルを開く。
ソフトを起動して、ドラッグ&ドロップでrawファイルをぶち込むとrawファイルを開く設定ができる。

今回は以下の設定でrawファイルを正常に表示できた。

  • Image width:1920
  • Image heigh:1080
  • BitsPerPixel:32 BPP[4 byte per pixel]
  • Options for 24 and 32 BPP:Color order BGR(32bit BGRA)
rawファイルは扱いにくい

rawファイルでスクリーンショットを撮影することはできた。
でもrawファイルは一般的な画像ビューアで表示できないし、ドキュメントに貼り付けることもできない。

...と参ってたら、チームのすごい人から
「昔、bitmapでスクリーンショット撮るツールあった気がする。ツール見つけられないけど確かbitmapヘッダをくっつけてただけだった気がする。」
と、神の導きを頂いたので、とりあえずbitmapヘッダを作ってみることにした。

bitmapヘッダを作る

bitmapのヘッダは、ファイルヘッダ(14byte)と情報ヘッダ(40byte)の54byteでできているらしい。
とりあえず空のバイナリファイルを作る。

dd if=/dev/zero of=bmp_head.bin bs=54 count=1

vscode拡張機能vscode-hexdump」でヘッダにデータを入れていく。

ファイルタイプ以外はすべてリトルエンディアンでデータを入れる。
以下は実際に入れたデータ

種類 オフセット サイズ メモ
ファイルタイプ 0 2byte 0x42、0x4D 固定値
ファイルサイズ(byte) 2 4byte 0x00 1F A4 36 ヘッダサイズ(54byte)+1920*1080
予約領域1 6 2byte 0x00 固定値
予約領域2 8 2byte 0x00 固定値
ヘッダサイズ 10 4byte 0x00 00 00 36 固定値
情報ヘッダサイズ 14 4byte 0x00 00 00 28 固定値
画像の横幅(ピクセル) 18 4byte 0x00 00 07 80 1920
画像の縦幅(ピクセル) 22 4byte 0x FF FF FB C8 -1080(縦幅の2の補数)
プレーン数 26 2byte 0x00 01 固定値(プレーンとは?)
1画素の色数 28 2byte 0x00 20 bits_per_pixelの値
圧縮形式 30 4byte 0x00 00 00 00 rawファイルなので0固定
画像サイズ 34 4byte 0x00 1F A4 00 1920*1080
水平解像度(ppm) 38 4byte 0x00 00 00 00 固定値
垂直解像度(ppm) 42 4byte 0x00 00 00 00 固定値
色数 46 4byte 0x00 00 00 00 固定値
重要色数 50 4byte 0x00 00 00 00 固定値
rawファイルにbitmapヘッダをくっつける

必死こいてポチポチ計算してヘッダファイル作ったらあとは、rawファイルにくっつけるだけ。

cat bmp_head.bin temp.raw > test.bmp
何故かできた

これで何故かbitmapファイルでスクリーンショットが作れてしまった。
f:id:gari30:20210505033140p:plain

まとめ

フレームバッファにbitmapヘッダをつけたら上手くいく理由がいまいち理解できていない。
けど何故かできてしまった。(絶対良くないやつ)
ggっても関連する話が全く出てこなかったので、理由をご存じの方いらっしゃったら教えて下さい。。


とりあえず動けばいいツールだし、ユーザ空間でデバイスファイルのReadしかしていないので
OSに影響も無いだろうから一旦これで良いことにしておく。
理由の理解は今後の課題。

RaspberryPiでカスタムイメージを作る

RaspberryPi OSのカスタムイメージ

最近、ラズパイゼロ向けにカスタムイメージを作る事があったのだが、
ggっても簡単に手順が出てこなかったのでここに書いておく。

カスタムイメージ作成環境

Windows10 ver.2004 PC
TeraTerm
SDCardFormatter
Win32DiskImager

RaspberryPi Zero WH
・2020-08-20-raspios-buster-armhf-lite.img
microSD 16GB

Ubuntu20.04 PC*1

手順

1. OSイメージのダウンロード

RaspberryPi OSを本家からダウンロード
こういうときこそtorrentが便利。これぞtorrentの正しい使い方!
Operating system images – Raspberry Pi

2. microSDのフォーマット

windowsmicroSDを接続して、SDCardFormatterでフォーマット
すでにRaspberryPi OSが入ってる場合は、パーティションが切られてるので、
スタートWindows 管理ツールコンピューターの管理ディスクの管理
microSDを探して右クリックからパーティションを削除する

3. RaspberryPi OSを焼く

Win32DiskImagerでダウンロードしたイメージファイルを選択してWriteする
ドライブレターを間違えないようにする

4. boot領域の変更

マウントされている/bootディレクトリの直下に、sshというファイルを作成する。
これで起動時からsshを有効化する。

次に、config.txtの一番下に

dtoverlay=dwc2

を追加する。
次に、commandline.txtの1行の一番うしろに

modules-load=dwc2,g_ether

を追加する。
これでUSB OTG Etherが有効になる。

更に、同じcommandline.txtファイルにある

init=/usr/lib/raspi-config/init_resize.sh

を削除する。
これで初回起動時の自動パーティション拡張が実行されなくなる。

5. OSのぶーと

WindowsからmicroSDを取り外して、ラズパイに接続、
PCとラズパイを接続する。
ラズパイのUSBとシルクがある方のUSB端子に接続する。

6. WindowsPCからラズパイへ接続


ラズパイのUSB OTG Etherのドライバを当てるためにドライバをダウンロード
USB OTG Etherドライバ

スタートWindows 管理ツールコンピューターの管理デバイスマネージャーポート(COMとLPT)から
ラズパイ接続して増えたCOMポートを選んで
右クリックドライバーの更新コンピューターを参照してドライバーを検索
ダウンロードしたドライバフォルダを選択

ドライバがあたると、ネットワークアダプターにUSB Ethernet/RNDIS Gadgetが追加される

teratermを起動して、raspberrypi.localで接続
ユーザ名とパスワードはいつものラズパイデフォルト

※ラズパイをUSB OTG Etherでインターネットに繋ぐ場合


設定ネットワークとインターネット状態アダプターのオプションを変更する
インターネットに接続しているNICを右クリック
プロパティ共有タブ→
ネットワークの他のユーザーに、このコンピューターの(略)のチェックを入れる
ホームネットワーク接続をラズパイのUSB OTG Ether NICを選んでOK

これでラズパイがインターネットに繋がる

7. RaspberryPi OSのカスタマイズ

必要なパッケージのインストールなど、カスタムする

8. 自動パーティション拡張のサービスを抽出

4. boot領域の変更で削除したinit=/usr/lib/raspi-config/init_resize.sh
RaspberryPi OSの初回起動時に自動でSDカードのサイズに合わせてリサイズしてくれるコマンドで
リサイズ後にこの一文が自動で削除される。

これを削除することで自動拡張を防いでいたが、これを有効化する必要がある。
ただ、これをcommandlist.txtに再度追加しても、次回起動時に自動拡張は実行されない。

原因としては、/etc/init.d/resize2fs_once/etc/rc3.d/S01resize2fs_once*2が初回起動時に削除されるためだった

要は、/etc/init.d/resize2fs_once/etc/rc3.d/S01resize2fs_onceを再度追加して
commandlist.txtinit=/usr/lib/raspi-config/init_resize.shを追加すれば良い*3

初回起動前の/etc/init.d/
f:id:gari30:20200926052923p:plain

初回起動後の/etc/init.d/
f:id:gari30:20200926053239p:plain


最初にダウンロードしたRaspberryPi OSを7zipで開いて*4
/etc/init.d/resize2fs_onceをコピーを使って取り出す

取り出したファイルをTeraTermで転送してやって、/etc/init.d/に移動させる
ディレクトリの別ファイルと同じowner、同じパーミッションを設定する

cd /etc/init.d/
sudo chmod 755 resize2fs_once
sudo chown root:root resize2fs_once

次に、code>/etc/rc3.d/S01resize2fs_onceにシンボリックリンクを貼る

cd /etc/rc3.d/
sudo ln -s ../init.d/resize2fs_once S01resize2fs_once

イメージファイル抽出するために現在のパーティションサイズを確認
一番下のデバイスのEndのセクタ番号を控えておく

sudo fdisk -l

これでラズパイをシャットダウンする

sudo shutdown -h now

9. イメージファイルの抽出


microSDからイメージファイルを抽出する

1セクタサイズは固定で512バイトらしい
ベースサイズを1Mバイト(1024*1024バイト)にした場合、
[Endセクタ番号]×512÷(1024×1024)の計算結果を繰り上げて使う

今回はEndセクタ番号が3604479だったので

3604479×512÷(1024×1024) = 1759.99951172

となり、コピーするサイズは1760となる。

ここから、UbuntuPCにmicroSDをマウントする
lsblkコマンドで、SDカードのデバイス名を確認する。
今回のUbuntuPCでは/dev/sdcにマウントされていたので、

dd if=/dev/sdc of=./original.img bs=1M count=1760

を実行し、できたファイルをwindowsに転送する
USBメモリとか使うか、慣れているならそのままUbuntuPCから書き込んでもいいかも
今回はwindowsのデフォルト共有を有効にしているので、ネットワークを使ってコピーした


これでカスタムイメージファイルができた
べつのmicroSDにイメージファイルを焼いて完了!!!やったね!!*5

*1:SDカードからイメージファイルを吸い出すのに使用

*2:こいつはただのシンボリックリンク

*3:詳しくコードを読んでいないから確実ではないけどこれで実際にできたのでOKとする

*4:解答ではなくアーカイブファイルの表示

*5:ホントできてよかった