
Explore how input and output with peripherals use memory-mapped I/O or port-mapped I/O, comparing shared memory space versus separate I/O spaces, and how CPUs implement these methods.
Read and write to registers at consecutive addresses in memory space or io space to control devices. Complex devices add more registers; basic devices use a minimum register set.
See how the CPU uses the address bus and control signals to distinguish memory access from I/O, with memory controllers handling data transfers and keyboards and mice.
Explore how x86 i/o ports map devices with their own i/o addresses, use 16-bit words, and combine consecutive ports for 32-bit access, with addresses aligned to four bytes.
Explore how the linux kernel provides functions like inb to access i/o ports, read a byte from a port address, and use cscope to count function calls.
Learn to manage i/o port access safely by requesting exclusive region with request_region, monitoring port usage, and releasing it on exit to prevent conflicts and crashes.
Explore a Linux kernel module example for requesting I/O ports and how conflicts arise when a port is already in use, showing success or failure outcomes.
Shows why a value read from a hardware register may differ from what you wrote, due to racing access and a bookkeeping routine tracking which drivers use which addresses.
Explore why /proc/ioports does not list every port, and how only certain drivers and claimed devices appear, illustrating how hardware resources are displayed by Linux device drivers.
Discover where to find processor ioports information in official documentation, especially the PCH documents and section 9.3, detailing fixed and variable ports and their mappings.
Learn how a Linux kernel module toggles the pc speaker by writing to i/o port 0x61, enabling and disabling the speaker with a five-second delay to observe audio.
Learn how to read a ports list to interpret device addresses and bit fields for a hardware board, and rely on manufacturer documentation over a legacy file.
Explore how an RTC keeps date and time across power loss with a battery, offers alarm functionality, and uses nonvolatile memory to trigger events.
Learn to access the RTC via two ports and registers, including timing-related and control registers, by first writing the register address to the address port, then reading or writing data.
Explain how RTC ports and registers handle binary and decimal values, use a bit to select 12- or 24-hour formats, and reflect system status and daylight settings.
Learn how a Linux kernel module communicates with an RTC by first writing the register address and then reading the value, demonstrating a simple two-step hardware access.
Explore the rtc driver in the Linux kernel through a practical walkthrough, highlighting how definitions, commands, and shortcuts relate to hardware communication in Linux device drivers.
Discover how hardware and software clocks work in Linux, including hours, minutes, seconds, time zones, current date, and time-related functions that drivers rely on.
Explore how a Linux kernel module updates time by writing to a memory address and reading back the new value, validating the change from 1747 to 1741.
The PC keyboard subsystem comprises a keyboard with an onboard processor that monitors key presses, a keyboard interface, and a motherboard keyboard controller that decodes data for the host.
Demonstrates how a keyboard processor scans the key matrix, sends make and break scan codes, and how the host interprets the unique make codes using the default code set.
Learn to find a key's scancode by switching to a virtual console with Ctrl+F3 and observing the codes produced by different keys.
Examine typematic keyboard behavior, showing how holding a key sends repeated characters after a delay and at a configurable rate, modified by keyboard commands.
Perform the keyboard diagnostic self-test (basic assurance test) and reset the device, validating scan codes, and toggling indicators like key caps, log, and scroll lock during the test.
Learn how a keyboard's onboard processor and keyboard controller manage key press and release events, using i/o ports and registers (0x60, 0x64) to read and write keyboard data for cpu.
Learn how a Linux kernel module sends keyboard controller commands via the command port, writes to the command register, and reads status to enable or disable operations.
Explore how a Linux kernel module enables and disables the mouse by sending command bytes and writing data to the device, with timed enablement and command sequencing.
Practice disabling a keyboard via a Linux kernel module, sending commands to the keyboard controller, observing key presses, and re-enabling the keyboard after a five-second delay.
Examine how a Linux kernel module reads the command byte after disabling the keyboard, illustrating hardware communication and command handling in Linux device drivers.
Explore how status registers reflect hardware conditions, with examples from keyboard input and input buffers, including potential timeouts and reading values like 64 or 60 to drive actions.
Learn how a Linux kernel module reads keyboard input by waiting for a key press, prints the scan code, and then converts it to the corresponding character.
Explore how to write a Linux kernel module to turn on keyboard LEDs by sending commands to the keyboard controller on the keyboard and motherboard, selecting LEDs like caps lock.
Learn how user-space programs gain permission to access iReports, control submissions with two functions, and manage privileges to access hardware ports in Linux device drivers.
explain how the ioperm system call grants or denies access to io ports for specific ranges, and how to determine if a program runs with normal user privileges.
Learn how to add an error message for a normal user when a condition fails in Linux device drivers that communicate with hardware.
Examine how missing a call to ioperm when accessing IO ports from userspace triggers permission errors and segmentation faults, and understand the consequences for hardware communication in Linux device drivers.
Explore accessing rtc registers from user space with a simple example that reads values and manages permissions to communicate via ipc.
Learn how the iopl call sets a process's I/O privilege level based on the parameter, with levels 0-3 granting different hardware access rights.
Explore how Linux device drivers access hardware resources and obtain permission to use them, illustrating access control and resource management in driver development.
Explore how a user space process pushes keyboard input events on Linux, simulating key presses and releases observed by the terminal, console, and scanners.
Explore how the keyboard controller interfaces with keyboard, mouse, and other peripherals, and demonstrate a simple two-line code approach to reboot a machine via keyboard port.
Explore multiple options to reset hardware via the pci port to resolve issues. Learn how different reset methods report to the hardware and what makes them distinct.
learn how to enable and disable the speaker in a Linux device driver by granting permission, writing to the speaker, and pausing for three seconds to manage buzzings.
The 8254 programmable interval timer drives a speaker by selecting a timer channel, loading counts and control words to create audible frequencies.
Explore how /dev/port enables reading and writing to hardware ports, outlining required permissions and a basic example of addressing and exchanging data with a device.
Compare memory-mapped I/O and port I/O as the CPU accesses memory and device registers using the same instructions, and learn why memory-mapped space is widely supported.
Explore how Linux device drivers request io memory with request_region, how memory maps track who reserves address ranges, and how devices share or prevent access.
Learn how Linux device drivers access io memory through memory-mapped io by mapping physical addresses to virtual addresses and performing 8-, 16-, and 32-bit reads and writes to port registers.
Explore why direct io memory access requires volatile and memory barriers to prevent compiler optimization from removing critical reads and writes, ensuring correct hardware interaction.
Demonstrates how a Linux kernel module example calls request_mem_region, but the region is already in use, causing the memory region request to fail.
Demonstrate a Linux kernel module example that calls request mem region in a success case, allocating an unused memory region and reflecting the allocation.
Map a physical address into kernel page tables using ioremap, then manage the base and virtual addresses and iounmap in a 64-bit Linux kernel module.
Demonstrate writing and reading a value in a Linux kernel module to device memory, then verify the read matches the written value across 64-bit and 32-bit architectures.
Modify the Linux kernel module example that calls ioread and iowrite, observe reads returning f f f, and discuss whether using volatile affects correctness when accessing an unknown device address.
Explore how a hardware random number generator communicates with the system via device registers, checks presence and enablement, and reads status to produce random numbers.
Learn how Linux device drivers communicate with a hardware RNG by checking the status register for a valid bit and reading data from the data register.
Map I/O resources to virtual addresses and access hardware ports as memory, while covering resource allocation and issuing control instructions for devices.
Explore accessing memory from userspace by mapping a memory image through a character device file that represents main memory, using hex dumps and strings to inspect and diagnose permission issues.
Explain how config_strict_devmem enforces strict access to /dev/mem, limiting user-space access to peripherals for security. Apply defaults on some platforms, including Raspberry Pi, keeping this option enabled by default.
Learn how to use devmem to read and write physical memory addresses, specify the write value as the third argument, and map a device’s registers and offsets for direct access.
Implement a simple devmem utility in C by mapping device memory into userspace with mmap, performing reads and writes, and then unmapping.
Update the linux device driver example to print a string instead of a single character, demonstrating how userspace can access the driver and interact with registered code.
Learn to configure GPIO using devmem by writing to memory-mapped addresses, choosing base addresses and registers to set pins as input or output, and reading back values.
Explore the RTC emulation on QEMU ARM, its memory map at 101830, and how reading the RTC register reveals a five-second delay between successive reads.
Dump bios data to a file from a virtual machine by selecting a memory range, using a line tool with end addresses, block size, and skip, then use strings.
Demonstrate how to write strings into RAM and read them back, showing how strings are stored, displayed, and accessed in memory during command execution.
Introduces a standard by the distributed management task force that extends the BIOS interface so the operating system can read hardware information such as make, model, serial number, BIOS version.
Discover where the SMBIOS entry point table sits in memory between 0xEF40 and 0xEF4F and locate it by searching for the identifying string, then print the address.
The lecture explains how to parse the entry point table in a Linux device driver, detailing the header, symbol table, and memory addresses.
Dmidecode dumps the SMBIOS data to reveal bios information, system information, processor information, memory module details, and manufacturer serial numbers.
Biosdecode explores memory and information about all structures it knows, highlights data biases and permission denied scenarios when accessing hardware locations.
Intel introduced a new standard on s.p.c.a. to create a flexible scheme for allocating addresses and memory for future peripherals, avoiding contention with fixed addresses.
Identify each device by bus, device, and function numbers and access its configuration space via ports, supporting up to 56 buses, 32 devices per bus, and eight functions per device.
Explore the PCI configuration space, a 256-byte region split into a 64-byte standard header and 192 bytes of device-specific data, where vendor and device IDs uniquely identify hardware.
Access PCI configuration space by addressing bus, device, and function numbers to locate registers, then perform read and write operations as PCI configuration transactions gated by an enable bit.
Explore how lspci identifies bus, device, and function for PCI hardware, display device details, configuration space, and driver information to analyze and read PCI configurations.
Learn how a Linux kernel module accesses the configuration space by specifying bus, device, function, and offset, performing configuration transactions to read and write data.
Demonstrate reading a device's 256-byte configuration space by printing default values, slot numbers, and function numbers, using the kernel's built-in functions to read and display the data.
Investigate what happens when you read a bus device function that doesn't exist; the host bridge completes the access without error, while the read data remains unspecified.
Explore how base address registers define memory and I/O space for devices, including 32-bit and 64-bit addressing, and how the lowest bits identify region type for memory-mapped versus I/O-mapped regions.
Identify how to derive the base address from the base address register by masking the lower bits for 32-bit and 64-bit memory spaces, to align and display the device.
Determine the memory size used by a PCI device by writing ones to a register, reading back, applying bitwise masking, and incrementing to reveal the mapped 64-bit space.
Learn how PCI Express extends the configuration space beyond 256 bytes and uses memory addresses with the same access method as legacy PCI configuration space.
What you will learn in this course:
Two modes of communication with hardware - IO Mapped IO and Memory Mapped IO
Kernel Drivers/Modules for IO Mapped IO - Speaker, RTC, Keyboard
Kernel Drivers/Modules for Memory Mapped IO - Hardware Random Generator, GPIO, UART
Accessing IO Mapped IO and Memory Mapped IO from user space
PCI and SMBIOS
API's/Macros/Structures
inb, outb, inw, outw, inl, outl
inb_p, outb_p, inw_p, outw_p, inl_p, outl_p
struct resource, request_region, release_region
ioperm, iopl, geteuid
request_mem_region, release_mem_region, ioremap, iounmap, ioread8, ioread16, ioread32, iowrite8, iowrite16, iowrite32
ioport_map, ioport_unmap,mmap
Files:
/dev/port, /dev/mem, /proc/iomem, /proc/ioports
Commands
hwclock
date
showkey
hexdump
strings
dd
lspci
biosdecode
dmidecode