GPS 18 + FreeBSD
Home Page Up Setup on Windows Using NTP Windows LAN tips Events Cable modem notes Monitoring with MRTG GPS 18 + FreeBSD GPS 18 + Windows GPS 18x firmware GPS 18x waveforms NTP 4.2.4 vs. 4.2.5 NTP 4.2.7p241 Rapco 1804M notes Raspberry Pi RPi - ntpheat RPi - quick-start RPi - notes RPi - cross-compile RPi vs BBBlack Sure GPS board Timestamp issues TSC Interpolation Vista & Windows-7/8 Wi-Fi warning Windows after reboot Win-7/8 & Internet Win-7 to Win-10 gains New versions


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


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.


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 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: or"

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

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


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

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       iburst
server       iburst
server       iburst
server          iburst
#       The GPS receiver on COM1 at 4800 baud
#       mode 1 = use $GPRMC statements
#       time1 = trimming offset
#       flag3 1 = enable Kernel PPS discipline
server    mode 1       prefer
fudge    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 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     iburst
server     iburst
server     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    minpoll 4       mode 1       prefer
fudge    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?

 Plot of offset for one day
(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 plotsPerformance historyAll 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:


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


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


  • 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
  • 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
==============================================================================  .STEP.          16 u  989   64    0    0.000    0.000 4000.00 .STEP.          16 u  418   64    0    0.000    0.000 4000.00
 ns0.exa-network    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   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
==============================================================================  .STEP.          16 u 1010   64    0    0.000    0.000 4000.00 .STEP.          16 u  439   64    0    0.000    0.000 4000.00
 ns0.exa-network    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   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
*    2 u   20   64    1   20.722   -4.448   2.257
+    2 u   19   64    1   27.903   -5.345   8.284
 ns0.exa-network    3 u   35   64    3   32.045    0.346 1421.36
+kryten.alphazed     2 u   19   64    1   22.097   -4.337   2.564   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
*    2 u   33   64    3   20.722   -4.448   3.898
+    2 u   35   64    3   27.903   -5.345   8.538
 ns0.exa-network    3 u   51  128    7   32.045    0.346   7.119
+kryten.alphazed     2 u   32   64    3   22.097   -4.337   3.483   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
*    2 u   16   64    7   21.446   -0.818   3.593
+    2 u   15   64    7   27.903   -5.345   9.062
 ns0.exa-network    3 u   97  128    7   32.045    0.346   7.119
+kryten.alphazed     2 u   13   64    7   22.097   -4.337   5.230   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
+    2 u    8   64   17   21.446   -0.818   4.854
+    2 u    6   64   17   28.349    0.523   5.450
 ns0.exa-network    3 u   27  256   17   32.045    0.346   7.903
+kryten.alphazed     2 u    7   64   17   21.891    2.511   4.282   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
+     2 u   16   64   37   21.446   -0.818   4.893
+    2 u   14   64   37   26.764    1.313   4.579
 ns0.exa-network    3 u  101  256   17   32.045    0.346   7.903
+kryten.alphazed     2 u   81   64   36   21.891    2.511   4.282   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
+     2 u   61   64   77   21.446   -0.818   6.598
+    2 u   57   64   77   26.764    1.313   4.050
 ns0.exa-network    3 u  210  256   17   32.045    0.346   7.903
+kryten.alphazed     2 u   60   64   75   21.792    2.579   3.447   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    mode 0  minpoll 4 maxpoll 4  prefer
fudge    flag1 1 flag3 1 refid PPS
server iburst minpoll 10 maxpoll 10  # pool server
server iburst minpoll 10 maxpoll 10  # pool server
server iburst minpoll 10 maxpoll 10  # pool server
server iburst minpoll 5 maxpoll 5  # local stratum-1 server
server 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. 


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 /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 (4.2.6p5@1.2349), 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 mode 0 minpoll 4 maxpoll 4 prefer
fudge flag1 1 flag3 1 refid PPS
pool iburst minpoll 10 maxpoll 10
server iburst minpoll 5 maxpoll 5
server 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 
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" /ssh  

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


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 netmask

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	mode 0 minpoll 4 maxpoll 4 prefer
fudge	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	iburst minpoll 5 maxpoll 5
server	iburst minpoll 5 maxpoll 5
# Internet backup servers
#   maxpoll 10 = use 1024s sampling
#   minpoll 10 = and don't decrease it
server	iburst minpoll 10 maxpoll 10
server	iburst minpoll 10 maxpoll 10
server	iburst minpoll 10 maxpoll 10


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

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 4.2.7p255@1.2483 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,


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

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:

Using the Sure Electronics GPS evaluation board

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

Animation of the Sure board working

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 ::1
restrict mask peer


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