I have two serial ports, one provided via motherboard (/dev/ttyS0) and one from PCIE to RS232 card (Startech 2S952) with Oxford chip (/dev/ttyS1) (there is /dev/ttyS2 but it does not enter this story). How do I interpret baud speed in my case?

[    1.111618] 00:03: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
[    1.112543] 0000:08:00.0: ttyS1 at I/O 0xf010 (irq = 40, base_baud = 4000000) is a 16550A

I attached a logic analyzer to the Tx/Rx lines of the serial port. When I do:

stty -F /dev/ttyS0 115200
echo "ABCDEFGH" > /dev/ttyS0

then I can decode "ABCDEFGH" string followed by 0x0D 0x0A on the logic analyzer, but I have to tell it that the baud speed is 115200. Also, when I connect a laptop with usb-serial adapter (via null modem cable) and read off the serial port, I get a meaningful output only when I set the receiver to 115200. This is as I understand it should be.

Now with /dev/ttyS1:

stty -F /dev/ttyS1 115200
echo "ABCDEFGH" > /dev/ttyS1

I clearly see in the logic analyzed that my message is significantly slower in terms of milliseconds. In fact, it is approx 34.7(2) times slower and 40000000/115200 = 34.7(2). In particular, a receiver laptop receives a message consisting of several 0x00's. When I set to 3200 baud, it sees gibberish. Evidently the message is in fact being transmitted with 115200/34.6 = 3339.13... bps.

With /dev/ttyS1:

stty -F /dev/ttyS1 4000000
echo "ABCDEFGH" > /dev/ttyS1

The communication to /dev/ttyS1 occurs with bit duration matching what one expects from 115200.

Then it would mean in my case:

[    1.112543] 0000:08:00.0: ttyS1 at I/O 0xf010 (irq = 40, base_baud = 4000000) is a 16550A

Should be interpreted "4000000" is frequency of some internal oscillator that results in 115200 transmission in the real world. I would expect this value to be internal to the hardware and hidden deep inside the driver.

What am I missing? This is the first time ever I have used a serial port, so I am completely lost.

If I pass "console=ttyS1,4000000n8" as a kernel parameter, then I am able to communicate over serial with setting 115200 on the laptop.

  • Did you need to download and install drivers from startech.com? Also, how have you configured the jumpers on the board?
    – Bravo
    Nov 28, 2021 at 23:16
  • I configured them as "Dos/Windows". Star-tech has just Linux 2.4 and Linux 2.6 drivers. So I am using default driver from 5.10 kernel. The other Jumper configuration "Windows" changes two things: /dev/ttyS1 gets configurated as MMIO (port is then 0x0000), but any attempt to echo to it from command line "hangs" with no output on Tx/Rx whatsoever.
    – lacek
    Nov 29, 2021 at 0:00
  • ouch - so linux supports the device out of the box - I take it it loads some kernel modules ... any configuration parameters for the modules?
    – Bravo
    Nov 29, 2021 at 0:03
  • None. Found though in the description of the "serial" module (which serves this pcie card) the notion of "divisor". sheep-thrills.net/Linux_custom_serial_baudrate.html By default "divisor" is set (setserial /dev/ttyS1 -a ) to the value of "0". I still don't see why 4000000 translates to 115200 in reality. It may have to something to do with the 5 undocumented jumpers on the card. There are 3 states for each jumper, so there are 243 configurations in total. I doubt if I will be able test them all.... I will try to get that infro from startech first.
    – lacek
    Nov 29, 2021 at 0:17
  • So for whatever reason, the kernel thinks the clock on the port runs faster than it does. Yes, one would hope that sort of stuff would be dealt with by the driver, but there's piles and piles of serial port devices, so I guess the driver could be wrong. Based on a quick search, the card has jumpers for setting the speed, but the choices I found were 115k and 460k, not 4000000, so that doesn't exactly match. Anyway, setserial looks to have a baud_base option, so see what happens if you do setserial /dev/ttyS1 baud_base 115200 ?
    – ilkkachu
    Nov 29, 2021 at 0:18

1 Answer 1


So, on a guess, it seems that for whatever reason, the kernel has the wrong idea of the base clock running on that card. Serial ports are simple devices and I wouldn't be surprised if there's no standard way for the system to find that out from the card. At least in some contexts, the part that gets configured is a divisor applied to the base clock, and getting that requires knowing the actual base clock.

(That card does have jumpers for setting the max speed, so perhaps it has some way of telling the setting to a driver that supports it.)

Anyway, setserial looks to have a baud_base option, and I'm guessing using that might help to manually fix the issue:

setserial /dev/ttyS1 baud_base 115200
  • Indeed it did help.
    – lacek
    Nov 29, 2021 at 0:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .