ioremap()将物理地址转换为虚拟地址
->ioremap(addr, size) arch/arm64/include/asm/io.h
->__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
{
#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN |
PTE_DIRTY | PTE_WRITE |
PTE_ATTRINDX(MT_DEVICE_nGnRE))
}
->__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot) arch/arm64/mm/ioremap.c
->_ioremap_caller(phys_addr_t phys_addr, size_t size, pgprot_t prot, void *caller)
{
若页表的大小为4K, offset是相对于页表的offsset
unsigned long offset = phys_addr & ~PAGE_MASK;
物理地址的分配以页表对齐,size的大小为PAGE_ALIGN(size + offset)
phys_addr &= PAGE_MASK;
size = PAGE_ALIGN(size + offset);
last_addr = phys_addr + size - 1;
/*如果物理地址在RAM的区间内,则不允许做map操作*/
if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr))))
return NULL;
在linux虚拟内存中找到一段的mem空间,用vm_struct数据结构进行描述
struct vm_struct *area;
area = get_vm_area_caller(size, VM_IOREMAP, caller); arch/arm64/mm/ioremap.c
VMALLOC_START和VMALLOC_END为VMALLOC的mem空间,定义在arch/arm64/include/asm/pgtable.h中
定义如下:
{
#define VMALLOC_START (MODULES_END)
#define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
}
->ioremap(addr, size) arch/arm64/include/asm/io.h
->__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
{
#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN |
PTE_DIRTY | PTE_WRITE |
PTE_ATTRINDX(MT_DEVICE_nGnRE))
}
->__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot) arch/arm64/mm/ioremap.c
->_ioremap_caller(phys_addr_t phys_addr, size_t size, pgprot_t prot, void *caller)
{
若页表的大小为4K, offset是相对于页表的offsset
unsigned long offset = phys_addr & ~PAGE_MASK;
物理地址的分配以页表对齐,size的大小为PAGE_ALIGN(size + offset)
phys_addr &= PAGE_MASK;
size = PAGE_ALIGN(size + offset);
last_addr = phys_addr + size - 1;
/*如果物理地址在RAM的区间内,则不允许做map操作*/
if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr))))
return NULL;
在linux虚拟内存中找到一段的mem空间,用vm_struct数据结构进行描述
struct vm_struct *area;
area = get_vm_area_caller(size, VM_IOREMAP, caller); arch/arm64/mm/ioremap.c
VMALLOC_START和VMALLOC_END为VMALLOC的mem空间,定义在arch/arm64/include/asm/pgtable.h中
定义如下:
{
#define VMALLOC_START (MODULES_END)
#define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
}