Ever since I learned that NetBSD had announced that they were making ARM a Tier 1 Architecture, I have been following their development work. A few weeks ago on the NetBSD’s ARM developers mailing list, Jared McNeill stated “... the GENERIC64 kernel now supports the Amlogic S905 SoC used in the ODROID-C2 board. Ethernet, USB, and SD/eMMC are all working...”. I immediately obtained an image and started some testing. I want to report my findings and encourage others to try it out. It is not often that ODROID’s get a new non-Linux operating system.

$ uname -a NetBSD odroid-c2 8.99.37 NetBSD 8.99.37 (GENERIC64) #0: Sat Apr 6 17:42:28 UTC 2019 mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/evbarm/compile/GENERIC64 evbarm

In the couple of weeks I have been using it, even though currently it is a development image, it does appear to be stable. I have not had any problems with the Ethernet, USB or SD/eMMC. There is no frame buffer driver yet, so all interaction is done through the serial console or ssh. Recently, both Armv7 and Arm64 for NetBSD have been moved over to an EFI boot using the latest U-Boot and what looks like the U-Boot Driver Model (DM). There was a recent FOSDEM'19 U-Boot presentation and slides that cover some of these features.

https://video.fosdem.org/2019/K.4.401/hw_uboot.mp4https://fosdem.org/2019/schedule/event/hw_uboot/attachments/slides/3324/export/events/attachments/hw_uboot/slides/3324/Jagan_Teki___U_Boot_from_Scratch_v2019_01_edition_v2.pdf

Benny Siegert’s NetBSD Update at FOSDEM’19 https://video.fosdem.org/2019/K.3.401/netbsd_update.mp4

NetBSD Odroid-C2 U-Boot

=> version U-Boot 2019.04-rc1-00141-g63f7e3fca3 (Feb 15 2019 - 20:11:48 -0400) odroid-c2

=> dm tree Class Index Probed Driver Name ----------------------------------------------------------- root 0 [ + ] root_driver root_driver firmware 0 [ ] psci |-- psci clk 0 [ ] fixed_rate_clock |-- xtal-clk simple_bus 0 [ + ] generic_simple_bus |-- soc simple_bus 1 [ ] generic_simple_bus | |-- bus@c1100000 reset 0 [ ] meson_reset | | |-- reset-controller@4404 i2c 0 [ ] i2c_meson | | `-- i2c@8500 simple_bus 2 [ + ] generic_simple_bus | |-- bus@c8100000 simple_bus 3 [ ] generic_simple_bus | | |-- sys-ctrl@0 syscon 0 [ ] syscon | | |-- ao-secure@140 serial 0 [ + ] serial_meson | | |-- serial@4c0 pinctrl 0 [ + ] meson-gxbb-pinctrl | | `-- pinctrl@14 pinconfig 0 [ ] pinconfig | | |-- bank@14 pinconfig 1 [ ] pinconfig | | | `-- usb-hub pinconfig 2 [ + ] pinconfig | | |-- uart_ao_a pinconfig 3 [ ] pinconfig | | | `-- mux pinconfig 4 [ ] pinconfig | | |-- uart_ao_a_cts_rts pinconfig 5 [ ] pinconfig | | | `-- mux pinconfig 6 [ ] pinconfig | | |-- uart_ao_b pinconfig 7 [ ] pinconfig | | | `-- mux pinconfig 8 [ ] pinconfig | | |-- uart_ao_b_cts_rts pinconfig 9 [ ] pinconfig | | | `-- mux pinconfig 10 [ ] pinconfig | | |-- remote_input_ao pinconfig 11 [ ] pinconfig | | | `-- mux pinconfig 12 [ ] pinconfig | | |-- i2c_ao pinconfig 13 [ ] pinconfig | | | `-- mux pinconfig 14 [ ] pinconfig | | |-- pwm_ao_a_3 pinconfig 15 [ ] pinconfig | | | `-- mux pinconfig 16 [ ] pinconfig | | |-- pwm_ao_a_6 pinconfig 17 [ ] pinconfig | | | `-- mux pinconfig 18 [ ] pinconfig | | |-- pwm_ao_a_12 pinconfig 19 [ ] pinconfig | | | `-- mux pinconfig 20 [ ] pinconfig | | |-- pwm_ao_b pinconfig 21 [ ] pinconfig | | | `-- mux pinconfig 22 [ ] pinconfig | | |-- i2s_am_clk pinconfig 23 [ ] pinconfig | | | `-- mux pinconfig 24 [ ] pinconfig | | |-- i2s_out_ao_clk pinconfig 25 [ ] pinconfig | | | `-- mux pinconfig 26 [ ] pinconfig | | |-- i2s_out_lr_clk pinconfig 27 [ ] pinconfig | | | `-- mux pinconfig 28 [ ] pinconfig | | |-- i2s_out_ch01_ao pinconfig 29 [ ] pinconfig | | | `-- mux pinconfig 30 [ ] pinconfig | | |-- i2s_out_ch23_ao pinconfig 31 [ ] pinconfig | | | `-- mux pinconfig 32 [ ] pinconfig | | |-- i2s_out_ch45_ao pinconfig 33 [ ] pinconfig | | | `-- mux pinconfig 34 [ ] pinconfig | | |-- spdif_out_ao_6 pinconfig 35 [ ] pinconfig | | | `-- mux pinconfig 36 [ ] pinconfig | | |-- spdif_out_ao_13 pinconfig 37 [ ] pinconfig | | | `-- mux pinconfig 38 [ ] pinconfig | | |-- ao_cec pinconfig 39 [ ] pinconfig | | | `-- mux pinconfig 40 [ ] pinconfig | | |-- ee_cec pinconfig 41 [ ] pinconfig | | | `-- mux gpio 0 [ ] meson-gx-gpio | | `-- meson-gpio simple_bus 4 [ + ] generic_simple_bus | |-- periphs@c8834000 pinctrl 1 [ + ] meson-gxbb-pinctrl | | `-- pinctrl@4b0 pinconfig 42 [ ] pinconfig | | |-- bank@4b0 pinconfig 43 [ + ] pinconfig | | |-- emmc pinconfig 44 [ ] pinconfig | | | `-- mux pinconfig 45 [ + ] pinconfig | | |-- emmc-ds pinconfig 46 [ ] pinconfig | | | `-- mux pinconfig 47 [ ] pinconfig | | |-- emmc_clk_gate pinconfig 48 [ ] pinconfig | | | |-- mux pinconfig 49 [ ] pinconfig | | | `-- cfg-pull-down pinconfig 50 [ ] pinconfig | | |-- nor pinconfig 51 [ ] pinconfig | | | `-- mux pinconfig 52 [ ] pinconfig | | |-- spi-pins pinconfig 53 [ ] pinconfig | | | `-- mux pinconfig 54 [ ] pinconfig | | |-- spi-ss0 pinconfig 55 [ ] pinconfig | | | `-- mux pinconfig 56 [ + ] pinconfig | | |-- sdcard pinconfig 57 [ ] pinconfig | | | `-- mux pinconfig 58 [ ] pinconfig | | |-- sdcard_clk_gate pinconfig 59 [ ] pinconfig | | | |-- mux pinconfig 60 [ ] pinconfig | | | `-- cfg-pull-down pinconfig 61 [ ] pinconfig | | |-- sdio pinconfig 62 [ ] pinconfig | | | `-- mux pinconfig 63 [ ] pinconfig | | |-- sdio_clk_gate pinconfig 64 [ ] pinconfig | | | |-- mux pinconfig 65 [ ] pinconfig | | | `-- cfg-pull-down pinconfig 66 [ ] pinconfig | | |-- sdio_irq pinconfig 67 [ ] pinconfig | | | `-- mux pinconfig 68 [ ] pinconfig | | |-- uart_a pinconfig 69 [ ] pinconfig | | | `-- mux pinconfig 70 [ ] pinconfig | | |-- uart_a_cts_rts pinconfig 71 [ ] pinconfig | | | `-- mux pinconfig 72 [ ] pinconfig | | |-- uart_b pinconfig 73 [ ] pinconfig | | | `-- mux pinconfig 74 [ ] pinconfig | | |-- uart_b_cts_rts pinconfig 75 [ ] pinconfig | | | `-- mux pinconfig 76 [ ] pinconfig | | |-- uart_c pinconfig 77 [ ] pinconfig | | | `-- mux pinconfig 78 [ ] pinconfig | | |-- uart_c_cts_rts pinconfig 79 [ ] pinconfig | | | `-- mux pinconfig 80 [ ] pinconfig | | |-- i2c_a pinconfig 81 [ ] pinconfig | | | `-- mux pinconfig 82 [ ] pinconfig | | |-- i2c_b pinconfig 83 [ ] pinconfig | | | `-- mux pinconfig 84 [ ] pinconfig | | |-- i2c_c pinconfig 85 [ ] pinconfig | | | `-- mux pinconfig 86 [ + ] pinconfig | | |-- eth-rgmii pinconfig 87 [ ] pinconfig | | | `-- mux pinconfig 88 [ ] pinconfig | | |-- eth-rmii pinconfig 89 [ ] pinconfig | | | `-- mux pinconfig 90 [ ] pinconfig | | |-- pwm_a_x pinconfig 91 [ ] pinconfig | | | `-- mux pinconfig 92 [ ] pinconfig | | |-- pwm_a_y pinconfig 93 [ ] pinconfig | | | `-- mux pinconfig 94 [ ] pinconfig | | |-- pwm_b pinconfig 95 [ ] pinconfig | | | `-- mux pinconfig 96 [ ] pinconfig | | |-- pwm_d pinconfig 97 [ ] pinconfig | | | `-- mux pinconfig 98 [ ] pinconfig | | |-- pwm_e pinconfig 99 [ ] pinconfig | | | `-- mux pinconfig 100 [ ] pinconfig | | |-- pwm_f_x pinconfig 101 [ ] pinconfig | | | `-- mux pinconfig 102 [ ] pinconfig | | |-- pwm_f_y pinconfig 103 [ ] pinconfig | | | `-- mux pinconfig 104 [ ] pinconfig | | |-- hdmi_hpd pinconfig 105 [ ] pinconfig | | | `-- mux pinconfig 106 [ ] pinconfig | | |-- hdmi_i2c pinconfig 107 [ ] pinconfig | | | `-- mux pinconfig 108 [ ] pinconfig | | |-- i2sout_ch23_y pinconfig 109 [ ] pinconfig | | | `-- mux pinconfig 110 [ ] pinconfig | | |-- i2sout_ch45_y pinconfig 111 [ ] pinconfig | | | `-- mux pinconfig 112 [ ] pinconfig | | |-- i2sout_ch67_y pinconfig 113 [ ] pinconfig | | | `-- mux pinconfig 114 [ ] pinconfig | | |-- spdif_out_y pinconfig 115 [ ] pinconfig | | | `-- mux gpio 1 [ + ] meson-gx-gpio | | `-- meson-gpio simple_bus 5 [ ] generic_simple_bus | |-- bus@c8838000 simple_bus 6 [ + ] generic_simple_bus | |-- bus@c883c000 simple_bus 7 [ + ] generic_simple_bus | | `-- system-controller@0 clk 1 [ + ] meson_clk | | |-- clock-controller syscon 1 [ + ] syscon | | `-- system-controller@0 clk 2 [ ] meson_clk | | `-- clock-controller eth 0 [ + ] eth_designware | |-- ethernet@c9410000 simple_bus 8 [ + ] generic_simple_bus | `-- apb@d0000000 mmc 0 [ + ] meson_gx_mmc | |-- mmc@72000 blk 0 [ ] mmc_blk | | `-- mmc@72000.blk mmc 1 [ + ] meson_gx_mmc | `-- mmc@74000 blk 1 [ ] mmc_blk | `-- mmc@74000.blk regulator 0 [ ] fixed regulator |-- regulator-usb-pwrs regulator 1 [ ] fixed regulator |-- regulator-tflash_vdd regulator 2 [ ] fixed regulator |-- regulator-vcc1v8 regulator 3 [ ] fixed regulator `-- regulator-vcc3v3

In further testing I found Hardkernel’s WiFi module 3 works well and module 0 is recognized but has an issue connecting. I have not spent much time trying to debug the issue. I do not have Module 4 to try and Modules 5 and 5a were not recognized. I suspect it is because there are no kernel drivers for them. There are some basic test results for LAN, WiFI, eMMC and USB posted on the Hardkernel Forum thread https://forum.odroid.com/viewtopic.php?f=138&t=34457

NetBSD Loading and Basic Configuration

For anyone that might want to try NetBSD on an ODROID-C2, here is a basic setup and configuration guide. You must have a serial console to initially bring this image up. This is not a Release image so Current images can only be found at the NetBSD Arm Current server. There is also an ODROID-XU4 and ODROID-C1+ image there. The ODROID-XU4 image is not usable at this time. The ODROID-C2 image will work with an SD-card or eMMC. On the first boot it will automatically resize the root filesystem and then reboot. http://www.invisible.ca/arm/

Uncompress and write image using dd, or use another application like etcher.io or Win32DiskImager:

$ gzip -d NetBSD-evbarm-aarch64-201904061750Z-odroidc2.img.gz $ dd if=./NetBSD-evbarm-aarch64-201904061750Z-odroidc2.img of=/dev/< your card reader location > e.g. sdb $ sync

$ passwd

$ vi /etc/rc.conf $ hostname=< your hostname >

$ useradd -m -G wheel < username > $ passwd < username >

$ echo "export LANG=\"en_US.UTF-8\"" >> /etc/profile $ echo "export LC_CTYPE=\"en_US.UTF-8\"" >> /etc/profile $ echo "export LC_ALL=\"\"" >> /etc/profile

Application Software loading

Once booted, root does not have a password. To set a password:To change the host name:To add a user – default directory is /home/< username >Set system-wide locale settings as appropriate for your location

Since this is a development snapshot there is not a complete user world. It is a bare bones OS image. Also there is not a complete listing of application binaries available so, I will cover installing binaries(pkg_add), compiling from source (pkgsrc) and updating with complete tar sets.

Fetching Binary Packages for Current Aarch64

The binaries are coming from a non-release server and require a slight alteration from normal practices.

$ export PKG_PATH="http://www.invisible.ca/arm/packages/arm64/current" $ pkg_add -v < package name >

Fetching pkgsrc from CVS (source code)

Using a web browser on another machine you can also look at what is available. Packages are being added as they are compiled so check regularly if you’re not planning to compile from source. http://www.invisible.ca/arm/packages/arm64/current

The complete user world is approximately 3.7GB so make sure you have enough room. Applications are grouped by functionality so take a minute to familiarize yourself with the layout after checkout.

$ cd /usr $ cvs -d anoncvs@anoncvs.netbsd.org:/cvsroot checkout -P pkgsrc

$ cd /usr/pkgsrc/< group directory >/< app name > $ make install

$ unset PKG_PATH

Using tar sets

To compile a specific applicationAll dependencies will be compiled for the application and will even be downloaded if necessary so make sure you leave your Internet connection up during this process. I compiled many packages with no problems. If you have set PKG_PATH previously you must unset it before using pkgsrc or it will remind you.

You can use tar sets to update to the latest Current kernel and user world. For development snapshots it is recommended that when you update your kernel and update the world.

Update kernel

$ mkdir -p /root/tmp/kernel $ cd /root/tmp/kernel $ cp /netbsd /onetbsd $ ftp $ https://nyftp.netbsd.org/pub/NetBSD-daily/HEAD/latest/evbarm-aarch64/binary/sets/kern-GENERIC64.tgz $ tar xzvf /root/tmp/kernel/kern-GENERIC64.tgz $ cp ./netbsd /netbsd $ cp meson-gxbb-odroidc2.dtb /boot/dtb/amlogic/ $ reboot

$ mkdir -p /root/tmp/sets $ cd /root/tmp/sets $ for x in base comp games man misc modules tests text xbase xcomp xfont xserver; do ftp https://nyftp.netbsd.org/pub/NetBSD-daily/HEAD/latest/evbarm-aarch64/binary/sets/$x.tgz; done $ for x in base comp games man misc modules tests text xbase xcomp xfont xserver; do tar -C / -zxvpf $x.tgz; done

$ for x in etc xetc; do ftp https://nyftp.netbsd.org/pub/NetBSD-daily/HEAD/latest/evbarm-aarch64/binary/sets/$x.tgz; done $ etcupdate -s etc.tgz -s xetc.tgz $ rm -Rf /root/tmp $ reboot

Example with sudo

Update world except for /etcUpdate /etc/ configuration

One of the typical applications you might choose to load is sudo. Here are examples using the Current binaries repository and pkgsrc.

Fetching sudo binary from current

$ export PKG_PATH="http://www.invisible.ca/arm/packages/arm64/current" $ pkg_add -v sudo

$ unset PKG_PATH $ cd /usr/pkgsrc/security/sudo $ make install

$ groupadd sudo $ usermod -G sudo < username > $ visudo $ %sudo ALL=(ALL) ALL

$ pkg_add -uv sudo

$ pkg_add -fuuv sudo

Notes

Compiling sudo from pkgsrc. Note: This assumes that you downloaded pkgsrc as described aboveRegardless of the installation method you must configure sudo to work. Using visudo as illustrated below, uncomment line 88 to allow members of group sudo to execute any command and or one of the other options like members of group wheel (line 82)Future updating of applications Updating sudo binary package from Current:Updating sudo and all of its dependencies:

Some packages will require additional configuration and they will usually tell you at installation time. Many times examples are provided such as the dbus installation example illustrated below:

$ cp /usr/pkg/share/examples/rc.d/dbus /etc/rc.d/

$ pkg_add -v mozilla-rootcerts openssl mozilla-rootcerts-openssl

$ pkg_add -v bash htop zip p7zip gzip dos2unix

WiFI Setup

If you’re going to load and use git, curl or wget remember to load CA root certificates.Other typical apps that can be loaded using pkg_add

Find the device name using ifconfig. If it is not listed, then there is probably no kernel driver; check dmesg.

$ ifconfig -a

$ vi /etc/wpa_supplicant.conf ctrl_interface=/var/run/wpa_supplicant ctrl_interface_group=wheel network={ ssid=< network name > scan_ssid=1 key_mgmt=WPA-PSK psk=< passwordkey > }

$ vi /etc/rc.conf wpa_supplicant=YES wpa_supplicant_flags="-i < device name > -c /etc/wpa_supplicant.conf"

$ chmod 600 /etc/wpa_supplicant.conf $ /etc/rc.d/wpa_supplicant start

$ wpa_supplicant -Bd -c /path/to/wpa-supplicant.conf -i < device name >

Edit wpa_supplicant and add appropriate entriesEnable at boot upStart WiFi serviceor for debuggingAdding "-f file" will send debugging messages (from using -d) to file.

One last note: this is a development image so, it is not for production. Like I said earlier I have not had any issues...until today when I pulled a fresh release with a new kernel. I had my first segmentation fault but the OS was still operational. It might make sense to hold the previous release for these occasions. I'm sure there will be more issues as development progresses. I want to take a minute and send a big thank you to the NetBSD Foundation, their development team and especially Jared McNeill. Let’s help support their wonderful work on bringing NetBSD to ARM and Hardkernel ODROIDs!

References

NetBSD Project https://www.netbsd.org/ NetBSD Guide https://www.netbsd.org/docs/guide/en/index.html NetBSD pkgsrc guide http://www.netbsd.org/docs/pkgsrc/index.html NetBSD pkgsrc browser http://pkgsrc.se/ NetBSD Mailing List https://www.netbsd.org/mailinglists/#port-arm NetBSD Arm Bootable Images http://www.invisible.ca/arm/ NetBSD Index of Arm64 Current http://www.invisible.ca/arm/packages/arm64/current/