Orange Pi R1 のSPIフラッシュにOSを入れてルーターにする

メニュー

SPIフラッシュ

Orange Pi R1 には 16MB のSPIフラッシュ(Macronix MX25L12835F)が搭載されています。
Squashfs などの圧縮ファイルシステムを利用すればLinuxシステム全体がなんとか入ります。
U-Boot , Linux ともに初期設定でビルドすると利用できません。

U-Bootで利用する

orangepi_r1_defconfig で設定してビルドしたU-Bootでは
u-boot/arch/arm/dts/sun8i-h2-plus-orangepi-r1.dts がデバイスツリーソースとなりますが、
&spi0 {
  status = "okay";

  flash@0 {
    compatible = "mxicy,mx25l12805d", "jedec,spi-nor";
  };
};
↑初期状態では上記の部分全体がコメントアウトされているので利用不可になっています。アンコメントします。
  aliases {
    ethernet1 = &rtl8189etv;
    spi0 = &spi0;
  };
↑さらにaliasesブロックにspi0を登録する必要があります。
=> sf probe
SF: Detected mx25l12805d with page size 256 Bytes, erase size 64 KiB, total 16 MiB
=> mtd list
List of MTD devices:
* nor0
  - type: NOR flash
  - block size: 0x10000 bytes
  - min I/O: 0x1 bytes
  - 0x000000000000-0x000001000000 : "nor0"
U-BootでSPIフラッシュを利用する際は sf probe コマンドを使う必要があります。

Linuxで利用する

Device Drivers  --->
  <*> Memory Technology Device (MTD) support  --->
    <*>   SPI-NOR device support  --->
この2つを有効にしてビルドしたkernelで /dev/mtd0 が出てきます。
が、mtdデバイスは直接mountすることができず、mtdblockデバイスが必要です。
Device Drivers  --->
  <*> Memory Technology Device (MTD) support  --->
    <*>   Caching block device access to MTD devices
なのでここも有効にする必要があります。
これでビルドすると /dev/mtdblock0が出てきます。
U-Bootから起動パラメータでパーティション情報を受け取るには、
Device Drivers  --->
  <*> Memory Technology Device (MTD) support  --->
    Partition parsers  --->
      <*> Command line partition table parsing
ここも有効にする必要があります。

U-BootスクリプトをMTDからロードして実行する。

include/configs/sunxi-common.h の CONFIG_EXTRA_ENV_SETTINGS を改造してU-Bootをビルドするとデフォルトの環境変数が変更できます。
#define CONFIG_EXTRA_ENV_SETTINGS \
/*
    CONSOLE_ENV_SETTINGS \
    MEM_LAYOUT_ENV_SETTINGS \
    DFU_ALT_INFO_RAM \
    "fdtfile=" FDTFILE "" \
    "console=ttyS0,115200" \
    SUNXI_MTDIDS_DEFAULT \
    SUNXI_MTDPARTS_DEFAULT \
    "uuid_gpt_esp=" UUID_GPT_ESP "" \
    "uuid_gpt_system=" UUID_GPT_SYSTEM "" \
    "partitions=" PARTS_DEFAULT "" \
    BOOTCMD_SUNXI_COMPAT \
    BOOTENV
*/\
    MEM_LAYOUT_ENV_SETTINGS \
    "fdtfile=" FDTFILE "" \
    "load_scr=if load mmc 0:1 $scriptaddr /boot.scr;then echo Found boot.scr in mmc;else mtd read nor0 $scriptaddr 0x80000 0x10000;fi;"\
    "distro_bootcmd=sf probe;run load_scr;source $scriptaddr;"

#else /* ifndef CONFIG_SPL_BUILD */
標準のものを丸ごとコメントアウトして変更しました。
初期設定でビルドした場合 distro_bootcmd が自動実行されるので、そこを改造しました。
SDカード用のU-Bootと共通化するため、SDの第1パーティション直下にboot.scrが存在する場合はそちらをロード。ない場合はSPIフラッシュのオフセット512kBから64kBをロードして実行するようにしました。
途中に改行コードが入れられないので行末をエスケープした上で最後に空行を入れる必要があります。
環境変数には1行毎に改行コードを入れます。

U-Bootスクリプトについては boot.scr を参照してください。

U-BootからLinuxにMTDパーティション情報を渡す。

setenv mtdparts spi0.0:512k(U-Boot),64k(boot.scr),5M(zImage),64k(dtb),7M(ro),-(rw)
setenv bootargs mtdparts=${mtdparts} root=/dev/mmcblk0p2 init=/init.sh console=ttyS0,115200
の様に bootargs に mtdparts を設定してkernel起動オプションとして渡すと /dev/mtd0 /dev/mtd1 ... と割れます。
長いので変数は2つに分けました。
kernelは"Command line partition table parsing"を有効にしてビルドしないと受け取れません。
spi0.0はLinux上のSPIフラッシュのデバイスIDです。
デバイスID:第1パーティションのサイズ(パーティション名),第2パーティションのサイズ(パーティション名)...,-(最終パーティションの名前)
のような書式になります。最終パーティションのサイズは - にすると残り全部になります。
変更可能かもしれませんが、
# cat /proc/mtd
で確認できる erasesize が64kBになっており、それを下回るサイズのパーティションはリードオンリーになってしまうので基本的に64kB以上にする必要があります。

パーティションに書き込む

package/busybox/busybox.config
CONFIG_FLASHCP=y
にしてBuildrootをビルドすればflashcpコマンドが利用できます。
# flashcp rootfs.img /dev/mtd4
イメージファイルからパーティション単位で書き込めます。
[編集]   [AD]
rentafree.net