- Peripheral Component Interconnect Express (PCIe)
- Coldplug and Hotplug Devices
- Plug and Play
- Small Computer System Interface (SCSI)
- Serial Advanced Technology Attachment (SATA)
- Universal Serial Bus (USB)
- Interrupts (IRQ)
- Input/Output Port Addresses
- Direct Memory Access
- Drivers
- /proc/
- /sys/
- userspace /dev (udev)
- Desktop Bus (D-Bus)
- udisks
- Hardware Commands
- The Linux Kernel
- The GNU/Linux System
- Documentation
Analyzing and configuring the various components that compose a computer are an important part of maintaining a GNU/Linux system.
Note: If you are not familiar with the GNU/Linux command line interface, review the Conventions page before proceeding.
Peripheral Component Interconnect Express (PCIe)
A computer bus is the system that connects the Central Processing Unit (CPU) and Random Access Memory (RAM) with the most important peripherals. Peripheral Component Interconnect Express (PCIe) is the current standard for computer bus systems.
PCIe:
- Is a serial bus that allows independent point-to-point connections between devices (formerly, with Industry Standard Architecture (ISA) buses, all devices shared a parallel bus).
- Allows the transfer of data packets over several connections (i.e., lanes).
- Enables automatic hardware detection. Every device connected to the bus reports a code specifying its type, manufacturer, and model.
lspci
The lspci
command queries devices connected to the PCIe bus. At the beginning of each line there is the PCI ID of each device, giving its position on the PCI bus.
$ lspci | head
00:00.0 Host bridge: Intel Corporation 82G33/G31/P35/P31 Express DRAM Controller
00:01.0 VGA compatible controller: Red Hat, Inc. QXL paravirtual graphic card (rev 04)
00:02.0 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
00:02.1 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
00:02.2 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
00:02.3 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
00:02.4 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
00:02.5 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
00:02.6 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
00:1b.0 Audio device: Intel Corporation 82801I (ICH9 Family) HD Audio Controller (rev 03)
Helpful options include:
-n
- Show PCI vendor and device codes as numbers instead of looking them up in the PCI ID list.
-t
- Show a tree-like diagram containing all buses, bridges, devices, and connections between them.
-v
- Be verbose and display detailed information about all devices.
Coldplug and Hotplug Devices
Coldplug devices can be physically connected to or disconnected from the system only when the system is powered off. Hotplug devices are designed to be dynamically connected and disconnected while the system is up and running.
Several GNU/Linux components are needed to manage hotplug devices:
- sysfs
- Desktop Bus (D-Bus)
- udevd (user space /dev (udev) Daemon)
The system recognizes the device when it is connected and loads the appropriate modules.
Plug and Play
Plug and play (PnP) allows devices to be automatically configured with system resources when the system is booted. A PnP system requires three components:
- A PnP-compatible firmware
- A PnP-compatible device
- A PnP-compatible operating system
Small Computer System Interface (SCSI)
Small Computer System Interface (SCSI) drives are optimized for high-speeds and longevity. Mostly, they are used in server systems.
SCSI devices are connected via a chain. To use SCSI, a computer needs at least one host adapter. Motherboard-based and high-quality card host adapters contain a SCSI firmware that lets you boot the system from a SCSI device.
Every SCSI host adapter supports one or more buses (i.e., channels). You can use the SCSI host adapter to check which SCSI IDs are available and which are used, and which SCSI device, if any, should be used for booting. The SCSI host adapter itself counts as a device on the bus.
Each SCSI device in the chain is assigned a SCSI ID. This ID is a logical number and does not correspond to the device's location on a connector cable.
SCSI ID numbers range between 0
and 7
(narrow bus), or 0
and 15
(wide bus). Some SCSI devices have jumpers or a switch that let you select the SCSI device's ID.
On other SCSI devices, doing input/output (I/O) to the adapter sets the SCSI ID. Alternatively, the host adapter may have software that needs to be installed on the host computer that configures the SCSI ID.
The lower the SCSI ID, the lower the device’s priority. The lower the ID number, the higher the device is in the boot order.
Each SCSI device has two numbers in its ID (e.g., x:n
, where x
is the ID of the SCSI host adapter the device is connected to and n
is the ID of the device on that adapter's bus). Each SCSI device can also support several Local Unit Numbers (LUNs), e.g., the individual volumes in a Redundant Array of Independent Disks (RAID).
Every SCSI device can be described by a quadruple (ex_host,ex_channel,ex_id,ex_lun>
). Usually, ex_host,ex_channel,ex_id
are sufficient to describe the device. No two SCSI devices on the same bus can share the same ID number.
Both ends of the SCSI chain must be terminated and nothing should be terminated in between these two points. Termination can be ensured via a special plug (i.e., terminator), or switched on or off on individual devices.
There is a large variety of SCSI buses and host adapters. SCSI bus widths range from 8-bit to 16-bit. SCSI speeds range from 5MB/s to 640 MB/s.
A serial version of SCSI exists, Serial Attached SCSI (SAS), which does not require termination. SAS is closely related to Serial Advanced Technology Attachment (SATA).
SAS allows things like accessing a drive via several cable paths for redundancy by default (i.e., multipath I/O), more extensive diagnosis and logging functions, and is based on a higher signaling voltage, which allows for longer cables and larger servers. You can use SATA disk drives on a SAS backplane (but not vice versa).
From the point of view of the Linux kernel, SATA and Universal Serial Bus (USB) devices are accessed like SCSI devices and use the same infrastructure.
Serial Advanced Technology Attachment (SATA)
Serial Advanced Technology Attachment (SATA) drives are a form of Integrated Drive Electronics (IDE) drive (i.e., their disk controller is integrated into the drive itself). IDE lets computers see block devices as a sequence of numbered blocks (i.e., Logical Block Addressing) without having to know about drive geometry (i.e., Cylinders, Heads, Sectors per Track).
SATA drives are much faster than their parallel predecessors, PATA drives. Despite being serial, SATA drives are faster than PATA drives because of electrical properties of their interface, which uses differential transmission and a signaling voltage of only 0.5V instead of 5V.
SATA drives are not subject to master/slave configuration rules. Each SATA drive in a system has its own dedicated channel that greatly enhances speed and throughput.
SATA cabling is simple and uses a seven-pin connector. SATA devices can transfer data at rates from 150 MB/sec up to a maximum of 600 MB/s.
The SATA drive connected to the SATA0
connector on the system motherboard is used as the boot drive by default because it will be assigned an ID of 0
.
Solid State Drives (SSDs)
A solid-state drive (SSD) is a storage device that functions like a standard hard disk drive, using the same block-based I/O operations. Unlike a hard disk drive, which uses magnetic storage via platters, SSDs use flash memory to store data.
SSDs use the same SATA interface used by traditional hard disk drives.
Universal Serial Bus (USB)
A single Universal Serial Bus (USB) bus controller allows you to connect up to 127 USB devices. USB devices are self-configuring and hot-swappable.
When a USB device is connected to the bus, it is assigned a number between 1
and 127
as its device number, and the computer reads the device's descriptor, which includes the type of device and the type of USB port it supports. Each USB device belongs to a class of devices that are handled in a similar fashion by the computer. Classes may have subclasses that narrow down the type of device even more.
USB devices on the bus are grouped into one of three categories:
- Hubs
- Functions
- Hub and Function
Traditionally, USB used a foolproof cabling concept with different sockets for computers (A) and peripherals (B), and appropriate plugs at the end of the cables to avoid mistakes.
USB hubs can be cascaded (i.e., connecting a USB hub to a USB hub), but this is likely inadvisable.
USB implementations are backwards-compatible. These are the USB Standards:
- 1.1, 1998, 1.5 Mbit/s for keyboards, mice, modems, audio devices, etc. 12 Mbit/s for 10 Mbit/s Ethernet, disks, etc.
- 2.0, 2000, 480 Mbit/s for disks, 100 Mbit/s Ethernet, video, etc.
- 3.0, 2008, 5 Gbit/s for disks, graphics, etc.
- 3.1, 2013, 10 Gbit/s for PCIe.
- 3.2, 2017, 20 Gbit/s over USB-C.
- 4.0, 2019, 40 Gbit/s over USB-C.
lsusb
The lsusb
command lists a system's USB devices by pulling information from /var/lib/usbutils/usb.ids
. It can be used to view device numbers and names.
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 0627:0001 Adomax Technology Co., Ltd
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Add the -v
(--verbose
) option for verbose output.
Alternatively, the usbview
command can be used for more nicely displayed output (this may need to be installed from your GNU/Linux distribution's repository, e.g., # apt install usbview
, # dnf install usbview
).
Interrupts (IRQ)
Interrupts (IRQ) are used to alert the CPU that a device needs attention. Every device in the system must have an interrupt assigned.
The default IRQ assignments are:
IRQ 0
System TimerIRQ 1
KeyboardIRQ 3
COM 2 (COM stands for Communications)IRQ 4
COM 1IRQ 5
LPT 2 (LPT stands for Line Printer)IRQ 6
Floppy DriveIRQ 7
LPT 1IRQ 8
Real Time Clock
Interrupts 0
, 1
, and 8
are hard-wired. These interrupts cannot be used for any other device in the system. However, if a device with a default interrupt assignment is not installed in the system or is disabled, its interrupt can be used for another device.
IRQ 2
and 9
are the same wire on the Programmable Interrupt Controller (PIC) chips. Either one can be assigned to a device in the system, but both cannot be assigned at the same time.
Two ISA devices cannot share an interrupt. Two PCI devices can share interrupts. However, a PCI device cannot share an interrupt with an ISA device.
Input/Output Port Addresses
Input/Output (I/O) port addresses are like mailboxes for computer devices and are written in hexadecimal notation. All devices must have a unique I/O port address assigned to them and most devices support a range of I/O port addresses, as well.
The default I/O port address assignments are:
0000h
Direct Memory Access (DMA) Controller0020h
PIC 10030h
PIC 20040h
System Timer0060h
Keyboard0070h
Complementary metal–oxide–semiconductor (CMOS) Clock00C0h
DMA Controller00F0h
Math Co-processor0170h
Secondary IDE Hard Disk Controller01F0h
Primary IDE Hard Disk Controller0200h
Joystick0278h
LPT202E8h
COM402F8h
COM20378h
LPT103E8h
COM303F0h
Floppy Disk Drive Controller03F8h
COM1
Direct Memory Access
Direct memory access (DMA) channels allow a device to directly communicate with the system RAM without using the CPU. Devices must use unique DMA channels.
Drivers
Drivers are small programs that are loaded into RAM that enable the CPU to communicate with a particular hardware component. For basic system components, driver software is stored in the computer's firmware. Other components require a driver that is stored on the system drive to be loaded into RAM.
On GNU/Linux, drivers can be loaded in two ways:
- Loaded as kernel modules after the operating system has started (from
/lib/modules/
) - Compiled directly into the kernel itself
The Linux kernel's mass storage subsystem uses a three-tier architecture:
- At the bottom, there are drivers for the individual SCSI host adapters, like SATA or USB controllers.
- There is a generic middle layer.
- At the top, there are drivers for the various devices (e.g., disks, drives) that you may encounter on a SCSI bus. This includes a generic driver that is used to access devices without a specialized driver (e.g., scanners).
modprobe
You can add a module with the modprobe
command:
# modprobe ex_module_name
Modules added with modprobe
are in a subdirectory of /lib/modules/ex_kernel_version/kernel/
.
You will only rarely have to manually run modprobe
, as the kernel can mostly take care of loading modules on-demand. For example, here is an excerpt from the /lib/modules/ex_kernel_version/modules.alias
file:
alias block-major-3-* ide_generic # Block device
alias char-major-10-1 psmouse # Character-oriented device
These entries connect device files in /dev/
to the corresponding drivers. Here are long listings for two such devices, /dev/sda1
and /dev/psaux
:
$ ls -l /dev/sda1 /dev/psaux
brw-rw---- 1 root disk 3, 1 Jan 22 02:03 /dev/sda1
crw-rw---- 1 root root 10, 1 Jan 22 02:03 /dev/psaux
Above, block-major-3-*
means that for block-oriented device files with a major device number of 3
and arbitrary minor device number, like /dev/sda1
, the ide_generic
driver module is appropriate. Access to /dev/psaux
, a character-oriented device file with numbers (10,1)
is managed through the driver named by alias char-major-10-1
, specifically psmouse
.
To remove a module, you can use modprobe
's -r
(--remove
) option:
# modprobe -r ex_module_name...
If the module you try to remove is the only one depending on another module, modprobe
tries to remove the other module, as well.
/etc/modprobe.d/
/etc/modprobe.d/
is for optional module configuration files that you would like to be loaded at startup. Modules options can be defined via directives according to the following format:
options ex_module_name ex_option_name=ex_option_value
Several options can be specified with a single directive.
On a GNU/Linux system using systemd, you can create a ex_module.conf
file in this directory that contains the module name. Then, when you reboot the system, ex_module
will be automatically loaded.
To verify this, you can run the following command:
systemctl status systemd-modules-load.service
The last line should have a process ID (PID) under Process
. Copy that PID and run:
journalctl -b _PID=ex_pid
This will tell you if ex_module
was loaded (the -b
option above tells journalctl
to give information for the current boot).
Module Commands
The following command-line utilities can be used to manage kernel modules:
lsmod
- Show loaded kernel modules, along with dependencies for those modules.
modinfo ex_module_name...
,modinfo ex_filename...
- View module information. If the module name is not a filename, the
/lib/modules/ex_kernel_version
directory is searched. # depmod
- Build a module dependency list. If module filenames are provided to this command as arguments, only those modules are examined.
- This command creates/updates the
/lib/modules/ex_kernel_version/modules.dep
file (which lists dependencies between modules)./lib/modules/ex_kernel_version/modules.dep
helps other kernel module management utilities ensure that dependent modules are loaded whenever you load a module. # modprobe ex_module_name
- Add a module to the Linux kernel. Module dependencies are taken into account.
- This command uses the files in
/lib/modules/ex_kernel_version/
to determine which kernel modules should be loaded at boot and in/etc/modprobe.d/
for optional configuration files (in modern GNU/Linux distributions, udev does automatic module handling). # modprobe -r ex_module_name...
,# modprobe --remove ex_module_name...
- Remove a module from the Linux kernel. Module dependencies are taken into account.
/proc/
Information about system hardware can be viewed within the /proc/
directory. Every process also has its own directory in /proc/
.
The environment variables associated with each process are located in the environ
file within a specific process's subdirectory (e.g., /proc/ex_pid/environ
). The variables in this file are separated by zero bytes, which can be converted to newlines with the tr
command (e.g., tr '\0' '\n' < /proc/ex_pid/environ
).
Some important /proc/
files/subdirectories include:
/proc/cpuinfo
- Contains details about the CPU.
/proc/devices
- Contains a list of installed devices.
/proc/dma
- Contains a list of DMA channel assignments.
/proc/driver/rtc
- Contains real-time clock information.
/proc/interrupts
- Contains a list of IRQ assignments. Also contains the interrupt number, number of interrupts triggered, and drivers handling that particular interrupt.
/proc/iomem
- Contains the current map of the system's memory for each physical device.
/proc/ioports
- Contains a list of currently registered port regions used for input or output communication with a device.
/proc/kcore
- Contains the computer's complete RAM and is required for debugging the kernel. It is probably best to stay away from this file.
/proc/loadavg
- Contains three numbers (i.e., the system load averages) measuring the CPU load during the last 1, 5, and 15 minutes.
/proc/meminfo
- Contains memory information.
/proc/modules
- Contains a list of all kernel modules currently being used.
/proc/scsi/
- Contains files with information about SCSI devices, if you are using a SCSI adapter.
/proc/swaps
- Contains currently active swap areas.
/proc/version
- Contains information about the version of the Linux kernel.
/sys/
In addition to /proc/
, the /sys/
directory also provides information about the hardware installed in the system.
The Linux kernel developers created /sys/
because of the uncontrolled growth of entries under /proc/
, specifically those whose purpose did not have anything to do with processes. Anything that does not involve processes is slowly being moved to the sysfs pseudo file system that is usually mounted on /sys/
, where stricter rules apply.
The /sys/
directory is organized in a tree structure grouped by:
- The hardware bus
- The hardware devices
- Their associated drivers
Each bus directory in /sys/bus/
(e.g., /sys/bus/pci/
) has two subdirectories:
devices
drivers
The /sys/bus/ex_bus/devices/
subdirectory contains entries for every device on that bus (each entry is a symbolic link to a directory stored in /sys/devices/
, e.g., the /sys/bus/usb/devices/usb1
symbolic link points to the /sys/devices/pci0000:00/0000:00:14.0/usb1/
directory):
$ ls -l '/sys/bus/usb/devices/' | tail -n 5
lrwxrwxrwx. 1 root root 0 Dec 29 12:20 2-4.4:1.0 -> ../../../devices/pci0000:00/0000:00:14.0/usb2/2-4/2-4.4/2-4.4:1.0
lrwxrwxrwx. 1 root root 0 Dec 29 12:20 2-4.4.4 -> ../../../devices/pci0000:00/0000:00:14.0/usb2/2-4/2-4.4/2-4.4.4
lrwxrwxrwx. 1 root root 0 Dec 29 12:20 2-4.4.4:1.0 -> ../../../devices/pci0000:00/0000:00:14.0/usb2/2-4/2-4.4/2-4.4.4/2-4.4.4:1.0
lrwxrwxrwx. 1 root root 0 Dec 29 12:20 usb1 -> ../../../devices/pci0000:00/0000:00:14.0/usb1
lrwxrwxrwx. 1 root root 0 Dec 29 12:20 usb2 -> ../../../devices/pci0000:00/0000:00:14.0/usb2
The /sys/bus/ex_bus/drivers/
directories (e.g., /sys/bus/usb/drivers/
) contain subdirectories for each driver loaded for a device on the bus (e.g., (e.g., /sys/bus/usb/drivers/hub/
)):
$ ls -l '/sys/bus/usb/drivers/'
total 0
drwxr-xr-x. 2 root root 0 Dec 29 12:16 hub
drwxr-xr-x. 2 root root 0 Dec 29 12:17 uas
drwxr-xr-x. 2 root root 0 Dec 29 12:17 usb
drwxr-xr-x. 2 root root 0 Dec 29 12:17 usbfs
drwxr-xr-x. 2 root root 0 Dec 29 12:17 usbhid
drwxr-xr-x. 2 root root 0 Dec 29 12:17 usbserial_generic
drwxr-xr-x. 2 root root 0 Dec 29 12:17 usb-storage
The /sys/devices/
subdirectories contain various files with information about the device in question (e.g., the /sys/devices/pci0000:00/0000:00:14.0/usb1/
subdirectory):
$ ls -l '/sys/devices/pci0000:00/0000:00:14.0/usb1/' | head
total 0
drwxr-xr-x. 16 root root 0 Dec 29 12:26 1-0:1.0
drwxr-xr-x. 6 root root 0 Dec 29 12:26 1-4
-rw-r--r--. 1 root root 4096 Dec 29 12:26 authorized
-rw-r--r--. 1 root root 4096 Dec 29 12:26 authorized_default
-rw-r--r--. 1 root root 4096 Dec 29 12:26 avoid_reset_quirk
-r--r--r--. 1 root root 4096 Dec 29 12:26 bcdDevice
-rw-r--r--. 1 root root 4096 Dec 29 12:26 bConfigurationValue
-r--r--r--. 1 root root 4096 Dec 29 12:26 bDeviceClass
-r--r--r--. 1 root root 4096 Dec 29 12:26 bDeviceProtocol
The sysfs file system at /sys/
allows for the assignation of interfaces to devices in an unambiguous fashion. Interfaces are located in the /sys/class/
subdirectories (e.g., the /sys/class/ata_device/
subdirectory). These subdirectories contain symbolic links to the subdirectories stored in /sys/devices/
:
$ ls -l '/sys/class/ata_device/'
total 0
lrwxrwxrwx. 1 root root 0 Dec 29 12:35 dev1.0 -> ../../devices/pci0000:00/0000:00:17.0/ata1/link1/dev1.0/ata_device/dev1.0
lrwxrwxrwx. 1 root root 0 Dec 29 12:35 dev2.0 -> ../../devices/pci0000:00/0000:00:17.0/ata2/link2/dev2.0/ata_device/dev2.0
$ ls -l /sys/devices/pci0000:00/0000:00:17.0/ata1/link1/dev1.0/ata_device/dev1.0
total 0
-r--r--r--. 1 root root 4096 Dec 29 12:44 class
lrwxrwxrwx. 1 root root 0 Dec 29 12:44 device -> ../../../dev1.0
-r--r--r--. 1 root root 4096 Dec 29 12:44 dma_mode
-r--r--r--. 1 root root 4096 Dec 29 12:44 ering
-r--r--r--. 1 root root 4096 Dec 29 12:44 gscr
-r--r--r--. 1 root root 4096 Dec 29 12:44 id
-r--r--r--. 1 root root 4096 Dec 29 12:44 pio_mode
drwxr-xr-x. 2 root root 0 Dec 29 12:44 power
-r--r--r--. 1 root root 4096 Dec 29 12:44 spdn_cnt
lrwxrwxrwx. 1 root root 0 Dec 29 12:44 subsystem -> ../../../../../../../../class/ata_device
-r--r--r--. 1 root root 4096 Dec 29 12:44 trim
-rw-r--r--. 1 root root 4096 Dec 29 12:44 uevent
-r--r--r--. 1 root root 4096 Dec 29 12:44 xfer_mode
/sys/block/
also exists, but is mostly the same as /sys/class/block/
and is there for backwards-compatibility. /sys/block/
only has symbolic links for devices, while /sys/class/block/
has symbolic links for devices and their partitions, when applicable.
/sys/class/
and /sys/block/
only list devices that are actually on the system.
Important /sys/
subdirectories include:
/sys/bus/
- Contains a subdirectory for each data bus in the system.
/sys/class/
- Contains a subdirectory for all available device classes.
/sys/class/block/
- Contains a symbolic link for each block device in the system.
/sys/class/scsi_host/
- Contains information about SCSI host adapters (one directory per adapter).
/sys/devices/
- Contains a subdirectory for every discovered device.
/sys/module/
- Contains subdirectories for each module loaded into the kernel.
userspace /dev (udev)
The GNU/Linux infrastructure for dynamically creating device files for only those devices that are available is called userspace /dev (udev). Mainly, it consists of a library called namedev
, which deals with assigning names to devices, and a daemon called udevd
that does (or delegates) the work.
Shortly after boot, the initramfs tmpfs is mounted over /dev/
, in which udev places the appropriate device files. Then, udevd
is started, which listens to uevents, i.e., event reports by the kernel concerning devices that have been added or removed. The uevent
file located in each device's /sys/devices/
entry is what is used to trigger a corresponding uevent for that device:
/sys/devices/pci0000:00/0000:00:17.0/ata1/host0/target0:0:0/0:0:0:0/block/sda/uevent
Each report is compared to a set of rules that decide under which name the device should appear under in the /dev/
directory managed by udev, and which can also execute additional actions (e.g., loading firmware available as a binary file to the device in order to initialize it).
These rules can be found in /lib/udev/rules.d/
and /etc/udev/rules.d/
. The /lib/udev/rules.d/
rules are the system's default udev rules. The rules placed in /etc/udev/rules.d/
will override the default rules.
The syntax of udev rule files involves rows that contain selection criteria and variable assignments. The selection criteria are used to select events where there is a need to react. Variable assignments define the action to take.
Rules are separated by commas and the operator used implicitly differentiates between a selection criteria (i.e., with comparison operators like ==
or !=
) or an assignment directive (i.e., with operators like =
, +=
, or :=
).
Here are some example rules from /lib/udev/rules.d/60-persistent-alsa.rules
:
ACTION=="remove", GOTO="persistent_alsa_end"
SUBSYSTEM!="sound", GOTO="persistent_alsa_end"
KERNEL!="controlC[0-9]*", GOTO="persistent_alsa_end"
For comparison operators, the right operands can use pattern expressions to simultaneously match several values. For example, *
matches any string, ?
matches any character, and []
matches the set of characters contained in the square brackets.
Comparison operators are used on the following variables:
ACTION
- The action corresponding to the event (e.g.,
add
,remove
). ATTR{ex_attribute}
- File contents of the
ex_attribute
file in the/sys/$devpath/
directory of the device. DEVPATH
- The path of the device's
/sys/
entry. KERNEL
- The name that the kernel assigns to the device.
KERNELS
,SUBSYSTEMS
, andATTRS{ex_attributes}
- Variations that try to match the different options on one of the parent devices of the current device.
PROGRAM
- Delegates the test to the indicated program (true if it returns
0
, false if not). The content of the program's standard output is stored so that it can be re-used by theRESULT
test. RESULT
- Execute tests on the standard output stored during the last call to
PROGRAM
. SUBSYSTEM
- The kernel subsystem that generated the request (e.g.,
usb
,firmware
).
For assignment operators, =
assigns a value (and replaces any current value), :=
does the same as =
(but prevents later changes to the same variable), and +=
adds an item to a list.
The following variables can be changed:
NAME
- The device filename to be created in
/dev/
. Only the first assignment will be considered. OWNER
,GROUP
, andMODE
- Define the user and group that owns the device, as well as the associated permissions.
RUN
- The list of programs to execute in response to this event.
SYMLINK
- The list of symbolic links that will point to the same device.
The values assigned to the above variables may use the following substitutions:
$attr{ex_attribute}
,%s{ex_attribute}
- Equivalent to
ATTRS{ex_attributes}
. $devpath
,%p
- Equivalent to
DEVPATH
. $kernel
,%k
- Equivalent to
KERNEL
. $major
,%M
- The kernel major number of the device.
$minor
,%m
- The kernel minor number of the device.
$number
,%n
- The order number of the device (e.g., for
sda2
, it would be2
). $result
,%c
- The string output by the last program invoked by
PROGRAM
. $$
,%%
- For the dollar and percent sign, respectively.
For more information on udev rules, run man 7 udev
.
The same device may appear in /dev/
multiple times (e.g., /dev/camera
and /dev/sd
). udev can also deal with devices that do not correspond to device files in /dev/
(e.g., network cards).
udev assigns symbolic names for devices on top of traditional device names. These can be found in /dev/disk/
(and the legacy /dev/block/
):
/dev/disk/by-id/
/dev/disk/path/
/dev/disk/by-uuid/
/dev/disk/by-label/
These device names are derived from data like the unique serial number of the drive, its position on the PCIe bus, or the UUID/name of the file system, and are independent of the name of the actual device file.
udevadm
The udevadm
command is the udev management tool. It controls the runtime behavior of systemd-udevd
, requests kernel events, manages the event queue, and provides simple debugging mechanisms.
To listen to kernel uevents and events sent out by a udev rule, and print the devpath of the event to the console, run:
# udevadm monitor
To query the udev database for device information, run:
# udevadm info -a -n ex_device
The -a
(--attribute-walk
) option prints all sysfs properties of the specified device that can be used in udev rules to match the specified device. The -n ex_file
(--name=ex_file
) option takes the name of the device node or a symlink to query (e.g., /dev/sda
).
uevents are reports by the kernel concerning devices that have been added or removed. The uevent
file located in each device's /sys/devices/
entry is what is used to trigger a corresponding uevent for that device:
/sys/devices/pci0000:00/0000:00:17.0/ata1/host0/target0:0:0/0:0:0:0/block/sda/uevent
If you write the string add
to that file, you will trigger the corresponding uevent.
/dev/ Device File Mappings
Different types of devices are associated with specific types of device files in /dev/
.
/dev/lp*
- Unidirectional parallel ports
/dev/parport*
- Bidirectional parallel ports
/dev/pts/0
- First pseudoterminal device
/dev/sg*
- Write/rewrite optical drives
/dev/sr*
- Read-only optical drives
/dev/tty
- Controlling terminal of the current process
/dev/tty1
- First virtual console
/dev/ttyACM*
- Asynchronous Communication Mechanism (ACM) devices
/dev/ttyS*
- Serial ports
/dev/usb/
- USB devices
Desktop Bus (D-Bus)
The Desktop Bus (D-Bus) is a simple system for inter-process communication that is supported by most desktop environments. Programs can tell D-Bus about services that they want to offer to other programs. Programs can also wait for events.
D-Bus has two major application areas:
- Communication between programs in the same graphical environment
- Communication between the operating system and the graphical environment
udisks
udisks is based on D-Bus and consists of two components:
- A background service (
udisksd
) - A user-accessible tool (
udisksctl
), which can communicate with the background service
udisksd
is accessible through D-Bus and will be started on-demand whenever a program issues a D-Bus query to udisks
. This way, programs can find out which storage devices are available, as well as execute operations like mounting and unmounting devices. This includes privilege checks.
udisksctl
The udisksctl status
command can be used to display high-level information about disk drives and block devices.
To view detailed information about a specific object, the following command can be run:
udisksctl info -b ex_object
The -b
option is short for --block-device
and ex_object
is a device's path (e.g., /dev/sda
).
Hardware Commands
The following command-line tools can be used to view information about the hardware in a GNU/Linux system:
hwinfo
- Display a comprehensive overview of the system hardware. This command may need to be installed from your distribution's repository (e.g.,
# apt install hwinfo
,# dnf install hwinfo
). hdparm -a ex_device_file...
- Display information about a SATA/IDE drive. The
-a
option retrieves/sets the sector count for filesystem read-ahead. - This command may need to be installed from your distribution's repository (e.g.,
# dnf install hdparm
). lsblk
- Display the block devices attached to a system.
lscpu
- Display information about the CPU architecture.
lsdev
- Gather information about a computer's installed hardware and provide a quick overview of which hardware uses what I/O addresses, and what IRQ and DMA channels.
- This command may need to be installed from your distribution's repository and is part of the
procinfo
package (e.g.,# apt install procinfo
,# dnf install procinfo
). lspci
- List all PCI devices installed in the system.
lsscsi
- List SCSI devices (or hosts) and their attributes.
- This command may need to be installed from your distribution's repository (e.g.,
# apt install lsscsi
,# dnf install lsscsi
). lsusb
- Display information about USB buses in the system and the devices connected to them.
upower -e
,upower --enumerate
- Display a list of all available power sources.
upower -i ex_object
,upower --show-info ex_object
- Display detailed information about a power source object.
The Linux Kernel
An operating system manages a computer's basic functionality and forms the interface between the hardware and application programs, as well as the interface between the hardware and users.
The kernel is the core of an operating system and facilitates interactions between the hardware and applications. It controls the hardware and makes the hardware interact with the applications via drivers.
Four areas the kernel maintains control over are:
- Memory
- Processes
- Drivers
- System Calls
The kernel limits access to non-networking hardware devices in a manner similar to regular file access. Applications engage the file system layer, which then opens special device files (i.e., the device nodes) under the /dev/
directory that correspond to the device being accessed.
The kernel validates the requests and enforces that no one gets access to other users' resources. The kernel also ensures that all processes in the system (and therefore all users) get the appropriate fraction of available CPU time.
Modern Linux kernel release versions are numbered at x.y
(e.g, 5.0
, 5.1
). At any moment, there are a number of stable kernels that incorporate minor fixes or security updates. These are numbered x.y.z
(e.g., 5.0.1
).
At the same time, the next development (prepatch) kernel with major new additions is worked on as a release candidate (e.g., 5.2-rc1
). Once this kernel is stable enough, it is released as the next mainline Linux kernel. After each mainline kernel is released, it is considered stable.
Modern Linux kernels support automatic hardware recognition. They can analyze a system's properties and locate/configure the correct driver modules for the hardware (this is mediated via a device's major number and udevd
).
Linux kernels can be viewed and downloaded at kernel.org.
The GNU/Linux System
GNU/Linux is source-code compatible with POSIX, BSD, and System V UNIX, and allows the use of nearly all UNIX software available in source form.
A full GNU/Linux distribution (i.e., an operating system) consists of the Linux kernel, plus a number of other software tools. These other software tools include:
- A C/C++ compiler (
gcc
) - A debugger (
gdb
) - Core system libraries that applications need to link to in order to run (
/lib
,/usr/lib
, etc.) - The low-level interface for drawing graphics on the screen (X.Org, Wayland)
- Higher-level desktop environment (GNOME Shell, KDE Plasma)
- Package manager (
dpkg
/apt
,rpm
/dnf
)
uname
The uname
command prints system information.
To see all system information, use the -a
(--all
) option:
$ uname -a
Linux amnesia 5.4.0-4-amd64 #1 SMP Debian 5.4.19-1 (2020-02-13) x86_64 GNU/Linux
If you just want to see the Linux kernel version a system is using, use the -r
(--kernel-release
) option:
$ uname -r
5.4.0-4-amd64
lsb_release
The lsb_release
command provides certain Linux Standard Base (LSB) and distribution-specific information.
$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 10 (buster)
Release: 10
Codename: buster
To get the most out of this command, you need to use it with its options.
-a
,--all
- Display all distribution information.
-c
,--codename
- Display distribution code name (e.g.,
Codename: buster
). -d
,--description
- Display distribution description. This includes the distribution release number and code name (e.g.,
Description: Debian GNU/Linux 10 (buster)
). -i
,--id
- Display distributor ID (e.g.,
Distributor ID: Debian
). -r
,--release
- Display distribution release number (e.g.,
Release: 10
).
nproc
The nproc
command prints the number of processing units available to the current process. This may be less than the number of online processors.
To print the number of all installed processors, use the --all
option.
$ nproc --all
2
dmesg
The dmesg
command allows you to print or control the kernel ring buffer.
# dmesg | head
[ 0.000000] Linux version 4.19.0-13-amd64 (debian-kernel@lists.debian.org) (gcc version 8.3.0 (Debian 8.3.0-6)) #1 SMP Debian 4.19.160-2 (2020-11-28)
[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-4.19.0-13-amd64 root=/dev/mapper/debianVM--vg-root ro quiet
[ 0.000000] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers'
[ 0.000000] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
[ 0.000000] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
[ 0.000000] x86/fpu: xstate_offset[2]: 576, xstate_sizes[2]: 256
[ 0.000000] x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, using 'compacted' format.
[ 0.000000] BIOS-provided physical RAM map:
[ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
[ 0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
The kernel ring buffer gives the Linux kernel a place to log information before the operating system's normal logging program starts.
free
The free
command displays the total amount of free and used physical and swap memory in the system, as well as the buffers and caches used by the kernel.
$ free
total used free shared buff/cache available
Mem: 4041128 656976 2815640 12184 568512 3143104
Swap: 4190204 0 4190204
The Mem:
line tells you how much RAM your system has. The second line, Swap:
, describes swap space utilization.
Columnar data includes:
- total
- Total installed memory (sum of MemTotal and SwapTotal in
/proc/meminfo
, respectively). - used
- Used memory (calculated as total - free - buff/cache).
- free
- Unused memory (sum of MemFree and SwapFree in
/proc/meminfo
, respectively). - shared
- Memory used (mostly) by tmpfs (Shmem in
/proc/meminfo
). - buff/cache
- Sum of buffers (memory used by kernel buffers; Buffers in
/proc/meminfo
) and cache (memory used by the page cache and slabs; Cached and SReclaimable in/proc/meminfo
). - available
- Estimation of how much memory is available for starting new applications, without swapping. Unlike the data provided by the cache or free fields, this field takes into account the page cache and that not all reclaimable memory slabs will be reclaimed due to items being in use (MemAvailable in
/proc/meminfo
; otherwise, the same as free).
To make free
's output more legible, you can use the -h
(--human
) option:
$ free -h
total used free shared buff/cache available
Mem: 3.9Gi 635Mi 2.7Gi 11Mi 564Mi 3.0Gi
Swap: 4.0Gi 0B 4.0Gi
Pay particular attention to the free values to gauge how much memory is available. The RAM of a computer (especially a server) should be enough so that practically no swap space is required during normal operations.
vmstat
The vmstat
command reports virtual memory statistics. Specifically, it reports highly detailed information about:
- Processes
- Memory
- Paging
- Block input/output
- Traps
- Disks
- CPU activity
$ vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 2189404 2116 1155852 0 0 457 0 102 328 4 5 91 0 0
The values reported are averages since the last reboot. Additional reports give information on a sampling period of length delay, if it is provided to the command as an argument.
hostname and hostnamectl
To view the system hostname, use the hostname
command. To display the system's complete Fully Qualified Domain Name (FQDN), use the --fqdn
option (e.g., hostname --fqdn
).
The hostname
command can also be used to temporarily change the system's hostname:
# hostname ex_new_hostname
The hostname change will only persist until the next system boot.
To permanently change a system's hostname, you can use the hostnamectl
command:
# hostnamectl set-hostname ex_new_hostname
This command alters the hostname value in the /etc/hostname
file.
XDG_
To determine what desktop environment a system is using, you can display the contents of the ${XDG_CURRENT_DESKTOP}
variable:
echo "${XDG_CURRENT_DESKTOP}"
To determine the session type of a system (e.g., x11
or wayland
), you can display the contents of the ${XDG_SESSION_TYPE}
variable:
echo "${XDG_SESSION_TYPE}"
${HOME}/.local/share/
The ${HOME}/.local/share/
directory contains several subdirectories of interest.
The ${HOME}/.local/share/Trash/files/
directory is the location of the system Trash, while the ${HOME}/.local/share/applications/
directory contains desktop integration files for applications that you install.
There are likely many other application-specific directories in ${HOME}/.local/share/
for programs installed on your GNU/Linux system.
wall
The wall
command sends a message to all logged in users.
wall ex_message
If you are not root, you can suppress the header line, Broadcast message ...
, using the -n
(--nobanner
) option.
shutdown
The shutdown
command can be used to bring down or restart a system.
# shutdown
Without any arguments, the command will shutdown a system in one minute and take you to single-user mode.
The shutdown
command ensures that all logged-in users are made aware of the impending system shut down, prevents new logins, and performs any requisite actions to shut down the system based on the options it is given.
A specific shut down time and wall message can be passed to the command as arguments:
# shutdown ex_options ex_time ex_wall_message
The +m
time specifies the amount of time (in minutes) before shutting down the system. The now
time can be used instead of +m
to specify that the system go down immediately. To make the system go down at a specific time, you can replace +m
with the time (entered as hh:mm
, where hh
is hours and mm
is minutes) when the shutdown should occur.
It is seldom necessary to shut down a GNU/Linux machine. You can install or remove software with impunity and reconfigure the system fairly radically without having to restart the operating system. The only cases where a restart is really necessary include kernel changes or adding/replacing hardware.
The Shutdown Process
When the shutdown
command is given, several things occur:
- All users receive a broadcast message that the system will be shut down, when it will be shut down, and why it will be shut down.
- The
shutdown
command automatically creates the/etc/nologin
file, which is checked by thelogin
program (or the Pluggable Authentication Module infrastructure), which prevents new user logins (except for the root user; other users will see the contents of/etc/nologin
or/etc/nologin.txt
). The/etc/nologin
file is automatically removed upon system start up. - The system changes to
poweroff.target
(runlevel0
) orreboot.target
(runlevel6
). All services are terminated (at least all services that do not occur inpoweroff.target
orreboot.target
, which is usually all of them). - All still-running processes are first sent
SIGTERM
signals (i.e., kill the process; can be ignored/trapped). - Shortly afterwards, all processes that still exist are forcibly terminated by
SIGKILL
signals (i.e., kill the process immediately; cannot be ignored/trapped). - The file systems are unmounted and the swap spaces are deactivated.
- All system activities are finished. Then, either a warm start is initiated or the computer shuts off using Advanced Power Management (APM) or Advanced Configuration and Power Interface (ACPI). If this does not work, the message
System halted
is displayed on the console. At this point, you can use the physical power switch yourself.
shutdown Commands
# shutdown -c
- Cancel a shutdown.
# shutdown -H now
,# shutdown --halt now
,# halt
- Halt the system.
# shutdown now
,# init 1
- Move to single-user mode.
# shutdown -P now
,# shutdown --poweroff now
,# shutdown -h now
,# poweroff
,# init 0
- Power off a system.
# shutdown -r now
,# shutdown --reboot now
,# reboot
,# init 6
- Reboot the system.
Documentation
You can find more information on the commands discussed above by examining the Linux User's Manual, either at the command line or online.