0

enter image description here

I have got user-space app ready, device file mknoded, device driver insmoded into kernel, and there is the device with UART protocol. I am trying to find out what happens between Device Driver (it has base address and IRQ line number of the Hardware) and Hardware. When user-space app raises a request device driver with base address of the hardware would handle it and when hardware want to raise a request it activates IRQ line.

Question:

  1. Do I need to dump code somewhere like we do in 8051 micro-controller?
  2. When should I switch-on the device?

I am missing the flow.

  • Are we talking about an add-on PCI/PCIe card with a UART on it, a device with a built-in USB-to-serial converter, a serial-connected device connected to a built-in serial port on the motherboard, or something else? Traditional PC UARTs are legacy devices: if they exist in the system, they are generally expected to be in the same I/O addresses the original IBM PC/AT had them, back in year 1984. – telcoM Jan 31 at 12:05
  • Add-on PCI/PCIe card with a UART on it. I don't think that there is a need to dump code into PCI/PCIe cards. – Arshad Nazeer Jan 31 at 12:42
  • I mean, the driver code would run in kernel-space and the device need not have memory to burn code into it. – Arshad Nazeer Jan 31 at 12:48
  • The flow that I am missing is that if I have user-space app ready, device file mknoded, device driver insmoded into kernel, and hardware ready then how do I make the device functional? I need to switch ON the device and automatically the device would start to run based on code in Device Driver Module? – Arshad Nazeer Jan 31 at 12:57
1

A PCI/PCIe bus has hardware autoconfiguration, so the Linux kernel includes a PCI bus driver that can read the hardware IDs of all PCI/PCIe devices. With lspci -nn, you can see these IDs yourself.

If there is no driver already loaded for the hardware at that point, the kernel will generate a driver module load request, which is equivalent to:

modprobe pci:v0000<PCI vendor ID>d000<PCI device ID>sv<subvendor ID>sd<subdevice ID>bc<base class ID>sc<subclass ID>i<programming interface ID>

Driver modules are supposed to include the corresponding modalias information, which is used by modprobe to find the matching module. If you run modprobe -c | grep pci:, you'll see the modalias lines for all the currently-installed driver modules.

After the driver is loaded (and/or if there are any kernel-level PCI(e) hot-plug events, in hot-plug capable hardware) the driver gets to look for hardware the driver knows about. If the driver finds a device it can run, it will usually trigger an udev hot-plug event to automatically create the necessary device file.

You can use udev rules to modify the path, name, ownership and permissions of the device file, and/or to run arbitrary script actions, if the defaults are not suitable for your use case. Manual mknod should not be necessary in most cases, and since Linux has been using a non-persistent /dev device filesystem since kernel version 2.6, the effect of any manual mknod commands will be lost at next reboot anyway.

The driver may take further steps to interrogate/initialize the device as soon as the device is detected, or the driver may simply set up the kernel-side infrastructure corresponding to the device node and wait for input from the userspace.

If the driver does not find any relevant hardware, it remains loaded in memory, waiting for kernel-level hot-plug events that might tell it to look for devices again.

But a PCI(e) UART card is most likely going to be detected as just a serial port device (i.e. a /dev/ttyS* device). Because serial port technology is so old, there is no guaranteed way to probe a serial port to identify what's connected to the port; there are some detection schemes, but in Linux these are usually implemented in userspace, like gpsd for GPS receiver devices and ModemManager for 3G/4G wireless modems. These services will look for serial ports, check the state of the handshaking lines of the port(s) and if it looks like there is something connected (i.e. the incoming DSR line of the serial port is active), they will look for incoming data and/or send some standard query strings.

For example, ModemManager might send AT to a new serial port: if the device responds with OK, the device at the other end seems to understand classic Hayes AT commands, so it might be a modem of some sort; then ModemManager will send further commands to identify it more accurately.

Such active probing may well interfere with some uses of UART devices. If necessary, you can use udev rules to tell ModemManager that it should completely ignore a particular UART device.

For example, I have a system with a PCIe serial port card:

# lspci -nn
...
04:00.0 Serial controller [0700]: Oxford Semiconductor Ltd OXPCIe952 Dual 16C950 UART [1415:c158]
...

It has two ports, and running udevadm info -q all -a -n /dev/ttyS<number> for all my /dev/ttyS* devices allows me to identify them. The first port has an udev attribute ATTR{line}=="1" and the second one has ATTR{line}=="2".

I could now connect my special serial device to port #1 of this card, and write an udev rule like this into, for example, file /etc/udev/rules.d/99-my-uart-device.rules:

SUBSYSTEM=="tty", DRIVERS=="serial", ATTRS{vendor}=="0x1415", ATTRS{device}=="0xc158", ATTRS{line}=="1", ALIAS="my_serial_device", ENV{ID_MM_DEVICE_IGNORE}="1"

This rule will cause an alias name (a symbolic link) /dev/my_serial_device to be created to always refer to port #1 of that serial port card, no matter what other UART-like devices might be added to the system and what order they happen to be detected in. It will also tell ModemManager to not probe this port (the ENV{ID_MM_DEVICE_IGNORE}="1" part).

I could now set up an application to use /dev/my_serial_device instead of e.g. /dev/ttyS1 and trust that it will always be using the correct physical serial port to communicate with the device.

The serial port card is powered by the PCIe slot, so it will always power on and be detectable as soon as the computer does. The device connected to the port could remain powered off until just before starting the application that uses the device.

  • What if the device device is not hot plug capable hardware? I can load driver and connect the hardware with switch on. Will knowing device base address and IRQ in device driver code sufficient to make a activity happen between device driver and hardware? – Arshad Nazeer Feb 1 at 15:27
  • I can know base address and use them in device driver code in inb() and outb() and the hardware will work? – Arshad Nazeer Feb 1 at 15:38

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.