Linux kernel space and user space

I am confused by how the kernel and user space are structured and what parts of the memory are occupied. My current (possibly wrong) understanding is this:

  • A process is created, and the virtual memory of these processes is divided into user space and the kernel space region, where, when the user space region contains data, code, stack, heap, etc. the process and the kernel space area contains things like the page table for the process and kernel code. I'm not sure what the kernel code will be ... driver code or similar stuff?

  • Also, is the system call table always mapped to the same area in the process core space? (Is it even possible to say "core-space of a process"?

  • If I write my own driver / module and paste it, will this driver code be automatically copied to the kernel space of each new process that will be created? If not ... how exactly does it work?

Thanks in advance for any materials, literature / links that may help clarify my questions, also good.

Cheers, Brick

+7
source share
2 answers

You have a general idea that is basically correct, but do this setup: there is only one โ€œnuclear spaceโ€ for the whole machine, and all processes share it.

When a process is active, it can work either in user mode or in kernel mode.

In user mode, the instructions executed by the CPU are on the user space side of the memory card. The program runs its own code or code from the user space library. In user mode, the process has limited capabilities. There is a flag in the CPU that says that it does not allow the use of privileged instructions, and the kernel memory, although it exists on the process memory card, is not available. (You would not want any program to simply read and write kernel memory - all protection would be lost.)

When a process wants to do something else than move data in its own (user) virtual memory, for example, open a file, it must do syscall. Each CPU architecture has its own unique fancy method of creating system calls, but they all boil down to the following: a magic instruction is executed, the processor turns on the privileged mode flag and jumps to a special address in kernelspace, the "syscall entry point".

Now the process runs in kernel mode. Executable instructions are in kernel memory, and they can read and write whatever memory they want. The kernel checks the request that it just made and decides what to do with it.

In the open example, the kernel receives 2 or 3 parameters corresponding to the arguments int open(const char *filename, int flags[, int mode]) . The first argument gives an example of when kernelspace needs access to user space. You said open("foo", O_RDONLY) , so the string "foo" is part of your user space program. The syscall mechanism only passed a pointer, not a string, so the kernel should read the string from user memory.

To find the requested file, the kernel can consult the file system drivers (to find out where the file is) and block device drivers (to load the necessary blocks from the disk) or network device drivers and protocols (to download the file from a remote source). All these things are part of the kernel, that is, in the nuclear space, regardless of whether they are built-in or loaded as modules.

If the request cannot be satisfied immediately, the kernel can cause the process to sleep. This means that the process will be removed from the CPU until a response is received from the disk or network. Another process may get a chance to start now. Later, when the answer arrives, your process starts again (still in kernel mode). Now that he has found the file, syscall open can finish (check permissions, create a file descriptor) and return to user space.

Returning to user space is a simple matter of returning the CPU to non-privileged mode and restoring the registers to what they were before the user โ†’ kernel transition, with an instruction pointer pointing to the instruction after the magic syscall command.

Besides system calls, there are other things that can lead to a switch from user mode to kernel mode, including:

  • page errors - if your process accesses a virtual memory address that does not have a physical address assigned to it, the CPU switches to kernel mode and switches to the page error handler. The kernel then decides whether the virtual address is valid or not, and it either creates a physical page, or resumes the process in the user space where it stopped, or sends SIGSEGV.
  • interruptions - some hardware (network, disk, serial port, etc.) notifies the CPU of the need for its attention. The CPU goes into kernel mode and goes to the handler, the kernel responds to it, and then resumes the user space process that was started before the interrupt.

The module is loaded using syscall, which asks the kernel to copy the module code and data into the kernel space and run its initialization code in kernel mode.

It's quite a long time, so I stop. I hope that the end-to-end focus on core-core transitions has provided enough examples to reinforce the idea.

+29
source

There is no kernel space on the process virtual memory card. A virtual memory card has: text, bss, data, a bunch, a stack of a loaded program, and shared libraries. On Linux, you can check the / proc / $ PID / cards of any user space process for an example.

When a user-space process accesses some kernel code using a system call, kernel code is executed on behalf of the process in its stack. Obviously, after returning from the system call, all kernel / driver code will be pulled from the stack. To clarify, if at some point part of the kernel code is not used by any process, it will not be part of any process virtual memory card.

If you are using Linux, I would recommend Robert Luv's book, Linux Kernel Development.

+2
source

All Articles