OS installation

After 6 years running a GPS disciplined NTP server on old hardware I thought it’s time to setup a new system. I took a Banana PI4 and I installed this image


I used the GPS hat I already have since about 6 years.

As you can see the vendor is M0UPU. You can buy the GPS modules at uputronics.com
At that time an ublox MAX-M8Q was used as chip on the gps hat.

I decided to compile GPSD and NTPD by myself and not to use a possible available package. To do so a lot of packages are needed:

scons libncurses5 libncurses5-dev ncurses-doc python3-matplotlib python3-matplotlib-dbg pps-tools libusb-1.0-0 libusb-1.0-0-dev libusb-1.0-doc asciidoctor asciidoctor-doc cu minicom libgtk-3-dev gtk+-3.0 python3-gi-cairo libcap-dev ksh


For complete documentation I want to refer to the Internet



But compiling is quite straight forward:

scons ; scons check ; scons install

If you decide later on to update to the latest version run:

git pull origin master --rebase
scons --config=force


For NTP I took the tar ball from ntp.org http://www.ntp.org/downloads.html. Currently the latest version is 4.2.8p15 With the following commands compilation was easy

export CC=gcc
./configure  '--with-sntp' '--enable-RAWDCF' --enable-SHM --enable-ATOM -enable-NMEA '--enable-autokey' '--enable-simulator' --with-crypto --enable-clockctl --enable-linuxcaps

OS configuration

To make it runnable some minor changes are necessary in the system. And this is maybe the most tricky part.


This was the original content:

console=serial0,115200 console=tty1 root=PARTUUID=09abe25e-02 rootfstype=ext4 fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles

Strip away which makes troubles. Then it looks like this

root=PARTUUID=09abe25e-02 rootfstype=ext4 fsck.repair=yes rootwait quiet splash


Add two lines:



Add one line:


I also stoppped hciuart

systemctl disable hciuart

I modified /etc/group to be sure not having permission issues:



Now reboot the PI4 and check the logs. With

dmesg | egrep 'gpio|pps|AMA|serial|gps'

you should see something like this:

[    0.172164] pps_core: LinuxPPS API ver. 1 registered
[    0.172177] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    1.288574] gpiomem-bcm2835 fe200000.gpiomem: Initialised: Registers at 0xfe200000
[    1.415873] uart-pl011 fe201000.serial: there is not valid maps for state default
[    1.416154] uart-pl011 fe201000.serial: cts_event_workaround enabled
[    1.416301] fe201000.serial: ttyAMA0 at MMIO 0xfe201000 (irq = 19, base_baud = 0) is a PL011 rev2
[    1.424233] bcm2835-aux-uart fe215040.serial: there is not valid maps for state default
[    1.424976] fe215040.serial: ttyS0 at MMIO 0xfe215040 (irq = 20, base_baud = 62500000) is a 16550
[    3.209970] pps pps0: new PPS source pps@12.-1
[    3.210095] pps pps0: Registered IRQ 65 as PPS source
[    9.483539] pps_ldisc: PPS line discipline registered
[    9.485867] pps pps1: new PPS source serial0
[    9.485911] pps pps1: source "/dev/ttyS0" added

Check if the pps_gpio module is loaded

pi4:root# lsmod | grep pps_gpio
pps_gpio               16384  2

modinfo pps_gpio gives also some information

There are new devices

pi4:mayer# ls -ld /dev/serial? /dev/pps0
crw-rw---- 1 root root 250, 0 Jun 19 13:28 /dev/pps0
lrwxrwxrwx 1 root root      5 Jun 19 13:28 /dev/serial0 -> ttyS0
lrwxrwxrwx 1 root root      7 Jun 19 13:28 /dev/serial1 -> ttyAMA0

Checking pps0 is useable. It could also be that it is pps1

pi4:root# ppstest /dev/pps0
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1655239442.996967522, sequence: 49 - clear  0.000000000, sequence: 0
source 0 - assert 1655239443.996906114, sequence: 50 - clear  0.000000000, sequence: 0
source 0 - assert 1655239444.996843175, sequence: 51 - clear  0.000000000, sequence: 0
source 0 - assert 1655239445.996787475, sequence: 52 - clear  0.000000000, sequence: 0

If this is the result then it’s fine.

To see if data are received run

minicom -b 9600 -o -D /dev/serial0

You should see a lot of clear text data coming from the GPS module. Of course the speed could be a different. If you see some wired character then it’s the wrong speed. In my case it’s working with 9600 bd.

Now it’s time to start gpsd and see if it is working

/usr/local/sbin/gpsd -n -s 9600 /dev/serial0 /dev/pps0

Now the following test should bring some results:

pi4:root# ntpshmmon
ntpshmmon: version 3.24.1~dev
#      Name  Seen@                 Clock                 Real                 L Prc
sample NTP0  1655647858.246635278  1655647858.161288573  1655647858.000016114 0  -1
sample NTP2  1655647858.246747648  1655647858.000497546  1655647858.000000000 0 -20
sample NTP2  1655647859.000767703  1655647859.000496185  1655647859.000000000 0 -20
sample NTP0  1655647859.152066030  1655647859.151809902  1655647859.000018310 0  -1
sample NTP2  1655647860.001379136  1655647860.000496214  1655647860.000000000 0 -20

To verify the working daemon run cgps -s -u m. You should see some satellite information.

Now it’s time for ntpd

The relevant part in /etc/ntp.conf is the following

# pps needs another server as peer
# for easy start I take another stratum-1 in my network
server minpoll 4 maxpoll 4 prefer

# Enabling PPS/ATOM support
server minpoll 4 maxpoll 4
fudge refid PPS time1 0.000500
fudge flag3 1 flag4 1  # enable kernel PLL/FLL clock discipline and clockstats

# gpsd shared memory clock
server minpoll 4 maxpoll 4 # PPS requires at least one preferred peer
fudge refid GPS
fudge time1 +0.15 flag4 1 # coarse processing delay offset

The time parameter “time1” you have to adjust for your situation. And of course several other configuration lines are necessary. If ntp.conf is ready start the deamon.

After some time you should see:

pi4:root# ntpq -pn
     remote           refid      st t when poll reach   delay   offset  jitter
o127.127.22.0    .PPS.            0 l    5   16  377    0.000   +0.001   0.001
+    .GPS.            0 l    3   16  377    0.000   +5.908   2.857
* .GPS.            1 u   10   16  377    0.712   +0.243  21.012

That’s it.

Just a word about NTP classic.

As you can see the current and latest version of NTP is very old. I am not sure how long it will be available. There are alternatives, for example ntpsec.

But there is one reason. For this see my other blog https://blog.mayer.tv/2022/06/20/NTP-classic-with-.ntprc-file.html