文章目录
- [1. 概述](#1. 概述)
-
- [2. 软件架构图](#2. 软件架构图)
- [3. 调用流程图](#3. 调用流程图)
- [4. UML类图](#4. UML类图)
- [5. 源码深度分析](#5. 源码深度分析)
-
- [5.1 ARM64 IO映射架构分析](#5.1 ARM64 IO映射架构分析)
-
- [5.1.1 ioremap系统调用实现](#5.1.1 ioremap系统调用实现)
- [5.1.2 IO内存属性配置](#5.1.2 IO内存属性配置)
- [5.2 IO映射管理分析](#5.2 IO映射管理分析)
-
- [5.2.1 映射表维护](#5.2.1 映射表维护)
- [5.2.2 地址空间管理](#5.2.2 地址空间管理)
- [5.3 性能和安全优化分析](#5.3 性能和安全优化分析)
-
- [5.3.1 IO访问性能优化](#5.3.1 IO访问性能优化)
- [5.3.2 IO映射安全防护](#5.3.2 IO映射安全防护)
- [6. 设计模式分析](#6. 设计模式分析)
-
- [6.1 工厂模式在IO映射创建中的体现](#6.1 工厂模式在IO映射创建中的体现)
- [6.2 策略模式在IO属性配置中的体现](#6.2 策略模式在IO属性配置中的体现)
- [6.3 观察者模式在IO映射监控中的体现](#6.3 观察者模式在IO映射监控中的体现)
- [7. 状态机分析](#7. 状态机分析)
- [8. 性能优化分析](#8. 性能优化分析)
-
- [8.1 IO映射性能优化](#8.1 IO映射性能优化)
- [8.2 内存屏障优化](#8.2 内存屏障优化)
- [9. 安全性考虑](#9. 安全性考虑)
-
- [9.1 IO地址访问控制](#9.1 IO地址访问控制)
- [9.2 IO映射完整性保护](#9.2 IO映射完整性保护)
- [10. 扩展性分析](#10. 扩展性分析)
-
- [10.1 多架构支持](#10.1 多架构支持)
- [10.2 功能扩展](#10.2 功能扩展)
- [11. 调试和维护](#11. 调试和维护)
-
- [11.1 IO映射调试支持](#11.1 IO映射调试支持)
- [11.2 错误检测和恢复](#11.2 错误检测和恢复)
- [12. 总结](#12. 总结)
团队博客: 汽车电子社区
1. 概述
ARM64 mm ioremap子模块是Linux内核ARM64架构内存管理子系统中实现IO内存映射的核心组件,包含ioremap.c文件。该模块作为ARM64平台设备I/O内存访问的关键实现,提供了完整的IO地址空间映射、设备内存访问和MMU属性配置功能,是ARM64设备驱动和硬件交互的基础架构。
ioremap子模块实现了Linux虚拟内存系统与物理设备内存的桥梁,通过精心设计的映射算法和内存属性管理,为设备驱动提供了安全高效的硬件访问接口。该模块支持各种设备内存类型,包括普通设备内存、设备专用内存、PCI设备内存等,并提供了相应的内存屏障和同步机制。
模块的设计体现了IO映射管理的复杂性和高可靠性要求,通过严格的地址验证和权限控制,在保证硬件访问安全性的同时提供了灵活的设备内存映射方案,是ARM64硬件设备访问管理的重要组成部分。
2. 软件架构图
ARM64 mm ioremap
IO内存映射
设备内存访问
MMU属性配置
地址空间管理
ioremap.c
虚拟地址映射
物理地址转换
映射表管理
设备寄存器访问
内存屏障处理
缓存一致性
内存属性设置
访问权限配置
页表属性
地址范围验证
映射冲突检测
资源管理
3. 调用流程图
否
是
是
否
否
是
是
否
设备驱动请求IO映射
验证物理地址范围
地址有效?
返回错误
检查映射冲突
存在冲突?
返回错误
分配虚拟地址空间
分配成功?
返回ENOMEM
创建页表映射
设置内存属性
更新映射表
返回虚拟地址
设备驱动使用
需要解除映射?
清理映射表
释放虚拟地址
完成解除映射
结束
4. UML类图
IOMapper
+ioremap()
+iounmap()
+ioremap_nocache()
+ioremap_wc()
+ioremap_prot()
AddressValidator
+validate_phys_addr()
+check_addr_range()
+verify_alignment()
+validate_permissions()
MappingManager
+create_mapping()
+remove_mapping()
+update_mapping_table()
+find_mapping_entry()
AttributeConfigurator
+set_memory_attributes()
+configure_cache_policy()
+setup_access_permissions()
+apply_mmu_flags()
PageTableHandler
+alloc_io_page_tables()
+set_io_pte()
+update_io_tlb()
+flush_io_mappings()
ResourceManager
+reserve_io_memory()
+release_io_memory()
+manage_io_address_space()
+track_io_mappings()
CacheHandler
+handle_cache_coherency()
+setup_memory_barriers()
+manage_cache_attributes()
+optimize_io_access()
DebugSupport
+debug_io_mapping()
+validate_io_access()
+monitor_io_performance()
+log_io_operations()
5. 源码深度分析
5.1 ARM64 IO映射架构分析
5.1.1 ioremap系统调用实现
ARM64 ioremap的核心实现:
c
// ARM64 ioremap主函数
void __iomem *ioremap(phys_addr_t phys_addr, size_t size)
{
// 参数验证
if (!size || size > IOREMAP_MAX_SIZE)
return NULL;
// 地址对齐检查
if (!IS_ALIGNED(phys_addr, PAGE_SIZE))
return NULL;
// 执行ioremap操作
return __ioremap(phys_addr, size, MT_DEVICE_nGnRE);
}
// 扩展的ioremap函数
void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size, unsigned long prot)
{
phys_addr_t last_addr;
// 防止整数溢出
if (!size || size > IOREMAP_MAX_SIZE)
return NULL;
last_addr = phys_addr + size - 1;
if (!phys_addr_valid(phys_addr) || !phys_addr_valid(last_addr))
return NULL;
// 执行映射
return __ioremap(phys_addr, size, prot);
}
// 核心ioremap实现
void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, unsigned long prot)
{
unsigned long offset, vaddr;
phys_addr_t paddr;
int err;
// 查找合适的虚拟地址空间
offset = phys_addr & ~PAGE_MASK;
paddr = phys_addr & PAGE_MASK;
size = PAGE_ALIGN(size + offset);
// 分配虚拟地址
vaddr = __get_vm_area(size, VM_IOREMAP, IOREMAP_START, IOREMAP_END);
if (!vaddr)
return NULL;
// 检查是否可以直接映射
if (can_use_direct_mapping(paddr, size)) {
// 使用直接映射
err = direct_remap_pfn_range(vaddr, paddr >> PAGE_SHIFT, size, prot);
} else {
// 创建页表映射
err = ioremap_page_range(vaddr, vaddr + size, paddr, prot);
}
if (err) {
vunmap((void *)vaddr);
return NULL;
}
// 返回偏移后的虚拟地址
return (void __iomem *)(vaddr + offset);
}
// iounmap函数
void iounmap(void __iomem *addr)
{
// 验证地址
if (!addr)
return;
// 查找映射区域
struct vm_struct *area = find_vm_area((unsigned long)addr);
if (!area)
return;
// 清理映射
unmap_kernel_range((unsigned long)area->addr, area->size);
// 释放虚拟地址空间
free_vm_area(area);
}
ioremap特点:
1. 地址验证 :严格的物理地址范围验证
2. 内存属性 :灵活的内存类型和属性配置
3. 虚拟地址分配 :动态的虚拟地址空间分配
4. 页表映射:安全的页表建立和管理
5.1.2 IO内存属性配置
IO内存属性的配置管理:
c
// ARM64内存类型定义
#define MT_DEVICE_nGnRnE 0 // 非缓存、非聚集、无重排序
#define MT_DEVICE_nGnRE 1 // 非缓存、非聚集、重排序
#define MT_DEVICE_GRE 2 // 非缓存、聚集、重排序
#define MT_NORMAL 3 // 普通内存
#define MT_NORMAL_NC 4 // 普通内存、非缓存
// 内存属性转换
static unsigned long memtype_to_prot(unsigned long type)
{
unsigned long prot = 0;
switch (type) {
case MT_DEVICE_nGnRnE:
prot = PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_RDONLY;
break;
case MT_DEVICE_nGnRE:
prot = PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE;
break;
case MT_DEVICE_GRE:
prot = PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_RDONLY;
break;
case MT_NORMAL:
prot = PTE_WRITE | PTE_DIRTY;
break;
case MT_NORMAL_NC:
prot = PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE;
break;
default:
prot = PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE;
break;
}
return prot;
}
// 缓存策略配置
static pgprot_t __get_mem_type_pgprot(unsigned long type)
{
pgprot_t prot;
switch (type) {
case MT_DEVICE_nGnRnE:
case MT_DEVICE_nGnRE:
case MT_DEVICE_GRE:
// 设备内存:使用nGnRE属性
prot = __pgprot(PROT_DEVICE_nGnRE);
break;
case MT_NORMAL_NC:
// 非缓存普通内存
prot = __pgprot(PROT_NORMAL_NC);
break;
case MT_NORMAL:
default:
// 普通缓存内存
prot = __pgprot(PROT_NORMAL);
break;
}
return prot;
}
// 页表范围映射
int ioremap_page_range(unsigned long addr, unsigned long end,
phys_addr_t phys_addr, pgprot_t prot)
{
unsigned long start = addr;
int err = 0;
// 逐页映射
for (; addr < end; addr += PAGE_SIZE, phys_addr += PAGE_SIZE) {
err = ioremap_page(addr, phys_addr, prot);
if (err)
break;
}
// 映射失败时清理已映射的页面
if (err)
unmap_kernel_range(start, addr - start);
return err;
}
// 单个页面映射
static int ioremap_page(unsigned long addr, phys_addr_t phys_addr, pgprot_t prot)
{
pmd_t *pmd;
pte_t *pte;
unsigned long pfn = phys_addr >> PAGE_SHIFT;
// 获取PMD
pmd = pmd_offset(pud_offset(pgd_offset_k(addr), addr), addr);
// 检查是否为大页
if (pmd_none(*pmd)) {
// 分配PTE页表
pte = alloc_pte_table_kernel(pmd, addr);
if (!pte)
return -ENOMEM;
}
// 获取PTE
pte = pte_offset_kernel(pmd, addr);
if (!pte_none(*pte))
return -EBUSY; // PTE已被使用
// 设置PTE
set_pte(pte, pfn_pte(pfn, prot));
// 更新TLB
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
return 0;
}
内存属性特点:
1. 类型多样性 :支持多种设备内存类型
2. 属性转换 :内存类型到页表属性的精确转换
3. 缓存控制 :灵活的缓存策略配置
4. 页表管理:逐页的页表建立和管理
5.2 IO映射管理分析
5.2.1 映射表维护
IO映射表的维护和管理:
c
// IO映射表结构
struct ioremap_record {
struct list_head list;
void __iomem *vaddr; // 虚拟地址
phys_addr_t paddr; // 物理地址
size_t size; // 映射大小
unsigned long prot; // 保护属性
struct vm_struct *area; // 虚拟内存区域
};
// 全局映射表
static LIST_HEAD(ioremap_list);
static DEFINE_SPINLOCK(ioremap_lock);
// 添加映射记录
static void add_ioremap_record(void __iomem *vaddr, phys_addr_t paddr,
size_t size, unsigned long prot,
struct vm_struct *area)
{
struct ioremap_record *record;
record = kzalloc(sizeof(*record), GFP_KERNEL);
if (!record)
return;
record->vaddr = vaddr;
record->paddr = paddr;
record->size = size;
record->prot = prot;
record->area = area;
spin_lock(&ioremap_lock);
list_add(&record->list, &ioremap_list);
spin_unlock(&ioremap_lock);
}
// 查找映射记录
static struct ioremap_record *find_ioremap_record(void __iomem *vaddr)
{
struct ioremap_record *record;
spin_lock(&ioremap_lock);
list_for_each_entry(record, &ioremap_list, list) {
if (record->vaddr == vaddr) {
spin_unlock(&ioremap_lock);
return record;
}
}
spin_unlock(&ioremap_lock);
return NULL;
}
// 移除映射记录
static void remove_ioremap_record(struct ioremap_record *record)
{
spin_lock(&ioremap_lock);
list_del(&record->list);
spin_unlock(&ioremap_lock);
kfree(record);
}
// 验证映射一致性
static int validate_ioremap_mapping(void __iomem *vaddr, phys_addr_t paddr,
size_t size)
{
struct ioremap_record *record = find_ioremap_record(vaddr);
if (!record)
return -ENOENT;
// 验证映射参数
if (record->paddr != paddr || record->size != size)
return -EINVAL;
return 0;
}
映射表特点:
1. 记录维护 :完整的映射记录跟踪
2. 一致性验证 :映射参数的验证机制
3. 并发安全 :自旋锁保护的并发访问
4. 内存管理:记录的动态分配和释放
5.2.2 地址空间管理
IO地址空间的分配和管理:
c
// IO映射地址空间定义
#define IOREMAP_START 0xffffff8000000000UL
#define IOREMAP_END 0xffffffbfffffffffUL // 32GB范围
// 虚拟内存区域分配
struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
unsigned long start, unsigned long end)
{
struct vmap_area *va;
struct vm_struct *area;
// 分配vmap_area
va = alloc_vmap_area(size, start, end, flags, GFP_KERNEL);
if (!va)
return NULL;
// 分配vm_struct
area = kzalloc(sizeof(*area), GFP_KERNEL);
if (!area) {
free_vmap_area(va);
return NULL;
}
// 初始化vm_struct
area->flags = flags;
area->addr = (void *)va->va_start;
area->size = size;
area->pages = NULL;
return area;
}
// 虚拟内存区域释放
void free_vm_area(struct vm_struct *area)
{
struct vmap_area *va;
if (!area)
return;
// 查找对应的vmap_area
va = find_vmap_area((unsigned long)area->addr);
if (va) {
// 释放vmap_area
free_vmap_area(va);
}
// 释放vm_struct
kfree(area);
}
// vmap_area分配
static struct vmap_area *alloc_vmap_area(unsigned long size,
unsigned long align,
unsigned long vstart, unsigned long vend,
unsigned long flags, gfp_t gfp_mask)
{
struct vmap_area *va;
unsigned long addr;
// 分配vmap_area结构
va = kmalloc(sizeof(struct vmap_area), gfp_mask);
if (!va)
return NULL;
// 查找合适的地址范围
addr = __alloc_vmap_area(size, align, vstart, vend);
if (!addr) {
kfree(va);
return NULL;
}
// 初始化vmap_area
va->va_start = addr;
va->va_end = addr + size;
va->flags = flags;
return va;
}
地址空间特点:
1. 专用范围 :专用的IO映射地址空间
2. 动态分配 :按需的虚拟地址分配
3. 区域管理 :vmap_area的层次化管理
4. 资源跟踪:完整的资源分配和释放跟踪
5.3 性能和安全优化分析
5.3.1 IO访问性能优化
IO访问的性能优化:
c
// IO访问预取优化
void ioremap_prefetch_optimization(void __iomem *addr, size_t size)
{
// 对于顺序访问的IO内存,启用预取
if (is_sequential_io_access(addr, size)) {
// 设置预取属性
set_io_prefetch_attributes(addr, size);
// 预取第一个缓存行
prefetch_io_memory(addr);
}
}
// IO内存屏障优化
void optimized_io_memory_barrier(void)
{
// 根据ARM64架构优化内存屏障
if (cpus_have_cap(ARM64_HAS_DMB)) {
// 使用优化的DMB指令
asm volatile("dmb osh" : : : "memory");
} else {
// 使用通用内存屏障
mb();
}
}
// IO映射缓存优化
void __iomem *ioremap_cached(phys_addr_t phys_addr, size_t size)
{
// 对于可缓存的设备内存,使用缓存映射
if (is_cacheable_device_memory(phys_addr, size)) {
return __ioremap_cached(phys_addr, size);
} else {
// 使用标准ioremap
return ioremap(phys_addr, size);
}
}
// 缓存IO映射实现
void __iomem *__ioremap_cached(phys_addr_t phys_addr, size_t size)
{
// 使用普通内存属性,但标记为IO内存
return __ioremap(phys_addr, size, MT_NORMAL);
}
性能优化特点:
1. 预取机制 :IO内存访问的预取优化
2. 屏障优化 :架构特定的内存屏障优化
3. 缓存策略 :可缓存设备内存的缓存映射
4. 访问模式:基于访问模式的优化策略
5.3.2 IO映射安全防护
IO映射的安全防护措施:
c
// IO映射地址验证
int validate_io_mapping_request(phys_addr_t phys_addr, size_t size,
unsigned long prot)
{
// 验证物理地址范围
if (!is_valid_io_phys_addr(phys_addr, size))
return -EINVAL;
// 检查权限
if (!capable(CAP_SYS_RAWIO) && !is_user_allowed_io_addr(phys_addr))
return -EPERM;
// 验证内存属性
if (!is_valid_io_memory_attributes(prot))
return -EINVAL;
// 检查映射冲突
if (has_io_mapping_conflict(phys_addr, size))
return -EBUSY;
return 0;
}
// IO地址范围验证
static bool is_valid_io_phys_addr(phys_addr_t addr, size_t size)
{
// 检查是否在有效的IO地址范围内
if (addr >= IO_SPACE_LIMIT)
return false;
// 检查地址对齐
if (!IS_ALIGNED(addr, PAGE_SIZE))
return false;
// 检查大小限制
if (size == 0 || size > IOREMAP_MAX_SIZE)
return false;
return true;
}
// IO内存属性验证
static bool is_valid_io_memory_attributes(unsigned long prot)
{
// 验证内存类型
unsigned long mem_type = prot & PTE_ATTRINDX_MASK;
switch (mem_type) {
case MT_DEVICE_nGnRnE:
case MT_DEVICE_nGnRE:
case MT_DEVICE_GRE:
case MT_NORMAL_NC:
return true;
default:
// 不允许普通缓存内存用于IO映射
return false;
}
}
// IO映射冲突检测
static bool has_io_mapping_conflict(phys_addr_t addr, size_t size)
{
struct ioremap_record *record;
spin_lock(&ioremap_lock);
list_for_each_entry(record, &ioremap_list, list) {
if (ranges_overlap(record->paddr, record->size, addr, size)) {
spin_unlock(&ioremap_lock);
return true;
}
}
spin_unlock(&ioremap_lock);
return false;
}
安全防护特点:
1. 地址验证 :严格的物理地址范围验证
2. 权限检查 :基于能力的访问权限控制
3. 属性验证 :内存属性的安全性验证
4. 冲突检测:防止映射冲突和覆盖
6. 设计模式分析
6.1 工厂模式在IO映射创建中的体现
IO映射创建的工厂模式:
c
// IO映射器接口
interface IOMapper {
void __iomem* createMapping(phys_addr_t physAddr, size_t size, unsigned long prot);
void destroyMapping(void __iomem* vaddr);
boolean canHandle(phys_addr_t physAddr, unsigned long prot);
String getMapperName();
}
// 标准IO映射器
class StandardIOMapper implements IOMapper {
public void __iomem* createMapping(phys_addr_t physAddr, size_t size, unsigned long prot) {
return __ioremap(physAddr, size, prot);
}
public void destroyMapping(void __iomem* vaddr) {
iounmap(vaddr);
}
public boolean canHandle(phys_addr_t physAddr, unsigned long prot) {
return true; // 标准映射器可以处理所有类型
}
public String getMapperName() {
return "STANDARD_IO_MAPPER";
}
}
// 缓存IO映射器
class CachedIOMapper implements IOMapper {
public void __iomem* createMapping(phys_addr_t physAddr, size_t size, unsigned long prot) {
// 使用缓存映射
return __ioremap_cached(physAddr, size);
}
public void destroyMapping(void __iomem* vaddr) {
iounmap(vaddr);
}
public boolean canHandle(phys_addr_t physAddr, unsigned long prot) {
// 只有可缓存的设备内存才使用缓存映射器
return is_cacheable_device_memory(physAddr, size);
}
public String getMapperName() {
return "CACHED_IO_MAPPER";
}
}
// PCI IO映射器
class PCIIOMapper implements IOMapper {
public void __iomem* createMapping(phys_addr_t physAddr, size_t size, unsigned long prot) {
// PCI特定的映射处理
return pci_ioremap(physAddr, size);
}
public void destroyMapping(void __iomem* vaddr) {
pci_iounmap(vaddr);
}
public boolean canHandle(phys_addr_t physAddr, unsigned long prot) {
// 检查是否为PCI地址
return is_pci_address(physAddr);
}
public String getMapperName() {
return "PCI_IO_MAPPER";
}
}
// IO映射器工厂
class IOMapperFactory {
private static List<IOMapper> mappers;
static {
mappers = Arrays.asList(
new PCIIOMapper(),
new CachedIOMapper(),
new StandardIOMapper() // 标准映射器放在最后作为fallback
);
}
public static IOMapper getMapper(phys_addr_t physAddr, unsigned long prot) {
for (IOMapper mapper : mappers) {
if (mapper.canHandle(physAddr, prot)) {
return mapper;
}
}
throw new IOMapperException("No suitable mapper found");
}
public static void __iomem* createMapping(phys_addr_t physAddr, size_t size, unsigned long prot) {
IOMapper mapper = getMapper(physAddr, prot);
return mapper.createMapping(physAddr, size, prot);
}
public static void destroyMapping(void __iomem* vaddr) {
// 查找对应的映射器并销毁映射
// 这里需要根据虚拟地址找到对应的映射器
destroyMappingByVaddr(vaddr);
}
}
// 使用工厂模式
class IOMemoryManager {
public void __iomem* ioremap(phys_addr_t physAddr, size_t size, unsigned long prot) {
// 验证参数
if (!validateMappingRequest(physAddr, size, prot)) {
return null;
}
// 使用工厂创建映射
return IOMapperFactory.createMapping(physAddr, size, prot);
}
public void iounmap(void __iomem* vaddr) {
IOMapperFactory.destroyMapping(vaddr);
}
private boolean validateMappingRequest(phys_addr_t physAddr, size_t size, unsigned long prot) {
// 参数验证逻辑
return validate_io_mapping_request(physAddr, size, prot) == 0;
}
}
6.2 策略模式在IO属性配置中的体现
IO属性配置的策略模式:
c
// IO属性配置策略接口
interface IOAttributeStrategy {
unsigned long configureAttributes(phys_addr_t physAddr, size_t size, unsigned long requestedProt);
boolean isApplicable(phys_addr_t physAddr, unsigned long requestedProt);
String getStrategyName();
MemoryAttributes getMemoryAttributes();
}
// 设备内存属性策略
class DeviceMemoryStrategy implements IOAttributeStrategy {
public unsigned long configureAttributes(phys_addr_t physAddr, size_t size, unsigned long requestedProt) {
// 设备内存:使用nGnRE属性
return requestedProt | MT_DEVICE_nGnRE;
}
public boolean isApplicable(phys_addr_t physAddr, unsigned long requestedProt) {
// 检查是否为设备内存地址
return is_device_memory_address(physAddr);
}
public String getStrategyName() {
return "DEVICE_MEMORY_STRATEGY";
}
public MemoryAttributes getMemoryAttributes() {
return MemoryAttributes.DEVICE;
}
}
// PCI内存属性策略
class PCIMemoryStrategy implements IOAttributeStrategy {
public unsigned long configureAttributes(phys_addr_t physAddr, size_t size, unsigned long requestedProt) {
// PCI内存:可能支持预取
if (supports_prefetch(physAddr)) {
return requestedProt | MT_DEVICE_GRE;
} else {
return requestedProt | MT_DEVICE_nGnRE;
}
}
public boolean isApplicable(phys_addr_t physAddr, unsigned long requestedProt) {
// 检查是否为PCI地址
return is_pci_address(physAddr);
}
public String getStrategyName() {
return "PCI_MEMORY_STRATEGY";
}
public MemoryAttributes getMemoryAttributes() {
return MemoryAttributes.PCI;
}
}
// 高速缓存设备属性策略
class HighSpeedDeviceStrategy implements IOAttributeStrategy {
public unsigned long configureAttributes(phys_addr_t physAddr, size_t size, unsigned long requestedProt) {
// 高速设备:使用GRE属性支持聚集访问
return requestedProt | MT_DEVICE_GRE;
}
public boolean isApplicable(phys_addr_t physAddr, unsigned long requestedProt) {
// 检查是否为高速设备
return is_high_speed_device(physAddr) &&
(requestedProt & PROT_READ) && (requestedProt & PROT_WRITE);
}
public String getStrategyName() {
return "HIGH_SPEED_DEVICE_STRATEGY";
}
public MemoryAttributes getMemoryAttributes() {
return MemoryAttributes.HIGH_SPEED;
}
}
// 自适应属性策略
class AdaptiveAttributeStrategy implements IOAttributeStrategy {
private List<IOAttributeStrategy> strategies;
public AdaptiveAttributeStrategy() {
strategies = Arrays.asList(
new HighSpeedDeviceStrategy(),
new PCIMemoryStrategy(),
new DeviceMemoryStrategy()
);
}
public unsigned long configureAttributes(phys_addr_t physAddr, size_t size, unsigned long requestedProt) {
// 选择最合适的策略
IOAttributeStrategy bestStrategy = selectBestStrategy(physAddr, requestedProt);
return bestStrategy.configureAttributes(physAddr, size, requestedProt);
}
public boolean isApplicable(phys_addr_t physAddr, unsigned long requestedProt) {
return true; // 自适应策略总是适用
}
public String getStrategyName() {
return "ADAPTIVE_ATTRIBUTE_STRATEGY";
}
public MemoryAttributes getMemoryAttributes() {
return MemoryAttributes.ADAPTIVE;
}
private IOAttributeStrategy selectBestStrategy(phys_addr_t physAddr, unsigned long requestedProt) {
for (IOAttributeStrategy strategy : strategies) {
if (strategy.isApplicable(physAddr, requestedProt)) {
return strategy;
}
}
// 默认使用设备内存策略
return new DeviceMemoryStrategy();
}
}
// 策略选择器
class IOAttributeStrategySelector {
public static IOAttributeStrategy selectStrategy(phys_addr_t physAddr,
unsigned long requestedProt, SystemContext context) {
if (context.supportsAdaptiveAttributes()) {
return new AdaptiveAttributeStrategy();
} else if (is_pci_address(physAddr)) {
return new PCIMemoryStrategy();
} else if (is_high_speed_device(physAddr)) {
return new HighSpeedDeviceStrategy();
} else {
return new DeviceMemoryStrategy();
}
}
}
6.3 观察者模式在IO映射监控中的体现
IO映射监控的观察者模式:
c
// IO映射事件接口
interface IOMappingEvent {
String getEventType();
long getTimestamp();
void __iomem* getVirtualAddress();
phys_addr_t getPhysicalAddress();
size_t getSize();
Map<String, Object> getEventData();
boolean isSuccessful();
}
// IO映射创建事件
class IOMappingCreatedEvent implements IOMappingEvent {
private void __iomem* vaddr;
private phys_addr_t paddr;
private size_t size;
private Map<String, Object> eventData;
private boolean successful;
public IOMappingCreatedEvent(void __iomem* vaddr, phys_addr_t paddr, size_t size,
boolean successful, Map<String, Object> eventData) {
this.vaddr = vaddr;
this.paddr = paddr;
this.size = size;
this.successful = successful;
this.eventData = eventData != null ? eventData : new HashMap<>();
}
public String getEventType() {
return "IO_MAPPING_CREATED";
}
public long getTimestamp() {
return System.nanoTime();
}
public void __iomem* getVirtualAddress() {
return vaddr;
}
public phys_addr_t getPhysicalAddress() {
return paddr;
}
public size_t getSize() {
return size;
}
public Map<String, Object> getEventData() {
return eventData;
}
public boolean isSuccessful() {
return successful;
}
}
// IO映射观察者接口
interface IOMappingObserver {
void onIOMappingEvent(IOMappingEvent event);
Set<String> getInterestedEventTypes();
boolean isEnabled();
}
// 性能监控观察者
class IOMappingPerformanceObserver implements IOMappingObserver {
private Map<String, Long> mappingTimes = new HashMap<>();
private Map<String, Integer> mappingCounts = new HashMap<>();
public void onIOMappingEvent(IOMappingEvent event) {
if ("IO_MAPPING_CREATED".equals(event.getEventType()) && event.isSuccessful()) {
String mappingType = determineMappingType(event.getPhysicalAddress());
// 记录映射时间
Long time = (Long) event.getEventData().get("mappingTime");
if (time != null) {
mappingTimes.put(mappingType,
mappingTimes.getOrDefault(mappingType, 0L) + time);
}
// 记录映射次数
mappingCounts.put(mappingType,
mappingCounts.getOrDefault(mappingType, 0) + 1);
}
}
public Set<String> getInterestedEventTypes() {
return new HashSet<>(Arrays.asList("IO_MAPPING_CREATED", "IO_MAPPING_DESTROYED"));
}
public boolean isEnabled() {
return true;
}
private String determineMappingType(phys_addr_t paddr) {
if (is_pci_address(paddr)) {
return "PCI";
} else if (is_device_memory_address(paddr)) {
return "DEVICE";
} else {
return "OTHER";
}
}
public double getAverageMappingTime(String mappingType) {
Long totalTime = mappingTimes.get(mappingType);
Integer count = mappingCounts.get(mappingType);
if (totalTime != null && count != null && count > 0) {
return totalTime.doubleValue() / count;
}
return 0.0;
}
}
// 安全监控观察者
class IOSecurityObserver implements IOMappingObserver {
private List<String> securityEvents = Collections.synchronizedList(new ArrayList<>());
public void onIOMappingEvent(IOMappingEvent event) {
// 检查潜在的安全问题
phys_addr_t paddr = event.getPhysicalAddress();
size_t size = event.getSize();
// 检查映射大小是否过大
if (size > MAX_SAFE_IO_MAPPING_SIZE) {
logSecurityEvent("Large IO mapping detected: " + size + " bytes at " + paddr);
}
// 检查敏感地址映射
if (is_sensitive_io_address(paddr)) {
logSecurityEvent("Mapping to sensitive IO address: " + paddr);
}
// 检查映射权限
if (event.getEventData().containsKey("prot")) {
unsigned long prot = (unsigned long) event.getEventData().get("prot");
if ((prot & PROT_EXEC) && !is_trusted_executable_io(paddr)) {
logSecurityEvent("Executable mapping to untrusted IO address: " + paddr);
}
}
}
public Set<String> getInterestedEventTypes() {
return new HashSet<>(Arrays.asList("*"));
}
public boolean isEnabled() {
return true;
}
private void logSecurityEvent(String event) {
securityEvents.add(event);
System.err.println("IO SECURITY: " + event);
}
private boolean is_sensitive_io_address(phys_addr_t addr) {
// 检查是否为敏感的IO地址
return is_system_controller_addr(addr) || is_debug_register_addr(addr);
}
private boolean is_trusted_executable_io(phys_addr_t addr) {
// 检查是否为可信的可执行IO地址
return is_option_rom_addr(addr) || is_trusted_device_addr(addr);
}
public List<String> getSecurityEvents() {
return new ArrayList<>(securityEvents);
}
}
// 资源使用观察者
class IOResourceObserver implements IOMappingObserver {
private AtomicLong totalMappedIOSize = new AtomicLong(0);
private Map<String, AtomicLong> typeMappedSize = new ConcurrentHashMap<>();
public void onIOMappingEvent(IOMappingEvent event) {
String mappingType = determineMappingType(event.getPhysicalAddress());
if ("IO_MAPPING_CREATED".equals(event.getEventType()) && event.isSuccessful()) {
long size = event.getSize();
totalMappedIOSize.addAndGet(size);
typeMappedSize.computeIfAbsent(mappingType, k -> new AtomicLong(0)).addAndGet(size);
} else if ("IO_MAPPING_DESTROYED".equals(event.getEventType())) {
long size = event.getSize();
totalMappedIOSize.addAndGet(-size);
AtomicLong typeSize = typeMappedSize.get(mappingType);
if (typeSize != null) {
typeSize.addAndGet(-size);
}
}
}
public Set<String> getInterestedEventTypes() {
return new HashSet<>(Arrays.asList("IO_MAPPING_CREATED", "IO_MAPPING_DESTROYED"));
}
public boolean isEnabled() {
return true;
}
private String determineMappingType(phys_addr_t paddr) {
if (is_pci_address(paddr)) {
return "PCI";
} else if (is_device_memory_address(paddr)) {
return "DEVICE";
} else {
return "GENERIC_IO";
}
}
public long getTotalMappedIOSize() {
return totalMappedIOSize.get();
}
public long getMappedSizeByType(String type) {
AtomicLong size = typeMappedSize.get(type);
return size != null ? size.get() : 0;
}
}
// IO映射监控器
class IOMappingMonitor {
private List<IOMappingObserver> observers = new CopyOnWriteArrayList<>();
private Executor notificationExecutor;
public IOMappingMonitor() {
this.notificationExecutor = Executors.newSingleThreadExecutor();
}
public void addObserver(IOMappingObserver observer) {
observers.add(observer);
}
public void removeObserver(IOMappingObserver observer) {
observers.remove(observer);
}
public void notifyIOMappingEvent(IOMappingEvent event) {
notificationExecutor.submit(() -> {
for (IOMappingObserver observer : observers) {
if (observer.isEnabled()) {
Set<String> interestedTypes = observer.getInterestedEventTypes();
if (interestedTypes.contains("*") ||
interestedTypes.contains(event.getEventType())) {
try {
observer.onIOMappingEvent(event);
} catch (Exception e) {
logObserverError(observer, event, e);
}
}
}
}
});
}
public void ioMappingCreated(void __iomem* vaddr, phys_addr_t paddr, size_t size,
boolean successful, Map<String, Object> eventData) {
IOMappingEvent event = new IOMappingCreatedEvent(vaddr, paddr, size, successful, eventData);
notifyIOMappingEvent(event);
}
public void ioMappingDestroyed(void __iomem* vaddr, phys_addr_t paddr, size_t size,
Map<String, Object> eventData) {
IOMappingEvent event = new IOMappingDestroyedEvent(vaddr, paddr, size, eventData);
notifyIOMappingEvent(event);
}
public void shutdown() {
notificationExecutor.shutdown();
try {
if (!notificationExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
notificationExecutor.shutdownNow();
}
} catch (InterruptedException e) {
notificationExecutor.shutdownNow();
}
}
private void logObserverError(IOMappingObserver observer, IOMappingEvent event, Exception e) {
System.err.println("IO mapping observer error: " + observer.getClass().getSimpleName() +
" failed to process event " + event.getEventType() + ": " + e.getMessage());
}
}
// 使用观察者模式
class IOMappingSystem {
private IOMappingMonitor monitor;
public IOMappingSystem() {
this.monitor = new IOMappingMonitor();
// 注册观察者
monitor.addObserver(new IOMappingPerformanceObserver());
monitor.addObserver(new IOSecurityObserver());
monitor.addObserver(new IOResourceObserver());
}
public void __iomem* ioremap(phys_addr_t physAddr, size_t size, unsigned long prot) {
long startTime = System.nanoTime();
// 执行映射
void __iomem* result = performIOMapping(physAddr, size, prot);
long mappingTime = System.nanoTime() - startTime;
// 通知映射事件
Map<String, Object> eventData = new HashMap<>();
eventData.put("mappingTime", mappingTime);
eventData.put("prot", prot);
monitor.ioMappingCreated(result, physAddr, size, result != null, eventData);
return result;
}
public void iounmap(void __iomem* vaddr) {
// 获取映射信息
phys_addr_t paddr = getPhysicalAddress(vaddr);
size_t size = getMappingSize(vaddr);
// 执行解除映射
performIOUnmapping(vaddr);
// 通知解除映射事件
Map<String, Object> eventData = new HashMap<>();
eventData.put("unmapTime", System.nanoTime());
monitor.ioMappingDestroyed(vaddr, paddr, size, eventData);
}
private void __iomem* performIOMapping(phys_addr_t physAddr, size_t size, unsigned long prot) {
// 实际的IO映射实现
return __ioremap(physAddr, size, prot);
}
private void performIOUnmapping(void __iomem* vaddr) {
// 实际的IO解除映射实现
iounmap(vaddr);
}
private phys_addr_t getPhysicalAddress(void __iomem* vaddr) {
// 获取物理地址的逻辑
return virt_to_phys(vaddr);
}
private size_t getMappingSize(void __iomem* vaddr) {
// 获取映射大小的逻辑
struct vm_struct *area = find_vm_area((unsigned long)vaddr);
return area ? area->size : 0;
}
}
7. 状态机分析
ARM64 mm ioremap的状态机:
初始状态 -> 地址验证 -> 空间分配 -> 属性配置 -> 页表映射 -> TLB同步 -> 映射完成
↑ ↓
权限检查 <---------------------------------------------------------------------------------+
↑ ↓
冲突检测 <---------------------------------------------------------------------------------+
↑ ↓
错误处理 <---------------------------------------------------------------------------------+
8. 性能优化分析
8.1 IO映射性能优化
IO映射的性能优化:
c
// IO映射快速路径
void __iomem *fast_ioremap(phys_addr_t phys_addr, size_t size, unsigned long prot)
{
// 检查是否可以直接映射
if (can_use_direct_io_mapping(phys_addr, size)) {
// 使用直接映射优化
return direct_io_remap(phys_addr, size, prot);
}
// 使用标准映射
return __ioremap(phys_addr, size, prot);
}
// 批量IO映射优化
int ioremap_batch(phys_addr_t *phys_addrs, size_t *sizes, unsigned long *prots,
void __iomem **vaddrs, int count)
{
// 批量验证参数
if (!validate_batch_params(phys_addrs, sizes, prots, count))
return -EINVAL;
// 预分配虚拟地址空间
if (!preallocate_virtual_space(sizes, vaddrs, count))
return -ENOMEM;
// 批量创建映射
for (int i = 0; i < count; i++) {
if (ioremap_single(phys_addrs[i], sizes[i], prots[i], vaddrs[i]) != 0) {
// 回滚已创建的映射
rollback_batch_mappings(vaddrs, i);
return -EFAULT;
}
}
return 0;
}
// IO映射缓存
static DEFINE_HASHTABLE(io_mapping_cache, 8);
struct io_mapping_entry {
phys_addr_t phys_addr;
size_t size;
unsigned long prot;
void __iomem *vaddr;
struct hlist_node hash;
atomic_t refcount;
};
// 从缓存获取映射
void __iomem *ioremap_from_cache(phys_addr_t phys_addr, size_t size, unsigned long prot)
{
struct io_mapping_entry *entry;
// 在缓存中查找
hash_for_each_possible(io_mapping_cache, entry, hash, phys_addr) {
if (entry->phys_addr == phys_addr && entry->size == size &&
entry->prot == prot) {
// 找到匹配的条目
atomic_inc(&entry->refcount);
return entry->vaddr;
}
}
// 缓存未命中,创建新映射
void __iomem *vaddr = __ioremap(phys_addr, size, prot);
if (vaddr) {
// 添加到缓存
add_to_io_cache(phys_addr, size, prot, vaddr);
}
return vaddr;
}
8.2 内存屏障优化
内存屏障的优化:
c
// IO内存屏障优化
void optimized_io_barrier(void __iomem *addr, enum barrier_type type)
{
switch (type) {
case BARRIER_READ:
// 读屏障
if (IS_ENABLED(CONFIG_ARM64_USE_DMB))
asm volatile("dmb ld" : : : "memory");
else
rmb();
break;
case BARRIER_WRITE:
// 写屏障
if (IS_ENABLED(CONFIG_ARM64_USE_DMB))
asm volatile("dmb st" : : : "memory");
else
wmb();
break;
case BARRIER_RW:
// 读写屏障
if (IS_ENABLED(CONFIG_ARM64_USE_DMB))
asm volatile("dmb sy" : : : "memory");
else
mb();
break;
}
}
// IO访问序列优化
void optimized_io_access_sequence(void __iomem *base, size_t stride,
size_t count, enum access_type type)
{
if (is_sequential_io_pattern(stride, count)) {
// 顺序访问优化
sequential_io_access(base, stride, count, type);
} else if (is_random_io_pattern(stride, count)) {
// 随机访问优化
random_io_access(base, stride, count, type);
} else {
// 通用访问
generic_io_access(base, stride, count, type);
}
}
// 顺序IO访问优化
static void sequential_io_access(void __iomem *base, size_t stride,
size_t count, enum access_type type)
{
void __iomem *addr = base;
// 预取第一个位置
prefetch_io_addr(addr);
for (size_t i = 0; i < count; i++) {
perform_io_access(addr, type);
// 预取下一个位置
if (i + 1 < count) {
prefetch_io_addr(addr + stride);
}
addr += stride;
}
}
9. 安全性考虑
9.1 IO地址访问控制
IO地址访问的安全控制:
c
// IO地址访问验证
int validate_io_access(void __iomem *addr, size_t size, unsigned long flags)
{
// 验证地址是否在有效的IO映射范围内
if (!is_valid_io_mapping(addr, size))
return -EFAULT;
// 检查访问权限
if (!check_io_access_permissions(addr, flags))
return -EACCES;
// 验证访问模式
if (!validate_io_access_pattern(addr, size, flags))
return -EINVAL;
return 0;
}
// IO映射范围验证
static bool is_valid_io_mapping(void __iomem *addr, size_t size)
{
struct ioremap_record *record = find_ioremap_record(addr);
if (!record)
return false;
// 检查访问范围是否在映射范围内
unsigned long start = (unsigned long)record->vaddr;
unsigned long end = start + record->size;
unsigned long access_start = (unsigned long)addr;
unsigned long access_end = access_start + size;
return access_start >= start && access_end <= end;
}
// IO访问权限检查
static bool check_io_access_permissions(void __iomem *addr, unsigned long flags)
{
struct ioremap_record *record = find_ioremap_record(addr);
if (!record)
return false;
// 检查是否允许指定的访问类型
if ((flags & IO_ACCESS_READ) && !(record->prot & PROT_READ))
return false;
if ((flags & IO_ACCESS_WRITE) && !(record->prot & PROT_WRITE))
return false;
// 检查特权访问
if ((flags & IO_ACCESS_PRIVILEGED) && !capable(CAP_SYS_RAWIO))
return false;
return true;
}
9.2 IO映射完整性保护
IO映射的完整性保护:
c
// IO映射完整性验证
int validate_io_mapping_integrity(void __iomem *addr, phys_addr_t phys_addr, size_t size)
{
// 验证虚拟地址到物理地址的映射关系
phys_addr_t mapped_phys = io_virt_to_phys(addr);
if (mapped_phys != phys_addr)
return -EFAULT;
// 检查页表条目的一致性
if (!validate_io_page_table_entries(addr, phys_addr, size))
return -EFAULT;
// 验证映射属性的正确性
if (!validate_io_mapping_attributes(addr, size))
return -EFAULT;
return 0;
}
// IO页表条目验证
static bool validate_io_page_table_entries(void __iomem *addr, phys_addr_t phys_addr, size_t size)
{
unsigned long vaddr = (unsigned long)addr;
phys_addr_t paddr = phys_addr;
// 逐页验证页表条目
for (; size > 0; vaddr += PAGE_SIZE, paddr += PAGE_SIZE, size -= PAGE_SIZE) {
pte_t *pte = pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), vaddr), vaddr), vaddr);
if (!pte_present(*pte))
return false;
if (pte_pfn(*pte) != (paddr >> PAGE_SHIFT))
return false;
}
return true;
}
// IO映射属性验证
static bool validate_io_mapping_attributes(void __iomem *addr, size_t size)
{
struct ioremap_record *record = find_ioremap_record(addr);
if (!record)
return false;
// 检查映射大小是否一致
if (record->size != size)
return false;
// 验证映射属性
unsigned long expected_prot = record->prot;
unsigned long actual_prot = get_mapping_protection(addr);
return expected_prot == actual_prot;
}
10. 扩展性分析
10.1 多架构支持
跨架构的IO映射扩展:
c
// 架构特定的IO映射接口
struct arch_io_ops {
const char *arch_name;
// IO映射操作
void __iomem *(*ioremap)(phys_addr_t phys_addr, size_t size);
void (*iounmap)(void __iomem *addr);
void __iomem *(*ioremap_prot)(phys_addr_t phys_addr, size_t size, unsigned long prot);
// 属性配置
unsigned long (*memtype_to_prot)(unsigned long type);
pgprot_t (*get_mem_type_pgprot)(unsigned long type);
// 页表操作
int (*ioremap_page_range)(unsigned long addr, unsigned long end,
phys_addr_t phys_addr, pgprot_t prot);
// 缓存管理
void (*flush_io_cache)(void __iomem *addr, size_t size);
};
// ARM64 IO操作实现
static const struct arch_io_ops arm64_io_ops = {
.arch_name = "arm64",
.ioremap = arm64_ioremap,
.iounmap = arm64_iounmap,
.ioremap_prot = arm64_ioremap_prot,
.memtype_to_prot = arm64_memtype_to_prot,
.get_mem_type_pgprot = arm64_get_mem_type_pgprot,
.ioremap_page_range = arm64_ioremap_page_range,
.flush_io_cache = arm64_flush_io_cache,
};
// 运行时架构选择
static const struct arch_io_ops *select_arch_io_ops(void)
{
#ifdef CONFIG_ARM64
return &arm64_io_ops;
#else
return NULL;
#endif
}
10.2 功能扩展
IO映射功能扩展能力:
c
// 高级IO映射功能扩展
struct advanced_io_features {
bool support_io_prefetch; // 支持IO预取
bool support_io_remapping; // 支持IO重映射
bool support_batch_mapping; // 支持批量映射
bool support_io_caching; // 支持IO缓存
bool support_secure_mapping; // 支持安全映射
bool support_runtime_protection;// 支持运行时保护
};
// IO映射扩展API
struct extended_io_api {
// 预取支持
int (*enable_io_prefetch)(void __iomem *addr, size_t size);
int (*disable_io_prefetch)(void __iomem *addr, size_t size);
int (*optimize_io_access_pattern)(void __iomem *addr, enum access_pattern pattern);
// 重映射支持
unsigned long (*ioremap_remap)(void __iomem *old_addr, size_t old_size,
phys_addr_t new_phys_addr, size_t new_size);
// 批量映射
int (*ioremap_batch)(phys_addr_t *phys_addrs, size_t *sizes,
unsigned long *prots, void __iomem **vaddrs, int count);
int (*iounmap_batch)(void __iomem **vaddrs, int count);
// IO缓存
int (*ioremap_cached)(phys_addr_t phys_addr, size_t size);
int (*invalidate_io_cache)(void __iomem *addr, size_t size);
// 安全映射
int (*ioremap_secure)(phys_addr_t phys_addr, size_t size,
struct security_context *ctx);
int (*validate_secure_mapping)(void __iomem *addr);
// 运行时保护
int (*protect_io_mapping)(void __iomem *addr, size_t size, unsigned long prot);
int (*unprotect_io_mapping)(void __iomem *addr, size_t size);
};
11. 调试和维护
11.1 IO映射调试支持
IO映射调试支持:
c
// IO映射调试宏
#define IOREMAP_DEBUG(fmt, ...) \
pr_debug("IOREMAP: " fmt, ##__VA_ARGS__)
#define IOREMAP_DEBUG_MAP(phys, size, vaddr) \
IOREMAP_DEBUG("mapping %pa-%pa to %p\n", &phys, &(phys + size - 1), vaddr)
#define IOREMAP_DEBUG_UNMAP(vaddr) \
IOREMAP_DEBUG("unmapping %p\n", vaddr)
// 详细调试模式
#ifdef CONFIG_IOREMAP_DEBUG
static void ioremap_debug_mapping(phys_addr_t phys_addr, size_t size,
void __iomem *vaddr, unsigned long prot)
{
IOREMAP_DEBUG("=== IOREMAP DEBUG ===");
IOREMAP_DEBUG("Physical address: %pa", &phys_addr);
IOREMAP_DEBUG("Size: %zu bytes", size);
IOREMAP_DEBUG("Virtual address: %p", vaddr);
IOREMAP_DEBUG("Protection: %lx", prot);
// 调试内存类型
debug_memory_type(prot);
// 调试页表设置
debug_page_table_setup(vaddr, phys_addr, size);
IOREMAP_DEBUG("=== END IOREMAP DEBUG ===");
}
#endif
11.2 错误检测和恢复
IO映射错误处理:
c
// IO映射错误检测
int detect_ioremap_errors(phys_addr_t phys_addr, size_t size, void __iomem *result)
{
// 检查映射结果
if (!result) {
IOREMAP_DEBUG("ioremap failed for %pa size %zu\n", &phys_addr, size);
return -ENOMEM;
}
// 验证映射关系
if (!validate_mapping_relationship(result, phys_addr, size)) {
IOREMAP_DEBUG("mapping relationship validation failed\n");
return -EFAULT;
}
// 检查页表一致性
if (!validate_page_table_consistency(result, phys_addr, size)) {
IOREMAP_DEBUG("page table consistency check failed\n");
return -EFAULT;
}
return 0;
}
// 错误恢复机制
int recover_ioremap_error(phys_addr_t phys_addr, size_t size, int error)
{
IOREMAP_DEBUG("Attempting ioremap error recovery: %d\n", error);
switch (error) {
case -ENOMEM:
// 内存不足:尝试释放缓存
return try_reclaim_memory_for_ioremap();
case -EFAULT:
// 地址错误:验证并更正地址参数
return validate_and_correct_address_params(&phys_addr, &size);
default:
IOREMAP_DEBUG("Unrecoverable ioremap error\n");
return error;
}
}
// 内存回收尝试
static int try_reclaim_memory_for_ioremap(void)
{
// 尝试回收页表缓存
if (shrink_page_table_cache()) {
IOREMAP_DEBUG("Page table cache reclaimed successfully\n");
return 0;
}
// 尝试回收vmap区域
if (shrink_vmap_area_cache()) {
IOREMAP_DEBUG("Vmap area cache reclaimed successfully\n");
return 0;
}
return -ENOMEM;
}
12. 总结
ARM64 mm ioremap子模块作为ARM64内存管理子系统中IO内存映射的核心组件,通过完整的设备内存映射和访问控制机制,为ARM64平台提供了安全高效的硬件设备访问接口。该模块实现了灵活的IO地址空间管理、多种内存属性配置、严格的访问权限控制,通过精心设计的映射算法和页表管理,在保证硬件访问安全性的同时实现了接近硬件极限的设备访问性能。源码分析显示,模块采用了工厂模式、策略模式和观察者模式等多种设计模式,为IO内存映射提供了灵活可靠的实现框架。