Problem with serial-getty@ttyAMA0.service on an NTP server

After setting up an NTP server on an RPi 4 using a GPS module (serial), I have the following problem.

Under dietpi-config-4-Serial/UART, ttyAMA0 console and ttyS0 (mini UART) device must be set to ON for the whole thing to work.
So in the cmdline.txt it says console=ttyAMA0,115200.
After a restart, the output under cgps or gpsmon no longer works, as gpsd.service outputs ttyAMA0 is used elsewhere.
I have now found out that it is serial-getty@ttyAMA0.service that is causing the problem.
As a workaround I enter the following commands:

systemctl stop serial-getty@ttyAMA0.service

systemctl disable serial-getty@ttyAMA0.service

The whole system works fine until the next reboot and the game starts all over again.

Now to my actual question:
How can I permanently disable serial-getty@ttyAMA0.service?

Does systemctl mask serial-getty@ttyAMAO.service help?
or adding systemd.getty_auto=no to the cmdline.txt?

Before I try that, I would like to ask here what the best way is.

In various instructions for setting up an NTP server, it is often described to remove the entry console=ttyAMA0,115200 or similar from the cmdline.txt. However, if I do this, the whole thing does not work.

I would be very grateful for any information or tips!

You need to remove the console=ttyAMA0 entry from cmdline.txt, as it triggers a serial-getty as well, and furthermore spams the device with kernel logs. You can do this via dietpi-config advanced options > serial/UART as well, which also disables and masks the serial-getty unit.

In how far does it not work if you remove the console entry? Note there is a difference between disabling the serial console on ttyAMA0 and disabling the whole UART device itself. The UART device must exist, but no serial console/output must be done on it, so the GPS daemon can use it instead.

EDIT: Ah wait, in case of RPi 4, the ttyS0 device is used for GPS, at least when following the instructions and info from this issue: Add tools for easy GPS module configuration (and, ideally, setup with time servers as a timing source) · Issue #6385 · MichaIng/DietPi · GitHub
But it can be consigured either way. Important is that the device used by gpsd is not blocked by console I/O.

Thanks for the advice, but if I do what you say, it stops working.
All the instructions say as they confirm, but what should I do.

If I set the ttyAMA0 console to OFF, the entry in the cmdline.txt is no longer present and the GPS procedure no longer runs on the next restart.

Only when I use exactly the following settings, everything works:

Serial/UART

Toggle console
ttyS0 condole = OFF
ttyAMA0 console = ON

Toggle device
ttyS0 (mini UART) = ON

I’m a little confused about ttyS0 (mini UART), isn’t that the 3-pin connector that is only on the RPi 5?

I then have to stop and deactivate serial-getty@ttyAMA0.service, restart the gpsd.service and then cgps or gpsmon work perfectly.

As you can see, I can only explain everything in very layman’s terms, but it is what it is.

The GPS module used is a Waveshare LC29H(AA) Hat.

Here is some information about the system:

chronyc sources
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
#* PPS0                          0   4   377    24   -531ns[-1840ns] +/-   86ns
#? GPS                           0   4   377    24    +14ms[  +14ms] +/-  200ms
^- 130.162.222.153               2  10   377   725   +377us[ +271us] +/- 9521us
^- cloudrouter.1in1.net          2  10   377   798  +1466us[+1328us] +/-   52ms
^- where-you.at                  2  10   377   837  +1306us[+1151us] +/-   51ms
^- time1.uni-paderborn.de        2  10   377   592  -2254us[-2299us] +/-   25ms

chronyc sourcestats
Name/IP Address            NP  NR  Span  Frequency  Freq Skew  Offset  Std Dev
==============================================================================
PPS0                        6   3    79     -0.007      0.065     -4ns   501ns
GPS                         6   3    77     +7.313    154.208    +13ms  1158us
130.162.222.153            35  21  175m     -0.053      0.070    +35us   380us
cloudrouter.1in1.net       37  16  174m     -0.224      0.162    +56us   894us
where-you.at               37  22  173m     -0.210      0.177   +581us   971us
time1.uni-paderborn.de     23  14  125m     -0.134      0.109  -2967us   272us

chronyc tracking
Reference ID    : 50505330 (PPS0)
Stratum         : 1
Ref time (UTC)  : Thu May 08 18:37:43 2025
System time     : 0.000000000 seconds fast of NTP time
Last offset     : -0.000000710 seconds
RMS offset      : 0.000002546 seconds
Frequency       : 19.773 ppm fast
Residual freq   : -0.002 ppm
Skew            : 0.053 ppm
Root delay      : 0.000000001 seconds
Root dispersion : 0.000025561 seconds
Update interval : 16.0 seconds
Leap status     : Normal
| Time:        2025-05-08T18:53:18.000Z (0) ││GNSS   PRN  Elev   Azim   SNR Use│
│ Latitude:         XX.XXXXXXXX N           ││GP  3    3  27.0  111.0  39.0  Y │
│ Longitude:        XX.XXXXXXXX E           ││GP  4    4  67.0   69.0  33.0  Y │
│ Alt (HAE, MSL):     81.790,     36.818 m  ││GP  6    6  57.0  270.0  19.0  Y │
│ Speed:             0.31 km/h              ││GP  9    9  74.0  237.0  16.0  Y │
│ Track (true, var):   315.9,   4.0     deg ││GP 26   26  14.0   62.0  30.0  Y │
│ Climb:            -0.36 m/min             ││SB126   39  19.0   38.0  21.0  Y │
│ Status:         3D DGPS FIX (17 secs)     ││SB147   60   5.0  109.0  30.0  Y │
│ Long Err  (XDOP, EPX):  1.06, +/-  4.0 m  ││GL  9   73   6.0  141.0  16.0  Y │
│ Lat Err   (YDOP, EPY):  0.81, +/-  3.0 m  ││GL 16   80  30.0   91.0  17.0  Y │
│ Alt Err   (VDOP, EPV):  0.70, +/-  4.0 m  ││GL  7   71  60.0  286.0  20.0  N │
│ 2D Err    (HDOP, CEP):  0.72, +/-  3.4 m  ││GL  8   72  12.0  263.0  14.0  N │
│ 3D Err    (PDOP, SEP):  1.00, +/-  4.8 m  ││GL 21   85  17.0  194.0   0.0  N │
│ Time Err  (TDOP):       1.29              ││GA  2  302   7.0   12.0   0.0  N │
│ Geo Err   (GDOP):       2.49              ││GA  7  307  25.0   61.0  39.0  N │
│ ECEF X, VX:              n/a    n/a       ││GA  7  307  25.0   61.0  36.0  N │
│ ECEF Y, VY:              n/a    n/a       ││GA 10  310  29.0  314.0   0.0  N │
│ ECEF Z, VZ:              n/a    n/a       ││GA 11  311   5.0  325.0   0.0  N │
│ Speed Err (EPS):       +/- 28.5 km/h      ││GA 12  312  50.0  296.0  12.0  N │
│ Track Err (EPD):        n/a               ││GA 19  319  48.0  232.0  17.0  N │
│ Time offset:            0.222295040 s     ││GA 19  319  48.0  232.0  18.0  N │
│ Grid Square:            JO62nn14          ││GA 26  326  12.0  161.0   0.0  N |
|Time: 2025-05-08T18:54:37.000Z   Lat: XX XX.XXXXXX' N   Lon:  XX XX.XXXXXX' E │
└───────────────────────────────── Cooked TPV ─────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────┐
│ GNRMC GNVTG GNGGA GNGSA GPGSV GLGSV GAGSV GBGSV GNGLL                        │
└───────────────────────────────── Sentences ──────────────────────────────────┘
┌───────────────────────┌─────────────────────────┌────────────────────────────┐
│ SVID  PRN  Az El SN HU│Time:     185437.000     │Time:      185437.000       │
│GP  3    3 111 27 39  Y│Latitude:  XXXX.XXXXXX N │Latitude:  XXXX.XXXXXX      │
│GP  4    4  69 67 35  Y│Longitude: XXXX.XXXXXX E │Longitude: XXXX.XXXXXX      │
│GP  6    6 270 57 18  Y│Speed:    0.27           │Altitude:  36.705           │
│GP  9    9 237 74 18  Y│Course:   35.69          │Quality:   2   Sats: 42     │
│GP 26   26  62 14 34  Y│Status:   A        FAA:D │HDOP:      0.71             │
│SB126   39  38 19 18  Y│MagVar:                  │Geoid:     44.97            │
│SB147   60 109  5 30  Y└───────── RMC ───────────└─────────── GGA ────────────┘
│GL  9   73 140  7 17  Y┌─────────────────────────┌────────────────────────────┐
│GL 16   80  90 31 17  Y│Mode: A3 Sats: 3 4 6 9 + │UTC:           RMS:         │
│GL  6   70  52 59  0  N│DOP H=0.71 V=0.69 P=0.99 │MAJ:           MIN:         │
│GL  7   71 288 61 16  N│TOFF:  0.093029292       │ORI:           LAT:         │
│GL  8   72 264 13  0  N│PPS: -0.000000574        │LON:           ALT:         |     

You know your system inside out, could it possibly be a problem with the module, which has peculiarities?

As long as I don’t have to reboot, the world is fine for me. I could live with “my" workarount, but it would be nicer if there was a permanent solution.

Can I provide any further information?
If so, please with exact instructions on what I should do.

Thanks again for your time!

Edit: Since I was a little unsure about my statements, I set the ttyAMA0 console back to OFF, rebooted and lo and behold, no more output from cgps or gpsmon.
Then I set the ttyAMA0 console back to ON and rebooted. I had to run the workaround with serial-getty@ttyAMA0.service again, restart gpsd and everything works as it should.

Now I have installed DietPi on a completely new hardware (RPi 4 1GB).
Following the same instructions, I have created another NTP server with a GPS module (GT-U7).
The behavior regarding ttyAMA0 and agetty is exactly the same as on the other RPi 4, where the NTP server is also running.

In the meantime, I set up a dirty workaround by creating a new service:

sudo nano /etc/systemd/system/gps-setup.service

The following content is there:

[Unit]
Description=Stoppt serial-getty und startet gpsd neu
After=network.target

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'sleep 60 && systemctl stop serial-getty@ttyAMA0.service && systemctl disable serial-getty@ttyAMA0.service && systemctl restart gpsd.service'
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

I saved the file and activated the service.
Then executed the following:

sudo systemctl enable gps-setup.service
sudo systemctl start gps-setup.service

Now, after a restart, both systems work to my satisfaction.

What makes me wonder, however, is the following:

Following the same instructions, I set up the NTP server on the second hardware with PiOS Lite and none of the problems I described occurred.

Could it be that this behavior is caused by DietPi? It’s just a thought of mine, but admittedly I’m not passing judgment on it.

Because DietPi is and remains my favorite SBC OS!

You can prevent the serial-getty service from starting by masking it:

sudo systemctl mask --now serial-getty@ttyAMA0

When the cmdline entry is present, the kernel output to this console triggers the getty spawn, even if it is disabled. The other way around it is probably more logic:

  1. Disable the console in dietpi-config
  2. Add the console entry back to /boot/cmdline.txt.

But the result is exactly the same. The dietpi-config toggle also sets the mask.

I have no idea how the console entry can fix things for you. It should not do any special to the UART device, but only write kernel logs to it. This also means that currently, your GPS output should be distored whenever the kernel prints logs, which however happens rarely after boot finished.

Does journalctl -u gpsd show any relevant logs when the cmdline console entry is missing?

Thank you very much for answering my question again!
At the moment I can’t answer or test your questions as the hardware is not active due to construction work. It should be possible from the middle of next week.
But I have a few basic questions in advance to help you understand.

Under Serial/Uart settings in DietPi you have the options described above for activating ttyS0 console, ttyAMA0 console or ttyS0 device.
Why is there no ttyAMA0 device to choose from?
Under PiOS you can only activate or deactivate the serial login shell and/or the serial interface.

My “research” has shown that ttyAMA0 should be the better choice for setting up a GPS based time server, because it should be independent of the CPU frequency.
Please correct me if I am wrong!

In my humble understanding, I only need one ttyAMA0 device, which I can’t obviously select.

To summarize again, with the workaround described above, which is not really good, it works!
I don’t have these problems under PiOS, it worked straight away.

So what is my comprehension problem?

You mean for disabling the ttyAMA0 device completely? The enable_uart config.txt option toggles the primary UART only, the one which is available from the GPIO header pins 6-8-10. On RPi models without WiFi, this is ttyAMA0 by default. On RPi models with WiFi, ttyAMA0 is used for Bluetooth, and hence ttyS0 is the primary UART there, and hence the one you can enable/disable.

Thinking about it: You do not have Bluetooth enabled, do you?

Yes that should be the same: The serial login shell is the serial-getty@tty*, and the serial interface is the primary UART device itself. However, I guess in raspi-config you can toggle the getty for the primary UART, hence for ttyS0 only (on RPi 4). There is a way to swap primary and secondary UART devices, so Bluetooth would then use the mini UART ttyS0, while enable_uart would then toggle the full UART device ttyAMA0.

Yes, same as why it is used for Bluetooth by default. If you do not need the UART login console or debug output, disable the ttyS0 device entirely, so it does not fix the core frequency to 250 MHz.

Not sure what you mean with “can’t select”? It is always enabled on RPi 4. What should be needed is to disable the console output (and login prompt) on it, and assure that Bluetooth does not use it (have Bluetooth disabled). Check that the /dev/ttyAMA0 node exists. Then it can be used by gpsd without anything else messing I/O or blocking the device node. Still no idea why for you it was somewhat needed that the kernel logs there, hence the journalctl -u gpsd to see why it actually fails, if kernel logs are not done to this UART.

No, I have deliberately deactivated Bluetooth. Wifi is also deactivated.

Please excuse me if I only reply in bits and pieces, I am writing with my mobile phone, DeepL is helping me with the English translation and I am currently doing building work in my apartment, which means I have no GPS reception.

It is probably due to my partial lack of understanding of the subject that I have chosen such a strange configuration.

I got the information for the implementation from various instructions on the Internet.

Now I will try to answer as best I can.

In the config.txt enable_uart=1 is set. Does this mean that the ttyS0 device is enabled instead of the ttyAMA0 device?

If I deactivate the ttyS0 device, then the whole construct no longer works. I have tried everything, really!

The core frequency should be 500Mhz as I have set it in the config.txt.
I mean by “can’t select” that I don’t see the possibility to activate a ttyAMA0 device, in the settings I can only find a ttyS0 device.

As I said, I cannot provide a log at the moment because GPS reception is not possible. However, this is certainly necessary for a usable log.

I know it is difficult to follow a layman when you are as deeply involved in the subject as you are.
I can understand this well in my professional work in a different field.

Here is the output from journalctl:

root@adsb-feeder-falconcrest:~# journalctl -u gpsd
Mai 26 15:58:56 adsb-feeder-falconcrest systemd[1]: Starting gpsd.service - GPS (Global Positioning System) Daemon...
Mai 26 15:58:56 adsb-feeder-falconcrest systemd[1]: Started gpsd.service - GPS (Global Positioning System) Daemon.

I have looked again at your statements here and tried to find any error on my part, but I cannot find any.

I also disabled the ttyAMA0 console in the settings, disabled the workaroud(gps-setup.service) described above and gpsd did not work again.
I had to start gpsd.service manually, only then did it work correctly.
I don’t know where to start, so I think it’s better to leave it as it is now.

Without criticizing DietPi, I just wonder what is so different about PiOS that my project worked right away without any problems.

Many thanks for your efforts!

ttyS0 is additionally enabled. ttyAMA0 is always enabled on RPi 4, unless you add an additional setting to swap primary and secondary UART. Just check at /dev/tty* which one is present, and whether it matches expectations.

This sounds like you use ttyS0 with gpsd. Check it’s config and assure it uses ttyAMA0.

When enabling ttyS0 on WiFi-capable RPi models, the core frequency is forced to be 250 MHz, since the mini-UART it tied to the core frequency and would otherwise not work.

Yes, as said, it is always enabled. Unless you add dtoverlay=miniuart-bt to config.txt which assigns ttyS0 to Bluetooth (if Bluetooth is enabled) and makes ttyAMA0 the primary UART. Then enable_uart=1 would enable ttyAMA0. It toggles the primary UART, which is the one not used by/reserved for Bluetooth.

All the same, which is why I also wonder what the problem is. So gpsd does not report any error, but still does not work? Or do I remember wrong and the UART device used by GPS is configured elsewhere? I mean there needs to be an error message about it somewhere …

Here is one last attempt to explain the problem as I understand it:

  • ttyAMA0 is present in both Pi 4.
root@pi-ntp-server:~# ls /dev/tty*
/dev/tty    /dev/tty12  /dev/tty17  /dev/tty21  /dev/tty26  /dev/tty30  /dev/tty35  /dev/tty4   /dev/tty44  /dev/tty49  /dev/tty53  /dev/tty58  /dev/tty62  /dev/ttyAMA0
/dev/tty0   /dev/tty13  /dev/tty18  /dev/tty22  /dev/tty27  /dev/tty31  /dev/tty36  /dev/tty40  /dev/tty45  /dev/tty5   /dev/tty54  /dev/tty59  /dev/tty63  /dev/ttyprintk
/dev/tty1   /dev/tty14  /dev/tty19  /dev/tty23  /dev/tty28  /dev/tty32  /dev/tty37  /dev/tty41  /dev/tty46  /dev/tty50  /dev/tty55  /dev/tty6   /dev/tty7   /dev/ttyS0
/dev/tty10  /dev/tty15  /dev/tty2   /dev/tty24  /dev/tty29  /dev/tty33  /dev/tty38  /dev/tty42  /dev/tty47  /dev/tty51  /dev/tty56  /dev/tty60  /dev/tty8
/dev/tty11  /dev/tty16  /dev/tty20  /dev/tty25  /dev/tty3   /dev/tty34  /dev/tty39  /dev/tty43  /dev/tty48  /dev/tty52  /dev/tty57  /dev/tty61  /dev/tty9
  • pps0 is also available:
root@pi-ntp-server:~# ls /dev/pps*
/dev/pps0

The following entries are available in the settings under dietpi-config, some of which are probably relevant for the intended use as a GPS-based NTP server:

  • ttyS0 console OFF
  • ttyAMA0 console ON
  • ttyS0 device ON

Only with these settings, which are probably a bit strange, can I realize the NTP server function.
If I understand it correctly, I should only need a ttyAMA0 device for the function and not the ttyS0, I don’t know why it only works with these settings.

But for it to actually work, I have to stop and deactivate the ttyAMA0 console after booting either manually or via script.
After that, the system runs 24/7 without any problems.

Here is the cmdline.txt as it is when the system is running:

root=PARTUUID=deccea20-02 rootfstype=ext4 rootwait net.ifnames=0 logo.nologo console=tty1 console=ttyAMA0,115200 nohz=off

The output below also shows that theoretically everything is fine, but only with small pull-ups:

root@pi-ntp-server:~# journalctl -u gpsd
Mai 29 09:29:09 pi-ntp-server systemd[1]: Starting gpsd.service - GPS (Global Positioning System) Daemon...
Mai 29 09:29:09 pi-ntp-server systemd[1]: Started gpsd.service - GPS (Global Positioning System) Daemon.

It might also be worth mentioning that an RTC is also installed, which is why the I2C state is ON.

As already described several times, under PiOS I only had to set the serial console to OFF and the serial device to ON in the raspi-config and it worked straight away.

I am happy to repeat myself, this is not a criticism of DietPi!

Unfortunately, nobody here in the forum seems to have encountered the same problem, or is using a Pi 4 as a GPS-based NTP server.

If you can’t find a solution, that’s not a problem, because it works fine this way too!

Thank you for taking care of my request anyway, so I didn’t want to leave your last post unanswered!

Can you try to disable the ttyAMA0 console in dietpi-config, and instead add console=ttyAMA0,115200 manually to /boot/cmdline.txt? So you do not need to stop the console spawn on that UART every boot.

Also can you show whether there are other serial console services active:

systemctl | grep 'serial-getty@'

The “workaround” gps-setup.service is deactivated, ttyAMA0 console is OFF and console=ttyAMA0,115200 is entered manually in /boot/cmdline.txt and reboot.

The output of systemctl | grep 'serial-getty@' shows nothing.

But now, the NTP server no longer works or I no longer get any output with cgps -s or gpsmon.

Now I have set the ttyAMA0 console back to ON, checked the entry in the /boot/cmdline.txt (available), reactivated the gps-setup.service, restarted and lo and behold, everything works again to my satisfaction.
I don’t know where the worm is supposed to be. :thinking:

So weird, as if the service is somehow needed to enable the device. Does it work to just start and stop it:

systemctl start serial-getty@ttyAMA0
systemctl stop serial-getty@ttyAMA0

I have an idea … maybe the UART device is ready too late, respectively gpsd starts too early. So aside of above test:

mkdir -p /etc/systemd/system/gpsd.service.d
echo -e '[Unit]\nAfter=dev-ttyAMA0.device' > /etc/systemd/system/gpsd.service.d/ttyAMA0.conf

So it assures that gpsd start after the device. But then a simple restart of gpsd should also do :thinking::

systemctl restart gpsd

Also please check the device status when booting with the serial console enabled vs disabled:

systemctl status dev-ttyAMA0.device

Maybe also this works to get is working:

systemctl start dev-ttyAMA0.device
  • Status restored without workaround
  • gpsmon no output
root@pi-ntp-server:~#systemctl enable serial-getty@ttyAMA0
Einheit konnte nicht aktiviert werden: Die Unit-Datei /etc/systemd/system/serial-getty@ttyAMA0.service ist maskiert.

The service is masked.

I then entered the commands with mkdir and echo and restarted.

root@pi-ntp-server:~# systemctl status gpsd
○ gpsd.service - GPS (Global Positioning System) Daemon
     Loaded: loaded (/lib/systemd/system/gpsd.service; disabled; preset: enabled)
    Drop-In: /etc/systemd/system/gpsd.service.d
             └─ttyAMA0.conf
     Active: inactive (dead)
TriggeredBy: ● gpsd.socket
root@pi-ntp-server:~#

gpsd does not start automatically!

systemctl restart gpsd

causes

root@pi-ntp-server:~# systemctl status gpsd
● gpsd.service - GPS (Global Positioning System) Daemon
     Loaded: loaded (/lib/systemd/system/gpsd.service; disabled; preset: enabled)
    Drop-In: /etc/systemd/system/gpsd.service.d
             └─ttyAMA0.conf
     Active: active (running) since Sat 2025-05-31 21:00:46 CEST; 5s ago
TriggeredBy: ● gpsd.socket
    Process: 3547 ExecStart=/usr/sbin/gpsd -p $GPSD_OPTIONS $OPTIONS $DEVICES (code=exited, status=0/SUCCESS)
   Main PID: 3549 (gpsd)
      Tasks: 3 (limit: 1064)
        CPU: 551ms
     CGroup: /system.slice/gpsd.service
             └─3549 /usr/sbin/gpsd -p -n -G /dev/ttyAMA0 /dev/pps0

Mai 31 21:00:46 pi-ntp-server systemd[1]: Starting gpsd.service - GPS (Global Positioning System) Daemon...
Mai 31 21:00:46 pi-ntp-server systemd[1]: Started gpsd.service - GPS (Global Positioning System) Daemon.

But gpsmon does not work.

A systemctl unmask serial-getty@ttyAMA0 followed by a successful systemctl start serial-getty@ttyAMA0 and reboot did nothing new.

The gpsd service is actually disabled, is this intended?

systemctl enable gpsd

Ah, it is triggered by a socket. Then the After= thing cannot have an effect. What triggers it to start normally? chrony? Then e.g. chrony would need to start after the device is ready:

mkdir -p /etc/systemd/system/chrony.service.d
echo -e '[Unit]\nAfter=dev-ttyAMA0.device' > /etc/systemd/system/chrony.service.d/ttyAMA0.conf

And did we already test whether console=ttyAMA0 can be removed from /boot/cmdline.txt, while the console (the getty service) is enabled? Since the cmdline entry alone does not solve the issue, is seems to be something the getty service start implies.

Yeah I forgot about the mask. So the full test, with console disabled, would be:

systemctl unmask serial-getty@ttyAMA0
systemctl start serial-getty@ttyAMA0
systemctl stop serial-getty@ttyAMA0