A Little About Linux: Determining and Configuring Hardware Settings

This section covers all sorts of things relating to how hardware is accessed and managed on a standard PC.  If you've only come into computing from a Windows background and after the year 2000, it's entirely possible that with Plug and Play technology, you've never come across some of this stuff before.  Don't worry, it's not a bad thing, it's more of an indication on how far this has progressed recently.  In fact, with a modern Linux distribution, you will probably not have to deal with this on a day to day basis, but I think it's always nice to have a bit of background, so here it is if you want it.

BIOS or UEFI
These elements are the first bits of software loaded in the boot process and also configure certain hardware, they both perform broadly the same function but do things in different ways.  As this section is regarding hardware, all we need to know is that the options available in standard legacy BIOS or the UEFI 'BIOS' are broadly similar.  They include things like CPU temperature, Fan Speed, SATA Disc Ports and Memory DIMMs etc. and allow for the disabling of integrated peripherals serial ports, parallel ports, sound and graphics hardware built-in to the Motherboard. Once Linux fully boots, it users its own device drivers and no longer needs the information from this level.

Interrupt Requests (IRQs)
These are signals that get sent to the CPU to tell it it to temporarily stop what it's currently doing and concentrate on something else for awhile.  This signal could be generated from a key press on a keyboard, a floppy drive (remember them?) or some other peripheral.

Different IRQ numbers are allocated to different devices (or ports that devices are plugged into) and there are a minimum of 16 IRQ allocations (these days, usually a much higher number.)  Most books will print a table with all of the basic IRQs listed, but if you want to know about these, Wikipedia is your friend.

In Linux, you can view the list of IRQs that are currently available on your Linux machine by running;

$ cat /proc/interrupts

           CPU0       CPU1       CPU2       CPU3

  0:        140          0          2          1   IO-APIC-edge      timer
  1:          1          0          0          1   IO-APIC-edge      i8042
  3:          0          0          1          0   IO-APIC-edge
  4:          0          0          0          1   IO-APIC-edge
  7:          0          0          0          0   IO-APIC-edge      parport0
  8:          0          1          0          0   IO-APIC-edge      rtc0
  9:          0          0          0          0   IO-APIC-fasteoi   acpi
 12:          0          1          2          1   IO-APIC-edge      i8042
 14:       3539       3561       3527       3562   IO-APIC-edge      ata_piix
 15:         42         38         38         46   IO-APIC-edge      ata_piix
 16:          0          0          0          0   IO-APIC-fasteoi   uhci_hcd:usb5
 18:          0          0          0          0   IO-APIC-fasteoi   uhci_hcd:usb4
 19:          0          0          0          0   IO-APIC-fasteoi   uhci_hcd:usb3
 23:       5475       5470       5485       5458   IO-APIC-fasteoi   ehci_hcd:usb1, uhci_hcd:usb2
 26:          0          0          0          0   PCI-MSI-edge      i915
 27:         57         58         57         58   PCI-MSI-edge      snd_hda_intel
 28:       5666       5652       5671       5653   PCI-MSI-edge      eth0
NMI:         14         21         16         18   Non-maskable interrupts
LOC:      58297      52080      38292      53201   Local timer interrupts
SPU:          0          0          0          0   Spurious interrupts
PMI:         14         21         16         18   Performance monitoring interrupts
IWI:          0          0          0          0   IRQ work interrupts
RES:       2011        811        983        890   Rescheduling interrupts
CAL:       2431       8230        151        170   Function call interrupts
TLB:        510        427        902        734   TLB shootdowns
TRM:          0          0          0          0   Thermal event interrupts
THR:          0          0          0          0   Threshold APIC interrupts
MCE:          0          0          0          0   Machine check exceptions
MCP:          4          4          4          4   Machine check polls
ERR:          0
MIS:          0

The above output will only show the currently allocated interrupts, so some devices may not appear if they haven't been used or accessed within this session.


I/O Addressing, Serial and Parallel Ports
It's been a long time since I've plugged in a printer into the parallel port on the back of a PC, but I will admit that I have needed to add a software dongle to a serial port, so I suppose that there is some relevance in this part and again, it's still useful to know.

An I/O address (Input/Output, funnily enough) is a location in memory specifically used for CPU and hardware communication.  The memory location and associated hardware located at that location.

$ cat /proc/ioports

0000-0cf7 : PCI Bus 0000:00

0000-001f : dma1
0020-0021 : pic1
0040-0043 : timer0
0050-0053 : timer1
0060-0060 : keyboard
0064-0064 : keyboard
0070-0071 : rtc0
0080-008f : dma page reg
00a0-00a1 : pic2
00c0-00df : dma2
00f0-00ff : fpu
0170-0177 : 0000:00:1f.2
0170-0177 : ata_piix
01f0-01f7 : 0000:00:1f.2
01f0-01f7 : ata_piix
0290-029f : pnp 00:06
02f8-02ff : serial
0376-0376 : 0000:00:1f.2
0376-0376 : ata_piix
0378-037a : parport0
03c0-03df : vga+
03f6-03f6 : 0000:00:1f.2
03f6-03f6 : ata_piix
03f8-03ff : serial
0400-041f : 0000:00:1f.3
0400-041f : i801_smbus
0480-04bf : gpio_ich
0480-04bf : pnp 00:07
04d0-04d1 : pnp 00:07
0800-087f : pnp 00:07
0800-0803 : ACPI PM1a_EVT_BLK
0804-0805 : ACPI PM1a_CNT_BLK
0808-080b : ACPI PM_TMR
0810-0815 : ACPI CPU throttle
0828-082f : gpio_ich
0828-082f : ACPI GPE0_BLK
0830-0833 : iTCO_wdt
0830-0833 : iTCO_wdt
0860-087f : iTCO_wdt
0860-087f : iTCO_wdt
0a00-0a0f : pnp 00:06
0a20-0a2f : pnp 00:06
0a30-0a3f : pnp 00:06
0cf8-0cff : PCI conf1
0d00-ffff : PCI Bus 0000:00
1000-1fff : PCI Bus 0000:03
d400-d407 : 0000:00:02.0
d480-d49f : 0000:00:1d.0
d480-d49f : uhci_hcd
d800-d81f : 0000:00:1d.1
d800-d81f : uhci_hcd
d880-d89f : 0000:00:1d.2
d880-d89f : uhci_hcd
dc00-dc1f : 0000:00:1d.3
dc00-dc1f : uhci_hcd
e000-efff : PCI Bus 0000:02
e800-e8ff : 0000:02:00.0
e800-e8ff : r8169
ff90-ff9f : 0000:00:1f.2
ff90-ff9f : ata_piix

N.B. If you need to further investigate the serial port settings or change the IRQ or baud rate, you can use the setserial command.  Start by finding out how many serial ports you have;

# ls /dev/ttyS*

/dev/ttyS0  /dev/ttyS1  /dev/ttyS2  /dev/ttyS3


Then, chose a serial port and run;

# setserial /dev/ttyS0

/dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4

Run the setserial command on its own to find the syntax for setting the serial port, but as an example, if you want to set the first serial port to a baud rate of 9600, use the syntax;

# setserial /dev/ttyS0 baud_base 9600

Direct Memory Addressing (DMA)

DMA is a different way of addressing hardware ports.  Using this method, the CPU isn't involved in the hardware communication, the device actually communicates directly.

To find out what DMA channels are currently in use, run the following command;

$ cat /proc/dma

Coldplug and Hotplug Devices

What are Coldplug and Hotplug devices?  Basically, they are the difference between devices that can be pulled out/unplugged when the computer is running and those that can only be removed when the computer is off.

I'm going to tread carefully on this one because as technology progresses, some Coldplug devices are moving to Hotplug systems (I'm thinking Hot-plug PCI) , but in general the following distinctions are made;
  • Coldplug (Traditionally): PCI cards, CPUs, Memory, Serial and Parallel Devices etc.
  • Hotplug: USB, Ethernet, Firewire etc.
Linux detects the changes when they are plugged and unplugged by using the software and utilities below;

Sysfs - This is a ram-based virtual file system which is mounted as /sys and provides
a means to export kernel data structures (e.g. devices and buses) and information about them to the user space programs (as opposed to the kernel which runs in kernel space.)  The devices each have folder under the /sys top level such as;

block  
bus
class  
dev 
devices 
firmware 
fs        
hypervisor  
kernel  
module
power
    
Hardware Abstraction Layer Daemon (hald or haldaemon) - This is a daemon (so it runs all of the time) that maintains a database telling user space programs about the hardware devices currently connected to the system. It connects to the D-Bus system message bus (explained below) and provides an API for applications to discover, monitor and invoke operations on devices. Although after about 2011 this has started to be phased out, it is still available in most recent Linux distributions.

Desktop Bus (D-Bus) - It runs all of the time as a daemon (dbus-daemon) and was specifically designed to fulfill a need with modern Linux GUI Desktops allowing applications to talk to one another, communicate information and request services and notification of events e.g. a USB device being plugged in.

udev - Before Hotplug devices, all devices were created as static files in /dev, but with the advent of devices that can be plugged and unplugged constantly, something was needed to manage this operation.  udev is a Device Manager that performs this operation which is a virtual file system mounted at /dev and creates dynamic files at this location when needed.  The daemon (udevd) is configured under /etc/udev/ with the config file at /etc/udev/udev.conf.

PCI Cards
The PCI (Peripheral Component Interface) standard is inherently Plug and Play in its design and for 99% of time it will just work.  However, for that 1% of cases when you need to change something, these are your options;

Through the Kernel - The kernel configuration option of Bus Options -> PCI Support -> PCI Access Mode has four values 1) BIOS 2) MMConfig 3) Direct 4) Any.  Any is usually the best option but all others could be tried if you're having issues.

Directly in BIOS - You could play about with the settings directly in BIOS.

Within the Drivers - It may be possible to make changes of a case by case basis directly at the driver config level.  The driver documentation will be your friend in this instance.

setpci - This tool can be used but for low level PCI fettling, but you could quite easily bork your card so be careful...

Finally, to list all the PCI devices in the system and how they are configured use the lspci command in its basic form to get;

# lspci

00:00.0 Host bridge: Intel Corporation Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge (rev 02)
00:02.0 VGA compatible controller: Intel Corporation Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller (rev 02)
00:02.1 Display controller: Intel Corporation Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller (rev 02)
00:1b.0 Audio device: Intel Corporation NM10/ICH7 Family High Definition Audio Controller (rev 02)
00:1c.0 PCI bridge: Intel Corporation NM10/ICH7 Family PCI Express Port 1 (rev 02)
00:1c.1 PCI bridge: Intel Corporation NM10/ICH7 Family PCI Express Port 2 (rev 02)
00:1d.0 USB controller: Intel Corporation NM10/ICH7 Family USB UHCI Controller #1 (rev 02)
00:1d.1 USB controller: Intel Corporation NM10/ICH7 Family USB UHCI Controller #2 (rev 02)
00:1d.2 USB controller: Intel Corporation NM10/ICH7 Family USB UHCI Controller #3 (rev 02)
00:1d.3 USB controller: Intel Corporation NM10/ICH7 Family USB UHCI Controller #4 (rev 02)
00:1d.7 USB controller: Intel Corporation NM10/ICH7 Family USB2 EHCI Controller (rev 02)
00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev e2)
00:1f.0 ISA bridge: Intel Corporation NM10 Family LPC Controller (rev 02)
00:1f.2 IDE interface: Intel Corporation NM10/ICH7 Family SATA Controller [IDE mode] (rev 02)
00:1f.3 SMBus: Intel Corporation NM10/ICH7 Family SMBus Controller (rev 02)
02:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 03)

You can even add verbosity as well, for instance if you want to see more information about the LOM Ethernet Controller shown as the last item above, use the -v switch for verbose and the -s switch to specify the slot number and you'll see something like this;

# lspci -v -s 02:00.0

02:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 03)
        Subsystem: ASUSTeK Computer Inc. M4A785TD Motherboard
        Flags: bus master, fast devsel, latency 0, IRQ 28
        I/O ports at e800 [size=256]
        Memory at fafff000 (64-bit, prefetchable) [size=4K]
        Memory at faff8000 (64-bit, prefetchable) [size=16K]
        Expansion ROM at fbff0000 [disabled] [size=64K]
        Capabilities: [40] Power Management version 3
        Capabilities: [50] MSI: Enable+ Count=1/1 Maskable- 64bit+
        Capabilities: [70] Express Endpoint, MSI 01
        Capabilities: [ac] MSI-X: Enable- Count=4 Masked-
        Capabilities: [cc] Vital Product Data
        Capabilities: [100] Advanced Error Reporting
        Capabilities: [140] Virtual Channel
        Capabilities: [160] Device Serial Number 00-00-00-00-00-00-00-00
        Kernel driver in use: r8169
        Kernel modules: r8169

The Scary World of Loadable Kernel Modules (LKM)
Except, that its not that scary when you know the basics of what they are and why it makes life easier for us.  The basic definition of a kernel is the part of the of the OS that sits between the hardware and the software and sorts out all of the communication between these two areas.  Now, reading this definition you might think that if a new piece of hardware is added, we might have to do something to the kernel to allow this to start working... perhaps re-compile the kernel? I know, I'm sorry... I didn't mean to unnerve you just as you were getting comfortable... but fear not, this is where kernel modules come into play.  Kernel Modules are effectively (I say effectively, because its not exactly true... think of a LKM it as a way of pulling something into and attaching it to the kernel which may or may not be a device driver, it could also be filesystem or network driver or a system call to program.  For our purpose, it's needed to load the device driver into the kernel.) the device drivers that you would have in Windows.  They usually live in /lib/modules (under a sub directory of the current kernel) or /lib64.


Amazingly, they are called Loadable Kernel Modules as they are loaded by the kernel usually at boot time, but can also be added whilst the kernel is up and running (i.e. you don't need to reboot.)  Now, to see what modules are currently in use run the lsmod command;

# lsmod

Module                  Size  Used by
tun                    17095  2
ipv6                  318247  32
ppdev                   8537  0
iTCO_wdt                7115  0
iTCO_vendor_support     3056  1 iTCO_wdt
parport_pc             22690  0
parport                36209  2 ppdev,parport_pc
asus_atk0110           14216  0
i2c_i801               11359  0
serio_raw               4594  0
sg                     29350  0
lpc_ich                12803  0
mfd_core                1895  1 lpc_ich
r8169                  59863  0
mii                     5376  1 r8169
snd_hda_codec_idt      43592  1
snd_hda_intel          40562  0
snd_hda_codec         179208  2 snd_hda_codec_idt,snd_hda_intel
snd_hwdep               6780  1 snd_hda_codec
snd_seq                55727  0
snd_seq_device          6500  1 snd_seq
snd_pcm                87409  2 snd_hda_intel,snd_hda_codec
snd_timer              22443  2 snd_seq,snd_pcm
snd                    70569  8 snd_hda_codec_idt,snd_hda_intel,snd_hda_codec,snd_hwdep,snd_seq,snd_seq_device,snd_pcm,snd_timer
soundcore               7958  1 snd
snd_page_alloc          8888  2 snd_hda_intel,snd_pcm
ext4                  374405  4
jbd2                   93427  1 ext4
mbcache                 8193  1 ext4
sr_mod                 15177  0
cdrom                  39085  1 sr_mod
sd_mod                 39069  5
crc_t10dif              1541  1 sd_mod
pata_acpi               3701  0
ata_generic             3837  0
ata_piix               24601  2
usb_storage            49068  1
i915                  624543  1
drm_kms_helper         44321  1 i915
drm                   280012  2 i915,drm_kms_helper
i2c_algo_bit            5935  1 i915
i2c_core               31084  5 i2c_i801,i915,drm_kms_helper,drm,i2c_algo_bit
video                  20674  1 i915
output                  2409  1 video
dm_mirror              14384  0
dm_region_hash         12085  1 dm_mirror
dm_log                  9930  2 dm_mirror,dm_region_hash
dm_mod                 84337  11 dm_mirror,dm_log

It's fairly self explanatory, the 'Module' column shows the name of the module loaded, the 'Used By' column shows what's using the module and the number indicates the number of other modules or processes using it and may sometimes be incomplete.  This is essentially what is stored in /proc/modules and does include drivers compiled into the kernel.

If you want to delve into a specifically module a little more, you can use modinfo, so lets see what it says about the VIDEO module;

# modinfo video

filename:       /lib/modules/2.6.32-431.23.3.el6.centos.plus.x86_64/kernel/drivers/acpi/video.ko
license:        GPL
description:    ACPI Video Driver
author:         Bruno Ducrot
srcversion:     36C56143D43A36E4CF9051B
alias:          acpi*:LNXVIDEO:*
depends:        output
vermagic:       2.6.32-431.23.3.el6.centos.plus.x86_64 SMP mod_unload modversions
parm:           brightness_switch_enabled:bool


From this we can see where the kernel is used and what its called, video.ko (ko means kernel object), the license type, author etc.

Loading Modules
Now, the next step is to actually load these modules into the kernel and to do this its time to introduce insmod and modprobe.  For this explanation, we'll use the example of loading a floppy module, partially because I know that the module will already be on the filesystem, but according to the the lsmod command we ran earlier, it's not already loaded.

insmod /lib/modules/2.6.32-431.23.3.el6.centos.plus.x86_64/kernel/drivers/block/floppy.ko

modprobe floppy


insmod needs the full path to the module and will only successfully load if all other modules on which it depends are already loaded, whereas modprobe only requires the module name and sorts out dependencies for you.

modprobe also has a configuration file located at /etc/modprobe.conf or will also load all config files located in /etc/modprobe.d/.

Removing Modules
Generally, you probably won't see any benefit in removing an already loaded module apart from freeing up a small bit of memory, but if you need to remove a module you can use;

modprobe -r floppy

rmmod floppy

rmmod -f floppy

rmmod -w floppy

rmmod -f - Forces a module to be removed even if in use.

rmmod -w - Waits until a module is no longer used to be removed.

Dealing with USB Devices
So, you'll probably know lots about USB devices given that they're all over the place, but there are a few little things that might be useful to note here.  Firstly, the different versions of the USB standards means a faster data rate;

USB 1.0/1.1 - Usable Data Rate: 12 Mbit/s
USB  2.0 (Hi-Speed)Usable Data Rate: 280 Mbit/s
USB 3.0 (Superspeed)Usable Data Rate: 4Gbit/s
USB 3.1 (Superspeed+)Usable Data Rate: 7.2 Gbit/s

USB was designed to have allow a number of USB ports attached to a host, so as well as the ports attached to the motherboard, you can also attach more ports using a USB hub and the only thing to limit this the throughput.

No comments: