NetBSD For The ODROID-C2

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

Figure 1 - htop running on NetBSD

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
Once booted, root does not have a password. To set a password:
$ passwd
To change the host name:
$ vi /etc/rc.conf
$ hostname=< your hostname >
To add a user – default directory is /home/< username >
$ useradd -m -G wheel < username >
$ passwd < username >
Set system-wide locale settings as appropriate for your location
$ 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

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 >
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

Fetching pkgsrc from CVS (source code)

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
To compile a specific application
$ cd /usr/pkgsrc/< group directory >/< app name >
$ make install
All 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.
$ unset PKG_PATH

Using tar sets

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
Update world except for /etc
$ 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
Update /etc/ configuration
$ 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

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
Compiling sudo from pkgsrc. Note: This assumes that you downloaded pkgsrc as described above
$ unset PKG_PATH
$ cd /usr/pkgsrc/security/sudo
$ make install
Regardless 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)
$ groupadd sudo
$ usermod -G sudo < username >
$ visudo
$ %sudo ALL=(ALL) ALL
Future updating of applications Updating sudo binary package from Current:
$ pkg_add -uv sudo
Updating sudo and all of its dependencies:
$ pkg_add -fuuv sudo

Notes

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/
If you’re going to load and use git, curl or wget remember to load CA root certificates.
$ pkg_add -v mozilla-rootcerts openssl mozilla-rootcerts-openssl
Other typical apps that can be loaded using pkg_add
$ pkg_add -v bash htop zip p7zip gzip dos2unix

WiFI Setup

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

$ ifconfig -a
Edit wpa_supplicant and add appropriate entries
$ 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 >
}
Enable at boot up
$ vi /etc/rc.conf
wpa_supplicant=YES
wpa_supplicant_flags="-i < device name > -c /etc/wpa_supplicant.conf"
Start WiFi service
$ chmod 600 /etc/wpa_supplicant.conf
$ /etc/rc.d/wpa_supplicant start
or for debugging
$ wpa_supplicant -Bd -c /path/to/wpa-supplicant.conf -i < device name >
Adding "-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/

Be the first to comment

Leave a Reply