2.1 物理内存管理架构深度解析2.1.1 物理内存管理的设计挑战在实时嵌入式系统中物理内存管理面临独特的挑战资源极度受限嵌入式设备通常配备有限的内存从几KB到几GB不等必须高效利用确定性要求内存分配时间必须可预测最坏情况执行时间WCET必须受限硬件多样性需支持多种内存类型SRAM、DRAM、NOR/NAND Flash、DDR等和架构实时性约束内存管理操作不能引入不可预测的延迟安全隔离关键系统组件需要内存保护防止故障扩散VxWorks的物理内存管理架构针对这些挑战进行了专门设计在灵活性与确定性之间取得了精妙平衡。2.2 物理内存初始化与探测机制2.2.1 系统启动阶段的内存探测VxWorks在启动过程中通过多阶段方式建立物理内存视图/* 内存探测与初始化流程 */ void sysPhysMemInit(void) { /* 阶段1BSP提供的原始内存信息 */ MEM_DESC *bspMemDesc bspGetMemoryDescriptors(); /* 阶段2处理器特定内存初始化 */ cpuMemInit(); /* 阶段3内存控制器初始化 */ memCtrlInit(); /* 阶段4建立全局内存描述符表 */ buildGlobalMemMap(bspMemDesc); /* 阶段5保留系统关键区域 */ reserveCriticalRegions(); /* 阶段6初始化内存管理数据结构 */ initMemoryManager(); }内存描述符数据结构typedef struct mem_desc { PHYS_ADDR start; /* 起始物理地址 */ PHYS_ADDR end; /* 结束物理地址start size - 1 */ UINT32 size; /* 区域大小字节 */ UINT16 type; /* 内存类型 */ UINT16 flags; /* 属性标志 */ char name[16]; /* 区域名称 */ struct mem_desc *next; /* 下一个描述符 */ } MEM_DESC; /* 内存类型定义 */ #define MEM_TYPE_RAM 0x0001 /* 可读写的RAM */ #define MEM_TYPE_ROM 0x0002 /* 只读内存 */ #define MEM_TYPE_FLASH 0x0004 /* Flash内存 */ #define MEM_TYPE_DEVICE 0x0008 /* 设备内存内存映射I/O */ #define MEM_TYPE_RESERVED 0x0010 /* 系统保留内存 */ #define MEM_TYPE_DMA 0x0020 /* DMA专用内存 */ #define MEM_TYPE_NON_CACHEABLE 0x0040 /* 不可缓存内存 */ /* 内存属性标志 */ #define MEM_FLAG_READABLE 0x0001 #define MEM_FLAG_WRITABLE 0x0002 #define MEM_FLAG_EXECUTABLE 0x0004 #define MEM_FLAG_CACHEABLE 0x0008 #define MEM_FLAG_BUFFERABLE 0x0010 #define MEM_FLAG_SHAREABLE 0x0020 #define MEM_FLAG_SECURE 0x0040 #define MEM_FLAG_UNCERTAIN 0x0080 /* 内存存在性不确定 */2.2.2 内存区域自动检测算法对于支持内存自动检测的平台VxWorks实现了一套安全的内存探测算法/* 内存探测算法实现 */ STATUS memProbeRegion(PHYS_ADDR start, PHYS_ADDR end) { volatile UINT32 *testAddr; UINT32 pattern1 0xA5A5A5A5; UINT32 pattern2 0x5A5A5A5A; UINT32 originalValue; UINT32 readValue; /* 边界检查 */ if (end start) { return ERROR; } /* 按页对齐探测 */ for (PHYS_ADDR addr start; addr end; addr PAGE_SIZE) { testAddr (volatile UINT32 *)physToVirt(addr); /* 保存原始值 */ originalValue *testAddr; /* 测试写入和读取 */ *testAddr pattern1; asm volatile(dsb sy); /* 内存屏障确保写入完成 */ asm volatile(isb sy); /* 指令屏障 */ readValue *testAddr; if (readValue ! pattern1) { /* 写入失败可能不是有效的RAM */ return ERROR; } /* 测试模式翻转 */ *testAddr pattern2; asm volatile(dsb sy); asm volatile(isb sy); readValue *testAddr; if (readValue ! pattern2) { /* 模式翻转失败 */ *testAddr originalValue; /* 尝试恢复原始值 */ return ERROR; } /* 恢复原始值 */ *testAddr originalValue; } return OK; }2.2.3 内存映射表构建系统启动后构建全局内存映射表为后续内存管理提供基础/* 全局内存映射表结构 */ typedef struct mem_map_table { MEM_DESC *descriptors; /* 内存描述符链表 */ UINT32 numRegions; /* 区域数量 */ UINT64 totalMemory; /* 总内存大小 */ UINT64 usableMemory; /* 可用内存大小 */ SEM_ID lock; /* 表访问锁 */ BOOL initialized; /* 初始化标志 */ } MEM_MAP_TABLE; /* 构建内存映射表 */ STATUS buildMemoryMap(MEM_MAP_TABLE *pTable, MEM_DESC *bspDescs) { MEM_DESC *current, *newDesc, *prev NULL; UINT32 regionCount 0; UINT64 totalMem 0, usableMem 0; if (pTable NULL || bspDescs NULL) { return ERROR; } /* 初始化表锁 */ pTable-lock semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE); if (pTable-lock NULL) { return ERROR; } semTake(pTable-lock, WAIT_FOREVER); /* 复制并规范化BSP提供的内存描述符 */ current bspDescs; while (current ! NULL) { /* 创建新的描述符副本 */ newDesc (MEM_DESC *)malloc(sizeof(MEM_DESC)); if (newDesc NULL) { semGive(pTable-lock); return ERROR; } memcpy(newDesc, current, sizeof(MEM_DESC)); /* 确保地址对齐 */ newDesc-start ALIGN_DOWN(newDesc-start, PAGE_SIZE); newDesc-end ALIGN_UP(newDesc-end, PAGE_SIZE) - 1; newDesc-size newDesc-end - newDesc-start 1; /* 添加到链表 */ if (prev NULL) { pTable-descriptors newDesc; } else { prev-next newDesc; } /* 更新统计信息 */ regionCount; totalMem newDesc-size; if (newDesc-type MEM_TYPE_RAM !(newDesc-flags MEM_FLAG_RESERVED)) { usableMem newDesc-size; } prev newDesc; current current-next; } /* 设置表信息 */ pTable-numRegions regionCount; pTable-totalMemory totalMem; pTable-usableMemory usableMem; pTable-initialized TRUE; semGive(pTable-lock); return OK; }2.3 物理内存分配器设计与实现2.3.1 伙伴系统Buddy System分配器VxWorks使用改进的伙伴系统管理物理内存页框分配在碎片和效率之间取得平衡/* 伙伴系统数据结构 */ #define MAX_ORDER 11 /* 最大阶数支持最大块为2^112048页 */ typedef struct buddy_system { UINT32 totalPages; /* 总页数 */ UINT32 freePages; /* 空闲页数 */ UINT32 minOrder; /* 最小分配阶数 */ UINT32 maxOrder; /* 最大分配阶数 */ LIST freeLists[MAX_ORDER 1]; /* 各阶空闲链表 */ UINT8 *pageMap; /* 页状态位图 */ SEM_ID lock; /* 分配器锁 */ UINT32 allocCount; /* 分配次数统计 */ UINT32 freeCount; /* 释放次数统计 */ } BUDDY_SYSTEM; /* 页框结构 */ typedef struct page_frame { PHYS_ADDR physAddr; /* 物理地址 */ UINT32 order; /* 所属块的大小阶数 */ UINT32 index; /* 在位图中的索引 */ struct page_frame *buddy; /* 伙伴指针 */ LIST_NODE listNode; /* 链表节点 */ } PAGE_FRAME; /* 伙伴系统初始化 */ STATUS buddyInit(BUDDY_SYSTEM *buddy, PHYS_ADDR start, PHYS_ADDR end) { UINT32 totalPages, i; UINT8 *pageMap; /* 计算总页数 */ totalPages (end - start 1) / PAGE_SIZE; /* 分配页状态位图 */ pageMap (UINT8 *)malloc((totalPages 7) / 8); if (pageMap NULL) { return ERROR; } memset(pageMap, 0, (totalPages 7) / 8); /* 初始化伙伴系统结构 */ buddy-totalPages totalPages; buddy-freePages totalPages; buddy-minOrder 0; /* 最小1页 */ buddy-maxOrder 0; /* 计算最大阶数 */ while ((1U buddy-maxOrder) totalPages buddy-maxOrder MAX_ORDER) { buddy-maxOrder; } buddy-maxOrder--; /* 调整到实际最大阶数 */ /* 初始化各阶空闲链表 */ for (i 0; i buddy-maxOrder; i) { lstInit(buddy-freeLists[i]); } /* 初始化锁 */ buddy-lock semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE); if (buddy-lock NULL) { free(pageMap); return ERROR; } buddy-pageMap pageMap; buddy-allocCount 0; buddy-freeCount 0; /* 将所有内存作为单个大块插入最大阶空闲链表 */ PAGE_FRAME *firstBlock createPageFrame(start, buddy-maxOrder, 0); if (firstBlock NULL) { free(pageMap); semDelete(buddy-lock); return ERROR; } lstAdd(buddy-freeLists[buddy-maxOrder], firstBlock-listNode); return OK; } /* 页框分配函数 */ PAGE_FRAME *buddyAlloc(BUDDY_SYSTEM *buddy, UINT32 order) { UINT32 currentOrder; PAGE_FRAME *block, *buddyBlock; if (order buddy-maxOrder) { return NULL; } semTake(buddy-lock, WAIT_FOREVER); /* 从请求的阶数开始查找 */ currentOrder order; while (currentOrder buddy-maxOrder) { if (!lstEmpty(buddy-freeLists[currentOrder])) { /* 找到合适块从链表移除 */ block (PAGE_FRAME *)lstFirst(buddy-freeLists[currentOrder]); lstDelete(buddy-freeLists[currentOrder], block-listNode); /* 如果块比需要的大进行分裂 */ while (currentOrder order) { currentOrder--; /* 创建伙伴块 */ buddyBlock splitBlock(block, currentOrder); if (buddyBlock NULL) { semGive(buddy-lock); return NULL; } /* 将伙伴块插入对应阶的空闲链表 */ lstAdd(buddy-freeLists[currentOrder], buddyBlock-listNode); } /* 标记页为已分配 */ markPagesAllocated(buddy, block, order); buddy-freePages - (1 order); buddy-allocCount; semGive(buddy-lock); return block; } currentOrder; } semGive(buddy-lock); return NULL; /* 内存不足 */ } /* 页框释放函数 */ STATUS buddyFree(BUDDY_SYSTEM *buddy, PAGE_FRAME *frame) { UINT32 order frame-order; PAGE_FRAME *buddyFrame; if (frame NULL) { return ERROR; } semTake(buddy-lock, WAIT_FOREVER); /* 标记页为未分配 */ markPagesFree(buddy, frame, order); /* 尝试与伙伴合并 */ while (order buddy-maxOrder) { buddyFrame findBuddy(buddy, frame, order); if (buddyFrame NULL || !isFree(buddy, buddyFrame, order)) { break; /* 伙伴不存在或已分配停止合并 */ } /* 从空闲链表中移除伙伴 */ lstDelete(buddy-freeLists[order], buddyFrame-listNode); /* 合并块 */ if (frame-physAddr buddyFrame-physAddr) { PAGE_FRAME *temp frame; frame buddyFrame; buddyFrame temp; } /* 释放伙伴块结构 */ freePageFrame(buddyFrame); order; /* 合并后块大小增加一阶 */ } /* 将合并后的块插入对应阶的空闲链表 */ frame-order order; lstAdd(buddy-freeLists[order], frame-listNode); buddy-freePages (1 order); buddy-freeCount; semGive(buddy-lock); return OK; }2.3.2 物理内存池管理器针对频繁的小块物理内存分配需求VxWorks实现了一个物理内存池管理器/* 物理内存池结构 */ typedef struct phys_mem_pool { char name[16]; /* 池名称 */ PHYS_ADDR baseAddr; /* 池基地址 */ UINT32 blockSize; /* 块大小对齐到页大小 */ UINT32 blockCount; /* 块总数 */ UINT32 freeCount; /* 空闲块数 */ UINT32 *freeStack; /* 空闲块栈 */ UINT32 stackTop; /* 栈顶指针 */ SEM_ID lock; /* 池锁 */ UINT32 allocCount; /* 分配计数 */ UINT32 freeCountTotal; /* 释放计数 */ } PHYS_MEM_POOL; /* 创建物理内存池 */ PHYS_MEM_POOL *physPoolCreate(const char *name, PHYS_ADDR base, UINT32 blockSize, UINT32 blockCount) { PHYS_MEM_POOL *pool; UINT32 i; if (name NULL || base 0 || blockSize 0 || blockCount 0) { return NULL; } /* 分配池控制结构 */ pool (PHYS_MEM_POOL *)malloc(sizeof(PHYS_MEM_POOL)); if (pool NULL) { return NULL; } /* 初始化池信息 */ strncpy(pool-name, name, sizeof(pool-name) - 1); pool-name[sizeof(pool-name) - 1] \0; pool-baseAddr base; pool-blockSize ALIGN_UP(blockSize, PAGE_SIZE); pool-blockCount blockCount; pool-freeCount blockCount; /* 分配空闲块栈 */ pool-freeStack (UINT32 *)malloc(blockCount * sizeof(UINT32)); if (pool-freeStack NULL) { free(pool); return NULL; } /* 初始化空闲块栈后进先出提高缓存命中率 */ for (i 0; i blockCount; i) { pool-freeStack[i] i; /* 存储块索引 */ } pool-stackTop blockCount - 1; /* 创建保护锁 */ pool-lock semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE); if (pool-lock NULL) { free(pool-freeStack); free(pool); return NULL; } pool-allocCount 0; pool-freeCountTotal 0; return pool; } /* 从物理内存池分配块 */ PHYS_ADDR physPoolAlloc(PHYS_MEM_POOL *pool) { UINT32 blockIndex; PHYS_ADDR blockAddr; if (pool NULL) { return 0; } semTake(pool-lock, WAIT_FOREVER); if (pool-freeCount 0) { semGive(pool-lock); return 0; /* 池已空 */ } /* 从栈顶获取空闲块索引 */ blockIndex pool-freeStack[pool-stackTop]; pool-stackTop--; pool-freeCount--; pool-allocCount; /* 计算块物理地址 */ blockAddr pool-baseAddr (blockIndex * pool-blockSize); semGive(pool-lock); return blockAddr; } /* 释放块到物理内存池 */ STATUS physPoolFree(PHYS_MEM_POOL *pool, PHYS_ADDR blockAddr) { UINT32 blockIndex; if (pool NULL || blockAddr 0) { return ERROR; } /* 验证地址在池范围内 */ if (blockAddr pool-baseAddr || blockAddr pool-baseAddr pool-blockCount * pool-blockSize) { return ERROR; } /* 计算块索引 */ blockIndex (blockAddr - pool-baseAddr) / pool-blockSize; semTake(pool-lock, WAIT_FOREVER); if (pool-freeCount pool-blockCount) { semGive(pool-lock); return ERROR; /* 不应发生释放过多块 */ } /* 将块索引压入空闲栈 */ pool-stackTop; pool-freeStack[pool-stackTop] blockIndex; pool-freeCount; pool-freeCountTotal; semGive(pool-lock); return OK; }2.4 地址映射架构与MMU管理2.4.1 虚拟地址空间布局VxWorks采用灵活的虚拟地址空间布局策略支持多种处理器架构典型的ARM架构虚拟地址空间布局32位 0xFFFF FFFF ┌─────────────────────────────┐ │ 高端内存映射 │ │ 设备I/O、ROM、Flash等 │ 0xF000 0000├─────────────────────────────┤ │ 内核空间 │ │ 内核代码、数据、堆栈 │ 0xC000 0000├─────────────────────────────┤ │ 用户空间可选 │ │ 应用程序代码和数据 │ 0x8000 0000├─────────────────────────────┤ │ 共享内存区域 │ │ 进程间通信、多核共享 │ 0x4000 0000├─────────────────────────────┤ │ 任务私有空间 │ │ 各任务独立地址空间 │ 0x0000 0000└─────────────────────────────┘地址空间配置参数/* config.h 中的地址空间配置 */ #define VM_KERNEL_BASE_ADRS 0xC0000000 /* 内核空间基地址 */ #define VM_KERNEL_SIZE 0x40000000 /* 内核空间大小1GB */ #define VM_USER_BASE_ADRS 0x80000000 /* 用户空间基地址 */ #define VM_USER_SIZE 0x40000000 /* 用户空间大小1GB */ #define VM_SHARED_BASE_ADRS 0x40000000 /* 共享空间基地址 */ #define VM_SHARED_SIZE 0x40000000 /* 共享空间大小1GB */ #define VM_TASK_BASE_ADRS 0x00000000 /* 任务私有空间基地址 */ #define VM_TASK_SIZE 0x40000000 /* 任务私有空间大小1GB */ /* 页表配置 */ #define VM_PAGE_SIZE 4096 /* 页大小 */ #define VM_L1_PAGE_TABLE_ENTRIES 4096 /* 一级页表项数 */ #define VM_L2_PAGE_TABLE_ENTRIES 256 /* 二级页表项数 */2.4.2 多级页表管理VxWorks针对不同处理器架构实现相应的页表管理机制/* ARM架构页表管理 */ #ifdef CPU_ARM /* ARM页表项定义 */ typedef struct arm_pte { union { struct { UINT32 type : 2; /* 页表项类型 */ UINT32 buffer : 1; /* 缓冲位 */ UINT32 cache : 1; /* 缓存位 */ UINT32 ap : 2; /* 访问权限 */ UINT32 tex : 3; /* 类型扩展 */ UINT32 apx : 1; /* 扩展访问权限 */ UINT32 s : 1; /* 共享位 */ UINT32 ng : 1; /* 非全局位 */ UINT32 base : 20; /* 物理页基地址 */ } bits; UINT32 value; }; } ARM_PTE; /* ARM页表管理结构 */ typedef struct arm_mmu { ARM_PTE *l1Table; /* 一级页表4096项 */ ARM_PTE **l2Tables; /* 二级页表指针数组 */ UINT32 l1TablePhys; /* 一级页表物理地址 */ UINT32 l2TableCount; /* 二级页表数量 */ SEM_ID lock; /* 页表操作锁 */ BOOL enabled; /* MMU使能标志 */ } ARM_MMU; /* ARM MMU初始化 */ STATUS armMmuInit(ARM_MMU *mmu) { UINT32 i; if (mmu NULL) { return ERROR; } /* 分配一级页表16KB4096项 * 4字节 */ mmu-l1Table (ARM_PTE *)malloc(VM_L1_PAGE_TABLE_ENTRIES * sizeof(ARM_PTE)); if (mmu-l1Table NULL) { return ERROR; } /* 获取一级页表物理地址 */ mmu-l1TablePhys virtToPhys(mmu-l1Table); /* 分配二级页表指针数组 */ mmu-l2Tables (ARM_PTE **)calloc(VM_L1_PAGE_TABLE_ENTRIES, sizeof(ARM_PTE *)); if (mmu-l2Tables NULL) { free(mmu-l1Table); return ERROR; } /* 初始化所有一级页表项为无效 */ for (i 0; i VM_L1_PAGE_TABLE_ENTRIES; i) { mmu-l1Table[i].value 0; } mmu-l2TableCount 0; mmu-lock semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE); mmu-enabled FALSE; return OK; } /* 建立虚拟地址到物理地址映射 */ STATUS armMmuMap(ARM_MMU *mmu, VIRT_ADDR virt, PHYS_ADDR phys, UINT32 size, UINT32 flags) { UINT32 virtPage, physPage; UINT32 numPages; UINT32 i, l1Index, l2Index; ARM_PTE *l2Table; if (mmu NULL || size 0) { return ERROR; } /* 地址对齐检查 */ if ((virt (PAGE_SIZE - 1)) ! 0 || (phys (PAGE_SIZE - 1)) ! 0) { return ERROR; } numPages (size PAGE_SIZE - 1) / PAGE_SIZE; semTake(mmu-lock, WAIT_FOREVER); for (i 0; i numPages; i) { virtPage virt i * PAGE_SIZE; physPage phys i * PAGE_SIZE; /* 计算页表索引 */ l1Index (virtPage 20) 0xFFF; /* 12位一级索引 */ l2Index (virtPage 12) 0xFF; /* 8位二级索引 */ /* 检查一级页表项 */ if (mmu-l1Table[l1Index].bits.type 0) { /* 一级页表项无效需要分配二级页表 */ l2Table (ARM_PTE *)malloc(256 * sizeof(ARM_PTE)); if (l2Table NULL) { semGive(mmu-lock); return ERROR; } /* 初始化二级页表 */ memset(l2Table, 0, 256 * sizeof(ARM_PTE)); /* 设置一级页表项指向二级页表 */ mmu-l1Table[l1Index].bits.type 1; /* 粗页表 */ mmu-l1Table[l1Index].bits.base virtToPhys(l2Table) 10; mmu-l2Tables[l1Index] l2Table; mmu-l2TableCount; } else if (mmu-l1Table[l1Index].bits.type 1) { /* 粗页表已存在 */ l2Table mmu-l2Tables[l1Index]; } else { /* 其他类型段或细页表暂不支持 */ semGive(mmu-lock); return ERROR; } /* 设置二级页表项 */ l2Table[l2Index].bits.type 2; /* 小页4KB */ l2Table[l2Index].bits.base physPage 12; /* 设置页属性 */ if (flags VM_PROT_READ) l2Table[l2Index].bits.ap 0x3; if (flags VM_PROT_WRITE) l2Table[l2Index].bits.ap 0x3; if (flags VM_PROT_EXECUTE) l2Table[l2Index].bits.ap 0x3; if (flags VM_PROT_DEVICE) { l2Table[l2Index].bits.cache 0; l2Table[l2Index].bits.buffer 0; } else { l2Table[l2Index].bits.cache 1; l2Table[l2Index].bits.buffer 1; } if (flags VM_PROT_SHARED) { l2Table[l2Index].bits.s 1; } } semGive(mmu-lock); /* 刷新TLB */ asm volatile(mcr p15, 0, %0, c8, c7, 0 : : r (0)); asm volatile(dsb); asm volatile(isb); return OK; } #endif /* CPU_ARM */2.4.3 地址转换与查找/* 地址转换工具函数 */ PHYS_ADDR virtToPhys(VIRT_ADDR virt) { /* 简单的线性映射示例 */ #ifdef LINEAR_MAPPING return virt - VM_KERNEL_BASE_ADRS; #else /* 实际实现需要查询页表 */ ARM_MMU *mmu getCurrentMmu(); UINT32 l1Index, l2Index; ARM_PTE *l2Table; PHYS_ADDR phys; if (mmu NULL || !mmu-enabled) { return virt; /* MMU未启用虚拟地址等于物理地址 */ } l1Index (virt 20) 0xFFF; l2Index (virt 12) 0xFF; if (mmu-l1Table[l1Index].bits.type ! 1) { return 0; /* 无效映射 */ } l2Table mmu-l2Tables[l1Index]; if (l2Table[l2Index].bits.type ! 2) { return 0; /* 无效映射 */ } phys (l2Table[l2Index].bits.base 12) | (virt 0xFFF); return phys; #endif } VIRT_ADDR physToVirt(PHYS_ADDR phys) { /* 反向线性映射 */ #ifdef LINEAR_MAPPING return phys VM_KERNEL_BASE_ADRS; #else /* 实际实现需要反向查找页表效率较低 */ /* 通常只在调试时使用 */ ARM_MMU *mmu getCurrentMmu(); UINT32 i, j; if (mmu NULL || !mmu-enabled) { return phys; } /* 遍历所有页表项查找匹配的物理地址 */ for (i 0; i VM_L1_PAGE_TABLE_ENTRIES; i) { if (mmu-l1Table[i].bits.type 1) { ARM_PTE *l2Table mmu-l2Tables[i]; for (j 0; j 256; j) { if (l2Table[j].bits.type 2) { PHYS_ADDR pagePhys l2Table[j].bits.base 12; if (pagePhys (phys ~0xFFF)) { return (i 20) | (j 12) | (phys 0xFFF); } } } } } return 0; /* 未找到映射 */ #endif }2.5 多核内存管理机制2.5.1 核间内存同步与一致性/* 多核内存管理结构 */ typedef struct multi_core_mem { UINT32 coreCount; /* 核心数量 */ PHYS_ADDR perCoreBase; /* 每核私有内存基地址 */ UINT32 perCoreSize; /* 每核私有内存大小 */ PHYS_ADDR sharedBase; /* 共享内存基地址 */ UINT32 sharedSize; /* 共享内存大小 */ CACHE_COHERENCY *coherency; /* 缓存一致性控制器 */ SEM_ID *coreLocks; /* 每核内存分配锁 */ BOOL initialized; /* 初始化标志 */ } MULTI_CORE_MEM; /* 缓存一致性管理 */ typedef struct cache_coherency { UINT32 type; /* 一致性协议类型 */ void *regBase; /* 寄存器基地址 */ UINT32 lineSize; /* 缓存行大小 */ UINT32 wayCount; /* 路数 */ SEM_ID lock; /* 操作锁 */ /* 维护函数指针 */ STATUS (*invalidateRange)(void *addr, UINT32 size); STATUS (*cleanRange)(void *addr, UINT32 size); STATUS (*flushRange)(void *addr, UINT32 size); } CACHE_COHERENCY; /* 多核内存分配器 */ typedef struct multi_core_allocator { BUDDY_SYSTEM *globalBuddy; /* 全局伙伴系统 */ BUDDY_SYSTEM **perCoreBuddies; /* 每核伙伴系统 */ PHYS_MEM_POOL *globalPool; /* 全局内存池 */ PHYS_MEM_POOL **perCorePools; /* 每核内存池 */ UINT32 coreCount; /* 核心数量 */ SEM_ID globalLock; /* 全局分配锁 */ } MULTI_CORE_ALLOCATOR; /* 多核感知的内存分配 */ void *multiCoreAlloc(MULTI_CORE_ALLOCATOR *allocator, UINT32 size, UINT32 flags) { UINT32 coreId getCoreId(); void *memory NULL; if (allocator NULL) { return NULL; } /* 根据标志选择分配策略 */ if (flags MC_ALLOC_LOCAL) { /* 分配本地内存当前核私有 */ if (allocator-perCorePools ! NULL allocator-perCorePools[coreId] ! NULL) { memory (void *)physPoolAlloc(allocator-perCorePools[coreId]); } } else if (flags MC_ALLOC_SHARED) { /* 分配共享内存 */ semTake(allocator-globalLock, WAIT_FOREVER); if (size PAGE_SIZE allocator-globalPool ! NULL) { memory (void *)physPoolAlloc(allocator-globalPool); } else if (allocator-globalBuddy ! NULL) { UINT32 order sizeToOrder(size); PAGE_FRAME *frame buddyAlloc(allocator-globalBuddy, order); if (frame ! NULL) { memory (void *)frame-physAddr; } } semGive(allocator-globalLock); } /* 如果分配了内存确保缓存一致性 */ if (memory ! NULL (flags MC_ALLOC_SHARED)) { CACHE_COHERENCY *cc getCacheCoherency(); if (cc ! NULL cc-flushRange ! NULL) { cc-flushRange(memory, size); } } return memory; }2.5.2 核间通信内存/* 核间通信内存管理 */ typedef struct ipc_memory { PHYS_ADDR base; /* 物理基地址 */ VIRT_ADDR virt; /* 虚拟地址 */ UINT32 size; /* 总大小 */ UINT32 slotSize; /* 每个槽大小 */ UINT32 slotCount; /* 槽数量 */ SEM_ID *slotLocks; /* 槽访问锁 */ UINT8 *slotStatus; /* 槽状态位图 */ UINT32 producerCore; /* 生产者核心ID */ UINT32 consumerCore; /* 消费者核心ID */ } IPC_MEMORY; /* 创建核间通信内存 */ IPC_MEMORY *ipcMemCreate(UINT32 totalSize, UINT32 slotSize) { IPC_MEMORY *ipc; UINT32 i, slotCount; if (totalSize 0 || slotSize 0) { return NULL; } slotCount totalSize / slotSize; /* 分配IPC内存结构 */ ipc (IPC_MEMORY *)malloc(sizeof(IPC_MEMORY)); if (ipc NULL) { return NULL; } /* 分配物理内存 */ ipc-base physAllocContiguous(totalSize, PAGE_SIZE); if (ipc-base 0) { free(ipc); return NULL; } /* 映射到虚拟地址空间 */ ipc-virt vmMap(NULL, ipc-base, totalSize, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_SHARED); if (ipc-virt 0) { physFree(ipc-base, totalSize); free(ipc); return NULL; } ipc-size totalSize; ipc-slotSize slotSize; ipc-slotCount slotCount; /* 分配槽锁数组 */ ipc-slotLocks (SEM_ID *)malloc(slotCount * sizeof(SEM_ID)); if (ipc-slotLocks NULL) { vmUnmap(ipc-virt, totalSize); physFree(ipc-base, totalSize); free(ipc); return NULL; } /* 初始化每个槽的锁 */ for (i 0; i slotCount; i) { ipc-slotLocks[i] semBCreate(SEM_Q_FIFO, SEM_FULL); if (ipc-slotLocks[i] NULL) { /* 清理已创建的锁 */ for (UINT32 j 0; j i; j) { semDelete(ipc-slotLocks[j]); } free(ipc-slotLocks); vmUnmap(ipc-virt, totalSize); physFree(ipc-base, totalSize); free(ipc); return NULL; } } /* 初始化槽状态位图 */ ipc-slotStatus (UINT8 *)calloc((slotCount 7) / 8, 1); if (ipc-slotStatus NULL) { for (i 0; i slotCount; i) { semDelete(ipc-slotLocks[i]); } free(ipc-slotLocks); vmUnmap(ipc-virt, totalSize); physFree(ipc-base, totalSize); free(ipc); return NULL; } ipc-producerCore 0xFFFFFFFF; /* 未指定 */ ipc-consumerCore 0xFFFFFFFF; /* 未指定 */ return ipc; }2.6 内存保护与权限管理2.6.1 内存保护域/* 内存保护域结构 */ typedef struct mem_protection_domain { UINT32 domainId; /* 域ID */ char name[16]; /* 域名 */ UINT32 accessRights; /* 访问权限位图 */ LIST regionList; /* 保护区域链表 */ SEM_ID lock; /* 域锁 */ UINT32 refCount; /* 引用计数 */ } MEM_PROTECTION_DOMAIN; /* 内存保护区域 */ typedef struct protected_region { VIRT_ADDR start; /* 起始虚拟地址 */ VIRT_ADDR end; /* 结束虚拟地址 */ UINT32 size; /* 区域大小 */ UINT32 permissions; /* 权限位 */ UINT32 domainId; /* 所属域ID */ LIST_NODE listNode; /* 链表节点 */ } PROTECTED_REGION; /* 内存访问权限检查 */ BOOL checkMemoryAccess(UINT32 coreId, VIRT_ADDR addr, UINT32 accessType) { MEM_PROTECTION_DOMAIN *domain; PROTECTED_REGION *region; UINT32 coreDomainId; /* 获取当前核心的保护域 */ coreDomainId getCoreDomainId(coreId); domain getProtectionDomain(coreDomainId); if (domain NULL) { return FALSE; /* 核心无保护域拒绝访问 */ } semTake(domain-lock, WAIT_FOREVER); /* 查找包含该地址的保护区域 */ region (PROTECTED_REGION *)lstFirst(domain-regionList); while (region ! NULL) { if (addr region-start addr region-end) { /* 检查权限 */ BOOL allowed (region-permissions accessType) ! 0; semGive(domain-lock); return allowed; } region (PROTECTED_REGION *)lstNext(region-listNode); } semGive(domain-lock); /* 地址不在任何保护区域内使用默认策略 */ return (domain-accessRights accessType) ! 0; }2.7 总结物理内存管理与地址映射机制是VxWorks内存管理的基石它直接与硬件交互为上层提供可靠的内存服务。本部分深入分析了物理内存探测与初始化系统启动阶段如何发现和建立内存映射物理内存分配算法伙伴系统和内存池的实现细节地址映射架构多级页表管理和MMU配置多核内存管理核间同步、缓存一致性和通信内存内存保护机制访问权限控制和保护域这些机制共同确保了VxWorks在嵌入式实时环境中的确定性、可靠性和性能。在第三部分中我们将深入探讨动态内存分配算法与实现细节包括系统堆管理、内存池优化和碎片整理策略。