Kernel physical memory allocation function kernelapi

Source: Internet
Author: User
Article Title: kernelapi, the physical memory allocation function in the kernel. Linux is a technology channel of the IT lab in China. Includes basic categories such as desktop applications, Linux system management, kernel research, embedded systems, and open source.

I found several articles about linux driver written on the Internet, including the kmalloc () and _ get_free_page () return addresses. We all know kmalloc () it allocates physical memory with _ get_free_page (), but what does it return? In those articles about driver writing, the physical address is applied for and the physical address is still returned. But in one article, the author

This question was raised, but no answer was given. That's why I wrote this note. While finding the answer, I also analyzed the process of allocating physical memory to linux kernel. This is only a note, which is messy. You can understand it yourself.

Here, only the function for allocating consecutive physical addresses is analyzed. For vmalloc (), the function for allocating non-consecutive physical addresses is not in the scope of this record.

1. kmalloc () allocates consecutive physical addresses for small memory allocation.

2. _ get_free_page () allocates consecutive physical addresses for full-page allocation.

The following record explains why the above function allocates consecutive physical addresses and whether the returned physical addresses or virtual addresses.

The kmalloc () function is implemented based on slab. Slab is an efficient mechanism for allocating small memory. However, the slab allocation mechanism is not independent. It also divides more fine-grained memory for callers Based on the page distributor. That is to say, the system first allocates a consecutive physical address in the smallest unit of the page with the page distributor, and then kmalloc () splits the address based on the caller's needs.

For the above discussion, we can view the implementation of kmalloc (). The implementation of kmalloc () function is in _ do_kmalloc (), we can see in _ do_kmalloc () the Code finally calls _ cache_alloc () to allocate an slab. In fact

The implementation of functions such as kmem_cache_alloc () also calls this function to assign a new slab. We keep track of the call path of the _ cache_alloc () function. We will find that the kmem_getpages () function is used in the cache_grow () function to allocate a physical page, kmem_getpages () the alloc_pages_node () called in the function eventually uses _ alloc_pages () to return a struct page structure, which is used by the system to describe the physical page. As mentioned above, slab is implemented on a physical page. Kmalloc () is assigned a physical address.

_ Get_free_page () is the underlying memory allocation function provided by the page distributor to the caller. It allocates continuous physical memory. The _ get_free_page () function is implemented based on buddy. In the physical memory management implemented by buddy, the minimum allocation granularity is page-based. For the above discussion, we can view the implementation of _ get_free_page (). We can see that the _ get_free_page () function is just a very simple encapsulation, its entire function implementation is to call the _ alloc_pages () function unconditionally to allocate the physical memory. The preceding Implementation of the kmalloc () record also mentioned that when calling _ alloc_pages () function to allocate physical pages for slab management. So how is this function allocated to the physical page in what region? To answer this question, you can only look at the implementation. We can see that in the _ alloc_pages () function, we tried to call the get_page_from_freelist () function multiple times to retrieve the zone from zonelist, return an available struct page from the page (some call branches here are different because of the logo ). At this point, we can know that the allocation of a physical page is returned from the zone in the zonelist (structure array of a zone. So how is zonelist/zone associated with physical pages and initialized? Let's continue to look at the free_area_init_nodes () function. This function is indirectly called by the zone_sizes_init () function during system initialization. The zone_sizes_init () function fills in three areas: ZONE_DMA, ZONE_NORMAL, and. Call free_area_init_nodes () as a parameter. A pglist_data structure is allocated in this function, which contains the zonelist/zone structure and the physical page Structure of a struct page, at the end of the function, the free_area_init_node () function is called as a parameter. In this function, the calculate_node_totalpages () function is used to mark the related regions of pglist_data, and alloc_node_mem_map () is called () the function initializes the struct page physical page in the pglist_data structure. Finally, use the free_area_init_core () function to associate pglist_data with zonelist. Now, through the above analysis, the process for allocating physical memory by the _ get_free_page () function has been clarified. But there are a few new questions, that is, how is the physical page allocated by the function mapped? Where is it mapped? Here you have to look at the Boot Code related to VMM.

Before looking at the VMM-related Boot Code, let's take a look at the functions of pai_to_phys () and phys_to_virt. As the name implies, it is the conversion from a virtual address to a physical address and from a physical address to a virtual address. Function implementation is very simple. The former calls _ pa (address) to convert a virtual address to a physical address, and the latter calls _ va (addrress) to convert a physical address to a virtual address. Let's look at the two macros _ pa _ va.

# Define _ pa (x) (unsigned long) (x)-PAGE_OFFSET)

# Define _ va (x) (void *) (unsigned long) (x) + PAGE_OFFSET ))

We can see that only the address is added or subtracted from PAGE_OFFSET, and PAGE_OFFSET is defined as 0xC0000000 in x86. This raises another question. Anyone who has written driver in linux knows that kmalloc () and

_ Get_free_page () after the physical address is allocated, use javas_to_phys () to convert the physical address to the correct one. So why is this step necessary? Aren't we allocating physical addresses? How do I still need to switch after the allocation is completed? If a virtual address is returned, why can address translation be implemented only by PAGE_OFFSET Based on the above analysis of pai_to_phys? Do I need to check the page table for the conversion between virtual addresses and physical addresses? On behalf of the above questions, let's look at the VMM-related boot code.

Find VMM content directly from the start_kernel () kernel boot section. We can see that the first function to be concerned is setup_arch (). In this function, the paging_init () function is used to initialize and map the hardware page table (8 MB before initialization ).

Memory ing, which is not recorded here), while paging_init () is called pagetable_init () to map the physical address of the kernel and initialize the relevant memory. In the pagetable_init () function, the first is the PAE/PSE/PGE judgment.

Use the kernel_physical_mapping_init () function to map the physical memory of the kernel. In this function, we can clearly see that pgd_idx is mapped based on the starting address of PAGE_OFFSET. That is to say, all physical addresses are initialized cyclically starting from PAGE_OFFSET. Continue to observe. We can see that after the PMD is initialized, all address calculations are incremented by PAGE_OFFSET. The analysis shows that the physical address is mapped to PAGE_OFFSET.

The starting virtual address space. In this way, all the above questions will be answered. The physical pages allocated by kmalloc () and _ get_free_page () are mapped to the virtual addresses starting with PAGE_OFFSET. That is to say, there is a one-to-one relationship between the actual physical addresses and virtual addresses,

It is precisely because of this ing relationship that the allocation of virtual addresses starting with PAGE_OFFSET in the kernel is also the allocation of physical addresses (of course, this has a certain scope, it should be between PAGE_OFFSET and VMALLOC_START, and the latter allocates the starting address of the memory for the vmalloc () function ). This explains why the virt_to_phys () and phys_to_virt () functions can be converted between virtual addresses and physical addresses simply by adding/subtracting PAGE_OFFSET, it remains unchanged, so you do not need to query the page table for conversion. This also answers the initial question: kmalloc ()/_ get_free_page () allocates a physical address, and returns a virtual address (although this sounds awkward ). Because of this ing relationship, you need to subtract PAGE_OFFSET from their return addresses to obtain the real physical address.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.