ラベル Raspbian の投稿を表示しています。 すべての投稿を表示
ラベル Raspbian の投稿を表示しています。 すべての投稿を表示

2019年5月24日金曜日

Raspbianで/lib/modules以下のfilesがdisk容量を喰っていた

概要


* Raspbianで/lib/modules以下が肥大していた
* 不要なfilesの削除で8GB → 230MBにダイエット成功
* rpi-updateを頻繁にする人は気をつけよう


本編


Raspberry Pi 3 model Bで32GB (≒29.8GiB)のUSB flash memoryを使っているのだが、妙に使用量が多い気がしていた。DE (GNOMEとかKDEとか)をinstallしている訳でもないのに、30GiBのおおよそ半分程度が消費されている。

経験則に過ぎないが、Debian系distributionをCLI環境のみでinstallした場合は2〜3GB程度が良い所だ。そこにちょっと容量を食うdevelopment関連のpackageとか、gitのrepositoryのcloneとかを入れても5〜6GBぐらいだろう。

最初はBME280で取っているlogが消費しているのかとも思っていたのだが、それらをNASに移動しても容量にほぼ変化がなかった。

% sudo du -hc . | sort -h
...
8.0G /lib/modules
8.1G /lib
13G /
13G total

プログラム開発の格言に「何処で時間を消費しているのか計測しないうちから最適化するな」という意味合いの言葉があるけど正にその通り。思い込みって怖いな。

さて、/lib/modules以下に何があるのか?

% ls /lib/modules
...
drwxr-xr-x 3 root root 4.0K May 18 20:54 4.19.42+/
drwxr-xr-x 3 root root 4.0K May 18 20:54 4.19.42-v7+/

とまぁ、こんな感じで過去から現在最新版に至るまでのkernel modulesを収めたdirectoriesがある。古いのは4.9.Xとか4.14.Xなんてのがずらりと並んでいた。

1つのversionに対応するpairで100MiBちょっとあるので、うっかり消し忘れていると膨大な領域が消費され続ける (今回は8Gぐらいだったので、80弱のversionが残っていたようだ)。

なお、最新版と1つ前 (念のため)だけ残して全てrmした後は:

% du -hc /lib/modules
...
229M /lib/modules
229M total

全体で見ても:

% df -h
...
/dev/root        29G  4.5G   23G  17% /
...

rpi-updateでよくupgradeを行う方は注意されたい。

2019年1月26日土曜日

Raspberry Pi 1 Model Bを使ってWinbondのflash chipに書き込みしてみた

*** 更新記録 ***

* 2019-01-28 材料、接続方法について追記

*** 更新記録ここまで ***


Raspbianのflashrom v0.9.9-r1954でread/writeできたので記録として。

$ flashrom --version
flashrom v0.9.9-r1954 on Linux 4.14.79+ (armv6l)
flashrom is free software, get the source code at https://flashrom.org

教訓1: flashromで読み書きする時はspispeedを指定しよう (linux_spi時は特に)

教訓2: 面倒でもICテストクリップのピンの対応を確認しよう


動機


* Shuttle SZ170R8のUEFI (BIOS)が飛んだ (飛ばした)時に備えてやり方を知っておきたかった
* ↑ UEFI (BIOS)に含まれているIntel ME関連のcodeを排除したcustom UEFIを作り、書き込んでみたかった
* 普段使ってないRaspberry Pi 1 Model BがあるのでROM焼き器として流用したかった


概要


こんな具合で接続している。

図1 RPi1BとブレッドボードとICテストクリップ

図2 別の角度から

図3 ICテストクリップとSOIC


材料など


Hardware


* Raspberry Pi Model B (RasPi1B) ※ちなみにrev1とrev2があるがどちらかは不明
* microSD card (32GB) ※32GBも要らないのだが適当なものが余っていなかったので
* LAN cable ※Rasbpian install後update & SSHでheadless運用するため
* USB cable (Type A - micro B) ※電源
* USB電源 ※5V 2Aぐらいのもの
* ICテストクリップ for SOIC-8 ※ebayで適当に買った物。400円くらい
* Winbond W25Q64FVSIG ※これも多分ebayで入手。10個で600円ぐらい
* ピンケーブル ※RasPiのGPIO (ピンヘッダ)からブレッドボードに繋ぐメス→オスのものと、ブレッドボードからICテストクリップのソケットに繋ぐオス→オスのもの
* ブレッドボード ※その辺に余っていた物。多分秋月電子で買った200円ぐらいの品
* テスタ (DMM) ※ICテストクリップのピンの対応を調べるのに使う

Software


* Raspbian Stretch Lite ※2019-01の最新版stable
* flashrom v0.9.9-r1954 ※Stretchに含まれるversion
* 書き込むUEFI/BIOSのimage file ※場合によっては.exeなどから取り出す必要あり


接続方法


具体的な方法は既に他のwebsiteでなされているので省略。要点のみ挙げると:

* SPIの最もsimpleな接続方法を使う (dual SPIとかquad SPIとかは使わない)
* W25Q64FVSIGの場合は電源電圧が3.3 V
* W25Q64FVSIGの場合は/HOLDと/WPのpinをpullup (=3V3と接続)しておく (pullupでholdとwrite protectの機能をそれぞれ解除)
* Raspbianの初期状態ではSPIの機能が無効化されているので、raspi-configで有効化しておく


Pitfalls


ICテストクリップの接続先の対応について


非常に当たり前のことなのだが、テストクリップの先のピンが、コネクタ部分のどのピンと対応しているのかを予めテスタで調べておくこと。

これを怠ったが故に間違ったピンを接続し、flash chipから香ばしい臭いが漂ってきた (80〜90度Cくらいにはなっていたようだ)。Flash chipは安いし予備もあるから良いが、RasPiが壊れていたら大変だった。

危うく2019年の「今年破壊したモノ」リスト入りさせる所だった。こういう基本的な所で手を抜くとロクなことがないという実例である。

なお、今回は幸運にもRasPiは勿論、flash chipも破損していなかった (書き込み・読み取り共に正常に完了した)。


spispeed=指定について


Web上にはRaspberry Pi + flashromでW25Q64FV (W25Q64.V)を扱っている記事がたくさんあり、すんなりいくものとばかり思っていた。が、実際に (↑きちんと確認して)接続しても認識すらしなかったので一体何が悪いのか分からなくなった。そんな中でこのpageを見付け、速度が問題なのでは?と気付き、安定性を取って遅いspispeed (512)を指定したらうまく認識するようになった。

cf. [Does not work without spispeed= on RPi · Issue #29 · flashrom/flashrom · GitHub](https://github.com/flashrom/flashrom/issues/29)

要は、高周波をまともに扱えるような配線状況でもないのに最高速度を出して (?)無理するとchipもまともに認識できない、という至極当たり前なことだった訳だ。よって、spispeed=による速度 (kHz)指定が必要となる。

ちなみに、このoptionについて調べると以下のような記述も出て来た:

Flashrom uses the Linux-native SPI driver, which is implemented by flashrom's linux_spi module. To use the RaspberryPi with flashrom, you have to specify that driver. You should always tell it at what speed the SPI bus should run; you specify that with the spispeed parameter (given in kHz). You also have to specify the Linux SPI device, e.g.
flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=1000

cf. [RaspberryPi - flashrom](https://www.flashrom.org/RaspberryPi)

今回は写真 (図1及び図2)の通り、RPiのGPIO headerから一旦ブレッドボードに出して、そこから長さが不揃いのジャンパケーブルでテストクリップに接続している。この非常に残念な接続方法により、datasheetによれば104MHzまで出るらしいが30MHzが限界だった (少なくとも35MHzだと認識せず)。

spispeed=で指定しない場合にどれくらいの値が出ているのかは不明だが、遅い方が読み取り・書き込みできる可能性が高くなるのは言うまでもない。勿論、読み書きの速度も遅くなるが。


Command examples


Flash chipの認識


特にoperationを指定しないと、何のchipとして認識しているかをprobeしてくれる。

$ flashrom --verbose --programmer linux_spi:dev=/dev/spidev0.0,spispeed=30000
...
Probing for Generic unknown SPI chip (REMS), 0 kB: probe_spi_rems: id1 0xef, id2 0x16
Found Winbond flash chip "W25Q64.V" (8192 kB, SPI).
This chip may contain one-time programmable memory. flashrom cannot read
and may never be able to write it, hence it may not be able to completely
clone the contents of this chip (see man page for details).
No operations were specified.

Winbondのflash chip "W25Q64.V"として認識しているのが分かる。W25Q64FVを接続しているのでok。


Flash chipからの読み取り


$ flashrom --verbose --read /tmp/image.bin --programmer linux_spi:dev=/dev/spidev0.0,spispeed=30000

Flash chipから読み取った内容を/tmp/image.binにdumpする。


Flash chipへの書き込み


$ flashrom --verbose --write /tmp/image.bin --programmer linux_spi:dev=/dev/spidev0.0,spispeed=30000

Flash chipへ/tmp/image.binを書き込む。


flashromのcommandsとoptionsについて


$ flashrom --help

で見られる。

$ man flashrom

もある。


参照したwebsites


* [BIOSのアップデートに失敗するなどしてBIOSの内容が壊れ、PCが起動しなくなった場合の対処方法(Raspberry Pi を使用した)](http://www.floatgarden.net/pc/bios_flash_raspberry_pi.html)
* [Raspberry Piを使ってBIOSが飛んだマザーを修理したお話 - Qiita](https://qiita.com/Ellise_MX/items/ed12700dbce31c01b34d)
* [Raspberry Pi(Zero)でASUS Z97-CのBIOSを焼く | 純規の暇人趣味ブログ](https://jyn.jp/raspberrypi-bios-flash/)
* [Libreboot – How to program an SPI flash chip with the Raspberry Pi](https://libreboot.org/docs/install/rpi_setup.html)

2018年10月8日月曜日

Raspbianのawkがsegfaultを吐いた

atで登録しているcommandが失敗していたので何が起こったのかと調べてみた所、awkがsegmentation faultを起こしていると分かった。

試してに実行してみると:

% awk --version
awk: fatal error: internal error: segfault
zsh: abort      awk --version

以前、sudoがsegvったことを思い出し (cf. https://typeinf-memo.blogspot.com/2018/06/watchdograspiansudofork-bombreboot.html)、取り敢えずrebootをかけてみたら直った。

2018年6月15日金曜日

watchdogを導入したRaspbianでsudoが使えなくなったのでfork bombでrebootさせた話

Raspberry Pi 3 model BにRaspbian (armv7l)を入れて有線routerとして利用しているが、sudoがsegmentation faultを吐いて使えなくなる状況に陥った。

どうやらsudoのpermissionがおかしくなったことが要因らしいが、理由はどうあれRaspbianでsudoが使えないのは致命的である。普通にinstallして特に設定しない場合、Raspbianではrootとしてloginできない。一般userが必要に応じてsudoする運用が前提だからだ。

こうなると、aptでsystem updateも、rpi-updateでfirmware upgradeも、shutdownもできない。最終手段として強制的に電源を切る (=microUSBのcableを引っこ抜く)ぐらいしか思い付かないが、NAND flashのstorageではあまりやりたくない (HDDでも嫌だが)。

そこで、watchdogをinstallしていることを思い出し、fork bombでsystemをdownさせてrebootさせようと思い付いた。つまり:

* fork bombを発動
* watchdogが発動 → reboot
* boot processでfsckが実行される → filesystemが修復されpermissionが回復
* sudoが使えるようになる (はず)

fork bombにはshell scriptで実行する方法と、Cあたりでprogramを書いて実行する方法がある。今回はshell scriptより速く効きそうなCでprogramを書いて実行した。

#include <unistd.h>

int main(void){
  while(1){
    fork();
  }
}
これをforkbomb.cとして保存し、gcc -o forkbomb forkbomb.cでcompile。実行前に気休めとして一応syncを発行しておく。

./forkbombを実行。systemがfreeze → watchdogによりrebootがかかるのを待つ。

無事rebootし、fsckが実行されたのか、sudoは何事もなく使えるようになった。


2017年8月2日水曜日

Raspbianで起動時にscriptを自動実行させる

Raspberry Pi 3 Model B (RasPi3)で部屋のLED照明とか、RasPi3自身の冷却ファンのPWM制御とか、室温の計測&loggingをさせている。それらのscriptを起動時に自動実行させたくなったので調べてみた所、以下のwebpageがとても参考になった (というかそのものズバリ)。

* [Raspberry Piでプログラムを自動起動する5種類の方法を比較・解説](http://hendigi.karaage.xyz/2016/11/auto-boot/)

採用した方法と理由


題にもあるように5つの方法が紹介されているが、個人的な用途やpros/consを考えると
cronのjobとして登録する方法が一番のお勧め。

* 登録と削除がcrontab -eで出来て楽
* 起動するscriptはuser権限で起動する

cronを使う時の問題点 (2017-08-25追記)


RasPi3はRTCを持たないので再起動時した直後など暫く時刻がズレていることがある。室温・湿度などをCSV fileに記録する際にはこれが問題となり、本来時系列順であるべき所がいきなり時間が戻ったりする。

19:01:03 ...
19:01:04 ...
18:30:33 ... <--- ここから...
...
18:30:52 ... <--- ここまでおかしい
19:03:12 ... <--- NTPで補正された
19:03:13 ...

cron側でNTPで時刻が補正される迄実行しないようにできれば一番良い。試してはいないが、systemdを使っているのだから依存関係を適切に設定すればNTPの実行後にcronを立ち上げられるような気もする。

取り敢えずsensorから値を取得するscriptの冒頭で、現在時刻とlog fileのmtimeとを比較して、現在時刻がmtimeよりも前 (eg. 現在=16:30でmtime=17:00)なら異常と判断してNTPによるsyncを待つようにした。

発展


もしこれで足りなければ (super userで動かしたいとか)、/etc/rc.localに細工 (exit 0の前あたりに追記)する方法を取る。

正当なやり方はsystemdのserviceとして登録する方法なんだろうけど、たかが小さなscriptを自動実行させたいってだけであんな長ったらしい設定fileを書くのは面倒すぎる。

補足


検索時に気になったのは、あちこちに残っている古い情報が検索の上位に出て来ること。例えばRaspbianのdefault init systemがsystemdに移行したとかの事前情報が無いと、上手く起動しないとか、設定fileが無いとか、無駄に混乱する原因になりそう。