spin_lock_irqsave

unsigned long spin_lock_irqsave(spinlock_t *lock, unsigned long flags);

获取一个自旋锁,并且在获取锁的同时,禁用本地中断。

  • lock 是一个指向要获取的自旋锁的指针。
  • flags 是一个用于保存中断状态的变量。

内存管理

__get_vm_area

从虚拟地址start到end之间,获取一段可用的大小为size的虚拟地址区域。注意,由于内存管理是以页面进行的,因此size按页对齐。

struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
                                unsigned long start, unsigned long end)
  • size:分配字节的大小
  • flags:地址空间映射方式,会用来设置vm_struct->flags
#define VM_IOREMAP    0x00000001    /* 通过ioremap分配的页,将一个IO地址空间映射到内核的虚拟地址空间上去*/
#define VM_ALLOC    0x00000002        /* 通过vmalloc()分配的页在非直接映射区域分配的物理地址不是连续的*/
#define VM_MAP        0x00000004        /* 通过vmap()它将已经映射了的物理地址,
                                                                          又映射到了一些线性地址,所以对于这部分物理地址,
                                                                           现在有两个或两个以上的线性地址与其对应*/
#define VM_USERMAP    0x00000008    /*在用vmalloc_user(类似vmalloc)分配内核内存设置此标志,然后通过 
                                                                            remap_vmalloc_range将vmalloc_user分配的内存映射到用户空间*/
#define VM_VPAGES    0x00000010         /* 标志通过__vmalloc_node在非连续物理内存进行分配*/

返回值:

vm结构体 用来描述内核的一个连续的虚拟空间

头文件:#include <linux/vmalloc.h>

ioremap_page_range

将物理地址区间[phys_addr, phys_addr+size)映射到内核虚拟地址区间[addr, end), 其中size = end - addr,并且[addr, end)区间位于[VMALLOC_START, VMALLOC_END)区间之内。这里的地址也应该都是按页对齐。

int ioremap_page_range(unsigned long addr,
		       unsigned long end, phys_addr_t phys_addr, pgprot_t prot)

参数:

  • addr:虚拟地址区间[addr, end)的起始地址

  • end:虚拟地址区间[addr, end)的结束地址

  • phys_addr:物理地址区间[phys_addr, phys_addr+size)的起始地址

  • prot:页表的属性

返回值:0表示