Finding out about drivers at runtime

Once you have a running Linux system, it is useful to know which device drivers are loaded and what state they are in. You can find out a lot by reading the files in /proc and /sys.

First of all, you can list the character and block device drivers currently loaded and active by reading /proc/devices:

# cat /proc/devices

Character devices:

  1 mem
  2 pty
  3 ttyp
  4 /dev/vc/0
  4 tty
  4 ttyS
  5 /dev/tty
  5 /dev/console
  5 /dev/ptmx
  7 vcs
 10 misc
 13 input
 29 fb
 81 video4linux
 89 i2c
 90 mtd
116 alsa
128 ptm
136 pts
153 spi
180 usb
189 usb_device
204 ttySC
204 ttyAMA
207 ttymxc
226 drm
239 ttyLP
240 ttyTHS
241 ttySiRF
242 ttyPS
243 ttyWMT
244 ttyAS
245 ttyO
246 ttyMSM
247 ttyAML
248 bsg
249 iio
250 watchdog
251 ptp
252 pps
253 media
254 rtc

Block devices:

259 blkext
  7 loop
  8 sd
 11 sr
 31 mtdblock
 65 sd
 66 sd
 67 sd
 68 sd
 69 sd
 70 sd
 71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
179 mmc

For each driver, you can see the major number and the base name. However, this does not tell you how many devices each driver is attached to. It only shows ttyAMA but gives you no clue that it is attached to four real UARTS. I will come back to that later when I look at sysfs. If you are using a device manager such as mdev, udev, or devtmpfs, you can list the character and block device interfaces by looking in /dev.

You can also list network interfaces using ifconfig or ip:

# ip link show

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT qlen 1000
    link/ether 54:4a:16:bb:b7:03 brd ff:ff:ff:ff:ff:ff

3: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether aa:fb:7f:5e:a8:d5 brd ff:ff:ff:ff:ff:ff

You can also find out about devices attached to USB or PCI buses using the well-known commands lsusb and lspci. There is information about them in the respective manuals and plenty of online guides, so I will not describe them any further here.

The really interesting information is in sysfs, which is the next topic.

Getting information from sysfs

You can define sysfs in a pedantic way as a representation of kernel objects, attributes and relationships. A kernel object is a directory, an attribute is a file, and a relationship is a symbolic link from one object to another.

From a more practical point of view, since the Linux device driver model, which was introduced in version 2.6, represents all devices and drivers as kernel objects. You can see the kernel's view of the system laid out before you by looking in /sys, as shown here:

# ls /sys

block  bus  class  dev  devices  firmware  fs  kernel  module  power

In the context of discovering information about devices and drivers, I will look at three of the directories: devices, class, and block.

The devices: /sys/devices

This is the kernel's view of the devices discovered since boot and how they are connected to each other. It is organized at the top level by the system bus, so what you see varies from one system to another. This is the QEMU emulation of the Versatile Express:

# ls
 /sys/devices
armv7_cortex_a9  platform      system
breakpoint       software      virtual

There are three directories that are present on all systems:

  • system: This contains devices at the heart of the system, including CPUs and clocks.
  • virtual: This contains devices that are memory-based. You will find the memory devices that appear as /dev/null, /dev/random, and /dev/zero in virtual/mem. You will find the loopback device, lo, in virtual/net.
  • platform: This is a catch-all for devices that are not connected via a conventional hardware bus. This may be almost everything on an embedded device.

The other devices appear in directories that correspond to actual system buses. For example, the PCI root bus, if there is one, appears as pci0000:00.

Navigating this hierarchy is quite hard because it requires some knowledge of the topology of your system and the pathnames become quite long and hard to remember. To make life easier, /sys/class and /sys/block offer two different views of the devices.

The drivers: /sys/class

This is a view of the device drivers presented by their type, in other words, it is a software view rather than a hardware view. Each of the subdirectories represents a class of driver and is implemented by a component of the driver framework. For example, UART devices are managed by the tty layer and you will find them in /sys/class/tty. Likewise, you will find network devices in /sys/class/net, input devices such as the keyboard, the touchscreen, and the mouse in /sys/class/input, and so on.

There is a symbolic link in each subdirectory for each instance of that type of device pointing to its representation in /sys/device.

To take a concrete example, let's look at /sys/class/tty/ttyAMA0:

# cd  /sys/class/tty/ttyAMA0/
# ls
close_delay      flags            line             uartclk
closing_wait     io_type          port             uevent
custom_divisor   iomem_base       power            xmit_fifo_size
dev              iomem_reg_shift  subsystem
device           irq              type

The link device references the hardware node for the device and subsystem points back to /sys/class/tty. The others are attributes of the device. Some are specific to a UART, such as xmit_fifo_size and others apply to many types of device such as the interrupt number, irq, and the device number dev. Some attribute files are writable and allow you to tune parameters in the driver at runtime.

The dev attribute is particularly interesting. If you look at its value, you will find the following:

# cat /sys/class/tty/ttyAMA0/dev
204:64

These are the major and minor numbers of this device. This attribute is created when the driver registered this interface and it is from this file that udev and mdev read that information if they are being used without the help of devtmpfs.

The block drivers: /sys/block

There is one more view of the device model that is important: the block driver view that you will find in /sys/block. There is a subdirectory for each block device. This example is taken from a BeagleBone Black:

# ls /sys/block/

loop0  loop4  mmcblk0       ram0   ram12  ram2  ram6
loop1  loop5  mmcblk1       ram1   ram13  ram3  ram7
loop2  loop6  mmcblk1boot0  ram10  ram14  ram4  ram8
loop3  loop7  mmcblk1boot1  ram11  ram15  ram5  ram9

If you look into mmcblk1, which is the eMMC chip on this board, you can see the attributes of the interface and the partitions within it:

# cd /sys/block/mmcblk1
# ls

alignment_offset   ext_range     mmcblk1p1  ro
bdi                force_ro      mmcblk1p2  size
capability         holders       power      slaves
dev                inflight      queue      stat
device             mmcblk1boot0  range      subsystem
discard_alignment  mmcblk1boot1  removable  uevent

The conclusion, then, is that you can learn a lot about the devices (the hardware) and the drivers (the software) that are present on a system by reading sysfs.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.71.94