Source
x
:c:func:`copy_to_user()` / :c:func:`copy_from_user()` / :c:func:`get_user()` / :c:func:`put_user()`
.. _kernel_hacking_hack:
============================================
Unreliable Guide To Hacking The Linux Kernel
============================================
:Author: Rusty Russell
Introduction
============
Welcome, gentle reader, to Rusty's Remarkably Unreliable Guide to Linux
Kernel Hacking. This document describes the common routines and general
requirements for kernel code: its goal is to serve as a primer for Linux
kernel development for experienced C programmers. I avoid implementation
details: that's what the code is for, and I ignore whole tracts of
useful routines.
Before you read this, please understand that I never wanted to write
this document, being grossly under-qualified, but I always wanted to
read it, and this was the only way. I hope it will grow into a
compendium of best practice, common starting points and random
information.
The Players
===========
At any time each of the CPUs in a system can be:
- not associated with any process, serving a hardware interrupt;
- not associated with any process, serving a softirq or tasklet;
- running in kernel space, associated with a process (user context);
- running a process in user space.
There is an ordering between these. The bottom two can preempt each
other, but above that is a strict hierarchy: each can only be preempted
by the ones above it. For example, while a softirq is running on a CPU,
no other softirq will preempt it, but a hardware interrupt can. However,
any other CPUs in the system execute independently.
We'll see a number of ways that the user context can block interrupts,
to become truly non-preemptable.
User Context
------------
User context is when you are coming in from a system call or other trap:
like userspace, you can be preempted by more important tasks and by
interrupts. You can sleep, by calling :c:func:`schedule()`.
.. note::
You are always in user context on module load and unload, and on
operations on the block device layer.
In user context, the ``current`` pointer (indicating the task we are
currently executing) is valid, and :c:func:`in_interrupt()`
(``include/linux/preempt.h``) is false.
.. warning::
Beware that if you have preemption or softirqs disabled (see below),
:c:func:`in_interrupt()` will return a false positive.
Hardware Interrupts (Hard IRQs)
-------------------------------
Timer ticks, network cards and keyboard are examples of real hardware
which produce interrupts at any time. The kernel runs interrupt
handlers, which services the hardware. The kernel guarantees that this
handler is never re-entered: if the same interrupt arrives, it is queued
(or dropped). Because it disables interrupts, this handler has to be
fast: frequently it simply acknowledges the interrupt, marks a 'software
interrupt' for execution and exits.
You can tell you are in a hardware interrupt, because
:c:func:`in_irq()` returns true.
.. warning::
Beware that this will return a false positive if interrupts are
disabled (see below).
Software Interrupt Context: Softirqs and Tasklets
-------------------------------------------------
Whenever a system call is about to return to userspace, or a hardware
interrupt handler exits, any 'software interrupts' which are marked
pending (usually by hardware interrupts) are run (``kernel/softirq.c``).