二階建てFlash

今のところ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)を使って複数のデバイスとの接続を可能にしています。

![AtherosSPICS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/3064ab34-dd44-1838-ff57-9f3513dec16d.png)

ターゲットはAtherosのAR1321を使ったモジュールを選びました。メーカからクレームがくるといやなので製品名は書きませんが日本で売っている[これと](https://openwrt.org/toh/sitecom/wlr-2100-v2)同じ基板を使ったモデルです。

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に乗せて半田でブリッジしているのですが、結構苦戦しました。

![写真（2019-05-07 6.56）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/5e34cb32-a674-d59c-809b-9d9837be9bac.jpeg)

CSピンは図の上のような未実装なLEDのパターンがあったのでそこに接続しました。SPI FlashのCSはActive LOWなので図の下のようにPull UPして接続します。

![CS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/7147fd3b-6e93-e913-5a00-686fe925abfb.png)

従来の固定のアサインの場合ピンを探すのが大変で、そもそも出てないケースもあり、この動的なアサイン機能は画期的です。

```
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
```

アサイン機能のサポートをレビューを出してみました。

https://reviews.freebsd.org/D20170

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にするサポートを入れました。