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

Introduction

I have been interested in precise timekeeping for a long time,
and have run the excellent NTP
software on my PCs for several years.  Earlier, I had worked with Martin Burnicki
of Meinberg on improving the performance
of NTP in the Windows environment, however I remained envious of the reported
precision of GPS systems with microsecond accuracies.  When the low-cost
Garmin GPS 18 LVC became available, quite a few people reported using this
device with UNIX systems, and this triggered me into purchasing a GPS 18 LVC to
see what I could do with it.  There is now the even more sensitive GPS 18x
LVC available.  Initial tests with just the serial 4800 baud
NMEA output and no PPS using Windows were disappointing.  Whilst the device worked,
the accuracy and jitter were no better than could be achieved with a broadband
Internet connection and servers from the NTP
pool.  Realising that I had a spare old 133MHz PC, and hearing that
UNIX could run on such a system, in January 2006 I decided to rise to the challenge.  This
note is the result!

Although that PC used FreeBSD 5.4 which was the current
version available at the time, when the PC finally failed I updated to a new Intel
Atom system and Free BSD 8.  If you are more into using NTP with Debian Linux, you may find
this
RJ Systems page of interest.

The issues with Windows have now been largely resolved thanks
to the enthusiastic and tireless efforts of Dave Hart, so I have now also been
able to add precision timekeeping to
Windows also using the GPS 18LVC.

Hardware

PC Hardware

1995 PC with 133MHz Pentium processor, 48MB memory, and 10GB
ATA disk.  Two serial ports (although one would be enough in this application).
Top of the line kit in 1995!

GPS Hardware

I used the Garmin GPS 18
LVC, which has a cable connection you can wire
into your own system.  It needs 5V power at 60mA.

It should be
mounted where it has a clear view of at least 50% of the sky - ideally the whole
sky.  I tried mine on a window ledge but the more recent windows we had
fitted in 2005 do not seem to be transparent to the microwave signals.

The
GPS is now on a small bracket just outside the window, with the thin aluminium
bracket being shaped so that it is clamped by the window.  The unit
is secured to the bracket by a single screw in the base.  The cable
comes through the window and is clamped by the rubber sealing strips -
they don't seem to do too much harm.  Whilst this worked initially,
on 2006 Sep 22 I moved the GPS so that it now has a somewhat fuller view of the sky.

PDF - GPS 18
data sheet -
GPS
18
technical specifications

How do I know how many GPS satellites are visible?

I have written a program called WXtrack
which in its registered
version has a View, GPS Visibility function which provides a plot of
the number of satellites visible versus
time of day.  You can select a threshold angle and the quadrants
visible from your location.  For best accuracy, be sure to download
the current Kepler
data.

An oddity

During the initial tests of the GPS 18 LVC, after I had made
up the RS-232 connector, I discovered that the Garmin supplied software would
not connect to the device, even though the correct "sentences" could
be seen via a terminal emulator.  I didn't understand why this was the
case, and so I wrote a small program to send the command string to switch the
device to 19200 baud (or 4800 baud).  Once I'd done that, the Garmin
program worked OK.  Perhaps this is a common problem, as Tony Hoyle
reported:

Tony: "I got hold of one of these, and after much mucking around, it seems to work. (it's defaulted to startup in binary
mode and no linux drivers can understand that, so you have to switch it into NMEA using the Windows config program, then switch binary mode off
using a command from the spec sheet... the second step doesn't seem to be documented elsewhere)."

Me: "My GPS 18 LVC powered up in the correct mode (I think), but the Windows
control program wouldn't talk to it. HyperTerminal saw the sentences correctly, though!
I wrote a small piece of software to switch it to 19200 baud, and back to 4800 baud, and it's OK now."

Tony: "Mine was the other way around - the Windows control program could see it
but all hyperterminal (or minicom) could see was binary junk.  Had to switch it manually using $PGRMC1... you first get the windows program to
enable text mode (forcing 'enable NMEA mode' does this) then quit it and start
minicom, and issue a $PGRMC1 with 1 as the second digit (disable binary phase)."

Initial setup

For a long while after I first started the GPS it didn't
report a sensible position.  I suspect it was taking a long time to read
the almanac, and then to find the correct satellites.  It did eventually
sort itself out, but only after about 30 minutes of exposure to a good fraction
of clear sky.

The unit is quite a bit less sensitive than some of my other
GPS devices,
which have an add-on active antenna.

An attempted tweak

On 2006 June 06, I attempted to set the GPS 18 LVC into 2D
mode, which means that it assumes a fixed height and would only need three
satellites for a complete fix (as my sensor can only see half the sky).
This is done via the $PGRMC statement, setting the first value to "2",
and the second to the sensor height in metres.  I will see if this makes
any difference (I'm also unsure if the command "stuck").  I don't
think this made any difference, as I believe it only affects the initial
acquisition.

Moving the GPS 18 LVC

The opportunity later arose to put the unit on the slope of
the roof, which would mean that it only saw satellites above 25º elevation, but
over a 360º degree arc of the sky.  This does appear better than the
previous 180º arc of about 5º elevation.  No longer do I see spikes of
invalid GPS data (due to too few satellites), and now the winter is approaching
the central heating transients are, perhaps, the cause of worst errors!

Interconnection - separate power

The Garmin has a 5V power requirement, which I met from a 7805
and a 12V regulated supply already to hand.  You could, instead, take the
5V from a USB port (see: Terje
Mathisens' post).  I took this approach when I added a GPS 18x LVC on
May 2009.

The Garmin TX, RX and ground data connections go to DB-9 RX,
TX and ground connections.  It may also be that you find two thin black
lines in the Garmin cable once you have removed the test header and stripped the
cable back for use in your own system, in which case you can connect both lines
to signal ground.  If someone spots this, could they please check it both
thin blacks are connected so that I can report here?

The Garmin yellow PPS (pulse per second) line is connected to the DB-9 DCD (pin
1).  Mine is also connected to a LED via a 3.3K resistor so that there is a
visual indication of the PPS signal.  I still see over 4V on of the PPS
line.  Update: the LED was a little dark, so I changed the resistor to 1.5K
and replaced the LED with a special low-current (2mA) one from Maplins.
Now easily seen in daylight - I await being dazzled at night!

It seems that the GPS 18 has drive capability to support two
RS-232 receivers at the same time from the one connection, and I've used this to
support a second, parallel-connected PC with just Ground, DCD and TX data from
the GPS 18 LVC connected.

LVC connection

Colour

DB-9 pin

Function

PPS

thin yellow

1

Data Carrier Detect

TXD

thin white

2

Receive Data

RCV

thin green

3

Transmit Data

GND

thin black

5

Signal Ground

+5V power

thick red

0V

thick black

Interconnection - USB power

On a later arrangement, which happened to be with the newer
and more sensitive Garmin GPS 18x LVC (note the "x") I used the +5V
USB power from the PC to service the needs of the GPS.  It's well within
the capabilities of the USB port.  The GPS went faulty at one stage and had
to be returned to Garmin (who replaced it quite quickly - there is a suggestion
that it's actually a firmware fault).  To avoid the hassle of having to
solder the device connections to the RS-232 connector once again, I used a
couple of 5-way DIN connectors (not ideal, I know) to connect the new GPS into
the old cable, so now I have a 10m lead if I need it!  It makes for a very
simple and "clean" interface.  Although I needed to have the GPS
18 on the roof outside, the GPS 18x is sufficiently sensitive to work indoors
(at least on the top storey of the building).

If you want a pre-assembled unit with USB power and serial
RS-232 connectors, you could try here.
Be sure to specify the USB power option.  Dave Hart bought and comments:
"I've bought two, which were shipped promptly.  The USB and GPS cables meet in the DB-9 serial port hood. The fit and finish
is good."  As noted here,
be sure to use firmware version 3.70 (possibly or later).

Brian Inglis writes:  I simplified the wiring by connecting all +5V power leads to pin 6
DSR.  I connect USB power to the DB-9 pins 5/GND and 6/DSR (+5 V) and also connect the GPS GND and power leads to those pins.
As the GPS is connected as a DCE (comms/modem) where pin 6 is an output, and the PC as a DTE (terminal/device) where pin 6 is an input, no RS-232
interface should have a problem with +5 V input on DSR.  Nice one,
Brian!

See Wikipedia for a definition
of DCE and DTE.

The puck and the supplied cable, now terminated in a 5-pin DIN connector,
with the other end going off to the PC, reusing the lead from the faulty
GPS 18x LVC.

I built the yellow PPS LED and resistor into the RS-232 connector.

Software

Software installation

At the time of starting (around 2006) it seemed to be acknowledged that FreeBSD
was the best
operating system for accurate time keeping, so that's what installed having no
other particular preference.  Today, Linux may be equally as good - I
haven't compared the two.  It is also possible to use the same hardware
with Linux 2.6, and Philip M White has described
how to do this.

The FreeBSD formal documentation is here.

You can download the BSD 5.4 ISO disk images from here.
This is the version which I heard that other people use, and it has worked fine
for me.  I can't comment from experience if newer versions are any better.

You can use the IsoBuster
program to extract the floppy disk images from the ISO.

You use the fdimage
program to make floppy disks to boot from if, like me, your CD-ROM doesn't
boot.  There is a boot floppy, and two Kernel floppies.  There's a
fourth fixit floppy, but I didn't appear to need that.  When
choosing the type of distribution, be sure to install the
source so that you can re-compile the Kernel.

It seems that I could have saved myself a lot of time by using
Smart Boot Manager.  Geoff Rhodes writes:

"I notice that you were unable to boot from CD-ROM, so I thought you might be
interested in Smart Boot Manager.  I got this several years ago (then as part of Ranish
Partition Manager, I think) and it allows me to boot from
CD- ROM on my 486, either by installing it onto the HDD, or more usually having SBM
on a floppy.  I got really fed up with the time it took to use the floppy install method for W2K etc and this solves it quite neatly!

"It looks like SBM is now here:

http://btmgr.sourceforge.net/about.html or http://btmgr.webframe.org/"

Since I wrote my original comments, Ryan Doyle has written up
his notes on setting up the Garmin 18
LVC on the (rather more recent) FreeBSD 8.0.

FreeBSD Unix commands

to shutdown:  shutdown -p now  (power
down);  shutdown -r now (reboot)

to restart ntpd:  /etc/rc.d/ntpd restart

to logout:  logout

to choose the time-zone, and whether the BIOS clock works
in UTC or local time, see the tzsetup
command.

to edit a file, use "vi" - basic notes are here.

System software configuration

To allow remote login via Telnet, need to uncomment the
telnet entry in inet.conf.  Telnet is only recommended for a small
local system with no direct connection to the Internet.

To allow root to login via telnet, need to add the word
"secure" to the ttyp0 entry in /etc/ttys.  Be careful if you
enable this option!

A handy, free terminal emulator with VT100 etc.
capabilities will make editing files easier if you have to work remotely
from the FreeBSD box, and I've used Tera
Term.  Of course, you need to edit the files allowing remote access
locally first!  PuTTY
is a more capable alternative.

System software customisation

Need to add one line to the Kernel configuration:

options PPS_SYNC

and recompile
the Kernel.  On my 133MHz/48MB system this can take several hours.
Note the configuration suggestions below before you recompile the kernel.

Harlan Stenn comments:

Assuming an x86 box, you need to create a file - e.g. /usr/src/sys/i386/conf/PPS
- and put the following in it:

#

# PPS -- Generic kernel configuration file for FreeBSD/i386 PPS

#

include GENERIC

ident PPS-GENERIC

options PPS_SYNC

and then add the following line to /etc/make.conf:

KERNCONF= PPS GENERIC

(Assuming you want to "cd /usr/src" and "make buildkernel
installkernel") to build
both kernels and only install the PPS kernel).  (Later: I do this if I want both the GENERIC
and PPS kernels built, but the first one in the list is the one that gets installed).)

Kevin Oberman comments:

"The idea Harlan Stenn is putting forth is to create a very short kernel
config file named PPS containing only those three lines.  That way, if you upgrade, any changes in GENERIC will automagically be
folded in.  I would change one thing. I would change the name of the config file to match the
IDENT.  It makes it easier to keep track of things."

Harlan Stenn continues: I also add the lines:

link cuaa1 refclock-0

link cuaa1 pps0

to the end of /etc/devfs.conf, and *sometimes* it looks like those links are
not created soon enough in the boot sequence, but it's sporadic and I have
not had time to chase it down yet.

Per Hedeland comments:

Well, using PPS_SYNC shouldn't be *required* to use the PPS signal on
FreeBSD - what it does is make the kernel discipline the local clock directly from the PPS signal, but FreeBSD also supports the PPSAPI, to
let ntpd collect the timestamps from the PPS signal.  It should be possible to use this via the ATOM driver.
I haven't personally verified any of this though (hence the "should"s) - and I guess PPS_SYNC may give
better results, but it could be interesting to try both variants.

Dag-Erling Smørgrav noted on the NTP-Timekeepers list:

The device name changed from cuaa to cuad in later
versions.

There is some interesting information about configuring a single-board
computer to do this job here:

http://lists.soekris.com/pipermail/soekris-tech/2005-December/009702.html
- "NET4501 and ntp
server."

http://www.wraith.sf.ca.us/ntp/

http://phk.freebsd.dk/soekris/pps/

NTP configuration

NTP is configured by the file /etc/ntp.conf.  My simple version
contains:

# ntp.conf
#
driftfile /etc/ntp.drift
#
# The servers for sanity
#
server 0.uk.pool.ntp.org iburst
server 1.uk.pool.ntp.org iburst
server 2.uk.pool.ntp.org iburst
server ntp2.mcc.ac.uk iburst
#
# The GPS receiver on COM1 at 4800 baud
#
# mode 1 = use $GPRMC statements
# time1 = trimming offset
# flag3 1 = enable Kernel PPS discipline
#
server 127.127.20.1 mode 1 prefer
fudge 127.127.20.1 time1 0.000 flag3 1 refid PPS

What does the fudge line do?

The fudge command allows me to adjust certain parameters of the
specified server.  In this case, I alter:

the reference ID to the string "PPS"

flag 3 to the value 1, enabling the kernel PPS discipline

the time offset to 0.000 seconds

The latter adjustment does nothing, but had my pulses been the
opposite polarity to the ones I actually have, the NTP software might have
locked to the trailing edge of the pulse 200ms after the leading edge, and
rather than change that in hardware I could have set time1 to +0.200 (or
whatever) to get the correct time.

An update to the configuration

Once I had the two Windows
PCs working as stratum-1 servers, I could remove one feature I had been
slightly unhappy with - that the backup Internet servers were being hit once a
minute with the version of NTP and the configuration I had.  I decided to
replace two of the external Internet servers by the stratum-1 servers on my LAN,
and the third external server by another PC on the LAN, providing four total
servers (the GPS and three external).  These three servers are shown as
192.168.0.1 etc in the configuration file below.  This allowed me to reduce
the poll interval for the GPS device from 64s to 16s, and gain an improved
performance (I hope).

# ntp.conf
#
driftfile /etc/ntp.drift
#
# The servers for sanity
#
server 192.168.0.1 iburst
server 192.168.0.2 iburst
server 192.168.0.3 iburst
#
# The GPS receiver on COM1 at 4800 baud
#
# minpoll = use 16-second sampling
# mode 1 = use $GPRMC statements
# time1 = trimming offset
# flag3 1 = enable Kernel PPS discipline
#
server 127.127.20.1 minpoll 4 mode 1 prefer
fudge 127.127.20.1 time1 0.000 flag3 1 refid PPS

Useful NTP commands

To show the upstream systems:  ntpq -p

To show the state of the kernel:  ntpdc -c kern

To show the Most Recently Used IP addresses, including
clients: ntpq -n -cmrulist

ntpd maintains a "Most Recently Used" (MRU) list of source IP addresses seen in incoming NTP packets.
This list serves two

purposes, first allowing operator monitoring of client traffic, including the average time between packets from a given address.
This

can be seen with "ntpq -cmrulist" (or
"ntpq -n -cmrulist" to avoid
the delay of reversing IP addresses to names).  Second, the same MRU

list is the history used by the "restrict limited" rate-limiting mechanism.
More
on the mru list.

Showing before and after PPS_SYNC enabled in the Kernel

E:\>ntpdc -c kern pixie
pll offset: -3.75634 s
pll frequency: 45.503 ppm
maximum error: 0.485818 s
estimated error: 0.002825 s
status: 2001
pll time constant: 7
precision: 1e-006 s
frequency tolerance: 496 ppm

pixie# ntpdc -c kern
pll offset: -6.7e-08 s
pll frequency: 45.479 ppm
maximum error: 0.232597 s
estimated error: 0.001668 s
status: 2107 pll ppsfreq ppstime ppssignal nano
pll time constant: 6
precision: 1e-09 s
frequency tolerance: 496 ppm
pps frequency: 45.479 ppm
pps stability: 0.130 ppm
pps jitter: 1.183e-06 s
calibration interval: 128 s
calibration cycles: 23
jitter exceeded: 13
stability exceeded: 0
calibration errors: 1

How well does it work?

(click this image for summary history plots)

Here is a graph showing the offset from UTC reported by the
PC, with 20µs added so that the offset is positive.  (An ideal timekeeper
would be a straight line at 20µs).  As the offset value reported by NTPQ
is only accurate to 1µs, increasing the plotted time resolution would not
provide more information.  Please remember that this is a lowly 133MHz
processor system!  How I make these plots.
Performance history.  All
NTP plots.  The graph shows the performance up to the point of switch
off on 2009 March 24.

So far, with NTP, my experience in terms of the accuracy
achieved depends on the server source, and client operating system.
Briefly:

Good:

Multiple Internet servers with Windows NT/XP clients:
excursions of the order of 10 - 20ms caused mainly by diurnal temperature
variations.  The time constant on the NTP correction loop grows quite
long to minimise NTP network traffic and load on NTP servers, and the lookup
interval typically grows to 1024s.  This long time constant allows some
drift.

Serial GPS source to Windows NT/XP.  At the default
setting, 4800 baud, each bit occupies 0.2ms, and the uncertainty with which
the GPS sends out the data, and the operating system can report the time the
data was received, result in a somewhat higher short term offset jitter, and no
better daily drift than with multiple Internet sources.  You may be
able to do better using a high baud rate, and perhaps with a USB-connected
GPS and a much higher high baud rate.  It's possible
that the jitter would be less with a UNIX system, but I've not tested that.

Better:

Serial source to Windows XP or Windows-7/32/64 with PPS support.  This
provides some 250µs of offset jitter, which is a lot better than having
just the serial input, but not as good as a FreeBSD system.  Performance
graphs here.

Best:

PPS source to FreeBSD, with PPS_SYNC support in the
kernel.  Even on a lowly 133MHz PC, with a GPS antenna seeing less than
half of the sky, 10µs offset jitter is achieved.

System configuration updates require to run NTP

To start ntpd every time, add to /etc/rc.conf

ntpd_enable="YES"

To point the pseudo GPS1 device to the
actual serial port, add to /etc/rc.local

ln -s /dev/cuaa0 /dev/gps1

Startup sequence after reboot - a set of ntpq -p reports

pixie# ntpq -p

remote           refid
st t when poll reach   delay   offset  jitter

==============================================================================

194.153.168.75
.STEP.          16 u
989   64    0    0.000
0.000 4000.00

213.205.157.156
.STEP.          16 u
418   64    0    0.000
0.000 4000.00

ns0.exa-network 130.88.202.49    3 u
9   64    1  2874.71  1421.71
0.015

kryten.alphazed
.STEP.          16 u
832   64    0    0.000
0.000 4000.00

utserv.mcc.ac.u 194.81.227.227   2 u   10
64    1  2868.76  1417.38   0.015

GPS_NMEA(1)
.PPS.            0
l   15   64    0
0.000    0.000 4000.00

pixie# ntpq -p

remote           refid
st t when poll reach   delay   offset  jitter

==============================================================================

194.153.168.75
.STEP.          16 u
1010   64    0
0.000    0.000 4000.00

213.205.157.156
.STEP.          16 u
439   64    0    0.000
0.000 4000.00

ns0.exa-network 130.88.202.49    3 u
30   64    1  2874.71  1421.71
0.015

kryten.alphazed
.STEP.          16 u
852   64    0    0.000
0.000 4000.00

utserv.mcc.ac.u 194.81.227.227   2 u   30
64    1  2868.76  1417.38   0.015

GPS_NMEA(1)
.PPS.            0
l   35   64    0
0.000    0.000 4000.00

pixie# ntpq -p

remote           refid
st t when poll reach   delay   offset  jitter

==============================================================================

*194.153.168.75  195.66.241.10    2 u
20   64    1   20.722
-4.448   2.257

+213.205.157.156 130.149.17.21    2 u   19
64    1   27.903   -5.345   8.284

ns0.exa-network 130.88.202.49    3 u
35   64    3   32.045    0.346
1421.36

+kryten.alphazed 129.69.1.153     2 u
19   64    1   22.097
-4.337   2.564

utserv.mcc.ac.u 194.81.227.227   2 u   34
64    3   27.331   -3.080 1420.46

GPS_NMEA(1)
.PPS.            0
l   37   64    1
0.000   -7.169   0.015

pixie# ntpq -p

remote           refid
st t when poll reach   delay   offset  jitter

==============================================================================

*194.153.168.75  195.66.241.10    2 u
33   64    3   20.722
-4.448   3.898

+213.205.157.156 130.149.17.21    2 u   35
64    3   27.903   -5.345   8.538

ns0.exa-network 130.88.202.49    3 u   51
128    7   32.045    0.346
7.119

+kryten.alphazed 129.69.1.153     2 u
32   64    3   22.097
-4.337   3.483

utserv.mcc.ac.u 194.81.227.227   2 u   49
128    7   27.331   -3.080   8.172

GPS_NMEA(1)
.PPS.            0
l   47   64    3
0.000   -0.624   6.545

pixie# ntpq -p

remote           refid
st t when poll reach   delay   offset  jitter

==============================================================================

*194.153.168.75  195.66.241.10    2 u
16   64    7   21.446
-0.818   3.593

+213.205.157.156 130.149.17.21    2 u   15
64    7   27.903   -5.345   9.062

ns0.exa-network 130.88.202.49    3 u   97
128    7   32.045    0.346
7.119

+kryten.alphazed 129.69.1.153     2 u
13   64    7   22.097
-4.337   5.230

utserv.mcc.ac.u 194.81.227.227   2 u   96
128    7   27.331   -3.080   8.172

GPS_NMEA(1)
.PPS.            0
l   28   64    7
0.000   -0.058   5.044

pixie# ntpq -p

remote           refid
st t when poll reach   delay   offset  jitter

==============================================================================

+194.153.168.75  195.66.241.10    2 u
8   64   17   21.446
-0.818   4.854

+213.205.157.156 130.149.17.21    2 u
6   64   17   28.349
0.523   5.450

ns0.exa-network 130.88.202.49    3 u   27
256   17   32.045    0.346   7.903

+kryten.alphazed 129.69.1.153     2 u
7   64   17   21.891
2.511   4.282

+utserv.mcc.ac.u 194.81.227.227   2 u   24
256   17   27.331   -3.080   8.057

*GPS_NMEA(1)
.PPS.            0
l   20   64   17
0.000   -0.007   4.150

pixie# ntpq -p

remote           refid
st t when poll reach   delay   offset  jitter

==============================================================================

+194.153.168.75  195.66.241.3     2 u
16   64   37   21.446
-0.818   4.893

+213.205.157.156 130.149.17.21    2 u   14
64   37   26.764    1.313   4.579

ns0.exa-network 130.88.202.49    3 u  101
256   17   32.045    0.346   7.903

+kryten.alphazed 129.69.1.153     2 u
81   64   36   21.891
2.511   4.282

-utserv.mcc.ac.u 194.81.227.227   2 u   98
256   17   27.331   -3.080   8.057

*GPS_NMEA(1)
.PPS.            0
l   31   64   37
0.000   -0.005   3.595

pixie# ntpq -p

remote           refid
st t when poll reach   delay   offset  jitter

==============================================================================

+194.153.168.75  195.66.241.3     2 u
61   64   77   21.446
-0.818   6.598

+213.205.157.156 130.149.17.21    2 u   57
64   77   26.764    1.313   4.050

ns0.exa-network 130.88.202.49    3 u  210
256   17   32.045    0.346   7.903

+kryten.alphazed 129.69.1.153     2 u
60   64   75   21.792
2.579   3.447

-utserv.mcc.ac.u 194.81.227.227   2 u  207  256
17   27.331   -3.080   8.057

*GPS_NMEA(1)
.PPS.            0
l   11   64  177
0.000    0.003   2.939

Temporary Retirement

After several years of faultless active service from January
2006, this system
was retired on 2009 March 24, as satisfactory performance had been obtained from
a Windows system running a serial GPS NMEA port and a special serialpps.sys
serial port drive with the ATOM reference clock.  However, now that I have
a second GPS 18 LVC (actually an 18x), so I have three NMEA/PPS signals
available with parallel connecting one GPS, in March 2010 I decided to resurrect
the FreeBSD box to have even better timekeeping performance, however its PSU
failed on Monday, March 29, so I am temporarily without a FreeBSD box.

An Intel Atom system

In April 2010 I replaced the old Intel Pentium 133Mhz box with a
shiny new Intel Atom system, which runs at such low power that it doesn't need
any cooling fan.  The fun to be had getting the box to dual-boot FreeBSD
and Windows is described below.  Even more fun in this application was that the wire connecting
to pin 1 of the serial port was broken at the RS-232 end of the header
cable.  It took some time to find that one!

Current performance is shown here,
and a snapshot of the kernel variables shows the following.  (With later
NTP versions you may need the command: ntpq -c kern
<server>).

Shortly after install

After nearly 24 hours running

C:\>ntpdc -c kern pixie
pll offset: 0.007554 s
pll frequency: 24.759 ppm
maximum error: 0.002026 s
estimated error: 2e-006 s
status: 2107
pll time constant: 4
precision: 1e-006 s
frequency tolerance: 496 ppm
pps frequency: 24.759 ppm
pps stability: 0.024 ppm
pps jitter: 0.00159 s
calibration interval: 256 s
calibration cycles: 208
jitter exceeded: 19
stability exceeded: 0
calibration errors: 2

C:\>ntpdc -c kern pixie
pll offset: 0.003093 s
pll frequency: 24.883 ppm
maximum error: 0.009513 s
estimated error: 2e-006 s
status: 2107
pll time constant: 4
precision: 1e-006 s
frequency tolerance: 496 ppm
pps frequency: 24.883 ppm
pps stability: 0.010 ppm
pps jitter: 0.001977 s
calibration interval: 256 s
calibration cycles: 668
jitter exceeded: 75
stability exceeded: 0
calibration errors: 2

Note that there are calibration errors, but they don't change
in number.  On the later Intel Atom system I was initially concerned to see
25 calibration errors after a reboot, but the count was the same days later.

As I now have a couple of stratum-1 servers based on Windows,
the configuration file for PC Pixie is a little different.  It may also be
that the NTP ntpd 4.2.4p5-a (1) installed with the later FreeBSD 8.0 distribution
would allow more flexibility.  It has three sets of entries, the first for the
GPS/PPS stratum-1 server with details similar to those listed above, the second
is a set of three lines for external Internet servers from the UK pool, where
both minpoll and maxpoll are set to 10 (1024 seconds) so that minimum use is
made of those servers, and finally a third set for the two local stratum-1
servers polled at 64 second intervals.  These last two are probably
superfluous, but don't seem to do any harm;  32 seconds is the remote poll
interval I use for LAN-synced PCs.

driftfile /var/db/ntp.drift
#
server 127.127.20.1 mode 0 minpoll 4 maxpoll 4 prefer
fudge 127.127.20.1 flag1 1 flag3 1 refid PPS
#
server 0.uk.pool.ntp.org iburst minpoll 10 maxpoll 10 # pool server
server 1.uk.pool.ntp.org iburst minpoll 10 maxpoll 10 # pool server
server 2.uk.pool.ntp.org iburst minpoll 10 maxpoll 10 # pool server
#
server 192.168.0.2 iburst minpoll 5 maxpoll 5 # local stratum-1 server
server 192.168.0.7 iburst minpoll 5 maxpoll 5 # local stratum-1 server

How well does it work?

Here are a couple of snapshots of the system at work:

At the left-hand side of the Monthly graph, you can see a few
days of data from the earlier FreeBSD system. which shows rather more daily
variation than does the current system.  This improved performance is also
reflected in the daily data.  However, it shows that even a lowly
133MHz/48MB Pentium system is quite up to the NTP task.  The current data
may be seen here.

GPS 18x LVC firmware version issue

If you are using a Garmin GPS 18x LVC, be sure to use firmware
either 3.20 or before, or 3.70, as there is a problem with some versions of the
firmware where the NMEA data can be more that one second late compared to the
PPS pulse, and hence present the incorrect time information to NTP.  The
problem, and my flawed attempts to analyse it, and a working solution are
described here.  Note
that there is also an issue with some 3.x firmware which causes the device to
stop working and appear bricked.

Garmin
3.70 firmware download

Some notes on FreeBSD 8.0

As mentioned above, this is well documented on Ryan Doyle's
site although I stuck with the default shell and with the VI editor - these
notes on vi are helpful for the novice or occasional user.

Hardware

I bought a pre-assembled ITX system from ITX
Warehouse in the UK, who provided me with a W71
system built into a W42
box as that has the serial port on the rear of the case.  The main
board is an Intel
Desktop Board D410PT.

PPS support

You will need to recompile the kernel to add PPS
support.  Follow the steps suggested by Harlan Stenn above.  Allow an
hour or two.

Upgrading FreeBSD to 8.2

2012-Feb-09 - Basically, follow the notes here,
using a command like:

# freebsd-update -r 8.2-RELEASE upgrade

Allow an hour!  Note that the update will tamper with
some system configuration files, including those for remote access and for
ntpd.  If you don't check this, you may find you cannot log in remotely any
more, as the sshd daemon is no longer running!  You may get a "Network
error: Connection refused" error message.  Check /etc/ssh/ssh_config

Updating NTP to a later version

You need a port management package such as Portmaster, which
you can install as described here.
First install the ports if you didn't at initial install:

# csup -L 2 -h cvsup.FreeBSD.org /usr/share/examples/cvsup/ports-supfile

then install Portmaster:

# cd /usr/ports/ports-mgmt/portmaster
# make install clean

You may need to log out and back in at this point, before
running portmaster.

# portmaster -a

To update NTP using portmaster, use one of these commands:

# portmaster ntp

# portmaster net/ntp-devel

to get either the current release version, or the current
development version.  The portmaster step takes about 5 minutes on my Intel
Atom PC.  After updating to the release version ([email-masked]),
the "*" tally code in "ntpq -p" changed to "o",
the normal indication that PPS support was enabled.  After updating to the
development version, the command "ntpq -c kern pixie" returned the
kernel information correctly from the remote PC.

The new ntp binary files compiled by these ports typically appear
in
a directory like: /usr/local/sbin, and you need to stop ntpd, copy the updated
files, and restart ntpd.  Something like:

# /etc/rc.d/ntpd stop
# cp /usr/local/sbin/ntp* /usr/sbin/
# /etc/rc.d/ntpd start

You may want to take a backup copy of the current working
files first!

Chuck Swiger has kindly mentioned:  FreeBSD port-management tools like portmaster and portupgrade can download and install precompiled packages instead, if you tell them to (see the -P flag).
Thanks, Chuck, that should help speed things up if a precompiled is available.

With more recent versions of NTP (4.2.6 and later) you can
replace the multiple server ... pool lines with a single pool directive:

driftfile /var/db/ntp.drift
#
server 127.127.20.1 mode 0 minpoll 4 maxpoll 4 prefer
fudge 127.127.20.1 flag1 1 flag3 1 refid PPS
#
pool uk.pool.ntp.org iburst minpoll 10 maxpoll 10
#
server 192.168.0.2 iburst minpoll 5 maxpoll 5
server 192.168.0.7 iburst minpoll 5 maxpoll 5
#
leapfile /root/ntp/leap-seconds.3535142400

Updating the updater - telling portmaster about a newer version

Suppose that portmaster knows about ntp4.2.7p304, but you know
that a later version has been released and wish to build that.  Here's a
note from Steve Kostecke telling how:

You don't need to wait until someone else updates
portmaster.  Just update the port to the current version of
ntp-devel.  Doing so usually works unless there is a significant enough change in
the port codebase to "break" the port.

Here's how:

# cd /usr/ports/net/ntp-devel
# nano Makefile

Edit the Makefile with nano (or whatever) and update the version string, for example, change the line:
PORTVERSION= 4.2.7p304
to:
PORTVERSION= 4.2.7p401

Then run this command while still in the ntp-devel directory:
# make makesum

You can then follow the same sequence of commands as above to
replace the current NTP binaries with the ones you have just compiled.  The
portmaster step takes about 5 minutes on my Intel Atom PC.

# portmaster net/ntp-devel
# /etc/rc.d/ntpd stop
# cp /usr/local/sbin/ntp* /usr/sbin/
# cp /usr/local/sbin/ntpq /usr/bin # this needed with FreeBSD 10.1
# /etc/rc.d/ntpd start
# ntpq -crv -pn # optional, to check the new version number and that NTP is working OK

Dual-booting with Windows-7

I know you may ask why, but as I am more familiar with Windows
it was easier for me to set up the system using Windows-7 to start with, just to
be sure that all the hardware was present and intact.  When setting up the box, which has no CD/DVD drive,
getting FreeBSD
to dual boot with Windows-7 was "fun".  I ended up installing
FreeBSD 8.0 first, from DVD using a borrowed SATA drive (I've now bought one for
such purposes).  Once Windows-7 was installed, nothing else would boot, but
by using EasyBCD I could get a new
entry in the boot menu for FreeBSD.  Would it boot?  No, it would
not!  There appeared to be two issues - the file name wasn't correct -
FreeBSD has a file named boot1 (which is on the  installation DVD), but
EasyBCD insisted on calling it something different.  Easy solution, copy
boot1 to the file name it expected!  Still didn't work, and I suspect this
was due to the file being in a sub-directory created by EasyBCD.  Solution,
use the Windows-7 BCDedit
command to say that the file was in the root directory, and move it there as
well.

Remote Access

With the previous FreeBSD installation I had been able to
login with Telnet, but in spite of following these
instructions, I could not get this to work with root login.  As SSH
seemed to be the "correct" route today, I enabled SSH and followed these
instructions to allow root over SSH, and found this SSH
add-on for my existing TeraTerm
PRO terminal emulator for Windows.  I haven't yet found how to make
challenge/response the default for SSH, though.  You can make a shortcut to
automate the SSH option like this:

"C:\Program Files\TTERMPRO\ttssh.exe" 192.168.0.103:22 /ssh

A program which I found later and which appears more versatile
is PuTTY.

Networking

As I had deliberately not set the IP address during testing, I
needed to add both that, the DNS servers, and the main router address after
installing FreeBSD.  Notes
here.  This needed the magic commands:

To set the IP address:

# ifconfig ath0 inet 192.168.0.103 netmask 255.255.255.0

To set the default gateway and DNS server:

# route add default your_default_router
# echo "nameserver your_DNS_server" >> /etc/resolv.conf

NTP configuration

As I now have two Windows PCs also running as stratum-1
servers, I have a slightly different configuration file, but I have still kept
it simple.  I note that FreeBSD 8.0 stores the drift file in a different
location.

driftfile /var/db/ntp.drift
#
# The GPS receiver on COM1 at 4800 baud
# mode 0 = use any statements
# mode 1 = use $GPRMC statements
# minpoll 4 = use 16-second sampling
# maxpoll 4 = and don't increase it
#
# flag1 1 = enable PPS processing
# flag3 1 = enable Kernel PPS discipline
# refid = text string to define the reference as ".PPS."
#
server 127.127.20.1 mode 0 minpoll 4 maxpoll 4 prefer
fudge 127.127.20.1 flag1 1 flag3 1 refid PPS
#
# Local stratum-1 network servers
# minpoll 5 = use 32-second sampling
# maxpoll 5 = and don't increase it
#
server 192.168.0.2 iburst minpoll 5 maxpoll 5
server 192.168.0.7 iburst minpoll 5 maxpoll 5
#
# Internet backup servers
# maxpoll 10 = use 1024s sampling
# minpoll 10 = and don't decrease it
#
server 0.uk.pool.ntp.org iburst minpoll 10 maxpoll 10
server 1.uk.pool.ntp.org iburst minpoll 10 maxpoll 10
server 2.uk.pool.ntp.org iburst minpoll 10 maxpoll 10

Leap-seconds

In February 2012 I updated PC Pixie with the NTP leapseconds file as detailed here:

http://support.ntp.org/bin/view/Support/ConfiguringNTP#Section_6.14.

File is in: /root/ntp/leap-seconds.3535142400, and so I
added this line to the /etc/ntp.conf:

leapfile /root/ntp/leap-seconds.3535142400

I could check that the file had been seen by NTP by seeing the
"tai=34" and other data in the output from an  ntpq
-c rv  command, slightly emboldened below:

pixie-ii# ntpq -c rv
associd=0 status=0419 leap_none, sync_uhf_radio, 1 event, leap_armed,
version="ntpd [email-masked] Fri Feb 10 06:04:36 UTC 2012 (1)",
processor="i386", system="FreeBSD/8.2-RELEASE-p6", leap=00, stratum=1,
precision=-19, rootdelay=0.000, rootdisp=1.165, refid=PPS,
reftime=d2e7b51b.e633640c Thu, Feb 16 2012 17:02:19.899,
clock=d2e7b527.0f680a5a Thu, Feb 16 2012 17:02:31.060, peer=8406, tc=4,
mintc=3, offset=-0.001, frequency=28.050, sys_jitter=0.002,
clk_jitter=0.002, clk_wander=0.001, tai=34, leapsec=201207010000,
expire=201212280000

SNMP

You can install SNMP with a little help from these sites:

http://silverwraith.com/papers/freebsd-snmp.php

http://www.amitabhkant.com/installing-mrtg-graphs-for-monitoring-network-utilisation-of-multiple-servers-on-freebsd/

I find it amazing that these so-called install routines
actually appear to involve recompiling the software from scratch, so that should
take a few seconds turns into a 30-minute job.

Debian Lenny Linux

I was given this link by World
Time Solutions which may help those configuring Debian Lenny Linux:

http://www.worldtimesolutions.com/support/ntp/Debian_Lenny_Linux_PPS_support_for_ntpd.html

Using the Sure Electronics GPS evaluation board

Some experiments using the Sure
Electronics GPS evaluation board are described in more detail here.

Note the very bright blue Pulse Per
Second LED!

My boxed version, the box isn't

rusty - that's just the lighting.

Running a publicly accessible NTP server

If you are running a server which is accessible from the
public Internet - perhaps you are contributing to the NTP
Pool project - there are some simple precautions you should take to ensure
that your server is not used as the source of an attack on other PCs.  Note
that this doesn't apply to most end-user clients sitting on your local PC, you
would need to have specially opened a port in your firewall or router to allow
public incoming unsolicited UDP port 123 packets into your local network.
If you are using a development version (4.2.7p26 or later) you are already
protected.  The following notice explains more:

NTP users are strongly urged to take immediate action
to ensure that their NTP daemon is not susceptible to use in a reflected
denial-of-service (DRDoS) attack. Please see the NTP
Security Notice for vulnerability and mitigation details, and the Network
Time Foundation Blog for more information. (January 2014)

Be sure to include restrict statements in your ntp.conf file
such as:

# Suggestions for NTP restrictions:

restrict source notrap nomodify nopeer noquery

restrict 127.0.0.1

restrict ::1

restrict 192.168.0.0 mask 255.255.255.0 peer

Acknowledgements

I received much help from the kind folk in the comp.protocols.time.ntp newsgroup including
Terje
Mathisen, John Pettitt, Dave Hart, Steve Sommars and Harlan Stenn.  Thanks, guys!  For the
FreeBSD 8.0 install Ryan Doyle's notes
helped a lot.

Copyright © David
Taylor, Edinburgh

Last modified: 2015 Jan 18 at 09:32