All the drivers in the Linux running in the same context (address space of the kernel-space), or each in a different (similar to how the different processes work in a different address spaces in user-space)?
1 Answers
In x86-Linux, 32 bits, all drivers run in so called kernel mode (sometimes called Ring 0 mode because of the way Intel organized its CPU protection scheme).
When a driver is called by a process (say, you issue for example an read()
system call to a device driver), there's a function inside the driver that gets executed. That function is said to be executed in that process's context.
What this means is that the driver function executes within the memory map of the calling process. This implies that the driver function can access not only its own variables and structures stored in the kernel reserved addresses (virtual address 0xC0000000 and up) but can access variables and code of the user calling process. This allows functions like copy_to_user()
or copy_from_user()
to be able to interchange information with the user calling process.
Recall that the memory map of any process in Linux has two parts: one big part of a maximum of 3GB of memory available to the user process. This memory is private for that process. Another part of 1GB is for the kernel. This part is shared among all user processes' memory maps. The code, stack and global variables of a driver resides within this 1GB space.
There's another context: the interrupt context. A Linux driver can install a handler for a hardware interrupt. When this interrupt is triggered, the handler is executed, but this time, it will execute in the context of whatever process was being executed at that moment (i.e. the handler has not been called from an user process)
A typical driver is then a collection of functions, the majority of them are executed upon a request from an user process making a system call, so the most of the time, a driver is being executed (an instance of it actually) in the context of a particular user process (but unlike the code in the user process, the driver executes with all priviledges). Parts of the driver may be called asyncronously by other kernel functions, so they could be executing in another context, not related with the one belonging to the process that is using the driver.
Also remember that more than one user process could be using the driver, so each process executes the same code under its own context. A driver should be written so it can be reentered, so avoiding side effects.

- 11,128
- 2
- 24
- 32
-
Big thanks! But pair of clarifications: **1.** "This implies that the driver function can access not only its own variables and structures stored in the kernel reserved addresses (virtual address 0xC0000000 and up)... " - kernel reserved addresses located in 0xC0000000 and up, or 0x0 - 0xC0000000? – Alex Nov 22 '13 at 13:06
-
**2.** "** the handler is executed, but this time, it will execute in the context of whatever process was being executed at that moment**" - Does it mean that interrupt's handler can access to the data of some context, or it can not - i.e. handler is executed, but it will not execute in the any of contexts of any process, which being executed at that moment? – Alex Nov 22 '13 at 13:07
-
A driver running within a process context can access all memory assigned to that process, besides its own (kernel) memory. – mcleod_ideafix Nov 22 '13 at 13:25
-
Ok, but hardware interrupts occur by hardware, but does not occur by any process from user-space. – Alex Nov 22 '13 at 13:30
-
Interrupt context means that the handler is executing in an unknown process context (whichever was in execution when the interrupt arrived). Probably, not the same context of the user process that is currently interacting with the driver (and whose actions may have caused the device to generate an interrupt). It's a common mistake when writting device drivers to assume that if a process has opened a driver, every function inside the driver, including the interrupt handler, can access the memory of the user process. The user process could have been swapped out when the interrupt arrived. – mcleod_ideafix Nov 22 '13 at 13:30
-
@mcleod_ideafix Suppose I have a interrupt handler in my driver. And there is a global static variable flag = 0 which indicates if an interrupt has occurred. Now since the flag is in process context and interrupt simply has unknown context...how can I be able to access this flag variable in my handler. – Haswell Nov 25 '14 at 06:35
-
Your global static variable is in kernel space, which is shared among all user process, so it will be at your (interrupt code) hand. You couldn't be able to access it if it were in userspace. In other words, you cannot do a copy_from_user() or copy_to_user() to update such flag to the user because the interrupt handler cannot know what user process has been interrupted. – mcleod_ideafix Jan 13 '15 at 13:23