SOPINEでBareMetalプログラミング-準備編Part1 (機器、toolchain）

#◆はじめに
SOPINE(sun50i)でBareMetalプログラミングをするために色々と準備したことについてのメモです。
環境整備の手順についてまとめてるので、プログラミング自体はあまりないです。

#◆準備編Part1のゴール
[linux-sunxiのtools](https://github.com/linux-sunxi/sunxi-tools)にあるuart0-helloworld-sdbootをSOPINEで動かすことが目的です。
この時、FELモードでバイナリをSOPINEへ転送させます。
SDカードから起動させる時はこのバイナリをddで書き込めば、FELと（たぶん）同じ挙動になると思います。
またuart0-helloworld-sdbootのメッセージはUART経由で出力されるので、それも見れるようにします。

#◆必要な機材
自分が用意した機材の一覧です。
参考程度でよろしくお願いします。

1. SOPINE
1. SOPINE Baseboard "Model A"
1. MacBookPro 2013 Late
1. UART - USB 変換機器
1. USB - microUSB 変換アダプタ
1. microUSB - USB ケーブル
1. USBハブ

USB - microUSB 変換アダプタは、BaseboardとMacBookProがUSB Type-Aしかないので、それを接続するために用意しました。USB Type-A - Type A のケーブルは持ってないので・・・
あとUSBハブについてですが、なぜかMacBookProの左側のUSBポートだと、SOPINEをFELモードにしてつないでも認識されない、UART-USB変換機器が認識されないというトラブルがありました。
lsusbしても認識されてないという・・・
そこで、右側のUSBポートを使うためにハブを用意しました。

#◆ビルド環境の準備
AllwinnerのSoCは電源投入するとまずBROMが読み出されます。（BROMは書き換え不可）
このBROMがSDカード、NORフラッシュなどを準備読み取りBootableなデータがある場合、それをSRAMにロードして処理を移す仕組みになってます。
そしてどこにもBootableなデータが無い場合はFELモード（乱暴に言えばUSBからデータロードするモード）に移行します。
そこで、今回はBootableなuart0-helloworld-sdbootをFEL経由で転送します。
ここでは、uart0-helloworld-sdbootをビルドする手順について記載します。

##arm-none-eabi-*のインストール
homebrew経由でtoolchainをインストールします。

```bash:toolchainインストール
brew install gcc-arm-none-eabi
```

##mksunxibootの準備
[u-boot/u-boot-sunxi.git](http://git.denx.de/?p=u-boot/u-boot-sunxi.git;a=tree;f=tools)からmksunxiboot.cをダウンロードしてください。
その後、コンパイルして適当なフォルダ(/usr/local/bin）にコピーしてください。

```bash:mksunxibootのインストール
gcc -o mksunxiboot mksunxiboot.c
mv mksunxiboot /usr/local/bin/
````

##sunxi-felの準備
GitHubから[linux-sunxi/sunxi-tools](https://github.com/linux-sunxi/sunxi-tools)を落としてきてビルドとインストールをします。

```bash:sunxi-toolsのインストール
cd sunxi-tools
make tools
make install-tools
```
#◆uart0-helloworld-sdboot

## ビルド方法
実際にuart0-helloworld-sdbootをビルドしてBootableイメージを作る方法です。
まず、GitHubの[linux-sunxi/sunxi-tools](https://github.com/linux-sunxi/sunxi-tools)から、下記のファイルを落としてきます。

- uart0-helloworld-sdboot.c
- uart0-helloworld-sdboot.lds

そしてarm-none-eabiを使ってビルドします。

```bash:uart0-helloworld-sdboot
arm-none-eabi-gcc -g -Os -marm -fpic -Wall -fno-common -fno-builtin -ffreestanding -nostdinc ¥
 -fno-strict-aliasing -mno-thumb-interwork -fno-stack-protector -fno-toplevel-reorder ¥
 -Wstrict-prototypes -Wno-format-nonliteral -Wno-format-security uart0-helloworld-sdboot.c ¥
 -nostdlib -o uart0-helloworld-sdboot.elf -T uart0-helloworld-sdboot.lds -Wl,-N
arm-none-eabi-objcopy -O binary uart0-helloworld-sdboot.elf uart0-helloworld-sdboot.bin
mksunxiboot uart0-helloworld-sdboot.bin uart0-helloworld-sdboot.sunxi
```

uart0-helloworld-sdboot.sunxiがBootableなイメージとなります。
FELモードではこれを転送することでUART経由でメッセージが送信されます。
SDカード経由で実行する場合はddを使ってこのイメージをSDカードへ書き込むとOKです。
(diskXはSDカードのマウントポジションなので適宜書き換えてください)

```bash:sdカードへの書き込み
dd if=./uart0-helloworld-sdboot.sunxi of=/dev/diskX bs=1024 seek=8 
```

## FELモードで起動
以下の手順で接続＆FELモード起動を行ってください。
なお、UARTでメッセージを受信する方法も含みます。

1. SOPINEをBaseboardに装着する
1. BaseboardのUSBポートの上側にmicroUSBの変換アダプタを挿す
1. MacBookProの右側のUSBポートにハブを挿す
1. UART-USB変換とBaseboardを接続する
1. UARt-USB変換とUSBハブを接続する
1. Baseboardに電源アダプタを挿す
1. microUSB変換アダプタとUSBハブをケーブルで接続する

最後にmicroUSB変換アダプタとUSBハブをケーブルで接続するのは、そうしろと書いてあるから。
そうしないとFELモードに移行しないぽい？が検証していないので不明です。

最後にUARTからのメッセージを受信できるようにします。
新しいターミナルの画面を開き、下記コマンドを実行します。

```bash:UARTの受信
screen /dev/cu.usbserialHogeHoge　115200
```

cu.usbserialHogeHogeは適当に変えてください。
115200はSOPINEのデフォルトぽいです（というか、AllwinnerA64のデフォルトぽい？）。

## データ転送
最初に、下記のコマンドでSOPINEがMacBookProから見えているか確認してください。
見えてない場合は何か間違っているかもしれないので頑張って解決してください。

```bash:接続されているSOPINEが見えるかテスト
sunxi-fel -l
```

見えているようなら、下記のコマンドでuart0-helloworld-sdboot.sunxiをSOPINEへ転送してください。
問題がなければ、uart0-helloworld-sdbootのメッセージがuart経由で表示されます(screenコマンドを実行したターミナル）。

```bash:FEL経由でデータ転送
sunxi-fel -v sql uart0-helloworld-sdboot.sunxi 
```

#◆おわりに
SOPINEでBareMetalプログラミングの準備方法について記載しました。
これで最低限のHelloWorldは動かせたのであとは色々できるかと思います。
今後はRustで同じことをするための環境整備やuart0-helloworld-sdbootプログラムのコンバートをしていく予定です。