[成功] pcDuinoでFreeBSD 其の弐

[以前試して](https://qiita.com/yamori813/items/6a9da68e7c5d8f57a68b)ダメだったので、もう一度確認してみました。

ZRouterにビルドの設定は放り込んであるので、とりあえずビルドを流したら、arm.armと同じようにclangのエラーで引っかかるのでMakefile.inc1にパッチを当ててみます。

カーネルのリンクでxzと以前使ったEARYPRINTFでエラーが出たのでZRouterのmkファイルを修正します。

これでkernelとrootfsが出来ました。

以前試した時の手順でu-bootをSDに焼きtftpでkernelをメモリにロードして試してみます。

ELFも試しましたが、ELFが起動できるu-bootでもリンカースクリプトに依存してこけたりするので、binaryを利用した方が安全です。

binaryにするelfcopyはバグっているので、pkgのgnuなobjcopyを使います。ZRouterの変換処理のコマンドはMakefileの変数のオーバライドができるので、それを使います。

出来上がったkernelのelfファイルをobjdump -Dで確認してみます。

```
Pcduino_Lite_kernel:     file format elf32-littlearm


Disassembly of section .note.gnu.build-id:

c0200154 <.note.gnu.build-id>:
c0200154:       00000004        andeq   r0, r0, r4
c0200158:       00000014        andeq   r0, r0, r4, lsl r0
c020015c:       00000003        andeq   r0, r0, r3
c0200160:       00554e47        subseq  r4, r5, r7, asr #28
c0200164:       dcee33f1        stclle  3, cr3, [lr], #964      ; 0x3c4
c0200168:       fa150b00        blx     c0742d70 <_end+0x15ad70>
c020016c:       6539d3b7        ldrvs   sp, [r9, #-951]!        ; 0xfffffc49
c0200170:       ee92233f        mrc     3, 4, r2, cr2, cr15, {1}
c0200174:       c535863b        ldrgt   r8, [r5, #-1595]!       ; 0xfffff9c5

Disassembly of section .text:

c0200180 <_start>:
c0200180:       f10c01c0        cpsid   aif
c0200184:       e1a08000        mov     r8, r0
c0200188:       e1a09001        mov     r9, r1
c020018c:       e1a0a002        mov     sl, r2
c0200190:       e1a0b003        mov     fp, r3
c0200194:       e10f0000        mrs     r0, CPSR
c0200198:       e200001f        and     r0, r0, #31
c020019c:       e330001a        teq     r0, #26
```

.note.gnu.build-idといセクションが先頭についています。これだとobjcopyでbinaryにしたときに、load addressが0x40200154になりentory addressが0x40200180になります。このケースはいままでありませんでした。

load addressとentory addressを設定してu-bootイメージを作ってみました。

```
% file Pcduino_Lite_kernel.kbin.gz.uboot
Pcduino_Lite_kernel.kbin.gz.uboot: u-boot legacy uImage, FreeBSD Kernel Image, L
inux/ARM, OS Kernel Image (gzip), 1686101 bytes, Wed Apr 10 23:18:19 2019, Load 
Address: 0x40200154, Entry Point: 0x40200180, Header CRC: 0x0F172431, Data CRC: 
0x68D8B48A
```

bootしましたが落ちます。

```
=> tftpboot 0x41000000 Pcduino_Lite_kernel.kbin.gz.uboot
Using ethernet@1c0b000 device
TFTP from server 10.10.10.3; our IP address is 10.10.10.111
Filename 'Pcduino_Lite_kernel.kbin.gz.uboot'.
Load address: 0x41000000
Loading: #################################################################
         ##################################################
         5.3 MiB/s
done
Bytes transferred = 1686165 (19ba95 hex)
=> bootm
## Booting kernel from Legacy Image at 41000000 ...
   Image Name:   FreeBSD Kernel Image
   Image Type:   ARM Linux Kernel Image (gzip compressed)
   Data Size:    1686101 Bytes = 1.6 MiB
   Load Address: 40200154
   Entry Point:  40200180
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK

Starting kernel ...

---<<BOOT>>---
ARM Debug Architecture not supported
KDB: debugger backends: ddb
KDB: current backend: ddb
Copyright (c) 1992-2019 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
        The Regents of the University of California. All rights reserved.
FreeBSD is a registered trademark of The FreeBSD Foundation.
FreeBSD 13.0-CURRENT #2 a34b1232771(zrouter)-dirty: Thu Apr 11 08:18:16 JST 2019
    hiroki@zrouter:/usr/home/hiroki/zobj/usr/home/hiroki/ZRouter/tmp/usr/home/hi
roki/freebsd/arm.armv7/sys/Pcduino_Lite arm
FreeBSD clang version 8.0.0 (tags/RELEASE_800/final 356365) (based on LLVM 8.0.0
)
CPU: ARM Cortex-A8 r3p2 (ECO: 0x00000000)
CPU Features: 
  Thumb2, Security, VMSAv7
Optional instructions: 
  UMULL, SMULL, SIMD(ext)
LoUU:2 LoC:3 LoUIS:1 
Cache level 1:
 32KB/64B 4-way data cache WT WB Read-Alloc
 32KB/64B 4-way instruction cache Read-Alloc
Cache level 2:
 256KB/64B 8-way unified cache WT WB Read-Alloc Write-Alloc
real memory  = 1073741824 (1024 MB)
avail memory = 1041166336 (992 MB)
Fatal kernel mode data abort: 'Alignment Fault' on read
trapframe: 0xc060ac28
FSR=00000001, FAR=c04c8b46, spsr=200000d3
r0 =c1c01c3c, r1 =c04c8b46, r2 =c110b891, r3 =00000000
r4 =0000003c, r5 =00000014, r6 =0000001c, r7 =ffffffe4
r8 =00000000, r9 =c04c8b2f, r10=c1c01c78, r11=c060acf0
r12=ffffffff, ssp=c060acb8, slr=c0462a80, pc =c0462ad4

panic: Fatal abort
```

これは[以前にも書いた](https://qiita.com/yamori813/items/b93ee49161a2e34d5299)、LINUX_BOOT_ABIのカーネルオプションで拾えるようになるu-bootからのメモリサイズとdtsのメモリサイズを足して実際のサイズの倍になるためです。

rootfsはgpartでスライスを追加してそこにZRouterでビルドしたisoイメージをddで書き込みmountするようにしてみました。SDカードの中身はこんな感じです。

![SDImage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/dc8f0814-6b1b-fb24-7395-0d892851cbda.png)

これを直しても不安定で、いろいろ考えてみて、一度メモリサイズを256Mにしてみたところ安定したので、メモリコントローラの初期化由来の問題とピンときました。

違うボードのu-bootを使っていたのが問題で、u-bootを[pcDuino用にビルド](https://qiita.com/yamori813/items/771c4dd289c2241540d0)して使ったところ問題なく動くようになりました。

ZRouterのrootfsを置くために以下のようにして領域を確保します。

```
% sudo gpart add -s 1g -t '\!165' /dev/da0
```

SDのFATにkernelをコピーしてu-bootで以下の設定をすると自動起動になります。SDはたいてい大きので圧縮しないようにしました。

以下の内容でboot.cmdを作ります。

```
fatload mmc 0:1 0x41000000 Pcduino_Lite_kernel.kbin.uboot
bootm 0x41000000
```

ZRouterのオブジェクトディレクトリにある、uboot_mkimageコマンドを使ってboot.scrを作りPcduino_Lite_kernel.kbin.ubootと一緒にfatにコピーしておくとデフォルトのままでブートします。

```
% ./ztools/uboot_mkimage -C none -A arm -T script -d boot.cmd boot.scr
```

boot.scr作らずにbootcmdを直接書き換えてもsaveenvしてもブート出来ます。

```
=> setenv bootcmd 'fatload mmc 0:1 0x41000000 Pcduino_Lite_kernel.kbin.uboot;bootm 0x41000000'
=> saveenv
```

私は千石の処分品を購入しましたが、2019/4現在秋月でもFlash付きのpcDuinoが特売になっているようです。

ZRouterではFDT_DTB_STATICでカーネル内にdtbを持つようにビルドしています。u-bootにも入っているはずなのですが、渡し方がよくわかりません。

FreeBSDではHDMIが使えないなどありますが、いろいろ試したい人には良いかもしれません。ちょっといじると動くようになるものもあるので、楽しいですよ。