Generally, kernel has virtual address space 3G~4G. 3G~3G+962M is normal memory area, which is used for directly mapping, the rest is high memory area. High memory area can be used to setup contiguous mapping by creating page table.
vmalloc() is the interface function used by kernel code to request memory that is not contiguous in physical memory but linear in virtual memory.
When it manages the vmalloc area in virtual memory, the kernel must keep track of which sections are in use and which are free. To this end, it defines a data structure (struct vm_struct)to hold all used sections in a linked list.
struct vm_struct {
struct vm_struct *next;
void *addr;
unsigned long size;
unsigned long flags;
struct page **pages;
unsigned int nr_pages;
unsigned long phys_addr;
void *caller;
};
|
There is an instance of the structure in kernel memory for each area allocated with vmalloc. The meanings of the structure elements are as follows:
addr --- defines the start address of allocated area in virtual memory.
size --- specify the size of memory allocated.
flags --- specify the type of the memory area type. It accepts one of below three values:
VM_ALLOC specifies that the area was created by vmalloc;
VM_MAP is set to indicate that an existing collection of pages was mapped into the contiguous virtual address space;
VM_IOREMAP indicates that an (almost) random physical memory area was mapped into the vmalloc area; this is an architecture-specific operation.
pages --- it is a pointer to an array of page pointers. Each element represents the page instance of a physical page mapped into virtual address space.
nr_pages specifies the number of entries in pages and therefore the number of memory
pages involved.
phys_addr --- it is required only if physical memory areas described by a physical address are mapped with ioremap. This information is held in phys_addr
next --- it enables the kernel to hold all sections in the vmalloc area on a singly linked list
There is a global variable named
vmlist defined in mm/vmolloc.c, with which kernel can find other vm_struct area.
vm_struct *vmlist;
The kernel uses a data structure named struct vm_area_struct to manage virtual address space content of user processes.
/*
* This struct defines a memory VMM memory area. There is one of these
* per VM-area/task. A VM area is any part of the process virtual memory
* space that has a special rule for the page-fault handlers (ie a shared
* library, the executable area etc).
*/
struct vm_area_struct {
struct mm_struct * vm_mm; /* The address space we belong to. */
unsigned long vm_start; /* Our start address within vm_mm. */
unsigned long vm_end; /* The first byte after our end address
within vm_mm. */
/* linked list of VM areas per task, sorted by address */
struct vm_area_struct *vm_next, *vm_prev;
pgprot_t vm_page_prot; /* Access permissions of this VMA. */
unsigned long vm_flags; /* Flags, see mm.h. */
struct rb_node vm_rb;
/*
* For areas with an address space and backing store,
* linkage into the address_space->i_mmap prio tree, or
* linkage to the list of like vmas hanging off its node, or
* linkage of vma in the address_space->i_mmap_nonlinear list.
*/
union {
struct {
struct list_head list;
void *parent; /* aligns with prio_tree_node parent */
struct vm_area_struct *head;
} vm_set;
struct raw_prio_tree_node prio_tree_node;
} shared;
/*
* A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma
* list, after a COW of one of the file pages. A MAP_SHARED vma
* can only be in the i_mmap tree. An anonymous MAP_PRIVATE, stack
* or brk vma (with NULL file) can only be in an anon_vma list.
*/
struct list_head anon_vma_chain; /* Serialized by mmap_sem &
* page_table_lock */
struct anon_vma *anon_vma; /* Serialized by page_table_lock */
/* Function pointers to deal with this struct. */
const struct vm_operations_struct *vm_ops;
/* Information about our backing store: */
unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
units, *not* PAGE_CACHE_SIZE */
struct file * vm_file; /* File we map to (can be NULL). */
void * vm_private_data; /* was vm_pte (shared mem) */
unsigned long vm_truncate_count;/* truncate_count or restart_addr */
#ifndef CONFIG_MMU
struct vm_region *vm_region; /* NOMMU mapping region */
#endif
#ifdef CONFIG_NUMA
struct mempolicy *vm_policy; /* NUMA policy for the VMA */
#endif
};
|
阅读(2583) | 评论(1) | 转发(0) |