今のところZRouterでビルドするFreeBSDの最小サイズは4M弱で、4MのFlashだとそれ以外何も入りません。作戦としては以下があります。
- SPI Flash - 8Mに貼り替える
- USBがある - rootfsはusbストレージに置く
- CFI Flashで未実装のSPIのパターンがある - SPI Flashを増設する
- gpiospiでSPI Flashを増設する
- SPI FlashでCS1が使える - SPI Flashを増設する
一番下の方法を試してみます。
SPIバスはChip Select(CS)を使って複数のデバイスとの接続を可能にしています。
ターゲットはAtherosのAR1321を使ったモジュールを選びました。メーカからクレームがくるといやなので製品名は書きませんが日本で売っているこれと同じ基板を使ったモデルです。
AR1321はAR9341と同等のようです。AP123と呼ばれているようです。
このSOCはAtherosのAR7240からの流れのSOCで100BaseTXのSwitchが内蔵されています。
このSOCでは一つ前の世代のOnion Omegaで使われているAR9331にはなかったGPIOのマルチプレクサ(MUX)が搭載されました。この機能を使うと適当なピンに機能をアサインできます。
ネットにAR9341のデーターシートはあるのですが、書きかけのもののようでいろいろ抜けています。古いSOCでもCS0,1,2の3本のサポートがあったのですが、CS1,2の記載がまったくありません。いろいろ調べたところAR9344のデーターシートが見つかりこちらにはちゃんと書いてあります。
8ピンのSPI Flashを増設する場合は1ピンがCSなので、それ以外はそのまま接続します。いろいろ試してみて、増設するFlashのピンを下に向けて元のFlashに乗せて半田でブリッジしているのですが、結構苦戦しました。
CSピンは図の上のような未実装なLEDのパターンがあったのでそこに接続しました。SPI FlashのCSはActive LOWなので図の下のようにPull UPして接続します。
従来の固定のアサインの場合ピンを探すのが大変で、そもそも出てないケースもあり、この動的なアサイン機能は画期的です。
spi0: <AR71XX SPI> at mem 0x1f000000-0x1f00000f on nexus0
spibus0: <SPI bus> on spi0
mx25l0: <M25Pxx Flash Family> at cs 0 mode 0 on spibus0
mx25l0: device type en25q32, size 4096K in 64 sectors of 64K, erase size 64K
mx25l1: <M25Pxx Flash Family> at cs 1 mode 0 on spibus0
mx25l1: device type mx25ll32, size 4096K in 64 sectors of 64K, erase size 64K
もともと付いているFlashが4Mの場合はrootfsの一部(/usr/localなど)を増設したFlashに置くのがよさそうです。2Mの場合はもとのFlashにはkernelだけ置いて、増設したFlashにrootfsを置くのがよさそうです。
# df
Filesystem 1K-blocks Used Avail Capacity Mounted on
/dev/map/rootfs.uzip 9792 9792 0 100% /
devfs 1 1 0 100% /dev
/dev/md0 7543 99 6841 1% /tmp
<above>:/tmp/etc 17335 9891 6841 59% /etc
/dev/map/local.uzip 1762 1762 0 100% /usr/local
アサイン機能のサポートをレビューを出してみました。
2019/5/16追記:コミットされました。最初新たに機能を実装してみたら、その機能すでにあるはずと言われ、動かないのでパッチを当てたら、まだ話がかみ合わず、よくよくコードを見直したらAR9341の処理がぬけてただけでした。
hintsは設定は以下のようにします。
hint.gpio.0.pinmask=0x7fe800
hint.gpio.0.func.12.gpiofunc=7
hint.gpio.0.func.12.gpiomode=1
ZRouterにSEPARATE_LOCALFSというオプションを追加して、/usr/localを別のimageにできるようにしました。オプションを設定してmake localfsするとimageができます。
mkファイルは以下を追加します。
SEPARATE_LOCALFS=yes
PACKING_LOCALFS_IMAGE?=localfs.iso.ulzma
CFI Flashで4Mだとお手上げですが、USBがあればカーネルだけをFlashに置いてrootfsをUSBに置くのがいいです。USBメモリであれば容量も大きいので、圧縮せずに生のiso形式でmountするのがいいです。
SPI Flashはそれほど熱を持たないので、結構使える方法だと思います。またFlashをはがしたときにパターンをいためて使えなくなる心配もありません。
以下のようなスクリプトで更新してます。
#!/bin/sh
ZBOARD=`uname -i`
UPGRADETFTP=10.0.1.37
UPGRADEDEV=/dev/flash/spi1
UPGRADEBS=64k
IMG=${ZBOARD}_localfs.iso.ulzma
PIPE=/tmp/flashpipe
if [ `df | grep -c local` -eq 1 ]; then
umount /usr/local
fi
if [ ! -e ${PIPE} ]; then
mkfifo ${PIPE}
fi
dd if=${PIPE} of=${UPGRADEDEV} obs=${UPGRADEBS} conv=osync &
echo "bin
get ${IMG} ${PIPE}
quit" | tftp ${UPGRADETFTP} 69
mount_cd9660 /dev/map/local.uzip /usr/local
このモジュールで8Mに取り替えてみたのですが、オリジナルからコピーしたu-bootがMXのFlashに対応しいなかったため、結局元に戻して二階建てのままにしました。
二階建てにする時に、元々付いてたFlashからCSを外して、乗せたほうに回す方法もあります。
Ralinkの方はGPIOをCS1にするサポートを入れました。