Detailed explanation of Linux user space and kernel space

藏色散人
Release: 2020-12-08 17:01:31
forward
4176 people have browsed it

Recommended: "Linux Video Tutorial"

1. Introduction

  • Linux operating system and driver operation In kernel space, applications run in user space. The two cannot simply use pointers to transfer data. Because of the virtual memory mechanism used by Linux, user space data may be swapped out. When the kernel space uses user space pointers, the corresponding data may not be in memory. The memory mapping of user space adopts segment page type, while the kernel space has its own rules; this article aims to explore the address mapping of kernel space.
  • os allocates an independent, continuous, virtual address memory space to each process. The size is generally 4G (32-bit operating system, that is, 2 to the 32nd power), in which the high address value is The memory space is allocated to os, linux os occupies 1G, and window os occupies 2G; the remaining memory address space is allocated to processes.
  • Usually the 32-bit Linux kernel virtual address space is divided into 0~3G as user space and 3~4G as kernel space (note that the linear address that the kernel can use is only 1G). Note that this is the 32-bit kernel address space division, and the 64-bit kernel address space division is different.

  • Process addressing space 0~4G
  • The process is in user mode Only 0~3G can be accessed, and 3G~4G can only be accessed when entering the kernel state
  • The process enters the kernel state through system calls
  • The 3G~4G part of the virtual space of each process is the same
  • The process entering the kernel state from user mode will not cause changes in CR3 but will cause changes in the stack

2. Linux kernel high-end memory

1. Origin

When the kernel module code or thread accesses memory, the memory addresses in the code are all logical addresses, and corresponding to the real physical memory address, the addressone-to-one is required Mapping, for example, the physical address corresponding to logical address 0xc0000003 is 0×3, the physical address corresponding to 0xc0000004 is 0×4,…, the relationship between logical address and physical address is

Physical address = Logical address – 0xC0000000 : This is the address translation relationship of the kernel address space. Note that the virtual address of the kernel is at the "high end", but the physical memory address mapped by ta is at the low end.

##0xc00000010×10xc00000020×20xc00000030×3……0xe00000000×20000000……

Assuming that according to the above simple address mapping relationship, the kernel logical address space access is 0xc0000000 ~ 0xffffffff, then the corresponding physical memory range is 0×0 ~ 0×40000000, that is, only 1G physical memory can be accessed. If 8G of physical memory is installed in the machine, the kernel can only access the first 1G of physical memory, and the subsequent 7G of physical memory will be inaccessible because the kernel's address space has all been mapped to the physical memory address range 0×0 ~ 0×40000000. Even if 8G physical memory is installed, how does the kernel access the memory with the physical address 0×40000001? The code must have a memory logical address. The address space from 0xc0000000 ~ 0xffffffff has been used up, so the memory after the physical address 0×40000000 cannot be accessed.

Obviously the kernel address space 0xc0000000 ~ 0xfffffff cannot be used for simple address mapping. Therefore, the kernel address space is divided into three parts in the x86 architecture: ZONE_DMA, ZONE_NORMAL and ZONE_HIGHMEM. ZONE_HIGHMEM is high-end memory, which is the origin of the concept of high-end memory.


In the x86 structure, the three types of zones (calculated from 3G) are as follows:

ZONE_DMA 16MB starting from the memory

ZONE_NORMAL 16MB~896MB

ZONE_HIGHMEM 896MB ~ End (1G)

2. Understand

We explained the origin of high-end memory earlier. Linux divides the kernel address space into three parts: ZONE_DMA, ZONE_NORMAL and ZONE_HIGHMEM. The high-end memory HIGH_MEM address space ranges from 0xF8000000 to 0xFFFFFFFF (896MB to 1024MB). So if the kernel uses the 128MB high-end memory address space, how can it access all physical memory ?

When the kernel wants to access memory with a physical address higher than 896MB, it will find a free logical address space of corresponding size in the address space range of 0xF8000000 ~ 0xFFFFFFFF and borrow it for a while. Borrow this logical address space to map it to the physical memory you want to access (that is, fill in the kernel PTE page table), use it temporarily for a while, and return it after use. In this way, others can also borrow this address space to access other physical memories, achieving the use of a limited address space to access all physical memories. As shown below.

For example, the kernel wants to access a 1MB physical memory starting from 2G, that is, the physical address range is 0×80000000 ~ 0x800FFFFF. Before accessing, first find a 1MB free address space. Assume that the found free address space is 0xF8700000 ~ 0xF87FFFFF. Use this 1MB logical address space to map to the memory in the physical address space 0×80000000 ~ 0x800FFFFF. The mapping relationship is as follows:

Logical address Physical memory address
0xc0000000 0×0
0xffffffff 0×40000000 ??
##……##0xF87FFFFF

After the kernel accesses 0×80000000 ~ 0x800FFFFF physical memory, it releases the 0xF8700000 ~ 0xF87FFFFF kernel linear space. In this way, other processes or codes can also use the address 0xF8700000 ~ 0xF87FFFFF to access other physical memory.

From the above description, we can know the most basic idea of ​​high-end memory: Borrow a section of address space, establish a temporary address mapping, release it after use, and this address space can be recycled. , access all physical memory.

Seeing this, some people can't help but ask: What if a kernel process or module keeps occupying a certain logical address space and does not release it? If this situation really occurs, the high-end memory address space of the kernel will become increasingly tight. If it is occupied and not released, it will not be accessible even if it is not mapped to physical memory.

3. Division

The kernel divides the high-end memory into 3 parts: VMALLOC_START~VMALLOC_END, KMAP_BASE~FIXADDR_START and FIXADDR_START~4G.


For high-end memory, you can obtain the corresponding page through alloc_page() or other functions, but if you want to access the actual physical memory, you must convert the page to linear The address will do (why? Think about how the MMU accesses physical memory). That is to say, we need to find a linear space for the page corresponding to the high-end memory. This process is called high-end memory mapping.

Corresponds to the three parts of high-end memory. There are three ways to map high-end memory:
Mapped to "kernel dynamic mapping space" (noncontiguous memory allocation)
This method is very simple , because through vmalloc(), when applying for memory in the "kernel dynamic mapping space", it is possible to obtain pages from high-end memory (see the implementation of vmalloc), so it is possible that high-end memory is mapped to the "kernel dynamic mapping space".

Permanent kernel mapping
If the page corresponding to the high-end memory is obtained through alloc_page(), how to find a linear space for it?
The kernel specifically sets aside a linear space for this purpose, from PKMAP_BASE to FIXADDR_START, for mapping high-end memory. On the 2.6 kernel, this address range is between 4G-8M and 4G-4M. This space is called "Kernel Permanent Mapping Space" or "Permanent Kernel Mapping Space". This space uses the same page directory table as other spaces. For the kernel, it is swapper_pg_dir. For ordinary processes, it is pointed to by the CR3 register. Normally, this space is 4M in size, so only one page table is needed. The kernel searches for this page table through pkmap_page_table. Through kmap(), a page can be mapped to this space. Since this space is 4M in size, up to 1024 pages can be mapped at the same time. Therefore, unused pages should be released from this space in a timely manner (that is, the mapping relationship is released). Through kunmap(), the linear address corresponding to a page can be released from this space.

Temporary kernel mapping
The kernel reserves some linear space between FIXADDR_START and FIXADDR_TOP for special needs. This space is called "fixed mapping space". In this space, part of it is used for temporary mapping of high-end memory.

This space has the following characteristics:
(1) Each CPU occupies a space
(2) The space occupied by each CPU is divided into multiple small spaces. The size of each small space is 1 page, and each small space is used for a purpose. These purposes are defined in km_type in kmap_types.h.

When a temporary mapping is to be performed, the purpose of mapping needs to be specified. According to the mapping purpose, the corresponding small space can be found, and then the address of this space is used as the mapping address. This means that a temporary mapping will cause the previous mapping to be overwritten. Temporary mapping is achieved via kmap_atomic().

3. Others

1. Does the user space (process) have a high-end memory concept?

User processes have no concept of high-end memory. High memory exists only in kernel space. User processes can only access up to 3G of physical memory, while kernel processes can access all physical memory.

2. Is there high-end memory in the 64-bit kernel?

In current reality, high-end memory does not exist in the 64-bit Linux kernel because the 64-bit kernel can support more than 512GB of memory. If the physical memory installed on the machine exceeds the kernel address space, there will be high-end memory.

3. How much physical memory can the user process access? How much physical memory can kernel code access?

32-bit system user processes can access up to 3GB, and kernel code can access all physical memory.

64-bit system user processes can access a maximum of more than 512GB, and kernel code can access all physical memory.

4. What is the relationship between high-end memory and physical address, logical address, and linear address?

High-end memory is only related to logical addresses and has no direct relationship with logical addresses and physical addresses.

Logical address Physical memory address
0xF8700000 0×80000000
0xF8700001 0×80000001
0xF8700002 0×80000002
0x800FFFFF

The above is the detailed content of Detailed explanation of Linux user space and kernel space. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:csdn.net
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!