-
Notifications
You must be signed in to change notification settings - Fork 108
Kernel Execution Overview
The ELKS kernel is well-designed, and completely controls exactly what happens on any interrupt, system call and task switch.
The design is the same as Linux 2.0, with the exception of SMP (multiprocessor support).
The Linux 2.0 design has three rules, also present in ELKS (excerpted from Linux Kernel Internals, 2nd Ed, 1998):
- No process running in kernel mode is interrupted by another process in kernel mode, except when it releases control and sleeps. This rule ensures that large areas of the kernel are atomic with respect to other processes and thus simplifies many functions in the Linux kernel.
- Interrupt handling can interrupt a process in kernel mode, but that in the end control is returned back to this same process. A process can block interrupts and thus ensure it will not be interrupted.
- Interrupt handling can only be interrupted by an interrupt of higher priority. In ELKS, all interrupt code runs on a separate stack and never allows a process switch if kernel mode code was interrupted.
The ELKS kernel in this regard is well-coded and provides a well-defined mechanism that guarantees execution in certain ways for kernel code and interrupt drivers, and is quite stable. This implementation guarantees that the kernel itself is atomic and not reentrant across system calls. That is - a system call, such as read (a file, TTY, ethernet packet, etc) will not be interrupted by another process calling read or any other system call. The kernel system call code will always finish by returning to the user application that called it, or the process will be put to sleep using an explicity-coded sleep_on/wait_event/etc style wait function.
Hardware interrupts are only allowed to interrupt when three things are active: the 8259 controller must not be processing a higher-priority interrupt, it must have had any previous interrupt acknowledged, and the CPU must not have interrupts disabled. Obviously, the hardware must have been previously programmed to enable interrupts, and appropriately registered the C routine to call with request_irq().
On the 8086, system calls use the software interrupts use the INT 80h instruction which is interrupt 128, and hardware interrupts (0-15) use a low-memory table of addresses for each interrupt. The CPU itself handles a software or hardware interrupt nearly identically, and ELKS takes advantage of that by routing system calls and all hardware interrupts through the same routine, _irqit
.
The ELKS kernel handles interrupts as follows:
- For both software and hardware interrupts, all registers are saved, and the stack is switched to either a kernel stack for the currently executing application, or a special interrupt stack, and interrupts are re-enabled.
- In the case of a software interrupt, the system call for value in AX is called. If that system call doesn't explicitly make a call to sleep the process, on return the registers are restored and it returns to user mode.
- In the case of a system call that called sleep, a "task switch" to the next ready-to-run process will be executed, which will return from its previous call to sleep, registers restored, and return to user mode.
- In the case of a hardware interrupt, the registered driver routine for the interrupt number is called.
- On return from the hardware interrupt handling routine, ELKS disables interrupts, and then outputs an acknowledgement to the chained 8259 for interrupts 8-15, and then an acknowledgement to the master 8259.
- It is then determined whether the system was executing user code when the interrupt occurred. If not, the saved registers are restored and an interrupt return is performed, resuming the interrupted code.
- If user application code was being interrupted, schedule is called to perform a possible forced task switch. This only occurs from interrupted user code, never from interrupted kernel code.
- The 8259 will not allow another interrupt of the same priority until acknowledged by the ELKS kernel at interrupt exit.
For a detailed discussion of how system calls and interrupts are handled, see System Calls and Interrupts.