FreeBSD 14.4 on NanoPi NEO 512: Enabling NAS Dock v1.2 features including the DS1307 RTC
System
- Board: NanoPi NEO (Allwinner H3, 512 MB RAM)
- NAS board: FriendlyElec NAS Dock v1.2
- Operating System: FreeBSD 14.4-RELEASE-p6
- Boot loader: U-Boot
- Kernel: GENERIC or custom NANOPI
Project Goal
Enable the onboard hardware provided by the NanoPi NAS Dock v1.2 under FreeBSD.This includes:
- USB Host Port 1
- USB Host Port 2
- SSD connected through the NAS Dock
- I²C0 bus
- I²C1 bus
- SPI0 bus
- Dallas DS1307 Real-Time Clock connected through I²C
STEP 1 — Enable Device Tree Overlays
The overlay files are located in:/boot/dtb/overlays/
Edit:
ee /boot/loader.conf
Add:
fdt_overlays="sun8i-h3-i2c0.dtbo,sun8i-h3-i2c1.dtbo,sun8i-h3-spi0.dtbo,sun8i-h3-usb1.dtbo,sun8i-h3-usb2.dtbo"
Reboot:
shutdown -r now
During boot, U-Boot should report:
Loading DTB overlays:
sun8i-h3-i2c0.dtbo
sun8i-h3-i2c1.dtbo
sun8i-h3-spi0.dtbo
sun8i-h3-usb1.dtbo
sun8i-h3-usb2.dtbo
After reboot, the following controllers should be available:
- I²C0
- I²C1
- SPI0
- USB1
- USB2
STEP 2 — Add Support for the Onboard DS1307 RTC
Create a custom Device Tree overlay for the DS1307 RTC.Create:
ee /boot/dtb/overlays/sun8i-h3-ds1307.dtso
Content:
/dts-v1/;
/plugin/;
/ {
compatible = "allwinner,sun8i-h3";
fragment@0 {
target = <&i2c0>;
__overlay__ {
status = "okay";
rtc@68 {
compatible = "dallas,ds1307";
reg = <0x68>;
};
};
};
};
Compile:
dtc -@ -I dts -O dtb \
-o /boot/dtb/overlays/sun8i-h3-ds1307.dtbo \
/boot/dtb/overlays/sun8i-h3-ds1307.dtso
Add the new overlay to /boot/loader.conf:
fdt_overlays="sun8i-h3-i2c0.dtbo,sun8i-h3-i2c1.dtbo,sun8i-h3-spi0.dtbo,sun8i-h3-usb1.dtbo,sun8i-h3-usb2.dtbo,sun8i-h3-ds1307.dtbo"
reboot:
shutdown -r now
Verify:
dmesg | grep -Ei "rtc|ds1307|iic|i2c"
Expected result:
ds13070: <Dallas DS1307> at addr 0xd0 on iicbus0
ds13070: registered as a time-of-day clock, resolution 1.000000s
Note:
The overlay uses address 0x68. FreeBSD reports 0xd0. This is expected: 0x68 is the 7-bit I²C address, while 0xd0 is the 8-bit form.
If the RTC was never initialized before, FreeBSD may report:
ds13070: WARNING: RTC clock stopped, check the battery.
This is normal on first use. After setting a valid time, the warning should disappear.
Initialize the DS1307 using the current system time:
date `date "+%Y%m%d%H%M.%S"`
Reboot:
shutdown -r now
Verify again:
dmesg | grep -Ei "rtc|ds1307"
date
Expected result:
rtc0: <Allwinner RTC>
rtc0: registered as a time-of-day clock
ds13070: <Dallas DS1307> at addr 0xd0 on iicbus0
ds13070: registered as a time-of-day clock
Sat Jul 4 08:31:29 IST 2026
At this point, the DS1307 is detected and initialized.
STEP 3 — Prioritize the DS1307 RTC
Verify that the DS1307 stores the correct time:i2c -a 0x68 -d r -o 0 -c 8 -v
The DS1307 returns time registers in BCD format:
SS MM HH DW DD MM YY CTRL
Example:
59 41 08 06 04 07 26 03
Decoded:
2026-07-04 08:41:59
FreeBSD registers both RTC devices as time-of-day clocks:
rtc0: registered as a time-of-day clock, resolution 1.000000s
ds13070: registered as a time-of-day clock, resolution 1.000000s
The RTC framework in:
/usr/src/sys/kern/subr_rtc.c
Contains:
/*
* Registered clocks are kept in a list which is sorted by resolution;
* the more accurate clocks get the first shot at providing the time.
*/
Because both RTC devices have the same resolution, the internal Allwinner RTC is used first. It returns the default 2010 date, so the DS1307 is not used during boot.
Do not disable the internal Allwinner RTC in Device Tree. It also provides clock sources required by the SoC.
Instead, edit:
ee /usr/src/sys/dev/iicbus/rtc/ds1307.c
Replace:
clock_register_flags(dev, 1000000, CLOCKF_SETTIME_NO_ADJ);
with:
clock_register_flags(dev, 500000, CLOCKF_SETTIME_NO_ADJ);
This gives the DS1307 a higher priority than the internal Allwinner RTC.
Before building the kernel, make sure the system time is correct:
date
If needed, set it manually:
date YYYYMMDDHHMM.SS
Build and install the kernel:
cd /usr/src
make buildkernel KERNCONF=GENERIC
make installkernel KERNCONF=GENERIC
Or, for a custom kernel:
cd /usr/src
make buildkernel KERNCONF=NANOPI
make installkernel KERNCONF=NANOPI
Reboot:
shutdown -r now
Verify:
dmesg | grep -Ei "rtc|ds1307"
Expected result:
rtc0: registered as a time-of-day clock, resolution 1.000000s
ds13070: registered as a time-of-day clock, resolution 0.500000s
This confirms that DS1307 now has higher priority.
STEP 4 — Verify Cold Boot without NTP
Disable NTP temporarily:sysrc ntpd_enable="NO"
service ntpd stop
Power off the system:
shutdown -p now
Disconnect power from the NAS Dock.
Wait at least 5 minutes.
Reconnect power and boot the system.
Check the date:
date
Check that NTP is still not running:
service ntpd status
Expected result:
Sat Jul 4 12:19:24 IST 2026
ntpd is not running.
This confirms that FreeBSD initialized the system clock from the onboard DS1307 RTC, without network time synchronization.
Re-enable NTP:
sysrc ntpd_enable="YES"
service ntpd start
Result
- USB Host Port 1 works with JMicron External Disk 3.0 controler.
- USB Host Port 2 works.
- SSD connected through the NAS Dock works.
- I²C0 works.
- I²C1 works.
- SPI0 works.
- The onboard DS1307 RTC is detected.
- The DS1307 stores valid time.
- FreeBSD boots with correct time from DS1307 without NTP.