FreeBSD の RaspberryPi3 で arm64 の SMP をお試しする

※以下は2016年12月時点で一時的に必要な手順です。将来的にはこのような手順は不要になるはずです。

# RaspberryPi3 で SMP(arm64)
「FreeBSD の RaspberryPi3 対応がだいぶ良くなった」で書いた通り、2016/11/29 freebsd-arm ML に「[RaspberryPi3 で SMPが使えるレベルになりました](https://lists.freebsd.org/pipermail/freebsd-arm/2016-November/015092.html)」という報告と試す手順が投稿されたので、手元の環境で試してみました。

# ３つのポイント
MLのポイントは３つ　

- 新しい GENERIC kernelを使う
- FAT 領域に２つのファイル<br/>
  https://people.freebsd.org/~gonzo/arm/rpi3-smp/u-boot.bin 
  https://people.freebsd.org/~gonzo/arm/rpi3-smp/armstub8.bin <br/>を置く。
- FAT領域のconfig.txtを書き換えて、「device_tree_address=〜」の行を<br/>
  device_tree_address=0x4000
  と書き換える。

実際に RaspBSD のイメージ
http://download.raspbsd.org/FreeBSD-aarch64-12.0-GENERIC-UP-308109M.img.gz
をmicroSDにddで書き込んでからなにをすればいいか考えます。

このRaspBSDのイメージに入っているkernelは、「GENERIC-UP」というkernel confファイルでビルドされています。GENERICっぽい名前ですが、/sys/arm64/conf/GENERIC-UP の中身を見てみると

```
include         GENERIC
ident           GENERIC-UP
nooptions       SMP
```
となっていて「SMPを使えなくした」GENERIC であることがわかります。

そんなわけでこのイメージに入っているkernelそのままだとうまく行かないので、SMP が有効な GENERIC kernelを用意します。
自前でビルドしてもいいのですが、FreeBSD公式ftpサイトにsnapshots が上がっているので、それもってくればお手軽に試せます。

```
ftp://ftp.freebsd.org/pub/FreeBSD/snapshots/arm64/aarch64/12.0-CURRENT/kernel.txz
```
展開すれば boot/kernel が出来ますので、それをイメージの /boot/kernel と置き換えてやります。
これで最初のポイントはクリアです。

その後の二項目、MS-DOS領域にファイル置いたり config.txt 書き換えたりはそのまんま実行するだけです。
以上の準備をして起動してやれば、

```
Starting CPU 1 (1)
Starting CPU 2 (2)
Starting CPU 3 (3)
FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs
```

的なログが出て、0 以外の core が立ち上がってる様子がわかります。
起動後に sysctl コマンドで
sysctl hw.ncpu
hw.ncpu: 4

となっていれば SMP化完了です。おめでとうございます。

実際のパフォーマンスはまだ良くわかりません。
top コマンドは現時点では
```
top: sysctl(vm.stats.vm.v_cache_count...) failed: No such file or directory
```
で動きませんでした。

私の環境での dmesg は以下です。

```dmesg.txt
KDB: debugger backends: ddb
KDB: current backend: ddb
Copyright (c) 1992-2016 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 12.0-CURRENT #0 r309302: Wed Nov 30 13:33:15 UTC 2016
    root@releng3.nyi.freebsd.org:/usr/obj/arm64.aarch64/usr/src/sys/GENERIC arm64
FreeBSD clang version 3.9.0 (tags/RELEASE_390/final 280324) (based on LLVM 3.9.0)
WARNING: WITNESS option enabled, expect reduced performance.
VT: init without driver.
can't re-use a leaf (geom_label)!
module_register: cannot register g_label from kernel; already loaded from geom_label.ko
Module g_label failed to register: 17
Starting CPU 1 (1)
Starting CPU 2 (2)
Starting CPU 3 (3)
FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs
random: unblocking device.
random: entropy device external interface
kbd0 at kbdmux0
ofwbus0: <Open Firmware Device Tree>
simplebus0: <Flattened device tree simple bus> on ofwbus0
ofw_clkbus0: <OFW clocks bus> on ofwbus0
clk_fixed0: <Fixed clock> on ofw_clkbus0
clk_fixed1: <Fixed clock> on ofw_clkbus0
clk_fixed2: <Fixed clock> on ofw_clkbus0
clk_fixed3: <Fixed clock> on ofw_clkbus0
clk_fixed4: <Fixed clock> on ofw_clkbus0
clk_fixed5: <Fixed factor clock> on ofw_clkbus0
clk_fixed6: <Fixed clock> on ofw_clkbus0
psci0: <ARM Power State Co-ordination Interface Driver> on ofwbus0
local_intc0: <BCM2836 Interrupt Controller> mem 0x40000000-0x400000ff on simplebus0
intc0: <BCM2835 Interrupt Controller> mem 0x7e00b200-0x7e00b3ff irq 16 on simplebus0
generic_timer0: <ARMv7 Generic Timer> irq 37,38,39,40 on simplebus0
Timecounter "ARM MPCore Timecounter" frequency 19200000 Hz quality 1000
Event timer "ARM MPCore Eventtimer" frequency 19200000 Hz quality 1000
bcm_dma0: <BCM2835 DMA Controller> mem 0x7e007000-0x7e007eff irq 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 on simplebus0
mbox0: <BCM2835 VideoCore Mailbox> mem 0x7e00b880-0x7e00b8bf irq 17 on simplebus0
bcmwd0: <BCM2708/2835 Watchdog> mem 0x7e100000-0x7e100027 on simplebus0
gpio0: <BCM2708/2835 GPIO controller> mem 0x7e200000-0x7e2000b3 irq 18,19 on simplebus0
gpiobus0: <OFW GPIO bus> on gpio0
gpioc0: <GPIO controller> on gpio0
uart0: <PrimeCell UART (PL011)> mem 0x7e201000-0x7e201fff irq 20 on simplebus0
uart0: console (115200,n,8,1)
spi0: <BCM2708/2835 SPI controller> mem 0x7e204000-0x7e204fff irq 22 on simplebus0
spibus0: <OFW SPI bus> on spi0
spibus0: <unknown card> at cs 0
 mode 0spibus0: <unknown card> at cs 1
 mode 0sdhci_bcm0: <Broadcom 2708 SDHCI controller> mem 0x7e300000-0x7e3000ff irq 27 on simplebus0
mmc0: <MMC/SD bus> on sdhci_bcm0
iichb0: <BCM2708/2835 BSC controller> mem 0x7e804000-0x7e804fff irq 31 on simplebus0
iicbus0: <OFW I2C bus> on iichb0
bcm283x_dwcotg0: <DWC OTG 2.0 integrated USB controller (bcm283x)> mem 0x7e980000-0x7e98ffff,0x7e006000-0x7e006fff irq 33,34 on simplebus0
usbus0 on bcm283x_dwcotg0
gpioled0: <GPIO LEDs> on simplebus0
gpioled0: <led0> failed to map pin
fb0: <BCM2835 VT framebuffer driver> on simplebus0
fbd0 on fb0
VT: initialize with new VT driver "fb".
fb0: 656x416(656x416@0,0) 24bpp
fb0: fbswap: 1, pitch 1968, base 0x3db33000, screen_size 818688
pmu0: <Performance Monitoring Unit> irq 36 on simplebus0
cpulist0: <Open Firmware CPU Group> on ofwbus0
cpu0: <Open Firmware CPU> on cpulist0
bcm2835_cpufreq0: <CPU Frequency Control> on cpu0
cpu1: <Open Firmware CPU> on cpulist0
cpu2: <Open Firmware CPU> on cpulist0
cpu3: <Open Firmware CPU> on cpulist0
cryptosoft0: <software crypto>
Timecounters tick every 1.000 msec
The GEOM class LABEL is already loaded.
usbus0: 480Mbps High Speed USB v2.0
ugen0.1: <DWCOTG OTG Root HUB> at usbus0
uhub0: <DWCOTG OTG Root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus0
mmcsd0: 16GB <SDHC SA16G 1.8 SN 24B013FE MFG 01/2015 by 2 TM> at mmc0 41.6MHz/4bit/65535-block
bcm2835_cpufreq0: ARM 600MHz, Core 250MHz, SDRAM 400MHz, Turbo OFF
Release APs
CPU  0: ARM Cortex-A53 r0p4 affinity:  0
 Instruction Set Attributes 0 = <CRC32>
 Instruction Set Attributes 1 = <0>
         Processor Features 0 = <AdvSIMD,Float,EL3 32,EL2 32,EL1 32,EL0 32>
         Processor Features 1 = <0>
      Memory Model Features 0 = <4k Granule,64k Granule,MixedEndian,S/NS Mem,16bit ASID,1TB PA>
      Memory Model Features 1 = <>
             Debug Features 0 = <2 CTX Breakpoints,4 Watchpoints,6 BrKDB: debugger backends: ddb
```