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)

2019年1月24日木曜日

Firefox (nightly)をclang 8 + libc++でbuildする

Firefox (nightly)をmercurialのsource treeからbuildしているのだが、先日Debian experimentalに入ったGCC 9をinstallした時に入ったlibstdc++が原因でbuildできない。ただし、これがlibrary側のbugなのか、それともFirefox側の記述に問題があるのかは切り分けていないため不明。

以前から薄々気付いてはいたのだが、error messageを見るに、LLVM/Clangでbuildした場合でもC/C++ standard libraryとしてGCCに付属するlibstdc++が使われている。GCC 9付属のlibstdc++がだめでも、LLVM/Clangに付属するlibc++なら大丈夫なのでは?と思い実験してみた所無事にbuildできた。

なお、GCC 9とLLVM/Clang 8ではdevelopment stageが異なるのでcodeのmature具合が違っていて当然な点、更にはexperimental packagesにtroubleがつきものなのは当然なので予め申し述べておく。Firefox nightlyのbuildもGCC 8に付属のlibstdc++なら正常にできる。


software environment


* Firefox nightly (Mercurial) → cset 454868:c60e6c0c2e23
* llvm-8:amd64/experimental 1:8~svn351401-1~exp1
* llvm-8-runtime:amd64/experimental 1:8~svn351401-1~exp1
* clang-8:amd64/experimental 1:8~svn351401-1~exp1
* lld-8:amd64/experimental 1:8~svn351401-1~exp1
* libc++-8-dev:amd64/experimental 1:8~svn351401-1~exp1
* libc++1-8:amd64/experimental 1:8~svn351401-1~exp1


build instruction


.mozconfigに以下の記述を行う:

export CC='clang-8 -stdlib=libc++'
export CXX='clang++-8 -stdlib=libc++'
ac_add_options --with-clang-path='/usr/lib/llvm-8/bin/clang'
ac_add_options --with-libclang-path='/usr/lib/llvm-8/lib'
ac_add_options --enable-linker=lld-8
ac_add_options --with-ccache=/usr/bin/ccache

今回の肝は、compilerを指定する最初の2行の"-stdlib=libc++"というoption (ただし、これをclang-8の側 (C++ではなくてC)に適用して良いのか、意味があるのかは不明)。Debian packageのclangはdefaultでlibstdc++ (GCC由来)を使うため、-stdlib optionでlibc++ (LLVM/Clang由来)を使うよう明示する。

また、standard libraryの変更とは直接関係ないが、ついでにFirefoxが用いるlibclangなどのpathを指定し、更にlinkerをbinutilsのldではなくLLVM/Clang由来のlldを用いるよう明示する (ほとんど気分の問題)。

あとはいつも通り:

./mach build

で暫く待つ。


SwissMicros DM42のfirmware v.3.12がreleaseされた

SwissMicros DM42 (HP-42Sのclone)用firmware v3.12がreleaseされたので、早速upgradeしてみた。

cf. [Firmware History](https://www.swissmicros.com/dm42/firmware/history.html)

今回の更新内容は:

* Free42 (HP-42Sのemulator)のupgrade
* (様々なhardwareのreviewなどで有名な) EEVlogで指摘された不具合の修正
* etcetc

とのこと。

Upgrade instructionsは以前紹介した通りなので詳細は過去記事を参照されたい:
cf. https://typeinf-memo.blogspot.com/2017/12/swissmicros-dm42firmware-update.html ※dfu-utilを用いたfirmware updateの手順


Debian experimentalにGCC 9とClang 9が入った

GCC 9とClang/LLVM 9がそれぞれDebian experimentalに入った。

GCC 9


2019-01-23現在GCCは8.2 seriesがstableで、GCC 9は2019-04あたりにreleaseされる予定のようだ。

cf. [GCC Development Plan - GNU Project - Free Software Foundation (FSF)](https://gcc.gnu.org/develop.html)


LLVM/Clang 9


2019-01-23現在Clang 7.1 seriesがstableで、Clang 8は2019-02以降にreleaseされる予定:

cf. [The LLVM Compiler Infrastructure Project](https://llvm.org/)

2019年1月20日日曜日

emacsに-rvをつけて起動すると"invalid face: tooltip"を吐いて死ぬ

emacs-git (commit 551051596fe51d6e232315eeda8a0a79eb43bfdf)をsourceからbuildした後、早速立ち上げようとしたら:

% emacs -rv
invalid face: tooltip

……255を返して死んでしまった。

取り敢えずstraceでも見るか、と思い:

% strace emacs

は普通に立ち上がる (ただし-rvじゃないので真っ白なbgで)。

どうやら-rvをつけた時に立ち上がらないらしい。

問題が設定にあるのかemacs側にあるのか切り分けてすらいないので正確な原因は不明だが、取り敢えずこのままでは見た目が慣れないことこの上ないので、color themeを入れることにした。

el-get installでcolor-themeをinstallし、color-theme-clarityを採用。

White on black color theme by Richard Wellum, created 2003-01-16.

とのこと。何となく選んだ一発目で慣れた配色を引いた。

図1: color-theme-clarity (w/ transparent)

update-grubが"grub-probe: error: failed to get canonical path of ..."を吐いて失敗した原因と対策

Main machineではLinux kernel image (linux-image)を自前でbuildしているのだが、その際不要になった古いpackageの削除が失敗した。原因はlinux-image packageのpostrm scriptにhookされているupdate-grubが:

grub-probe: error: failed to get canonical path of sdb5_crypt

を吐いて失敗したことによる。なお、sdb5_cryptはLUKSでencryptしているpartitionであって、環境に依存して名前が変化する。

ちなみに、なぜlinux-imageの削除にupdate-grubがhookされているのかというと、linux-imageが削除されるとそのversionのkernelはもはや存在せずbootできないので、update-grubを実行してboot menu (/boot/grub/grub.cfg)をupdateする必要があるからだ。

最も簡単なworkaroundは、/dev/mapper/sdb5_cryptが存在しないので、これを作り直してやること。

sudo ln -s /dev/dm-0 /dev/mapper/sdb5_crypt

以前存在していた/dev/mapper/sdb5_cryptがなぜ無くなったのかについては不明だが、Linux kernelのupdate (4.19.11 → 4.20)、systemdのupdate、sysvinit → systemdへの変更、など幾つかの要因が考えられる。