Orange Pi Zeroでベアメタル

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)

#ツールチェーン

[gnu-toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm "gnu-toolchain")

コンパイルオプションは最低限、以下を指定しておく
>arm-none-eabi-gcc -march=armv7-a -mtune=cortex-a7 <input_file>



#データシート
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)選択可能。

1. BROM -> SPL (Secondary Program Loader)(*1) -> U-Boot -> Kernel
2. 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に展開して実行される。

1. SD Card0(MMC0) 
2. Internal NAND flash
3. SD Card1(MMC1)
4. SPI Connected NOR flash
5. 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から任意のプログラムを起動する形がよさそう。