4.2.2 · D5Operating Systems

Question bank — OS structure — monolithic, microkernel, hybrid

2,453 words11 min readBack to topic

Two pictures to hold in your head first

Before the traps, lock in the two mental images this whole page keeps testing. There are two separate axes, and almost every trap below lives in the gap between them:

  • Left picture — the SPEED axis. A request is a traveller climbing walls. The number of walls is (the boundary-crossing count); the height of each wall is (the cost of one crossing). Few short walls → fast.
  • Right picture — the RELIABILITY axis. A separate box whose size is , the amount of code running privileged. A bigger box means more code that can crash the whole machine.

The figure below draws both. On the left, follow the coral arrow: the green app block hops over two vertical "wall" lines — count them to read , and the label "each crossing costs " marks the wall height. On the right, the lavender box is : its area, not its position, is the quantity that matters. The dashed divider between the panels is the whole point — these are independent measurements, so a design can have a small (fast) and a huge (fragile) at the same time, which is exactly what monolithic kernels do.

The picture below makes the linear shape literal. The x-axis is (boundary crossings per request), the y-axis is (total overhead). Because every extra crossing adds the same chunk , the dots fall exactly on a straight line through the origin. The mint dot marks a monolithic read() (, low ); the coral dot marks a microkernel read() (, high ). The dashed line is the batched / fast-path case: the same request, but shared setup bends the cost below the straight line — the visual proof that the "strictly linear" assumption is only a first approximation.


True or false — justify

A monolithic kernel cannot be modular.
False — Linux is monolithic yet uses loadable modules; it is modular in source structure but the modules still run in kernel mode, so there is no runtime isolation between them.
In a microkernel, the file-system server runs in kernel mode.
False — the whole point is that the FS runs as an ordinary user-mode server process; only IPC, scheduling, and low-level memory stay privileged.
"Micro" in microkernel means the kernel executes faster because it is small.
False — "micro" describes how little runs in privileged mode (small ), not execution speed; pushing services to user space adds boundary crossings, so it is usually slower.
Windows NT is a pure microkernel.
False — it began with microkernel ideas (the Executive) but graphics and file-system code were pulled into kernel space for speed, making it a hybrid.
A hybrid kernel is more reliable than a pure microkernel.
False — by moving hot-path services back into kernel mode a hybrid re-enlarges the trusted code base , so its isolation sits between monolithic and microkernel, not above microkernel.
macOS/XNU is monolithic because it feels like UNIX to programmers.
False — the UNIX-like feel comes from a BSD layer, but XNU combines a Mach microkernel with that BSD chunk, so it is a hybrid.
Two device drivers in a monolithic kernel are protected from each other.
False — both run in the same kernel address space, so a bug in one can corrupt the other's memory; there is no protection boundary between them.
In a microkernel, a crashed driver forces a full machine reboot.
False — a driver is a user-mode server; if it dies the microkernel survives and can restart it, so the machine keeps running.
Every system call is exactly one boundary crossing regardless of kernel structure.
False — one request may need many crossings; in a microkernel a single read() can trigger 4–6+ crossings as it hops through separate servers.
A larger trusted code base always means faster execution.
False — measures how much code can crash you (reliability), not speed; speed tracks the number of boundary crossings , and these are independent quantities.
Batching many operations into one system call can make the real cost fall below .
True — if several logical crossings share a single trap/setup, they no longer each pay the full , so the naive overestimates; the true cost tracks the number of setups, not logical hops.

Spot the error

"Monolithic kernels avoid mode switches entirely, so a read() costs zero crossings."
Wrong — the app still starts in user mode, so it must trap into the kernel and return: about 2 crossings. Monolithic minimizes crossings inside the kernel (function calls), not the initial user→kernel trap.
"Because a microkernel passes messages, context switches are always required on every hop."
Wrong — a general IPC hop does force a context switch, but fast-path IPC (e.g. L4) can stay on the same CPU and skip it, so "always" is too strong; the effective for those hops is much smaller.
"The overhead model says communication cost grows with kernel size."
Wrong — is the number of boundary crossings per request and the per-crossing cost; neither is (kernel size). A big monolithic kernel can have small and thus low .
"To make Linux a microkernel, just compile the drivers as modules."
Wrong — modules still load into kernel mode. Becoming a microkernel would require running those drivers as isolated user-mode processes talking over IPC, which is a structural change, not a compile flag.
"Hybrids are slow because they use IPC for everything like a microkernel."
Wrong — hybrids deliberately keep hot-path services (the frequently-fired FS and graphics paths) in kernel space precisely to avoid IPC on those paths; that is why they land between monolithic and microkernel in speed.
"A driver bug in QNX (a microkernel) will corrupt the scheduler."
Wrong — the scheduler lives in the tiny privileged core while the driver is an isolated user process; the isolation boundary stops it from touching kernel memory.

Why questions

Why does more code in kernel mode buy speed but cost reliability?
Co-located services talk by plain function calls (few crossings ⇒ low ⇒ fast), but any bug among them runs privileged and can crash the whole machine (large ⇒ fragile).
Why can't we get microkernel isolation and monolithic speed at once?
Isolation requires a protection boundary between services, and every boundary must be crossed by a trap/IPC that costs time; you are trading crossings for safety, so the two goals pull in opposite directions.
Why did hybrids win the desktop market?
Pure microkernels were too slow in the 1990s and pure monoliths too fragile at scale, so hybrids kept microkernel-style modular structure while running hot-path services in kernel mode for "good enough" speed and safety.
Why does the Inter-process communication (IPC) cost dominate in a microkernel?
Because each service is a separate process, satisfying one request means several IPC hops, and each hop copies data plus (usually) reschedules — so cost scales with the number of hops , which the design makes large.
Why can fast-path IPC shrink the microkernel's disadvantage without changing ?
Because it lowers , not : keeping a hop on the same CPU and skipping the full context switch makes each crossing cheaper, so the same number of crossings costs less overall.
Why is verifying a microkernel's correctness more tractable than a monolithic kernel's?
The trusted core is only a few thousand lines, so there is far less code that must be proven bug-free; everything else runs unprivileged and cannot crash the machine even if wrong.
Why does a trap into the kernel exist at all instead of letting apps touch hardware directly?
Direct hardware access would let any buggy or malicious app corrupt the machine; the trap forces a controlled entry point where the privileged kernel validates the request before acting.
Why is speed measured by but reliability measured by , not the same number?
Speed is about how many walls a request climbs per request (); reliability is about how much code has the power to crash everything (). A design can have a huge yet tiny (monolithic) — proving these are genuinely different axes.

Edge cases

If a request needs zero privileged operations (pure arithmetic in user space), how many boundary crossings does it cost in any structure?
Zero — no trap is needed, so monolithic, microkernel, and hybrid all cost the same; structure only matters once a privileged service is involved.
An OS puts everything, including apps, in kernel mode (no user mode at all). What have you built?
A single-privilege system with maximal and no isolation — effectively an extreme monolithic design where any bug anywhere can crash everything; this is why early/embedded systems without an MMU are so fragile.
A "microkernel" that keeps its file system in kernel mode for speed — what is it really?
A hybrid, by definition, because it has already violated the microkernel rule that only IPC/scheduling/memory stay privileged; the label follows the structure, not the marketing.
In the model , what happens to as ?
— a request needing no boundary crossings has essentially no communication overhead, which is the limiting best case any structure shares.
If per-crossing cost were driven to nearly zero by fast-path IPC hardware, would the monolithic-vs-microkernel speed gap survive?
No — since , a tiny shrinks the penalty of large , so the microkernel's extra crossings would barely matter; this is exactly the argument modern fast-IPC microkernels (like L4) make.
If ten logical operations are batched into a single trap, what does effectively become for the cost model?
Effectively one setup rather than ten, so tracks the number of shared setups, not the ten logical hops — the batched cost falls below the naive .
A single request that would need 2 crossings in monolithic and 6 in microkernel — what is the microkernel's overhead ratio?
Roughly the communication cost, showing the penalty is the ratio of crossings, independent of the constant .
Recall One-line self-test before you leave

Speed order, reliability order, and what each tracks? Speed MONO > HYBRID > MICRO, driven by the crossing count ; reliability is exactly reversed (MICRO > HYBRID > MONO), driven by the trusted-base size — a different quantity from , which is why the two orderings are opposites rather than the same measurement.