Part 3: Character Device Drivers

Character devices are the most common type of driver and provide the foundation for interacting with hardware through the filesystem interface. In this part, you’ll learn how to create complete character device drivers that applications can open, read, write, and control.

What You’ll Learn

flowchart LR
    subgraph Application
        App["User Program"]
    end

    subgraph VFS["Virtual File System"]
        FD["File Descriptor"]
    end

    subgraph Driver["Your Driver"]
        FO["file_operations"]
        CD["cdev"]
    end

    subgraph Hardware
        HW["Device"]
    end

    App -->|"open(/dev/mydev)"| FD
    FD --> FO
    FO --> CD
    CD --> HW

    style Application fill:#7a8f73,stroke:#2e7d32
    style Driver fill:#8f8a73,stroke:#f9a825

Chapter Contents

Chapter Topic Key Concepts
3.1 Character Device Concepts Major/minor numbers, device nodes, /dev
3.2 File Operations file_operations structure, implementing handlers
3.3 Device Registration cdev_init, cdev_add, device_create
3.4 Read and Write copy_to_user, copy_from_user, data transfer
3.5 IOCTL Custom commands, _IO macros
3.6 Poll and Seek poll(), llseek(), blocking I/O
3.7 Misc Devices Simplified character device registration

Prerequisites

Before starting this part, ensure you understand:

  • Module lifecycle (Part 2)
  • Kernel memory access rules
  • Basic kernel coding style

Examples

This part includes complete working examples:

  • simple-char: Basic character device with read/write
  • ioctl-device: Device with custom ioctl commands

Character Device Overview

Character devices:

  • Transfer data as a stream of bytes (no block structure)
  • Appear as special files in /dev/
  • Support file operations: open, read, write, close, ioctl
  • Are identified by major and minor numbers

Common character devices include:

  • Serial ports (/dev/ttyS*)
  • Terminals (/dev/tty*)
  • Input devices (/dev/input/*)
  • Memory devices (/dev/mem, /dev/null, /dev/zero)
  • Custom hardware interfaces

The Big Picture

flowchart TB
    subgraph UserSpace["User Space"]
        App["Application"]
        LibC["glibc: open(), read(), write()"]
        DevFile["/dev/mydevice"]
    end

    subgraph KernelSpace["Kernel Space"]
        Syscall["System Call Handler"]
        VFS["Virtual File System"]
        CharDev["Character Device Layer"]
        subgraph YourDriver["Your Driver"]
            FO["file_operations"]
            Open["my_open()"]
            Read["my_read()"]
            Write["my_write()"]
            Ioctl["my_ioctl()"]
        end
    end

    App --> LibC
    LibC --> DevFile
    DevFile --> Syscall
    Syscall --> VFS
    VFS --> CharDev
    CharDev --> FO
    FO --> Open
    FO --> Read
    FO --> Write
    FO --> Ioctl

    style UserSpace fill:#7a8f73,stroke:#2e7d32
    style KernelSpace fill:#8f6d72,stroke:#c62828
    style YourDriver fill:#8f8a73,stroke:#f9a825

Further Reading

Next

Start with Character Device Concepts to understand how character devices are identified and accessed.


Table of contents


Back to top

Linux Driver Development Guide is a community resource for learning kernel driver development. Not affiliated with the Linux Foundation. Content provided for educational purposes.

This site uses Just the Docs, a documentation theme for Jekyll.