I'm not sure at which level I am having a problem.

System is a LeopardBoard DM368 running TI's own SDK / LSP / BusyBox kernel, the core Linux kernel is 2.6.x so using serial_core.c driver model.

By default the system has one UART enabled, UART0, mounted as /dev/ttyS0 which is also used/invoked via the bootargs console=ttyS0,115200n8 earlyprintk.

We want to enable UART1 as /dev/ttyS1, so have gone through the low-level board initialisation code which sets up the pinmux, clocks, etc.

On booting, the low-level init reports (via printk's I added in) that it's enabled the UART1, and the driver code reports happiness too:

[    0.547812] serial8250.0: ttyS0 at MMIO 0x1c20000 (irq = 40) is a 16550A
[    0.569849] serial8250.0: ttyS1 at MMIO 0x1d06000 (irq = 41) is a 16550A

However, the port does not appear in /dev/ (as /dev/ttyS1), and there are discrepancies with its status (flow control bits) which I suspect may be causing it to hang / never transmit:

cat /proc/tty/driver/serial
serinfo:1.0 driver revision:
0: uart:16550A mmio:0x01C20000 irq:40 tx:97998 rx:0 CTS|DSR
1: uart:16550A mmio:0x01D06000 irq:41 tx:0 rx:0 DSR

If I try to configure or modify it from the command line I get an error:

>: stty -F /dev/ttyS1
stty: can't open '/dev/ttyS1': No such file or directory

Bizarrely, if I change the bootargs to console=ttyS1,115200n8 earlyprintk the port works perfectly, and ttyS0 is still initialised correctly and works too:

cat /proc/tty/driver/serial
serinfo:1.0 driver revision:
0: uart:16550A mmio:0x01C20000 irq:40 tx:0 rx:0 CTS|DSR
1: uart:16550A mmio:0x01D06000 irq:41 tx:11563 rx:0 RTS|DTR|DSR

Now, that would be fine, but our bootloader must use UART0 so it would be nice to keep all the console stuff on ttyS0 and have ttyS1 for our secondary comms.

I inserted a couple of printk's into serial_core.c and it seems like uart_open() is never being called for ttyS1, I'm assuming it's something in the Linux init/startup sequence that needs modifying?

Edited: because I had fooled myself by doing an echo >/dev/ttyS1 which had created a file called /dev/ttyS1, which clouded matters somewhat. I'm now 99% sure /dev/ttyS1 is never created.

  • Have you tried to mknod the ttyS1 or the TI's SDK use some devfs udev?
    – Alex
    Oct 16 '13 at 15:33
  • I haven't mknoded, no, but I'll look into it. How would I find out if the SDK uses udev or devfs?
    – John U
    Oct 16 '13 at 16:26
  • Use mount to see how your /dev is mounted, it should mention udev or devfs if it is.
    – Alex
    Oct 16 '13 at 16:38

mknod /dev/ttyS1 c 4 65

(if /dev is read-only use any writable directory mounted without the option nodev)

If the node is created without errors you can check if your patch is working reading/writing to the node or with any terminal emulator.

The problem is that the node isn't created?

If you're using some auto-magic dynamic dev fs like devfs or udev probably there's some registration problem in the middle (but I think not as most of the code is the same to bring up the ttyS0 and I guess adding a serial port is like adding a configuration row in an array in some platform file).

If you aren't using dev fs like that probably you have a MAKEDEV file somewhere in your build tree where to manually add a line for your new device to be created statically. I've seen also a system where the dev nodes were created by an init script.

  • You have hit the nail on the head, mknod does the trick! Thanks very much, you've saved me a world of pain.
    – John U
    Oct 17 '13 at 12:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.