For some reason I decided that I needed a Really. Accurate. Clock. here in the ham shack, so, here we go.
Step 1: Get a GPS receiver. I picked one of the VK-162 USB devices on Amazon for about $15. This is a good way to get started but not the ultimate goal, which I’ll explain later.
Step 2: Install all the necessary stuff to talk to the GPS.
apt-get install ntpd gpsd-clients gpsd gpsd-clients
The VK-162’s simply pop a /dev/ttyACM0 serial device in, so it’s pretty straightforward. A little bit of configuration:
# Default settings for the gpsd init script and the hotplug wrapper.
# Start the gpsd daemon automatically at boot time
START_DAEMON="true"
# Use USB hotplugging to add new USB devices automatically to the daemon
USBAUTO="true"
# Devices gpsd should collect to at boot time.
# They need to be read/writeable, either by user gpsd or the group dialout.
DEVICES="/dev/ttyACM0"
GPSD_SOCKET="/var/run/gpsd.sock"
# Other options you want to pass to gpsd
GPSD_OPTIONS="-n"
Note the -n option. This tells gpsd to not wait for a client to connect before polling the GPS. Helps get the fix a bit faster, I believe.
Now we fire up the service and ensure we’re getting a GPS fix:

Step 3: Get chronyd installed and configured.
# Welcome to the chrony configuration file. See chrony.conf(5) for more
# information about usuable directives.
refclock SHM 0 offset 0.0700 delay 0.01 refid NTP0 noselect
#refclock SHM 0 offset 0.5 delay 0.01 refid NTP0 prefer
#pool 2.debian.pool.ntp.org iburst
pool 0.pool.ntp.org iburst
pool 1.pool.ntp.org iburst
pool 2.pool.ntp.org iburst
pool 3.pool.ntp.org iburst
pool 4.pool.ntp.org iburst
...
# Uncomment the following line to turn logging on.
log tracking measurements statistics
...
allow 10.0.3.1/24
gpsd and chronyd speak using a shared memory segment for speed. I kept that commented-out definition in there, because I want to give a short lecture about COPYING OTHERS’ CONFIG LINES AND NOT UNDERSTANDING THEM.
When I first set this up, I could NOT get chronyd to use the GPS as the ‘master’ if I had ANY other NTP servers configured. It always seemed to be right around 430 mS fast.
After peering at the config, I went OH MY GOD, threw something in a harmless direction, and removed the “offset 0.5” that somebody else’s config needed.
Why this makes sense: It takes about 68-70 mS on average for the GPS puck to send the string through the 9600 bps serial line it establishes.
So, now, after figuring that out, I’ve ballparked the offset I need. I’m now logging and collecting average data – comparing the GPS puck to a WHOLE BUNCH of NTP servers – and will dial it in. You’ll see the ‘noselect’ on the GPS device, which means that i don’t want to actually set the time using this today – just logging its delay. I expect to get mS accuracy out of the current setup.
And lo and behold, my other machines love and prefer it:

The next step is to set up a real source with a serial-only GPS board – one that has “pulse per second” (PPS) output. Linux can use this to hit an interrupt to advance the clock, and combined with the NMEA serial strings and internet NTP servers to know which second it is, I expect to have microsecond accuracy. Tightest FT8 signal on the block, friends.