r6 - 2013-11-16 - 12:55:31 - RobWindgassenYou are here: NTP >  Sandbox Web > TWikiUsers > RobWindgassen > RobWindgassenSandbox > HowtoPpsOnRaspberryPi
NTP users are strongly urged to take immediate action to ensure that their NTP daemons are not susceptible to being used in distributed denial-of-service (DDoS) attacks. Please also take this opportunity to defeat denial-of-service attacks by implementing Ingress and Egress filtering through BCP38.

ntp-4.2.8p15 was released on 23 June 2020. It addresses 1 medium-severity security issue in ntpd, and provides 13 non-security bugfixes over 4.2.8p13.

Please see the NTP Security Notice for vulnerability and mitigation details.

Are you using Autokey in production? If so, please contact Harlan - he's got some questions for you.

Howto get PPS working on a Raspberry Pi


The Raspberry Pi is a low cost platform that with its generic IO pins (GPIO) it is suited to attach a GPS with PPS support.
But the stock Pi kernel is (1) not well configured for PPS and (2) somehow it must be configured to assign a desired GPIO pin as PPS input. Furthermore the ATOM reference clock driver has not been enabled with the debian ntp package.

To start with the second one, Hauke Lampe (https://github.com/lampeh) has created a patch for that. It assigns GPIO pin 18 as PPS input. That is the pin next to the RXD of the serial port in the Pi's pin mapping

To get the raspberry kernel configuration properly the options

  • CONFIG_PPS ("PPS support")
  • CONFIG_NTP_PPS ("PPS kernel consumer support")

must be set. But it is only possible see and set the second when "tickless system" CONFIG_NO_HZ is turned off. The raspberry kernel turns this on by default making things a little harder when you are not aware of this.

When the CONFIG_NTP_PPS is not turned on and CONFIG_NO_HZ is, as is by default, it is possible to turn on CONFIG_PPS and get things running, more or less, but you may notice that the reported jitter in the loopstats file will be zero (see http://bugs.ntp.org/show_bug.cgi?id=2314).. The observed dynamic behaviour of the system, correcting the clock rate so that offset becomes small, is also different. With the proper kernel settings it converges faster and the reported offsets in the loopstats file get under 1 μs. With the "wrong" kernel settings I couldn't get that. I didn't test it but may be turning CONFIG_NO_HZ off for non-kernel-PPS configurations improves the dynamic behaviour too.

On kernel versions

My raspberry pi was running a 3.6.11 kernel. I downloaded the latest source for the 3.6.11 series, it is in the archive under rpi-3.6.y.
If you use or want to use another version of the kernel you have to adapt this version number in the following procedure accordingly.

In the case you want to use another kernel version than currently in use on your Pi check http://elinux.org/RPi_Kernel_Compilation, you may need to upgrade bootcode also (and in doing so making backups is recommended).

The procedure

The procedure below roughly follows http://elinux.org/RPi_Kernel_Compilation but assumes the kernel is being built on the Raspberry Pi (i.e. no cross compiling) and it's already running the same raspbian kernel version, and thus skips things like bootcode, needed when installing a different kernel for the first time.

Get the raspberry kernel. It can be downloadeded from https://github.com/raspberrypi/linux. It seems that downloading the zip files doesn't work and causes 'symlink error: File name too long' when unzipping. Downloading the .tar.gz works ok, but the downloaded file is missing the proper suffix and must be renamed.

 $ mkdir ppskernel
 $ cd ppskernel
 $ wget https://github.com/raspberrypi/linux/archive/rpi-3.6.y.tar.gz
 $ mv rpi-3.6.y rpi-3.6.y.tar.gz
 $ tar -xzf  rpi-3.6.y.tar.gz

Get the Lampeh patch from https://raw.github.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff in the ppskernel directory

 $ wget https://raw.github.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff

Apply the patch:

 $ HERE=$(pwd)
 $ cd linux-rpi-3.6.y/arch/arm/mach-bcm2708/
 $ patch --backup bcm2708.c < $HERE/linux-rpi-pps-gpio-bcm2708.diff
 $ cd $HERE

Go into the kernel source directory and get the current configuration of the running system

$ cd linux-rpi-3.6.y
$ make mrproper
$ zcat /proc/config.gz > .config
$ make oldconfig

Adapt the kernel configuration

$ make menuconfig

Now first make sure "tickless system" is off. Navigate through the menu like

     General setup --->
        Timers subsystem --->
            [ ] Tickless System (Dynamic Ticks) 

Enable "Generic memory-mapped GPIO controller support"

    Device Drivers --->
     -*- GPIO Support  --->
        --- GPIO Support
        [ ]   Debug GPIO calls
        [*]   /sys/class/gpio/... (sysfs interface)
              *** Memory mapped GPIO drivers: ***
        <*>   Generic memory-mapped GPIO controller support (MMIO platform”‚
       (no other options set here) 

Next turn on PPS support

    Device Drivers --->
        PPS support --->
            <M> PPS support  
            [ ]    PPS debugging messages
            [*]    PPS kernel consumer support   
                   *** PPS clients support ***         
            < >    Kernel timer client (Testing client, use for debug)
            < >    PPS line discipline
            <M>    PPS client using GPIO
                   *** PPS generators support *** 

Exit the menu and confirm to save the new kernel configuration file.

Now you can build a new kernel. Beware that this may take several hours.

 $ make 
 $ make modules

The next steps put the binaries of loadable modules and the kernel at their target postion and this must be performed with root privilege. To be sure the old kernel is left as is the new kernel is named kernel_new.img.

 $ sudo -i
 # cd ~pi/ppskernel/linux-rpi-3.6.y
 # make modules_install
 # cp ./arch/arm/boot/zImage /boot/kernel_new.img

Edit /boot/config.txt to add the new kernel name. I use vi

 # vi /boot/config.txt 

and change/add the text that it looks like (the kernel= line may be missing, by default it uses kernel.img)


Now reboot the system.

 # reboot

Testing the new kernel

# modprobe pps-gpio
# dmesg|tail

Shall produce output that looks like

 pps pps0: new PPS source pps-gpio.-1
 pps pps0: Registered IRQ 188 as PPS source


# apt-get install pps-tools
# ppstest /dev/pps0

shall produce output like

trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1383433355.999955687, sequence: 18201 - clear  0.000000000, sequence: 0
source 0 - assert 1383433356.999961056, sequence: 18202 - clear  0.000000000, sequence: 0
source 0 - assert 1383433357.999955419, sequence: 18203 - clear  0.000000000, sequence: 0
source 0 - assert 1383433358.999955780, sequence: 18204 - clear  0.000000000, sequence: 0
source 0 - assert 1383433359.999955141, sequence: 18205 - clear  0.000000000, sequence: 0

[Okay I cheated a bit with the above output: I captured it after I had got ntpd running as you can see by the fraction of the seconds.]

When this went fine the pps-gpio module can be loaded automatically at startup by editing /etc/modules

# vi /etc/modules

and add the following lines

# kernel mode PPS (for ntp)

Configure ntp daemon with ATOM enabled

The ntp version that comes with debian has been compiled without ATOM reference clock, the one that supprt kernel PPS.

When selecting the ATOM reference clock, clock type 22, in your /etc/ntp.conf file and the ntp daemon does not support it (yet), this will be repored in /var/log/syslog when ntp is started:

Nov  2 23:49:27 rasp01 ntpd[3900]: peers refreshed
Nov  2 23:49:27 rasp01 ntpd[3900]: Listening on routing socket on fd #19 for interface updates
Nov  2 23:46:47 rasp01 ntpd[3796]: refclock_newpeer: clock type 22 invalid

There are different ways to get around this. The standard configure, make, make install way. Although this is straightforward it may clash with the debian package administration.

A. Using debian package system

Compiling using the debian package sources: Edit /etc/apt/sources.list. Duplicate the first line

deb http://mirrordirector.raspbian.org/raspbian/ wheezy .... etc

so that you have two copies of it.

deb http://mirrordirector.raspbian.org/raspbian/ wheezy .... etc
deb http://mirrordirector.raspbian.org/raspbian/ wheezy .... etc

Change in the second one the first word, deb, to deb-src so that it looks like

deb http://mirrordirector.raspbian.org/raspbian/ wheezy  .... etc
deb-src http://mirrordirector.raspbian.org/raspbian/ wheezy  .... etc

and save it.

Get sources

# apt-get build-dep ntp
# apt-get source ntp

In my case this will create a ntp-4.2.6.p5+dfsg directory

# cd ntp-4.2.6.p5+dfsg/debian

Edit the ./debian/rules file and add --enable-ATOM to the configure invocation so that it looks like

        ./configure CFLAGS='$(CFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' \
                --prefix=/usr \
                --enable-all-clocks --enable-parse-clocks --enable-SHM \
                --disable-debugging --sysconfdir=/var/lib/ntp \
                --with-sntp=no \
                --with-lineeditlibs=edit \
                --without-ntpsnmpd \
                --disable-local-libopts \
                --enable-ntp-signd \
                --disable-dependency-tracking \
                --with-openssl-libdir=/usr/lib/$(DEB_HOST_MULTIARCH) \

Note the the line before --enable-ATOM ends with a backslash symbol (\) to indicate a line continuation symbol. Change the ./debian/changelog file so that the version number between parenthesis is increased to just below the next number. E.g. change 4.2.6.p5+dfsg-2 to 4.2.6.p5+dfsg-3~pps1.


# dpkg-buildpackage -b

Install the new package

# dpkg -i ntp_4.2.6.p5+dfsg-3~pps1_armhf.deb

B. Configure / make / make install

For when you don't care much about the debian package administration for ntp - you do it yourself anyhow. Download ntp (see http://www.ntp.org/downloads.html for current release) and unpack it

$ wget http://www.eecis.udel.edu/~ntp/ntp_spool/ntp4/ntp-4.2/ntp-4.2.6p5.tar.gz
$ tar -xzf ntp-4.2.6p5.tar.gz

Configure and build

$ cd ntp-4.2.6p5
$ ./configure --prefix=/usr  \
          --enable-all-clocks --enable-parse-clocks --enable-SHM \
          --disable-debugging --sysconfdir=/var/lib/ntp \
          --without-ntpsnmpd \
          --disable-local-libopts \
          --enable-ntp-signd \
$ make
$ sudo make install

And you are done.

Note that the --prefix option determines where the executables are installed. With --prefix=/usr they are placed in the same locations as debian does.

E.g. with --prefix=/usr the root priviliged ntpd is placed in /usr/sbin/ but ordinary user executable ntpq is placed in /usr/bin/ .

-- RobWindgassen - 2013-11-16

Edit | WYSIWYG | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r6 < r5 < r4 < r3 < r2 | More topic actions
SSL security by CAcert
Get the CAcert Root Certificate
This site is powered by the TWiki collaboration platform
IPv6 Ready
Copyright &© 1999-2021 by the contributing authors. All material on this collaboration platform is the property of the contributing authors. Ideas, requests, problems regarding the site? Send feedback