Kenyon Ralph/

Time server

Edit

RecentChanges

History

Source

Preferences

This page documents my project to build a stratum 1 NTP time server at my house. Its hostname is einstein.kenyonralph.com and it is part of the NTP pool.

GPS selection

Cable Construction

GPS preparation

Debian GNU/Linux setup

FreeBSD setup

/etc/rc.conf

/etc/devfs.conf

/etc/ttys

Kernel configuration

/etc/make.conf

/etc/ntp.conf

Example output

Conclusion

Notes

References

GPS selection

I selected the Garmin GPS 18x LVC for the following reasons:

Plenty of documentation exists by people who have used this unit as an NTP timing source.

The receiver and antenna are integrated into one enclosure.

Minimal assembly and soldering necessary, compared to bare-board receivers.

Available on Amazon for a decent price.

I ordered the 18x (and a serial cable) on Amazon on 2011-09-05. UPS delivered it on 2011-09-09.

Cable Construction

I simply spliced the GPS 18x LVC wires onto serial and USB wires. This matches what's documented in Garmin's GPS 18x LVC Technical Specifications.

GPS preparation

I used a Windows Vista computer with Garmin's SNSRXCFG_270.exe to upgrade the firmware from version 3.60 to the latest, 3.70. I also used SNSRXCFG_270.exe to set the PPS pulse width to 200 ms, and disable all NMEA sentences except GPGGA.

Debian GNU/Linux setup

Here are the steps in summary (written for Debian wheezy in February 2015):

Install pps-tools

Create udev rules

Build a customized ntp package which enables debugging and builds against the timepps.h header installed by pps-tools (there is no PPS support in the current Debian package of NTP, but there is a bug report requesting that it be built-in)

Build a custom kernel which enables CONFIG_NTP_PPS (make all -j8 && make deb-pkg in kernel source tree)

Some details:

When you do sudo ldattach PPS /dev/ttyS0, the PPS modules will be loaded automatically and the device /dev/pps0 will be created. Place some udev rules in /etc/udev/rules.d/77-local.rules to create device symlinks and run ldattach automatically:

SUBSYSTEM=="pps", MODE="0664" GROUP="dialout"
KERNEL=="ttyS0" SYMLINK+="gps0"
KERNEL=="ttyS0", RUN+="/usr/sbin/ldattach pps /dev/%k"
KERNEL=="pps0" SYMLINK+="gpspps0"

Here is my working ntp.conf:

rlimit memlock 128
driftfile /var/lib/ntp/ntp.drift
restrict localhost
restrict default limited kod noquery
server darwin.kenyonralph.com iburst
pool 2.us.pool.ntp.org iburst
server 127.127.20.0 mode 16 minpoll 3 iburst
fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 0.545
leapfile /etc/ntp/leap-seconds.list

Example output after letting ntpd run for about 8 hours:

kenyon@einstein ~ % ntpq -ccv -p -crv -ckern -csysinfo
associd=0 status=0000 no events, clk_unspec,
device="NMEA GPS Clock",
timecode="$GPGGA,172617,1111.3839,N,11111.4417,W,2,11,0.8,126.3,M,-35.5,M,,*71",
poll=3418, noreply=0, badformat=0, baddata=0, fudgetime2=545.000,
stratum=0, refid=GPS, flags=5
remote refid st t when poll reach delay offset jitter
==============================================================================
2.us.pool.ntp.o .POOL. 16 p - 64 0 0.000 0.000 0.000
oGPS_NMEA(0) .GPS. 0 l - 8 377 0.000 0.000 0.004
+darwin.kenyonra 127.67.113.92 2 u 50 64 377 28.478 4.232 0.953
-2001:470:c:4a1: 131.188.3.220 2 u 45 64 377 200.027 11.259 0.586
-2604:a880:800:1 184.105.182.7 3 u 39 64 377 82.776 4.196 1.805
-ntp.jtsage.com 216.218.254.202 2 u 24 64 377 69.561 -1.286 0.490
-2604:a880:800:1 184.105.182.7 3 u 46 64 377 82.421 3.827 0.603
*yurizoku.tk 209.51.161.238 2 u 59 64 377 80.916 1.554 0.619
+198.110.48.12 ( 204.9.54.119 2 u 35 64 377 100.437 1.796 1.330
-108.61.194.85 ( 201.198.247.252 2 u 53 64 377 45.230 -5.521 1.041
associd=0 status=041d leap_none, sync_uhf_radio, 1 event, kern,
version="ntpd [email-masked] Mon Feb 9 09:59:02 UTC 2015 (1)",
processor="x86_64", system="Linux/3.16.7-ckt2", leap=00, stratum=1,
precision=-23, rootdelay=0.000, rootdisp=1.015, refid=GPS,
reftime=d884bdb9.bc1f69e3 Tue, Feb 10 2015 9:26:17.734,
clock=d884bdba.e1639551 Tue, Feb 10 2015 9:26:18.880, peer=27173, tc=3,
mintc=3, offset=-0.000130, frequency=-13.457, sys_jitter=0.004033,
clk_jitter=0.051, clk_wander=0.031, tai=35, leapsec=201507010000,
expire=201512280000
associd=0 status=041d leap_none, sync_uhf_radio, 1 event, kern,
pll offset: 0
pll frequency: -13.4565
maximum error: 0.0015
estimated error: 3.4e-05
kernel status: pll ppsfreq ppstime ppssignal nano
pll time constant: 3
precision: 1e-06
frequency tolerance: 500
pps frequency: -13.4874
pps stability: 0.280609
pps jitter: 0.050
calibration interval 256
calibration cycles: 152
jitter exceeded: 45
stability exceeded: 2
calibration errors: 0
associd=0 status=041d leap_none, sync_uhf_radio, 1 event, kern,
system peer: GPS_NMEA(0)
system peer mode: client
leap indicator: 00
stratum: 1
log2 precision: -23
root delay: 0.000
root dispersion: 1.015
reference ID: GPS
reference time: d884bdb9.bc1f69e3 Tue, Feb 10 2015 9:26:17.734
system jitter: 0.004033
clock jitter: 0.051
clock wander: 0.031
broadcast delay: 0.000
symm. auth. delay: 0.000

I also tried setting up a time server with FreeBSD to see if it's any easier or better.

FreeBSD setup

This section was written in October 2011. I no longer run this FreeBSD system. I'm running the NTP server on the Linux machine described above.

I am using ntp-devel from ports.

/etc/rc.conf

ntpd_enable="YES"
ntpd_flags="-N -p /var/run/ntpd.pid -f /var/db/ntpd.drift"
ntpd_program="/usr/local/sbin/ntpd"
ntpd_sync_on_start="YES"

/etc/devfs.conf

link cuau0 gps0

/etc/ttys

Commented out ttyu*.

Kernel configuration

Put this in /usr/src/sys/amd64/conf/PPS-GENERIC:

#
# PPS -- Generic kernel configuration file for FreeBSD/amd64 PPS
#
include GENERIC
ident PPS-GENERIC
options PPS_SYNC

/etc/make.conf

KERNCONF= PPS-GENERIC GENERIC

/etc/ntp.conf

server 127.127.20.0 minpoll 3
fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 0.600
server darwin.kenyonralph.com iburst
server voodoo.kenyonralph.com iburst
server grunt.kenyonralph.com iburst
pool 2.us.pool.ntp.org iburst

Example output

Example output after running for a few minutes and while doing buildworld and buildkernel:

kenyon@gauss ~ % ntpq -p -c clockvar -c readvar; ntpdc -c kerninfo
remote refid st t when poll reach delay offset jitter
==============================================================================
oGPS_NMEA(0) .GPS. 0 l 38 64 377 0.000 0.648 0.249
2.us.pool.ntp.o .POOL. 16 p - 64 0 0.000 0.000 0.002
*darwin.kenyonra 127.67.113.92 2 u 63 64 377 20.431 3.263 3.354
-voodoo.kenyonra 106.61.18.129 3 u 61 64 377 0.243 4.485 0.124
+grunt.kenyonral 106.61.18.129 3 u 64 64 377 0.182 3.521 0.225
-conquest.kjsl.c 69.36.224.15 2 u 62 64 377 26.374 5.768 2.522
-bindcat.fhsu.ed 128.138.140.44 2 u 63 64 377 75.219 4.115 1.846
-peachesgeldof.k 204.9.54.119 2 u 64 64 377 94.141 3.787 2.844
-ip-173-201-38-8 198.153.152.52 2 u 58 64 377 24.752 6.104 1.801
-druid.storyinme 130.207.244.240 2 u 56 64 377 65.657 -2.773 4.542
+cheezum.mattnor 129.7.1.66 2 u 65 64 377 45.797 2.972 2.286
associd=0 status=0000 no events, clk_unspec,
device="NMEA GPS Clock",
timecode="$GPGGA,085740,1111.1111,N,11111.1111,W,1,09,0.9,103.2,M,-35.3,M,,*77",
poll=14, noreply=0, badformat=0, baddata=0, fudgetime2=600.000,
stratum=0, refid=GPS, flags=5
associd=0 status=04ad leap_none, sync_uhf_radio, 10 events, kern,
version="ntpd [email-masked] Fri Oct 21 04:59:50 UTC 2011 (1)",
processor="amd64", system="FreeBSD/9.0-RC1", leap=00, stratum=1,
precision=-19, rootdelay=0.000, rootdisp=2.380, refid=GPS,
reftime=d24d03df.edabdc26 Sat, Oct 22 2011 1:57:03.928,
clock=d24d0405.3f696dad Sat, Oct 22 2011 1:57:41.247, peer=38673, tc=6,
mintc=3, offset=0.648, frequency=-4.048, sys_jitter=0.249,
clk_jitter=0.000, clk_wander=0.005
pll offset: 0.000624065 s
pll frequency: -4.048 ppm
maximum error: 2.0824e-05 s
estimated error: 1.7e-08 s
status: 2007 pll ppsfreq ppstime nano
pll time constant: 6
precision: 1e-09 s
frequency tolerance: 496 ppm
kenyon@gauss ~ % ntpq -c "rv 38673"
associd=38673 status=973a conf, reach, sel_pps.peer, 3 events, sys_peer,
srcadr=GPS_NMEA(0), srcport=123, dstadr=127.0.0.1, dstport=123, leap=00,
stratum=0, precision=-20, rootdelay=0.000, rootdisp=0.000, refid=GPS,
reftime=d24d03de.ffd6d0b6 Sat, Oct 22 2011 1:57:02.999,
rec=d24d03df.edabdc26 Sat, Oct 22 2011 1:57:03.928, reach=377,
unreach=0, hmode=3, pmode=4, hpoll=6, ppoll=6, headway=0, flash=00 ok,
keyid=0, offset=0.648, delay=0.000, dispersion=0.928, jitter=0.249,
filtdelay= 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00,
filtoffset= 0.65 0.70 0.76 0.80 0.86 0.91 0.99 1.06,
filtdisp= 0.00 0.96 1.92 2.88 3.84 4.80 5.76 6.72

Here is what kerninfo looks like with the PPS_SYNC kernel option:

pll offset: 0.000123674 s
pll frequency: -3.918 ppm
maximum error: 0.000111415 s
estimated error: 1.51e-07 s
status: 2107 pll ppsfreq ppstime ppssignal nano
pll time constant: 6
precision: 1e-09 s
frequency tolerance: 496 ppm
pps frequency: -3.918 ppm
pps stability: 0.033 ppm
pps jitter: 4.729e-06 s
calibration interval: 64 s
calibration cycles: 27
jitter exceeded: 5
stability exceeded: 0
calibration errors: 10

Conclusion

FreeBSD is much nicer than Linux (as of late 2011) at being a stratum 1 NTP server using a NMEA GPS with PPS reference clock.

As of early 2015, I would say it's about an equal amount of effort between FreeBSD and Debian Linux. Debian Linux is a little more effort if you want to create a proper Debian package of NTP, but since I've already done that, you don't have to. You may use the NTP package from my Debian repository by adding the following line to your sources.list:

deb http://kenyonralph.com/repo/ wheezy/

Notes

Show serial port settings:

Linux: stty --all --file=/dev/ttyS0

FreeBSD: stty -a -f /dev/cuau0

Set serial port baud rate to 4800:

Linux: stty --file=/dev/ttyS0 4800

FreeBSD (but not really necessary since cu can do it, and doesn't seem to take effect anyway): stty -f /dev/cuau0 4800

Observe NMEA output:

Linux: cat /dev/ttyS0

FreeBSD: cu -l /dev/cuau0 -s 4800

References

NTP documentation: Reference Clock Support

NTP support wiki: Configuring Garmin Refclocks

NTP support wiki: Configuring NMEA Refclocks

NTP support wiki: Garmin Refclock Users

Adding a FreeBSD NTP server based on an GPS 18 LVC device by David Taylor

Enabling ntpd PPS support for Debian Lenny Linux by World Time Solutions

Garmin GPS 18x OEM

NTP server using PC gnu/linux and freebsd by Steven Bjork

Stratum 1 NTP, Garmin GPS 18 LVC on FreeBSD 8.0 by Ryan Doyle

Synchronising to a Garmin GPS 18 LVC by R.J. van der Putten

Synchronizing an NTP server to GPS/PPS by Pela-Suros

Synchronizing ntpd to a Garmin GPS 18 LVC via gpsd by Jaap Winius

Last edited 2015-02-17T14:20:37-0800