PREEMPT_RT Linux Kernel Tutorial: Build a Real-Time Kernel from Source (Updated 2026)-Free Linux Device Drivers Course online

← Previous Lecture  |  Next Lecture →

PREEMPT_RT Linux Kernel Tutorial: Build a Real-Time Kernel from Source (Updated 2026)

Free Linux Kernel Programming Course • Free Linux Device Drivers Course • Free Embedded Systems Course

Level
Intermediate
Reading Time
14 min
Kernel Used
6.12+ LTS
Category
Linux Kernel Programming
PREEMPT_RT Real-Time Linux Kernel RTOS on Linux Free Linux Kernel Course Free Linux Device Drivers Course Embedded Linux

If you are searching for a hands-on PREEMPT_RT Linux kernel tutorial, you are in the right place. This lesson is part of EmbeddedPathashala’s free Linux kernel programming course and free Linux device drivers course, and it walks you through what the real-time Linux kernel actually is, why it matters for embedded systems, and how to configure and build one yourself on a modern kernel.

What You Will Learn

  • What the PREEMPT_RT patch set is and why it exists
  • The big 2024 milestone: PREEMPT_RT becoming part of mainline Linux
  • How to enable and build a real-time Linux kernel today, with no external patch needed
  • How to verify that your system is really running in real-time mode
  • Design rules for user-space and driver code that must behave deterministically
  • Common mistakes beginners make when building their first RT kernel

Prerequisites

  • Comfort with basic Linux commands and building software from source
  • A Linux kernel source tree (mainline.org or your distribution’s source package)
  • Familiarity with make menuconfig from our earlier kernel-building lessons
  • A test machine or virtual machine you don’t mind rebooting a few times

Why a Standard Linux Kernel Is Not “Real Time”

Standard, general-purpose Linux is designed to maximize overall throughput — it tries to keep every CPU busy and every process fed, but it makes no promise about exactly when any single task will run. A background job doing disk I/O is free to hold a lock or occupy the CPU for a little while longer if that improves overall system efficiency. For a web server or a desktop, that trade-off is perfectly fine. For a robot arm, a motor controller, or an industrial protocol stack, an occasional multi-millisecond delay can be the difference between a working product and a safety incident.

This gap between “usually fast” and “guaranteed on time” is exactly what the real-time Linux effort set out to close.

What Is PREEMPT_RT?

PREEMPT_RT is a long-running engineering effort, started in the early 2000s, to make almost every part of the Linux kernel preemptible — meaning a high-priority task can interrupt lower-priority kernel work almost anywhere, not just at a handful of safe points. Instead of forking Linux into a separate real-time operating system, the project’s philosophy was always to feed its changes back into mainline Linux over time.

Three ideas sit at the heart of PREEMPT_RT:

  • Threaded interrupt handlers — most interrupt processing runs inside a schedulable kernel thread instead of in a hard, non-preemptible context, so a high-priority user task can still cut in.
  • Sleeping (RT) spinlocks — ordinary spinlocks are converted into a mutex-like primitive with priority inheritance, so a low-priority task holding a lock cannot silently block a high-priority one for long.
  • High-resolution, priority-aware scheduling — nanosecond-resolution timers and a scheduler tuned for predictable wake-up latency instead of raw throughput.

The 2024 Milestone: PREEMPT_RT Is Now Part of Mainline

Here is the update that most older tutorials and books miss: for roughly two decades, PREEMPT_RT lived as an out-of-tree patch that you had to download separately and apply on top of a matching mainline kernel version. That changed in September 2024, when the final pieces of PREEMPT_RT were merged directly into Linux kernel version 6.12, which also became that year’s Long Term Support (LTS) release.

What this means for you in practice:

  • On kernel 6.12 and newer, you no longer need to hunt for a separate -rt patch file that matches your exact kernel version.
  • A configuration option, CONFIG_PREEMPT_RT, is available directly inside make menuconfig under the preemption model settings.
  • Driver and subsystem maintainers are now expected to keep real-time compatibility in mind by default, instead of an external patch trying to catch up after the fact.
  • If you’re on an older kernel (5.x or early 6.x), the classic external -rt patch workflow described in older books is still the correct approach — the mainline option only applies from 6.12 onward.
Real-Time Linux Timeline
Milestone What Happened
Early 2000sPREEMPT_RT project begins as an out-of-tree patch set
2007–2014Threaded IRQs, high-resolution timers, lockdep, and deadline scheduling merge piece by piece into mainline
September 2024Final RT pieces merged; PREEMPT_RT becomes a standard mainline config option in Linux 6.12
TodayReal-time support ships in-tree for x86_64, ARM64, and RISC-V, with more architectures being added

Step-by-Step: Building a Real-Time Kernel on 6.12+

The overall workflow follows the same kernel-building steps you learned earlier in this course, with one extra menu choice.

Step 1: Get a Recent Kernel Source Tree

git clone --depth 1 --branch v6.12 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux

Step 2: Start From a Known-Good Config

cp /boot/config-$(uname -r) .config
make olddefconfig

Step 3: Select the Fully Preemptible Model

make menuconfig
# General Setup ---> Preemption Model ---> (X) Fully Preemptible Kernel (Real-Time)

If the fully preemptible choice is not visible, enable the expert-level option that exposes advanced preemption settings first, then return to the Preemption Model menu.

Step 4: Set a Recognizable Version Suffix

General Setup ---> Local version - append to kernel release ---> -rt-epk

Giving your build a custom suffix like -rt-epk makes it easy to pick out later in the GRUB boot menu and in uname -r.

Step 5: Build and Install

make -j$(nproc)
sudo make modules_install
sudo make install

Step 6: Reboot and Select the New Kernel

Hold Shift during boot (BIOS systems) to force the GRUB menu to appear, then choose the newly built real-time kernel entry.

Step 7: Verify Real-Time Mode Is Active

uname -r
# example: 6.12.16-rt-epk

cat /sys/kernel/realtime
# expected output: 1

The /sys/kernel/realtime file is the most reliable check — it only appears and only reports 1 when CONFIG_PREEMPT_RT is actually compiled in and active, regardless of what your kernel version string looks like.

A Real-Time Kernel Alone Is Not Enough

This is the point most beginners miss. Booting an RT kernel does not automatically make your application deterministic. Real-time behavior has to be designed into your user-space code and drivers as well:

  • Lock down memory — use mlockall() so your process’s pages cannot be paged out, avoiding unpredictable page-fault latency at the worst possible moment.
  • Pre-fault your stack and heap — touch memory you plan to use before entering your time-critical loop, so the first real page fault doesn’t happen mid-deadline.
  • Set the right scheduling policy and priority — use SCHED_FIFO or SCHED_DEADLINE with sched_setscheduler() instead of the default time-sharing policy.
  • Isolate CPUs — use the isolcpus and nohz_full boot parameters together with CPU affinity so your real-time thread doesn’t compete with the rest of the system on the same core.
  • Avoid blocking system calls in the hot path — logging, dynamic memory allocation, and unbounded I/O all introduce latency you cannot bound in advance.

Common Mistakes and Troubleshooting

SymptomLikely Cause & Fix
/sys/kernel/realtime is missingYour running kernel isn’t actually the RT build — check GRUB default entry and uname -r.
Fully Preemptible option missing in menuconfigEnable “Configure standard kernel features (expert users)” under General Setup first.
High latency despite RT kernelFirmware-level System Management Interrupts (SMI), power-saving C-states, or an unbounded user-space loop are usually the culprit — not the kernel config.
Build fails on GCC version mismatchMatch your GCC version to what the chosen kernel release expects; check Documentation/process/changes.rst in the source tree.

Best Practices

  • Always benchmark before and after enabling PREEMPT_RT — some workloads that are throughput-bound can actually get slower under RT scheduling.
  • Keep a non-RT kernel entry in GRUB as a fallback while you’re still testing.
  • Version-control your .config file alongside your project so builds are reproducible.
  • Document the exact kernel command-line parameters (isolcpus, nohz_full, irqaffinity) you used — they matter as much as the kernel config itself.

Performance and Security Considerations

Performance: PREEMPT_RT trades some raw throughput for lower, more predictable worst-case latency. Systems that need maximum bandwidth (large file servers, batch compute) rarely benefit from it; systems that need bounded response time (motor control, data acquisition, industrial protocol stacks) usually do.

Security: real-time scheduling classes can starve normal processes if misused — a runaway SCHED_FIFO task can lock out everything else on a core. Linux mitigates this with sched_rt_runtime_us, which reserves a slice of CPU time for non-real-time tasks by default; don’t disable it without a good reason on a production system.

Key Takeaways

  • PREEMPT_RT converts most of the Linux kernel into preemptible, priority-aware code so high-priority tasks aren’t blocked for long.
  • Since kernel 6.12, real-time support is built into mainline Linux — no external patch is required for new projects.
  • Enabling the config option is only half the job; user-space and driver code must also be written for determinism.
  • A real-time Linux kernel provides soft real-time guarantees, not the hard guarantees of a microcontroller RTOS.

Conclusion

The merge of PREEMPT_RT into mainline Linux is one of the most significant embedded Linux milestones of the last few years, and it directly affects how you should approach real-time projects today. Instead of chasing a matching out-of-tree patch for your exact kernel version, you can now select real-time preemption straight from make menuconfig on kernel 6.12 and later. In the next lesson in this free Linux kernel programming course, we’ll go deeper into exactly how the internal mechanisms — spinlocks, threaded IRQs, and the scheduler — differ between the standard and real-time preemption models, and in the lesson after that, we’ll measure real latency numbers on your own hardware.

Frequently Asked Questions About PREEMPT_RT

Do I still need to download a separate RT patch?

Only if you’re building a kernel older than 6.12. From 6.12 onward, PREEMPT_RT is a standard mainline configuration option.

Is PREEMPT_RT a hard real-time solution?

No. It provides soft real-time behavior with very low, statistically bounded latency. Applications needing hard guarantees (flight control, anti-lock brakes) typically use a dedicated RTOS or a co-processor instead.

Which architectures support the mainline PREEMPT_RT option?

x86_64, ARM64, and RISC-V were supported at merge time, with further architecture support continuing to expand.

How much RAM does a real-time Linux kernel need?

Practically speaking, plan for at least 32 MB of RAM for the kernel and core services; real applications will need more depending on their workload.

Will enabling PREEMPT_RT slow down my system?

It can reduce peak throughput slightly because of the added preemption checks and locking overhead, but for latency-sensitive workloads the predictability gain is usually worth the trade-off.

How do I check if PREEMPT_RT is really active?

Read /sys/kernel/realtime. If it exists and prints 1, real-time preemption is active on the running kernel.

Continue the Free Linux Kernel Programming Course

Next up: Mainline vs PREEMPT_RT internals, then hands-on latency measurement with cyclictest and rtla.

Browse the Full Course Join EmbeddedPathashala

← Previous Lecture  |  Next Lecture →

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *