DEV Community

Cover image for OS and Hardware Interaction( Kernel and Drivers )
Sarthak
Sarthak

Posted on

OS and Hardware Interaction( Kernel and Drivers )

Ever wondered how your operating system is interacting with bluetooth or wifi card!!!

Let's begin with a simple scenario:

Assume you want to connect your bluetooth headphones to your PC,you click on connect button and get message like "Connected" or "Unable to connected"....

What happened in between your click and message is:
UserActions --> UI Framework --> UserSubsystem makes Systemcalls --> Kernel Mode --> Kernel calls respective drivers --> Hardware

Seems easy???Nahh its not!
Your user subsytem makes a system call to access the hardware which is passed to kernel.Thats when the main part kicks in.

Lets deep dive into kernel first:

Kernel is usually not a layered structure....its a mixture of modular,monolithic as well as layered structure....but layered approach help us understand the working of kernel easily.
On receiving a system call:

1. Kernel Syscall Dispatcher gets control:

  • Validates system call number and details.

  • Pointer lookup-Can be said that this maps syscalls to C functions..(Ofcourse its all code that works underneath)

2. Syscall Handler Invoked:

  • Kernel Subsystem takes over which has different layers like VFS(virtual file system),Network Stack,Memory Subsystem,Process Scheduler,Device Management

  • Depending on the system call , it enters a layer

3.Driver Call

  • Drivers dont directly recieve a systemcall.
  • They receive instructions from kernel subsystem(VFSops,netdevops etc) Ex:To access hardwares Device Management layer is accessed in kernel which usually creates an ioctlops which is passed to suitable drivers.

But the job doesn't end here....Kernels interact with drivers which then interact with hardware.

Lets deep dive into drivers too:
Drivers don't have any specific structure,it depends on the hardware that the driver deals with.
But flow of operations usually remains same in all drivers-

  • Register itself with kernel That function basically walks up to the kernel like:

“Heyy kernel, I'm a driver for this kind of device.
If you ever see hardware with this ID, call me.”

  • Create ops Table (Collection of function pointers that driver gives to kernel) Think of it like the driver saying:

“Hey kernel, if you want me to do X, call this function.
If you want Y, call that one.
If you ask for Z, here’s the address of the function.”

  • Initialize Hardware (Inside probe() function) Once the kernel matches driver ↔ hardware, it calls the driver’s probe(). This is where the driver:

1) maps MMIO registers

2) requests interrupts (request_irq())

3) allocates kernel memory

4) resets/initializes the hardware

5) registers itself into kernel subsystems (netdev, blockdev, char device, etc.)

Think of probe() like the driver moving into its apartment and setting up the furniture.

  • Handle Interrupts Hardware doesn’t politely send emails. It screams at the CPU. So the driver registers an interrupt handler: request_irq(irq_number, my_handler, ...)

When hardware finishes something (packet received, DMA complete, buffer empty):
→ CPU triggers interrupt
→ Kernel interrupt manager dispatches
→ Driver’s interrupt handler runs
→ Driver processes event
→ Notifies the proper kernel subsystem

  • Data Transfer (MMIO / DMA) Drivers use:

MMIO → read/write registers directly

DMA → tell hardware to perform large data transfers without CPU babysitting

Driver sets these up, kernel keeps everything safe.

What happens when the Linux subsystem sends an ioctl (or any ops-table call) to the driver?

  • User calls ioctl() → enters kernel through the syscall interface.

  • Kernel checks the file descriptor → finds which device/driver it belongs to.

  • Kernel looks up the driver’s ops table (like .unlocked_ioctl).

  • Kernel calls the driver function via the ops pointer (no direct linking, just a function pointer jump).

  • Driver processes the command (configure hardware, read/write registers, trigger DMA, etc.).

  • Driver returns output/status back to the kernel.

  • Kernel returns the result to the user application.

And thats how you interact with hardwares...
Some references for further exploring:

https://elixir.bootlin.com/linux/v6.18/source/drivers/usb/core/usb.c
https://eng.libretexts.org/Bookshelves/Computer_Science/Operating_Systems/Linux_-_The_Penguin_Marches_On_(McClanahan)/06:_Kernel_Module_Management/1.03:_Linux_Kernel_Subsystem

Top comments (0)