Orange Pi zero でベアメタル(OSなし)プログラミングをするための情報収集
ハードウェアスペック
AllWinner H2+ SoC
CPU: Quad-core Cortex-A7
Onboard Storage : TF card (Max. 32GB) / NOR flash(2MB)
Memory (SDRAM) : 512MB DDR3
#開発環境
CentOs (virtualBox)
#ツールチェーン
コンパイルオプションは最低限、以下を指定しておく
arm-none-eabi-gcc -march=armv7-a -mtune=cortex-a7
#データシート
Orange Pi zeroはAllWinner H2+ SoCが搭載されているのでそちらのデータシートを参照する。
こちらからダウンロードできました。
http://wiki.friendlyarm.com/wiki/index.php/File:Allwinner_H2%2B_Datasheet_V1.2.pdf
AllwinnerはArmアーキテクチャのSoC。
H2+はH3とほぼ互換性あり。
Allwinner SOCについての情報
https://linux-sunxi.org/Main_Page
今回のターゲット(Orange Pi zero)はこちら
https://linux-sunxi.org/Xunlong_Orange_Pi_Zero
起動シーケンス
SoC(H2+)としては入力ピン(UBOOT)によって2パターン(0:U-Boot, 1:Normal(FEL) Boot)選択可能。
- BROM -> SPL (Secondary Program Loader)(*1) -> U-Boot -> Kernel
- BROM -> Normal(FEL) Boot
しかし、Orange Pi ZeroにはNormal(FEL)モードを選択するためのコネクタやボタンがないのでデフォルトはU-Boot起動する。
SDカードやFlashに有効なイメージがない場合にFELモードで起動する。
(*1)SPLはU-Bootの一部。
Orange Pi ZeroのSRAMだとサイズ的にU-Bootを展開できないので、小さいSPLをSRAMに展開して、SPLがU-Boot本体を展開する。
その後、U-BootがKernelイメージを展開、起動する
BROM
データシートの
4.1. MemoryMap
より、以下の場所にBootRomが存在する。
電源投入、リセット解除時にここからプログラムが走り出す。
Module | Address | Size |
---|---|---|
N-BROM | 0xFFFF 0000 - 0xFFFF 7FFF | 32KB |
S-BROM | 0xFFFF 0000 - 0xFFFF 7FFF | 64KB |
"N-BROM"と"S-BROM"については仕様を見つけることができなかった。
あまり気にしないことにする。
開始アドレスが同じだから実装時にどちらか一方が選べる?
BROM
http://linux-sunxi.org/BROM
BROMのソースコード(ベクタテーブル、FELモード)
https://github.com/hno/Allwinner-Info/blob/master/BROM/ffff0000.s
起動時はBROMの先頭0xFFFF 0000にベクタテーブルが配置されている。
先頭のリセットベクタから 0xFFFF 4000のBROMへジャンプしている
CPUのリファレンスマニュアル "Cortex-A7 MPCore Technical Reference Manual"
によると入力信号VINITHI[3:0]を"1"にすることでベクタがアドレス0xFFFF 0000に配置することができる。
BROMのソースコード(本体)
https://github.com/hno/Allwinner-Info/blob/master/BROM/ffff4000.s
U-Boot
h2+はh3と互換性があるそうなのでこちらからゲットできる。
この中にSPL, U-Boot, Kernelが含まれている。
https://github.com/orangepi-xunlong/orangepi_h3_linux
SPL (Second Program Loader)
SPLの役割はu-bootをDRAMに展開すること。
SRAMは小さくてu-bootを直接展開できない。
SPL(Second Program Loader)はBROMからは以下の優先度(番号が小さいほうが高優先度)で内蔵SRAMに展開して実行される。
- SD Card0(MMC0)
- Internal NAND flash
- SD Card1(MMC1)
- SPI Connected NOR flash
- FEL Mode
SPLは0番地の内蔵SRAMに展開される
Orangi Pi Zeroの内蔵SRAMは以下の通り
Module | Address | Size |
---|---|---|
SRAM A1 | 0x0000 0000 - 0x0000 FFFF | 64KB |
SRAM A2 | 0x0004 4000 - 0x0004 BFFF | 32KB |
SRAM C | 0x0001 0000 - 0x0001 AFFF | 44KB |
##FEL Mode
BROM内に格納されている起動モード
USB経由でPCと通信して色々できるらしい
http://linux-sunxi.org/FEL
http://linux-sunxi.org/FEL/USBBoot
SDカードなしでOrange Pi ZeroとPCをUSB接続すると何やらUSBデバイスが検出される。
ただし"不明なデバイス"と表示される。
こちらの情報によると
http://linux-sunxi.org/FEL/USBBoot#Mandatory_USB_driver
Zadigを使ってドライバがインストールできる。
https://zadig.akeo.ie/
実際にUSB Serial(CDC)を選択して"Install Driver"ボタンをクリックしたら、ドライバがインストールできたのでTeratermでOrange Pi Zeroに接続できた。
何かキーを押すとOrange Pi Zeroは"AWUS"って文字列を返してきた。
しかし、windows用ツール(sunxi-fel.exe)がうまく動いてくれなかった。(dllがないといわれて起動しなかった)
http://linux-sunxi.org/FEL/USBBoot#Using_sunxi-fel_on_Windows
windows版は実験的なものだそうなので素直にLinuxで使うことする。
Linuxでは以下の手順で導入できた。
http://linux-sunxi.org/Sunxi-tools#Building
sunix-toolsでメモリの読み書きができる。
しかし、Orange Pi Zero ではデフォルトがU-Bootモードで起動し、意図的にFELモードでの起動ができない。
例えばsunix-toolsでフラッシュにプログラムを書き込んでしまうと、次回からFELモードで起動できなくなってしまう(FELモード起動は優先度が最も低いため)
そのため、Orange Pi Zeroでベアプログラミングをする方法としてはU-Bootから任意のプログラムを起動する形がよさそう。