Location of OS Kernel Data
Asked Answered
M

3

5

I'm a beginner with operating systems, and I had a question about the OS Kernel.

I'm used to the standard notion of each user process having a virtual address space of stack, heap, data, and code. My question is that when a context switch occurs to the OS Kernel, is the code run in the kernel treated as a process with a stack, heap, data, and code?

I know there is a dedicated kernel stack, which the user program can't access. Is this located in the user program address space?

I know the OS needs to maintain some data structures in order to do its job, like the process control block. Where are these data structures located? Are they in user-program address spaces? Are they in some dedicated segment of memory for kernel data structures? Are they scattered all around physical memory wherever there is space?

Finally, I've seen some diagrams where OS code is located in the top portion of a user program's address space. Is the entire OS kernel located here? If not, where else does the OS kernel's code reside?

Thanks for your help!

Mag answered 8/1, 2019 at 1:43 Comment(1)
You can find the address of the kernel code and data by reading from the file /proc/iomem as root. sudo cat /proc/iomem | grep KernelInchon
C
7

Yes, the kernel has its own stack, heap, data structures, and code separate from those of each user process.

The code running in the kernel isn't treated as a "process" per se. The code is privileged meaning that it can modify any data in the kernel, set privileged bits in processor registers, send interrupts, interact with devices, execute privileged instructions, etc. It's not restricted like the code in a user process.

All of kernel memory and user process memory is stored in physical memory in the computer (or perhaps on disk if data has been swapped from memory).

The key to answering the rest of your questions is to understand the difference between physical memory and virtual memory. Remember that if you use a virtual memory address to access data, that virtual address is translated to a physical address before the data is fetched at the determined physical address.

Each process has its own virtual address space. This means that some virtual address a in one process can map to a different physical address than the same virtual address a in another process. Virtual memory has many important uses, but I'm not going to go into them here. The important point is that virtual memory enforces memory isolation. This means that process A cannot access the memory of process B. All of process A's virtual addresses map to some set of physical addresses and all of process B's virtual addresses map to a different set of physical addresses. As long as the two sets of physical addresses do not overlap, the processes cannot see or modify the memory of each other. User processes cannot access physical memory addresses directly - they can only make memory accesses with virtual addresses.

There are times when two processes may have some virtual addresses that do map to the same physical addresses, such as if they both mmap the same file, both use a shared library, etc.

So now to answer your question about kernel address spaces and user address spaces.

The kernel can have a separate virtual address space from each user process. This is as simple as changing the page directory pointer in the cr3 register (in an x86 processor) on each context switch. Since the kernel has a different virtual address space, no user process can access kernel memory as long as none of the kernel's virtual memory addresses map to the same physical addresses as any of the virtual addresses in any address space for a user process.

This can lead to a minor problem. If a user process makes a system call and passes a pointer as a parameter (e.g. a pointer to a buffer in the read system call), how does the kernel know which physical address corresponds to that buffer? The virtual address in the pointer maps to a different physical address in kernel space, so the kernel cannot just dereference the pointer. There are two options:

  1. The kernel can traverse the user process page directory/tables to find the physical address that corresponds to the buffer. The kernel can then read/write from/to that physical address.

  2. The kernel can instead include all of its mappings in the user address space (at the top of the user address space, as you mentioned). Now, when the kernel receives a pointer through the system call, it can just access the pointer directly since it is sharing the address space with the process.

Kernels generally go with the second option, since it's more convenient and more efficient. Option 1 is less efficient because each time a context switch occurs, the address space changes, so the TLB needs to be flushed and now you lose all of your cached mappings. I'm simplifying things a bit here since kernels have started doing things differently given the recent Meltdown vulnerability discovered.

This leads to another problem. If the kernel includes its mappings in the user process address space, what stops the user process from accessing kernel memory? The kernel sets protection bits in the page table that cause the processor to prohibit the user process from accessing the virtual addresses that map to physical addresses that contain kernel memory.

Take a look at these slides for more information.

Cultivator answered 8/1, 2019 at 8:3 Comment(0)
R
2

I'm used to the standard notion of each user process having a virtual address space of stack, heap, data, and code. My question is that when a context switch occurs to the OS Kernel, is the code run in the kernel treated as a process with a stack, heap, data, and code?

One every modern operating system I am aware there is NEVER a context switch to the kernel. The kernel executes in the context of a process (some systems user the fiction of a reduced process context.

The "kernel" executes when a process enters kernel mode through an exception or an interrupt.

Each process (thread) normally has its own kernel mode stack used after an exception. Usually there is a single single interrupt stack for each processor.

https://books.google.com/books?id=FSX5qUthRL8C&pg=PA322&lpg=PA322&dq=vax+%22interrupt+stack%22&source=bl&ots=CIaxuaGXWY&sig=S-YsXBR5_kY7hYb6F2pLGjn5pn4&hl=en&sa=X&ved=2ahUKEwjrgvyX997fAhXhdd8KHdT7B8sQ6AEwCHoECAEQAQ#v=onepage&q=vax%20%22interrupt%20stack%22&f=false

I know there is a dedicated kernel stack, which the user program can't access. Is this located in the user program address space?

Each process has its own kernel stack. It is often in the user space with protected memory but could be in the system space. The interrupt stack is always in the system space.

Where are these data structures located? Are they in user-program address spaces?

They are generally in the system space. However, some systems do put some structures in the user space in protected memory.

Are they in some dedicated segment of memory for kernel data structures?

If they are in the user space, they are generally for an access mode more privileged than user mode and less privileged than kernel mode.

Are they scattered all around physical memory wherever there is space?

Thinks can be spread over physical memory pretty much at random.

Richellericher answered 8/1, 2019 at 19:39 Comment(0)
D
0

The data structures in questions are usually regular C structures situated in the RAM allotted to the kernel by the kernel allocator

They are not usually accessible from regular processes becuase of normal mechanisms for memory protection and paging (virtual memory)

A kind of exception to this are kernel threads which have no userspace address space so the code they execute is always the kernel code working with the kernel space data structures hence with the isolated kernel memory

Now for the interesting part: 64-bit Linux uses a thing called Direct Map for memory organization, which means that the full amount of physical memory available is mapped in the kernel page tables as just one contiguous chunk. This is not true for 32-bit as the HIGHMEM was used to avoid the limitation of 4GB address spaces

Since the kernel has all the physical RAM visible and available to its own allocator, the kernel data structures in question can be situated pretty randomly with respect to the physical addresses

You can google on there terms to gain additional information:

  • PTI (page table isolation)
  • __copy_from_user (esp. on esoteric architectures where this function is not just a bitwise copy)
  • EPT (Intel nested paging in virtual machines)
Decline answered 16/9, 2022 at 12:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.