NanoPi Neo2でNetBSDを動かしたい'''と思っていたら動いた'''の

2017年12月9日(土) 関西*BSDユーザ会 第19回定期総会 + 併設研究会

nanopineo2.png../../FreeBSD/BSD_squeak2013.files/kbug-bug-mini.pngfoil.png

むとうたけし@関西*BSDユーザ会 (@610t)

まずは使ってみてください

  • IP:
  • hostname: nanopineo2.local
  • user: guest
  • passwd: guest610
  • sudo可

FriendlyARM NanoPi Neo2

NanoPi NEO2 wiki

  • SoC: Allwinner’s 64-bit H5 quad-core (Cortex-A53)
  • GPU: Mail450
  • RAM: 512M DDR3
  • I/O: microSD, Ether 10/100/1000M, USB, Serial, GPIO, Audio
  • Size: 40 x 40mm, 13g
  • OS: UbuntuCore 16.04, Debian, NetBSD
  • Price: 秋月2400円, FriendlyARM: $14.99

NetBSD, OpenBSD, FreeBSDが動いているらしい

NetBSDはこんな感じ

FamilySoCNetBSD version Example boards Notes
sun50iH5 8.99.4 and laterFriendlyARM NanoPi NEO2aarch32 mode
sun5i R8 8.99.2 and laterPocket C.H.I.P.(C.H.I.P.)
sun8i H3 8.0 and later FriendlyARM NanoPi NEO
sun7i A207.0 and later LeMaker Banana Pi

NetBSD NanoPi Neo2を動かすための手順

  • [A] ディスクイメージを用意
  • [B] 32MB kernel対応u-boot作成
    • pkgsrc/sysutils/u-boot-nanopi-neo2 + patch
  • [C] boot用microSDを作成 (A,Bを焼く)
  • [D] kernel netbsd-SUNXI.ubを作成
    • build.sh kernel=SUNXI
  • [E] Device Tree情報を用意
    • sun50i-h5-nanopi-neo2.dtb from UbuntuCore
  • [F] boot.cmdを修正, boot.scrに変換
  • [G] D,E,FをSDのMS-DOSパーティションに配置

[A,D] ディスクイメージとkernelの作成

  • build.sh releaseで、SUNXI kernelを作るように指定
    • obj/releasedir/evbarm/binary/gzimg/armv7.img.gz
    • obj/releasedir/evbarm/binary/kernel/netbsd-SUNXI.ub.gz
% ./build.sh -V HOST_CXXFLAGS=-fbracket-depth=1000 \
    -uU -m evbearmv7hf-el tools
% ./build.sh -V HOST_CXXFLAGS=-fbracket-depth=1000 \
    -uU -m evbearmv7hf-el kernel=SUNXI release
  • FreeBSD/macOSでは、 -fbracket-depth=1000 を指定
/Users/mutoh/hobby/NetBSD/src/tools/gcc/ \
  ../../external/gpl3/gcc.old/dist/gcc/cofig/arm/neon.md:
  3467:10917: fatal error: \
    bracket nesting level exceeded maximum of 256
/Users/mutoh/hobby/NetBSD/src/tools/gcc/
  ../../external/gpl3/gcc.old/dist/gcc/cofig/arm/neon.md:
  3467:10917: note: \
    use -fbracket-depth=N to increase maximum nesing level

[A] armv7.img のMS-DOSパーティション

  • セクタサイズが違うせいかmacOSでマウントできない
% sudo mount_msdos /dev/disk3s1 /mnt
mount_msdos: Unsupported sector size (54810)
  • イメージそのものはマウント可能
% hdiutil mount armv7.img 
/dev/disk4   FDisk_partition_scheme
/dev/disk4s1 Windows_FAT_32         /Volumes/NETBSD
/dev/disk4s2 NetBSD
% file armv7.img 
armv7.img: DOS/MBR boot sector;
  partition 1 : ID=0xc, active, 
    start-CHS (0x0,130,3), end-CHS (0xc,60,48),
    startsector 8192, 188416 sectors; 
  partition 2 : ID=0xa9,
    start-CHS (0x1c,141,50), end-CHS (0xa0,101,5),
    startsector 458752, 2118016 sectors
  • u-bootの設定もてあそぶのに不便

[B] u-bootの作成

  • u-boot は pkgsrc/sysutlls/u-boot-nanopi-neo2
    • /usr/pkg/share/u-boot/nanopi-neo2/u-boot-sunxi-with-spl.bin

[B] kernelが大きすぎる

  • 27.1 MiBもある
  • u-bootのデフォルトでは8M
  • CONFIG_SYS_BOOTM_LEN を増やして u-bootをbuild
 ## Booting kernel from Legacy Image at 46000000 ...
   Image Name:   NetBSD/sunxi 8.99.7
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    28423316 Bytes = 27.1 MiB
   Load Address: 40008000
   Entry Point:  40008000
   Verifying Checksum ... OK
 ## Flattened Device Tree blob at 4fa00000
   Booting using the fdt blob at 0x4fa00000
   Loading Kernel Image ... Image too large:
    increase CONFIG_SYS_BOOTM_LEN
Must RESET board to recover
resetting ...

[B] u-boot 32M対応

  • pkgsrc/sysutils/u-boot-nanopi-neo2
    • work/u-boot-2017.11/common/bootm.c
% diff -u work/u-boot-2017.11/common/bootm.c{.org,}
--- work/u-boot-2017.11/common/bootm.c.org      2017-12-04 12:30:20.000000000 +0900
+++ work/u-boot-2017.11/common/bootm.c  2017-12-04 12:30:36.000000000 +0900
@@ -32,7 +32,7 @@
 
 #ifndef CONFIG_SYS_BOOTM_LEN
 /* use 8MByte as default max gunzip size */
-#define CONFIG_SYS_BOOTM_LEN   0x800000
+#define CONFIG_SYS_BOOTM_LEN   0x2000000
 #endif
 
 #define IH_INITRD_ARCH IH_ARCH_DEFAULT

[C] ブート用microSDの作成

  • How to create bootable microSD.
% dd if=armv7.img of=/dev/rld0d bs=1m conv=sync
% dd if=/usr/pkg/share/u-boot/nanopi-neo2/u-boot-sunxi-with-spl.bin \
   of=/dev/rld0d bs=1k seek=8 conv=sync

[E] Device Tree情報

  • デバイスプロパティを記述し、kernel側での実装を容易にする。
    • ベースアドレス, クロック, 割り込み番号など
  • Device Tree Source(.dts)をdtcでコンパイルし、.dtbにする。
    • src/external/gpl2/dtc (/usr/bin/dtc)
    • pkgsrc/sysutils/dtc

参考文献

[E] sun50i-h5-nanopi-neo2.dts

/dts-v1/;
/ {
  model = "FriendlyARM NanoPi NEO 2";
  compatible = "friendlyarm,nanopi-neo2"
     , "allwinner,sun50i-h5";
  aliases {
    serial0 = &uart0;
  };
  chosen {
    stdout-path = "serial0:115200n8";
  };
  leds {
    compatible = "gpio-leds";
    pwr {
      label = "nanopi:green:pwr";
      gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>;
      default-state = "on";
   };
             (snip)

[E] sun50i-h5-nanopi-neo2.dtb はどこ?

reading sun50i-h5-nanopi-neo2.dtb
21386 bytes read in 32 ms (652.3 KiB/s)
libfdt fdt_path_offset() returned FDT_ERR_BADPATH
  (snip)
ERROR: Did not find a cmdline Flattened Device Tree
Could not find a valid device tree

[E] dtsからdtbを作ってみよう

  • ソースはある: src/sys/external/gpl2/dts/dist/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts
  • ./build.sh release logには作っている形跡無し
  • #include とかあるので、ソースかき集めてcpp使ってみる
    • #address-cells, #clock-cells, #dma-cells, #phy-cells, #gpio-cells, #interrupt-cells, #sound-dai-cells, #pwm-cells をcppディレクティブと思っている
    • -x assembler-with-cpp を指定する必要があるらしい
% cpp -traditional -ferror-limit=1000 -I . sun50i-h5-nanopi-neo2.dts.src > sun50i-h5-nanopi-neo2.dts
  (snip)
In file included from sun50i-h5-nanopi-neo2.dts.src:44:
./sun50i-h5.dtsi:47:4: error: invalid preprocessing directive
                #address-cells = <1>;
                 ^
27 errors generated.
*** Error code 1

[E] pkgsrc/sysutils/dtb-arm64-sun50i

  • Linuxのソース取ってきて作る模様
  • sun50i-h5-nanopi-neo2.dts がない…
  • Makefile
% diff -u Makefile.org Makefile
--- Makefile.org        2017-12-02 20:40:28.000000000 +0900
+++ Makefile    2017-12-04 08:12:08.000000000 +0900
@@ -4,7 +4,9 @@
 DTB_DEVICE=    sun50i
 DTB_DTS=       allwinner/sun50i-a64-bananapi-m64.dts   \
                allwinner/sun50i-a64-pine64-plus.dts    \
-               allwinner/sun50i-a64-pine64.dts
+               allwinner/sun50i-a64-pine64.dts \
+               allwinner/sun50i-h5-nanopi-neo2.dts
+DTS_EXTRA_INC=/usr/pkgsrc/sysutils/dtb-arm64-sun50i/work/linux-4.11.3/arch/arm64/boot/dts/allwinner
 
 .include "../../sysutils/dtc/linux-dtb.mk"
  • /usr/pkgsrc/sysutils/dtc/linux-dtb.mk
% diff -u ../dtc/linux-dtb.mk{.org,}
--- ../dtc/linux-dtb.mk.org     2017-12-03 16:11:35.000000000 +0900
+++ ../dtc/linux-dtb.mk 2017-12-04 08:10:17.000000000 +0900
@@ -28,9 +28,9 @@
 do-build:
 .for d in ${DTB_DTS}
        cd ${DTS_DIR} && \
-           ${CPP} -P -x assembler-with-cpp -I ${DTS_INC} -I ${DTS_ARCH_INC} \
+           ${CPP} -P -x assembler-with-cpp -I ${DTS_EXTRA_INC} -I ${DTS_INC} -I ${DTS_ARCH_INC} \
                -include ${DTS_DIR}/${d} /dev/null | \
-               ${DTC} -i ${DTS_INC} -i ${DTS_ARCH_INC} -I dts -O dtb \
+               ${DTC} -i ${DTS_EXTRA_INC} -i ${DTS_INC} -i ${DTS_ARCH_INC} -I dts -O dtb \
                    -p 1024 -b 0 -o ${DTS_DIR}/${d:C/dts$/dtb/}
 .endfor
% cd /usr/pkgsrc/sysutils/dtb-arm64-sun50i/work/linux-4.11.3/arch/arm64/boot/dts/allwinner
% cp /usr/src/sys/external/gpl2/dts/dist/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts .
% cp /usr/src/sys/external/gpl2/dts/dist/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi .
% ln -s /usr/src/sys/external/gpl2/dts/dist/arch/arm/boot/dts arm
% ln -s /usr/src/sys/external/gpl2/dts/dist/include/dt-bindings dt-bindings 
% make
  (snip)
cd /usr/pkgsrc/sysutils/dtb-arm64-sun50i/work/linux-4.11.3/arch/arm64/boot/dts &&  cpp -P -x assembler-with-cpp -I /usr/pkgsrc/sysutils/dtb-arm64-sun50i/work/linux-4.11.3/arch/arm64/boot/dts/allwinner -I /usr/pkgsrc/sysutils/dtb-arm64-sun50i/work/linux-4.11.3/include -I /usr/pkgsrc/sysutils/dtb-arm64-sun50i/work/linux-4.11.3/arch/arm64/boot/dts/include  -include /usr/pkgsrc/sysutils/dtb-arm64-sun50i/work/linux-4.11.3/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts /dev/null |  /usr/pkg/bin/dtc -i /usr/pkgsrc/sysutils/dtb-arm64-sun50i/work/linux-4.11.3/arch/arm64/boot/dts/allwinner -i /usr/pkgsrc/sysutils/dtb-arm64-sun50i/work/linux-4.11.3/include -i /usr/pkgsrc/sysutils/dtb-arm64-sun50i/work/linux-4.11.3/arch/arm64/boot/dts/include -I dts -O dtb  -p 1024 -b 0 -o /usr/pkgsrc/sysutils/dtb-arm64-sun50i/work/linux-4.11.3/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dtb
Warning (unit_address_vs_reg): Node /soc/pinctrl@01c20800/mmc0@0 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /soc/pinctrl@01c20800/mmc0_cd_pin@0 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /soc/pinctrl@01c20800/mmc1@0 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /soc/pinctrl@01c20800/spdif@0 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /soc/pinctrl@01c20800/uart0@0 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /soc/pinctrl@01f02c00/ir@0 has a unit name, but no reg property

[F] boot.scrの修正

  • armv7.imgに含まれるboot.scrはtegra用
  • ソースはboot.cmd
  • mkimage(mkubootimage)でboot.scrに変換
% mkimage -C none -A arm -T script -d boot.cmd boot.scr
Image Name:
Created:      Mon Dec  4 10:45:14 2017
Image Type:   ARM Linux Script (uncompressed)
Data Size:    888 Bytes = 0.87 KiB = 0.00 MiB
Load Address: 00000000
Entry Point:  00000000
Contents:
   Image 0: 880 Bytes = 0.86 KiB = 0.00 MiB

[F] 暫定版 boot.cmd for u-boot

  • UbuntuCoreから拝借、修正
  • まだ電源ONで自動起動はできない
setenv kernel netbsd-SUNXI.ub
setenv bootargs root=ld0a
setenv fdtfile sun50i-h5-nanopi-neo2.dtb
setenv env_addr 0x45000000
setenv kernel_addr 0x46000000
setenv dtb_addr 0x48000000
setenv fdt_addr 0x48000000
fatload mmc 0 ${kernel_addr} ${kernel}
fatload mmc 0 ${dtb_addr} sun50i-h5-nanopi-neo2.dtb
fdt addr ${dtb_addr}
fdt set ethernet0 local-mac-address ${mac_node}
fdt set mmc${boot_mmc} boot_device <1>
bootm ${kernel_addr} - ${fdt_addr_r}

[G] D,E,FをSDのMS-DOSパーティションに配置

  • MS-DOSパーティションを/bootにmountしていると仮定
% cd /boot
  • kernelの差し替え: 8.99.7
% gunzip < ~/NetBSD/src/obj/releasedir/evbarm/binary/kernel/netbsd-SUNXI.ub.gz \
   > ./netbsd-SUNXI.ub
  • Device Tree情報の配置
% cp somewhere/sun50i-h5-nanopi-neo2.dtb .
  • boot.scrを配置
% mkimage -C none -A arm -T script -d boot.cmd boot.scr

動いた!!

Starting kernel ...

[ Kernel symbol table missing! ]
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 8.99.7 (SUNXI) #3: Mon Nov 27 09:39:44 JST 2017
        root@trueos-610:/usr/home/mutoh/NetBSD/src/sys/arch/evbarm/compile/obj/SUNXI
total memory = 512 MB
avail memory = 479 MB

LED点滅ぐらいはできる

  • LEDの状態を知る
% sysctl hw.led
hw.led.nanopi_blue_status = 0
hw.led.nanopi_green_pwr = 1
  • 書き込みはrootで
% sudo sysctl -w hw.led.nanopi_blue_status=1
hw.led.nanopi_blue_status: 0 -> 1
  • 点滅させるには、こんな感じ
% while true
do
  sudo sysctl -w hw.led.nanopi_blue_status=0
  sleep 1
  sudo sysctl -w hw.led.nanopi_blue_status=1
  sleep 1
done

TODO

  • 自動起動しない…: boot.cmd修正
  • NetBSD for NanoPi Neo2 の動いてないところを調べる
    • Network Interface, CPU1個しか動いてない
    • 電源供給に使うUSBをucomとumassとして見せる
  • NanoHat: NanoPi用拡張シールド
    • OLEDになんか表示したい, I2C, GPIO接続
    • Hub: いろいろなセンサー類が繋がる

まだまだ他にも...

Q&Aなど

  • GPIO使った面白い応用無い
    • あったら、自分で作ってます(^-^;)
  • u-bootのpkgsrcのデフォルトを32MBにするsend-prしては?
    • 現状が何故8MBなのか分からないので、どないすべきですかねぇ

海外からの反応

Last modified: 2017-12-18
Post-it: New Post-it (help)

Text color: [_][_][_][_]

Background: [_][_][_][_][_][_]

Draw Line:

x: y: