文章目录
- 1. 概述
- 2. 软件架构图
- 3. 调用流程图
- 4. UML类图
- 5. 源码深度分析
-
- 5.1 ARM64固定映射架构分析
-
- 5.1.1 固定映射核心实现
- 5.1.2 kmap原子映射实现
- 5.2 临时映射和高端内存管理分析
-
- 5.2.1 临时映射实现
- 5.2.2 高端内存映射处理
- 5.3 安全性和性能优化分析
-
- 5.3.1 固定映射安全验证
- 5.3.2 性能优化策略
- 6. 设计模式分析
-
- 6.1 单例模式在固定映射管理中的体现
- 6.2 策略模式在映射策略选择中的体现
- 6.3 观察者模式在映射监控中的体现
- 7. 状态机分析
- 8. 性能优化分析
-
- 8.1 固定映射性能优化
- 8.2 缓存一致性优化
- 9. 安全性考虑
-
- 9.1 映射访问控制
- 9.2 映射完整性保护
- 10. 扩展性分析
-
- 10.1 多架构支持
- 10.2 功能扩展
- 11. 调试和维护
-
- 11.1 固定映射调试支持
- 11.2 错误检测和恢复
- 12. 总结
团队博客: 汽车电子社区
1. 概述
ARM64 mm fixmap子模块是Linux内核ARM64架构内存管理子系统中实现固定映射管理的核心组件,包含fixmap.c文件。该模块作为ARM64平台编译时固定地址映射的关键实现,提供了完整的固定映射区域管理、kmap原子映射和临时映射功能,是ARM64内核固定地址访问的基础架构。
fixmap子模块实现了Linux虚拟内存系统中固定映射的核心机制,包括编译时确定的固定地址映射、运行时的kmap临时映射、高端内存的原子映射等功能。该模块通过精心设计的映射索引和地址分配策略,在保证固定映射稳定性的同时提供了灵活的临时映射接口。
模块的设计体现了固定映射的特殊性和高效性要求,通过静态分配和动态管理的结合,在减少运行时开销的同时保证了映射的稳定性和安全性,是ARM64固定地址映射的重要组成部分。
2. 软件架构图
#mermaid-svg-dbHEmCSLmNsY5ZEa{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-dbHEmCSLmNsY5ZEa .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-dbHEmCSLmNsY5ZEa .error-icon{fill:#552222;}#mermaid-svg-dbHEmCSLmNsY5ZEa .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dbHEmCSLmNsY5ZEa .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dbHEmCSLmNsY5ZEa .marker.cross{stroke:#333333;}#mermaid-svg-dbHEmCSLmNsY5ZEa svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dbHEmCSLmNsY5ZEa p{margin:0;}#mermaid-svg-dbHEmCSLmNsY5ZEa .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-dbHEmCSLmNsY5ZEa .cluster-label text{fill:#333;}#mermaid-svg-dbHEmCSLmNsY5ZEa .cluster-label span{color:#333;}#mermaid-svg-dbHEmCSLmNsY5ZEa .cluster-label span p{background-color:transparent;}#mermaid-svg-dbHEmCSLmNsY5ZEa .label text,#mermaid-svg-dbHEmCSLmNsY5ZEa span{fill:#333;color:#333;}#mermaid-svg-dbHEmCSLmNsY5ZEa .node rect,#mermaid-svg-dbHEmCSLmNsY5ZEa .node circle,#mermaid-svg-dbHEmCSLmNsY5ZEa .node ellipse,#mermaid-svg-dbHEmCSLmNsY5ZEa .node polygon,#mermaid-svg-dbHEmCSLmNsY5ZEa .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-dbHEmCSLmNsY5ZEa .rough-node .label text,#mermaid-svg-dbHEmCSLmNsY5ZEa .node .label text,#mermaid-svg-dbHEmCSLmNsY5ZEa .image-shape .label,#mermaid-svg-dbHEmCSLmNsY5ZEa .icon-shape .label{text-anchor:middle;}#mermaid-svg-dbHEmCSLmNsY5ZEa .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-dbHEmCSLmNsY5ZEa .rough-node .label,#mermaid-svg-dbHEmCSLmNsY5ZEa .node .label,#mermaid-svg-dbHEmCSLmNsY5ZEa .image-shape .label,#mermaid-svg-dbHEmCSLmNsY5ZEa .icon-shape .label{text-align:center;}#mermaid-svg-dbHEmCSLmNsY5ZEa .node.clickable{cursor:pointer;}#mermaid-svg-dbHEmCSLmNsY5ZEa .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-dbHEmCSLmNsY5ZEa .arrowheadPath{fill:#333333;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-dbHEmCSLmNsY5ZEa .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dbHEmCSLmNsY5ZEa .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-dbHEmCSLmNsY5ZEa .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dbHEmCSLmNsY5ZEa .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-dbHEmCSLmNsY5ZEa .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-dbHEmCSLmNsY5ZEa .cluster text{fill:#333;}#mermaid-svg-dbHEmCSLmNsY5ZEa .cluster span{color:#333;}#mermaid-svg-dbHEmCSLmNsY5ZEa div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-dbHEmCSLmNsY5ZEa .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-dbHEmCSLmNsY5ZEa rect.text{fill:none;stroke-width:0;}#mermaid-svg-dbHEmCSLmNsY5ZEa .icon-shape,#mermaid-svg-dbHEmCSLmNsY5ZEa .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dbHEmCSLmNsY5ZEa .icon-shape p,#mermaid-svg-dbHEmCSLmNsY5ZEa .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-dbHEmCSLmNsY5ZEa .icon-shape rect,#mermaid-svg-dbHEmCSLmNsY5ZEa .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dbHEmCSLmNsY5ZEa .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-dbHEmCSLmNsY5ZEa .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-dbHEmCSLmNsY5ZEa :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
ARM64 mm fixmap
固定映射管理
kmap原子映射
临时映射处理
高端内存映射
fixmap.c
固定地址分配
编译时映射
运行时管理
kmap接口
原子操作
并发安全
临时映射
栈保护
上下文切换
高端内存访问
64位地址空间
内存扩展
3. 调用流程图
#mermaid-svg-0SK7jHb4KtaSpDbo{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0SK7jHb4KtaSpDbo .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0SK7jHb4KtaSpDbo .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0SK7jHb4KtaSpDbo .error-icon{fill:#552222;}#mermaid-svg-0SK7jHb4KtaSpDbo .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0SK7jHb4KtaSpDbo .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0SK7jHb4KtaSpDbo .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0SK7jHb4KtaSpDbo .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0SK7jHb4KtaSpDbo .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0SK7jHb4KtaSpDbo .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0SK7jHb4KtaSpDbo .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0SK7jHb4KtaSpDbo .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0SK7jHb4KtaSpDbo .marker.cross{stroke:#333333;}#mermaid-svg-0SK7jHb4KtaSpDbo svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0SK7jHb4KtaSpDbo p{margin:0;}#mermaid-svg-0SK7jHb4KtaSpDbo .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-0SK7jHb4KtaSpDbo .cluster-label text{fill:#333;}#mermaid-svg-0SK7jHb4KtaSpDbo .cluster-label span{color:#333;}#mermaid-svg-0SK7jHb4KtaSpDbo .cluster-label span p{background-color:transparent;}#mermaid-svg-0SK7jHb4KtaSpDbo .label text,#mermaid-svg-0SK7jHb4KtaSpDbo span{fill:#333;color:#333;}#mermaid-svg-0SK7jHb4KtaSpDbo .node rect,#mermaid-svg-0SK7jHb4KtaSpDbo .node circle,#mermaid-svg-0SK7jHb4KtaSpDbo .node ellipse,#mermaid-svg-0SK7jHb4KtaSpDbo .node polygon,#mermaid-svg-0SK7jHb4KtaSpDbo .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0SK7jHb4KtaSpDbo .rough-node .label text,#mermaid-svg-0SK7jHb4KtaSpDbo .node .label text,#mermaid-svg-0SK7jHb4KtaSpDbo .image-shape .label,#mermaid-svg-0SK7jHb4KtaSpDbo .icon-shape .label{text-anchor:middle;}#mermaid-svg-0SK7jHb4KtaSpDbo .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0SK7jHb4KtaSpDbo .rough-node .label,#mermaid-svg-0SK7jHb4KtaSpDbo .node .label,#mermaid-svg-0SK7jHb4KtaSpDbo .image-shape .label,#mermaid-svg-0SK7jHb4KtaSpDbo .icon-shape .label{text-align:center;}#mermaid-svg-0SK7jHb4KtaSpDbo .node.clickable{cursor:pointer;}#mermaid-svg-0SK7jHb4KtaSpDbo .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0SK7jHb4KtaSpDbo .arrowheadPath{fill:#333333;}#mermaid-svg-0SK7jHb4KtaSpDbo .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0SK7jHb4KtaSpDbo .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0SK7jHb4KtaSpDbo .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0SK7jHb4KtaSpDbo .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0SK7jHb4KtaSpDbo .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0SK7jHb4KtaSpDbo .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0SK7jHb4KtaSpDbo .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0SK7jHb4KtaSpDbo .cluster text{fill:#333;}#mermaid-svg-0SK7jHb4KtaSpDbo .cluster span{color:#333;}#mermaid-svg-0SK7jHb4KtaSpDbo div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0SK7jHb4KtaSpDbo .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0SK7jHb4KtaSpDbo rect.text{fill:none;stroke-width:0;}#mermaid-svg-0SK7jHb4KtaSpDbo .icon-shape,#mermaid-svg-0SK7jHb4KtaSpDbo .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0SK7jHb4KtaSpDbo .icon-shape p,#mermaid-svg-0SK7jHb4KtaSpDbo .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0SK7jHb4KtaSpDbo .icon-shape rect,#mermaid-svg-0SK7jHb4KtaSpDbo .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0SK7jHb4KtaSpDbo .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0SK7jHb4KtaSpDbo .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0SK7jHb4KtaSpDbo :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
是
否
是
否
是
否
需要固定映射
选择映射类型
编译时固定映射?
使用FIXADDR宏
运行时kmap映射?
调用kmap函数
其他映射类型
分配固定索引
设置页表条目
返回固定地址
分配临时映射槽
建立映射关系
返回映射地址
使用其他映射
使用固定地址
需要解除映射?
清理映射
释放资源
4. UML类图
#mermaid-svg-24yK7n0cvFkVMwO6{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-24yK7n0cvFkVMwO6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-24yK7n0cvFkVMwO6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-24yK7n0cvFkVMwO6 .error-icon{fill:#552222;}#mermaid-svg-24yK7n0cvFkVMwO6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-24yK7n0cvFkVMwO6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-24yK7n0cvFkVMwO6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-24yK7n0cvFkVMwO6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-24yK7n0cvFkVMwO6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-24yK7n0cvFkVMwO6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-24yK7n0cvFkVMwO6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-24yK7n0cvFkVMwO6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-24yK7n0cvFkVMwO6 .marker.cross{stroke:#333333;}#mermaid-svg-24yK7n0cvFkVMwO6 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-24yK7n0cvFkVMwO6 p{margin:0;}#mermaid-svg-24yK7n0cvFkVMwO6 g.classGroup text{fill:#9370DB;stroke:none;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-24yK7n0cvFkVMwO6 g.classGroup text .title{font-weight:bolder;}#mermaid-svg-24yK7n0cvFkVMwO6 .nodeLabel,#mermaid-svg-24yK7n0cvFkVMwO6 .edgeLabel{color:#131300;}#mermaid-svg-24yK7n0cvFkVMwO6 .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-24yK7n0cvFkVMwO6 .label text{fill:#131300;}#mermaid-svg-24yK7n0cvFkVMwO6 .labelBkg{background:#ECECFF;}#mermaid-svg-24yK7n0cvFkVMwO6 .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-24yK7n0cvFkVMwO6 .classTitle{font-weight:bolder;}#mermaid-svg-24yK7n0cvFkVMwO6 .node rect,#mermaid-svg-24yK7n0cvFkVMwO6 .node circle,#mermaid-svg-24yK7n0cvFkVMwO6 .node ellipse,#mermaid-svg-24yK7n0cvFkVMwO6 .node polygon,#mermaid-svg-24yK7n0cvFkVMwO6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-24yK7n0cvFkVMwO6 .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 g.clickable{cursor:pointer;}#mermaid-svg-24yK7n0cvFkVMwO6 g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-24yK7n0cvFkVMwO6 g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-24yK7n0cvFkVMwO6 .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-24yK7n0cvFkVMwO6 .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-24yK7n0cvFkVMwO6 .dashed-line{stroke-dasharray:3;}#mermaid-svg-24yK7n0cvFkVMwO6 .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-24yK7n0cvFkVMwO6 #compositionStart,#mermaid-svg-24yK7n0cvFkVMwO6 .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #compositionEnd,#mermaid-svg-24yK7n0cvFkVMwO6 .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #dependencyStart,#mermaid-svg-24yK7n0cvFkVMwO6 .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #dependencyStart,#mermaid-svg-24yK7n0cvFkVMwO6 .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #extensionStart,#mermaid-svg-24yK7n0cvFkVMwO6 .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #extensionEnd,#mermaid-svg-24yK7n0cvFkVMwO6 .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #aggregationStart,#mermaid-svg-24yK7n0cvFkVMwO6 .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #aggregationEnd,#mermaid-svg-24yK7n0cvFkVMwO6 .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #lollipopStart,#mermaid-svg-24yK7n0cvFkVMwO6 .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 #lollipopEnd,#mermaid-svg-24yK7n0cvFkVMwO6 .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-24yK7n0cvFkVMwO6 .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-24yK7n0cvFkVMwO6 .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-24yK7n0cvFkVMwO6 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-24yK7n0cvFkVMwO6 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-24yK7n0cvFkVMwO6 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
FixmapManager
+__set_fixmap()
+__clear_fixmap()
+set_fixmap_offset()
+fixmap_page_set_flags()
KmapManager
+kmap()
+kunmap()
+kmap_atomic()
+kunmap_atomic()
TempMapManager
+kmap_local_page()
+kunmap_local()
+page_address()
+kmap_flush_unused()
FixmapAllocator
+__fix_to_virt()
+__virt_to_fix()
+fixmap_space_start()
+fixmap_space_end()
PageTableHandler
+set_pte_at()
+pte_clear()
+flush_tlb_kernel_range()
+update_mmu_cache()
MemoryBarrierManager
+dsb()
+isb()
+__flush_dcache_area()
+__invalidate_icache_area()
DebugSupport
+debug_fixmap_alloc()
+validate_fixmap_usage()
+monitor_fixmap_performance()
+log_fixmap_operations()
SecurityValidator
+validate_fixmap_access()
+check_fixmap_permissions()
+audit_fixmap_operations()
+prevent_fixmap_attacks()
5. 源码深度分析
5.1 ARM64固定映射架构分析
5.1.1 固定映射核心实现
固定映射的核心实现:
// 固定映射区域定义
#define FIXADDR_TOP ((unsigned long)(–PAGE_SIZE))
#ifdef CONFIG_ARM64_4K_PAGES
#define FIXADDR_SIZE PGDIR_SIZE
#else
#define FIXADDR_SIZE (PGDIR_SIZE * 2)
#endif
#define FIXADDR_START (FIXADDR_TOP – FIXADDR_SIZE)
// 固定映射索引枚举
enum fixed_addresses {
FIX_HOLE,
FIX_VVAR_PAGE,
FIX_TEXT_POKE1,
FIX_TEXT_POKE0,
FIX_KMAP_BEGIN,
FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) – 1,
__end_of_fixed_addresses
};
// 设置固定映射
void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
{
unsigned long addr = __fix_to_virt(idx);
pte_t *pte;
// 检查索引有效性
if (idx >= __end_of_fixed_addresses) {
BUG();
return;
}
// 获取PTE
pte = virt_to_kpte(addr);
if (!pte) {
BUG();
return;
}
// 设置PTE
set_pte_at(&init_mm, addr, pte, pfn_pte(phys >> PAGE_SHIFT, prot));
// 刷新TLB
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
}
// 清除固定映射
void __clear_fixmap(enum fixed_addresses idx)
{
unsigned long addr = __fix_to_virt(idx);
pte_t *pte;
// 获取PTE
pte = virt_to_kpte(addr);
if (!pte) {
BUG();
return;
}
// 清除PTE
pte_clear(&init_mm, addr, pte);
// 刷新TLB
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
}
// 虚拟地址到固定索引转换
unsigned long __virt_to_fix(unsigned long vaddr)
{
// 检查地址范围
if (vaddr >= FIXADDR_START && vaddr < FIXADDR_TOP) {
return (vaddr – FIXADDR_START) / PAGE_SIZE;
}
return FIX_HOLE;
}
// 固定索引到虚拟地址转换
void *__fix_to_virt(const unsigned int idx)
{
// 检查索引范围
if (idx >= __end_of_fixed_addresses)
BUG();
return (void *)(FIXADDR_START + (idx * PAGE_SIZE));
}
// 设置固定映射偏移
void set_fixmap_offset(enum fixed_addresses idx, phys_addr_t phys)
{
__set_fixmap(idx, phys, PAGE_KERNEL);
}
// 设置固定映射页面标志
void fixmap_page_set_flags(unsigned long vaddr, pgprot_t prot)
{
unsigned long idx = __virt_to_fix(vaddr);
phys_addr_t phys;
pte_t *pte;
// 获取当前物理地址
pte = virt_to_kpte(vaddr);
if (!pte || !pte_present(*pte))
return;
phys = pte_pfn(*pte) << PAGE_SHIFT;
// 重新设置映射
__set_fixmap(idx, phys, prot);
}
固定映射特点:
1. 编译时确定:地址在编译时确定,运行时固定 2. 索引管理:通过枚举索引管理固定映射 3. 页表操作:直接操作页表条目设置映射 4. TLB刷新:映射更改后的TLB一致性维护
5.1.2 kmap原子映射实现
kmap原子映射的核心实现:
// kmap原子映射
void *kmap_atomic(struct page *page)
{
unsigned int idx;
enum km_type type;
void *vaddr;
// 预取页面
prefetch_page(page);
// 获取映射类型
type = kmap_get_atomic_type();
if (type == KM_TYPE_NR)
return NULL;
// 分配映射槽
idx = kmap_atomic_idx_push();
// 计算虚拟地址
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx + (type * NR_CPUS));
// 建立映射
__kmap_atomic_set(page, vaddr);
return vaddr;
}
// kmap原子解除映射
void kunmap_atomic(void *vaddr)
{
unsigned long idx;
// 检查地址范围
if (vaddr < (void *)FIXADDR_START || vaddr >= (void *)FIXADDR_TOP)
return;
// 计算索引
idx = __virt_to_fix((unsigned long)vaddr);
if (idx < FIX_KMAP_BEGIN || idx >= FIX_KMAP_END)
return;
// 清除映射
__kunmap_atomic_clear(vaddr);
// 释放映射槽
kmap_atomic_idx_pop();
}
// 设置原子映射
static void __kmap_atomic_set(struct page *page, void *vaddr)
{
phys_addr_t phys = page_to_phys(page);
pgprot_t prot = kmap_prot;
// 设置固定映射
__set_fixmap(__virt_to_fix((unsigned long)vaddr), phys, prot);
}
// 清除原子映射
static void __kunmap_atomic_clear(void *vaddr)
{
// 清除固定映射
__clear_fixmap(__virt_to_fix((unsigned long)vaddr));
}
// 获取原子映射类型
static enum km_type kmap_get_atomic_type(void)
{
enum km_type type;
// 确定映射类型
if (in_nmi())
type = KM_NMI;
else if (in_hardirq())
type = KM_IRQ0;
else if (in_softirq())
type = KM_SOFTIRQ0;
else
type = KM_USER0;
return type;
}
// 原子映射索引管理
static unsigned int kmap_atomic_idx(void)
{
unsigned int idx = __this_cpu_read(kmap_atomic_idx);
return idx;
}
static unsigned int kmap_atomic_idx_push(void)
{
unsigned int idx = __this_cpu_inc_return(kmap_atomic_idx) – 1;
// 检查索引溢出
if (unlikely(idx >= KM_TYPE_NR)) {
__this_cpu_write(kmap_atomic_idx, 0);
BUG();
}
return idx;
}
static void kmap_atomic_idx_pop(void)
{
unsigned int idx = __this_cpu_dec_return(kmap_atomic_idx);
// 检查索引下溢
if (unlikely(idx >= KM_TYPE_NR)) {
__this_cpu_write(kmap_atomic_idx, KM_TYPE_NR – 1);
BUG();
}
}
kmap原子映射特点:
1. 原子操作:不可抢占的映射操作 2. 类型区分:根据上下文区分映射类型 3. 槽位管理:CPU本地的映射槽位管理 4. 快速映射:编译时预留的快速映射区域
5.2 临时映射和高端内存管理分析
5.2.1 临时映射实现
临时映射的核心实现:
// 本地页面映射
void *kmap_local_page(struct page *page)
{
unsigned long vaddr;
pte_t *pte;
phys_addr_t phys = page_to_phys(page);
// 预取页面
prefetch_page(page);
// 获取本地映射地址
vaddr = __kmap_local_pfn_prot(phys >> PAGE_SHIFT, kmap_prot);
// 验证映射
if (!vaddr)
return NULL;
// 获取PTE进行验证
pte = virt_to_kpte(vaddr);
if (pte && pte_present(*pte)) {
return (void *)vaddr;
}
return NULL;
}
// 解除本地页面映射
void kunmap_local(void *vaddr)
{
// 检查地址范围
if (vaddr < (void *)FIXADDR_START || vaddr >= (void *)FIXADDR_TOP)
return;
// 清除本地映射
__kunmap_local(vaddr);
}
// 页面地址获取
void *page_address(struct page *page)
{
unsigned long pfn = page_to_pfn(page);
// 检查是否为低端内存
if (pfn_valid(pfn) && pfn < max_low_pfn) {
return __va(PFN_PHYS(pfn));
}
// 检查是否为高端内存
if (pfn_valid(pfn)) {
return __kmap_local_pfn_prot(pfn, kmap_prot);
}
return NULL;
}
// 刷新未使用的kmap
void kmap_flush_unused(void)
{
unsigned int type;
unsigned int idx;
// 遍历所有类型
for (type = 0; type < KM_TYPE_NR; type++) {
// 遍历所有CPU
for_each_possible_cpu(idx) {
unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN +
idx + (type * NR_CPUS));
// 检查是否需要刷新
if (kmap_unused_idx_check(idx, type)) {
// 清除未使用的映射
__clear_fixmap(__virt_to_fix(vaddr));
kmap_unused_idx_clear(idx, type);
}
}
}
}
// 本地PFN映射保护
void __iomem *kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot)
{
return __kmap_local_pfn_prot(pfn, prot);
}
// 内核本地PFN映射
void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot)
{
// 检查PFN有效性
if (!pfn_valid(pfn))
return NULL;
// 获取本地映射地址
return __fix_to_virt(FIX_KMAP_BEGIN + kmap_local_idx_push());
}
// 本地映射索引管理
static unsigned int kmap_local_idx_push(void)
{
unsigned int idx = __this_cpu_inc_return(kmap_local_idx) – 1;
// 检查索引范围
if (unlikely(idx >= KM_TYPE_NR * NR_CPUS)) {
__this_cpu_write(kmap_local_idx, 0);
idx = 0;
}
return idx;
}
static void kmap_local_idx_pop(void)
{
unsigned int idx = __this_cpu_dec_return(kmap_local_idx);
// 检查索引范围
if (unlikely(idx >= KM_TYPE_NR * NR_CPUS)) {
__this_cpu_write(kmap_local_idx, KM_TYPE_NR * NR_CPUS – 1);
}
}
临时映射特点:
1. 本地映射:CPU本地的临时映射 2. 栈保护:映射在内核栈上保护 3. 自动管理:映射的自动分配和释放 4. 并发安全:支持并发访问的安全机制
5.2.2 高端内存映射处理
高端内存映射的处理:
// 高端内存页面地址
void *page_address_high(struct page *page)
{
unsigned long pfn = page_to_pfn(page);
// 检查是否为高端内存
if (pfn >= max_low_pfn) {
// 使用临时映射
return kmap_local_page(page);
}
return NULL;
}
// 高端内存访问优化
void *kmap_high(struct page *page)
{
// 检查页面状态
if (PageHighMem(page)) {
return kmap_local_page(page);
}
// 低端内存直接访问
return page_address(page);
}
// 解除高端内存映射
void kunmap_high(struct page *page)
{
// 检查页面状态
if (PageHighMem(page)) {
kunmap_local(page_address(page));
}
}
// 高端内存统计
void kmap_flush_unused_high(void)
{
// 刷新未使用的高端内存映射
kmap_flush_unused();
}
// 高端内存页面验证
bool page_is_highmem(struct page *page)
{
unsigned long pfn = page_to_pfn(page);
// 检查PFN是否在高端内存范围内
return pfn >= max_low_pfn;
}
// 高端内存范围检查
bool addr_is_highmem(unsigned long addr)
{
// 检查地址是否在高端内存映射区域
return addr >= PKMAP_BASE && addr < PKMAP_BASE + (LAST_PKMAP * PAGE_SIZE);
}
高端内存特点:
1. 64位支持:支持64位地址空间的高端内存 2. 动态映射:运行时的动态映射管理 3. 访问优化:针对高端内存的访问优化 4. 资源管理:高端内存映射资源的有效管理
5.3 安全性和性能优化分析
5.3.1 固定映射安全验证
固定映射的安全验证:
// 固定映射访问验证
int validate_fixmap_access(unsigned long addr, unsigned long size, unsigned long flags)
{
// 验证地址范围
if (!is_fixmap_addr(addr))
return –EINVAL;
// 检查访问权限
if (!check_fixmap_permissions(addr, flags))
return –EACCES;
// 验证映射状态
if (!validate_fixmap_state(addr))
return –EFAULT;
// 安全检查
if (!security_check_fixmap(addr, size, flags))
return –EPERM;
return 0;
}
// 固定映射地址检查
static bool is_fixmap_addr(unsigned long addr)
{
return addr >= FIXADDR_START && addr < FIXADDR_TOP;
}
// 权限检查
static bool check_fixmap_permissions(unsigned long addr, unsigned long flags)
{
// 检查内核访问权限
if (addr >= TASK_SIZE && !capable(CAP_SYS_RAWIO))
return false;
// 检查固定映射特权
if (!has_fixmap_privilege(addr, flags))
return false;
return true;
}
// 映射状态验证
static bool validate_fixmap_state(unsigned long addr)
{
unsigned long idx = __virt_to_fix(addr);
pte_t *pte;
// 检查索引有效性
if (idx >= __end_of_fixed_addresses)
return false;
// 检查PTE存在
pte = virt_to_kpte(addr);
if (!pte || !pte_present(*pte))
return false;
return true;
}
// 安全检查
static bool security_check_fixmap(unsigned long addr, unsigned long size, unsigned long flags)
{
// 检查是否访问敏感区域
if (is_sensitive_fixmap_addr(addr))
return false;
// 检查访问模式
if (!validate_access_pattern(addr, size, flags))
return false;
// 审计记录
audit_fixmap_access(addr, size, flags);
return true;
}
安全验证特点:
1. 地址验证:严格的固定映射地址验证 2. 权限控制:基于能力的访问权限控制 3. 状态检查:映射状态的完整性验证 4. 安全审计:固定映射访问的审计跟踪
5.3.2 性能优化策略
固定映射的性能优化:
// 固定映射缓存优化
struct fixmap_cache {
unsigned long vaddr;
phys_addr_t paddr;
pgprot_t prot;
unsigned long access_time;
bool valid;
};
// 缓存查找
phys_addr_t fixmap_cache_lookup(unsigned long vaddr)
{
struct fixmap_cache *cache = this_cpu_ptr(&fixmap_cache);
if (cache->valid && cache->vaddr == vaddr) {
cache->access_time = jiffies;
return cache->paddr;
}
return PHYS_ADDR_INVALID;
}
// 缓存存储
void fixmap_cache_store(unsigned long vaddr, phys_addr_t paddr, pgprot_t prot)
{
struct fixmap_cache *cache = this_cpu_ptr(&fixmap_cache);
cache->vaddr = vaddr;
cache->paddr = paddr;
cache->prot = prot;
cache->access_time = jiffies;
cache->valid = true;
}
// kmap预取优化
void kmap_prefetch_optimization(struct page *page)
{
// 预取页面内容
prefetch_page(page);
// 预取映射相关的页表
prefetch_fixmap_pagetable();
// 预取TLB条目
prefetch_tlb_entry();
}
// 批量kmap优化
int kmap_pages_bulk(struct page **pages, void **vaddrs, int count)
{
int i;
int success_count = 0;
// 预分配映射槽
if (!reserve_kmap_slots(count))
return 0;
// 批量映射
for (i = 0; i < count; i++) {
vaddrs[i] = kmap_atomic(pages[i]);
if (vaddrs[i]) {
success_count++;
} else {
break;
}
}
// 如果失败,回滚已映射的
if (success_count < count) {
for (i = 0; i < success_count; i++) {
kunmap_atomic(vaddrs[i]);
}
release_kmap_slots(success_count);
return 0;
}
return success_count;
}
// 并发优化
void fixmap_concurrency_optimization(void)
{
// 使用CPU本地缓存
enable_per_cpu_fixmap_cache();
// 优化自旋锁
optimize_fixmap_spinlocks();
// 减少原子操作
minimize_atomic_fixmap_ops();
}
// 内存屏障优化
void fixmap_barrier_optimization(unsigned long addr, size_t size)
{
// 根据操作类型选择屏障
if (is_write_operation(addr)) {
// 写操作需要较强的屏障
dsb(ishst);
} else {
// 读操作可以使用较弱的屏障
dsb(ishld);
}
// 指令同步
isb();
}
性能优化特点:
1. 缓存机制:固定映射的CPU本地缓存 2. 预取优化:内存访问的预取机制 3. 批量处理:多个映射的批量操作 4. 并发优化:减少锁竞争和原子操作
6. 设计模式分析
6.1 单例模式在固定映射管理中的体现
固定映射管理的单例模式:
// 固定映射管理器单例类
class FixmapManagerSingleton {
private static FixmapManagerSingleton instance;
private Map<enum fixed_addresses, FixmapEntry> fixmapTable;
private Lock fixmapLock;
private AtomicInteger[] kmapSlots;
private FixmapManagerSingleton() {
fixmapTable = new ConcurrentHashMap<>();
fixmapLock = new ReentrantLock();
kmapSlots = new AtomicInteger[KM_TYPE_NR * NR_CPUS];
initializeFixmapTable();
}
public static FixmapManagerSingleton getInstance() {
if (instance == null) {
synchronized(FixmapManagerSingleton.class) {
if (instance == null) {
instance = new FixmapManagerSingleton();
}
}
}
return instance;
}
public void* setFixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot) {
fixmapLock.lock();
try {
// 检查索引有效性
if (!isValidFixmapIndex(idx)) {
throw new IllegalArgumentException("Invalid fixmap index");
}
// 计算虚拟地址
void* vaddr = __fix_to_virt(idx);
// 设置页表
setPageTableEntry(vaddr, phys, prot);
// 更新缓存
updateFixmapCache(idx, vaddr, phys, prot);
return vaddr;
} finally {
fixmapLock.unlock();
}
}
public void clearFixmap(enum fixed_addresses idx) {
fixmapLock.lock();
try {
void* vaddr = __fix_to_virt(idx);
clearPageTableEntry(vaddr);
removeFixmapCache(idx);
} finally {
fixmapLock.unlock();
}
}
public void* kmapAtomic(struct page* page) {
// 获取当前CPU的映射槽
int cpu = getCurrentCpu();
int slot = allocateKmapSlot(cpu);
if (slot == –1) {
return null;
}
// 计算虚拟地址
void* vaddr = calculateKmapVaddr(cpu, slot);
// 建立映射
establishKmapMapping(page, vaddr);
return vaddr;
}
public void kunmapAtomic(void* vaddr) {
int cpu = getCurrentCpu();
int slot = calculateKmapSlot(vaddr);
freeKmapSlot(cpu, slot);
clearKmapMapping(vaddr);
}
private void initializeFixmapTable() {
// 初始化固定映射表
for (enum fixed_addresses idx : enum fixed_addresses.values()) {
fixmapTable.put(idx, new FixmapEntry(idx));
}
}
private boolean isValidFixmapIndex(enum fixed_addresses idx) {
return idx.ordinal() < __end_of_fixed_addresses;
}
private void setPageTableEntry(void* vaddr, phys_addr_t phys, pgprot_t prot) {
// 实现页表设置逻辑
__set_fixmap(virt_to_fix(vaddr), phys, prot);
}
private void clearPageTableEntry(void* vaddr) {
// 实现页表清除逻辑
__clear_fixmap(virt_to_fix(vaddr));
}
private int allocateKmapSlot(int cpu) {
// 分配kmap槽位
for (int i = 0; i < KM_TYPE_NR; i++) {
if (kmapSlots[cpu * KM_TYPE_NR + i].get() == 0) {
if (kmapSlots[cpu * KM_TYPE_NR + i].compareAndSet(0, 1)) {
return i;
}
}
}
return –1;
}
private void freeKmapSlot(int cpu, int slot) {
kmapSlots[cpu * KM_TYPE_NR + slot].set(0);
}
}
// 使用单例模式
class MemoryMappingSystem {
private FixmapManagerSingleton fixmapManager;
public MemoryMappingSystem() {
fixmapManager = FixmapManagerSingleton.getInstance();
}
public void* mapFixedAddress(enum fixed_addresses idx, phys_addr_t phys) {
return fixmapManager.setFixmap(idx, phys, PAGE_KERNEL);
}
public void* mapPageAtomically(struct page* page) {
return fixmapManager.kmapAtomic(page);
}
public void unmapPageAtomically(void* vaddr) {
fixmapManager.kunmapAtomic(vaddr);
}
}
6.2 策略模式在映射策略选择中的体现
映射策略选择的策略模式:
// 映射策略接口
interface MappingStrategy {
void* mapAddress(Object target, MappingContext context);
void unmapAddress(void* vaddr, MappingContext context);
boolean canHandle(Object target, MappingContext context);
String getStrategyName();
long getMappingLatency();
int getConcurrencyLevel();
}
// 固定映射策略
class FixedMappingStrategy implements MappingStrategy {
public void* mapAddress(Object target, MappingContext context) {
enum fixed_addresses idx = (enum fixed_addresses) target;
phys_addr_t phys = context.getPhysicalAddress();
pgprot_t prot = context.getProtection();
return __set_fixmap(idx, phys, prot);
}
public void unmapAddress(void* vaddr, MappingContext context) {
enum fixed_addresses idx = __virt_to_fix((unsigned long)vaddr);
__clear_fixmap(idx);
}
public boolean canHandle(Object target, MappingContext context) {
return target instanceof enum fixed_addresses;
}
public String getStrategyName() {
return "FIXED_MAPPING_STRATEGY";
}
public long getMappingLatency() {
return 50; // 较低延迟,编译时确定
}
public int getConcurrencyLevel() {
return 1; // 串行访问
}
}
// kmap原子映射策略
class KmapAtomicStrategy implements MappingStrategy {
public void* mapAddress(Object target, MappingContext context) {
struct page* page = (struct page*) target;
return kmap_atomic(page);
}
public void unmapAddress(void* vaddr, MappingContext context) {
kunmap_atomic(vaddr);
}
public boolean canHandle(Object target, MappingContext context) {
return target instanceof struct page && context.isAtomic();
}
public String getStrategyName() {
return "KMAP_ATOMIC_STRATEGY";
}
public long getMappingLatency() {
return 100; // 中等延迟,运行时分配
}
public int getConcurrencyLevel() {
return KM_TYPE_NR; // 支持多种类型
}
}
// kmap本地映射策略
class KmapLocalStrategy implements MappingStrategy {
public void* mapAddress(Object target, MappingContext context) {
struct page* page = (struct page*) target;
return kmap_local_page(page);
}
public void unmapAddress(void* vaddr, MappingContext context) {
kunmap_local(vaddr);
}
public boolean canHandle(Object target, MappingContext context) {
return target instanceof struct page && !context.isAtomic();
}
public String getStrategyName() {
return "KMAP_LOCAL_STRATEGY";
}
public long getMappingLatency() {
return 75; // 较低延迟,本地映射
}
public int getConcurrencyLevel() {
return NR_CPUS; // CPU本地
}
}
// 自适应映射策略
class AdaptiveMappingStrategy implements MappingStrategy {
private List<MappingStrategy> strategies;
public AdaptiveMappingStrategy() {
strategies = Arrays.asList(
new FixedMappingStrategy(),
new KmapAtomicStrategy(),
new KmapLocalStrategy()
);
}
public void* mapAddress(Object target, MappingContext context) {
MappingStrategy bestStrategy = selectBestStrategy(target, context);
return bestStrategy.mapAddress(target, context);
}
public void unmapAddress(void* vaddr, MappingContext context) {
MappingStrategy bestStrategy = selectBestStrategyForUnmap(vaddr, context);
bestStrategy.unmapAddress(vaddr, context);
}
public boolean canHandle(Object target, MappingContext context) {
return strategies.stream().anyMatch(s -> s.canHandle(target, context));
}
public String getStrategyName() {
return "ADAPTIVE_MAPPING_STRATEGY";
}
public long getMappingLatency() {
return 60; // 平均延迟
}
public int getConcurrencyLevel() {
return Integer.MAX_VALUE; // 自适应并发
}
private MappingStrategy selectBestStrategy(Object target, MappingContext context) {
return strategies.stream()
.filter(s -> s.canHandle(target, context))
.min(Comparator.comparingLong(MappingStrategy::getMappingLatency))
.orElse(new KmapLocalStrategy());
}
private MappingStrategy selectBestStrategyForUnmap(void* vaddr, MappingContext context) {
// 根据地址类型确定解除映射策略
if (is_fixed_addr(vaddr)) {
return new FixedMappingStrategy();
} else if (context.isAtomic()) {
return new KmapAtomicStrategy();
} else {
return new KmapLocalStrategy();
}
}
}
// 策略选择器
class MappingStrategySelector {
public static MappingStrategy selectStrategy(MappingRequirements reqs) {
if (reqs.requiresAdaptiveMapping()) {
return new AdaptiveMappingStrategy();
} else if (reqs.isFixedMapping()) {
return new FixedMappingStrategy();
} else if (reqs.isAtomicMapping()) {
return new KmapAtomicStrategy();
} else {
return new KmapLocalStrategy();
}
}
}
6.3 观察者模式在映射监控中的体现
映射监控的观察者模式:
// 映射操作事件接口
interface MappingOperationEvent {
String getEventType();
long getTimestamp();
void* getVirtualAddress();
phys_addr_t getPhysicalAddress();
enum mapping_type getMappingType();
Map<String, Object> getEventData();
boolean isSuccessful();
long getOperationDuration();
}
// 映射操作事件
class MappingOperationEventImpl implements MappingOperationEvent {
private String eventType;
private long timestamp;
private void* vaddr;
private phys_addr_t paddr;
private enum mapping_type mappingType;
private Map<String, Object> eventData;
private boolean successful;
private long duration;
public MappingOperationEventImpl(String eventType, void* vaddr, phys_addr_t paddr,
enum mapping_type mappingType, boolean successful,
long duration, Map<String, Object> eventData) {
this.eventType = eventType;
this.timestamp = System.nanoTime();
this.vaddr = vaddr;
this.paddr = paddr;
this.mappingType = mappingType;
this.successful = successful;
this.duration = duration;
this.eventData = eventData != null ? eventData : new HashMap<>();
}
public String getEventType() {
return eventType;
}
public long getTimestamp() {
return timestamp;
}
public void* getVirtualAddress() {
return vaddr;
}
public phys_addr_t getPhysicalAddress() {
return paddr;
}
public enum mapping_type getMappingType() {
return mappingType;
}
public Map<String, Object> getEventData() {
return eventData;
}
public boolean isSuccessful() {
return successful;
}
public long getOperationDuration() {
return duration;
}
}
// 映射操作观察者接口
interface MappingOperationObserver {
void onMappingOperationEvent(MappingOperationEvent event);
Set<String> getInterestedEventTypes();
boolean isEnabled();
}
// 性能监控观察者
class MappingPerformanceObserver implements MappingOperationObserver {
private Map<String, Long> operationTimes = new HashMap<>();
private Map<String, Integer> operationCounts = new HashMap<>();
public void onMappingOperationEvent(MappingOperationEvent event) {
if (event.isSuccessful()) {
String opType = event.getMappingType().name();
// 记录操作时间
operationTimes.put(opType,
operationTimes.getOrDefault(opType, 0L) + event.getOperationDuration());
// 记录操作次数
operationCounts.put(opType,
operationCounts.getOrDefault(opType, 0) + 1);
}
}
public Set<String> getInterestedEventTypes() {
return new HashSet<>(Arrays.asList("MAPPING_OPERATION", "UNMAPPING_OPERATION"));
}
public boolean isEnabled() {
return true;
}
public double getAverageMappingTime(String mappingType) {
Long totalTime = operationTimes.get(mappingType);
Integer count = operationCounts.get(mappingType);
if (totalTime != null && count != null && count > 0) {
return totalTime.doubleValue() / count;
}
return 0.0;
}
}
// 安全监控观察者
class MappingSecurityObserver implements MappingOperationObserver {
private List<String> securityEvents = Collections.synchronizedList(new ArrayList<>());
public void onMappingOperationEvent(MappingOperationEvent event) {
// 检查潜在的安全问题
void* vaddr = event.getVirtualAddress();
phys_addr_t paddr = event.getPhysicalAddress();
enum mapping_type type = event.getMappingType();
// 检查映射到敏感区域
if (isSensitiveVirtualRegion(vaddr) && type != MAPPING_FIXED) {
logSecurityEvent("Mapping to sensitive virtual region: " + vaddr);
}
// 检查物理地址安全
if (!isSafePhysicalAddress(paddr)) {
logSecurityEvent("Mapping unsafe physical address: " + paddr);
}
// 检查映射类型一致性
if (!isConsistentMappingType(vaddr, paddr, type)) {
logSecurityEvent("Inconsistent mapping type for address: " + vaddr);
}
// 检查映射权限
if (!validateMappingPermissions(vaddr, type)) {
logSecurityEvent("Invalid mapping permissions for: " + vaddr);
}
}
public Set<String> getInterestedEventTypes() {
return new HashSet<>(Arrays.asList("*"));
}
public boolean isEnabled() {
return true;
}
private boolean isSensitiveVirtualRegion(void* vaddr) {
unsigned long addr = (unsigned long)vaddr;
return addr >= KERNEL_TEXT_START && addr < KERNEL_TEXT_END;
}
private boolean isSafePhysicalAddress(phys_addr_t paddr) {
return paddr != 0 && paddr < MAX_PHYS_ADDR;
}
private boolean isConsistentMappingType(void* vaddr, phys_addr_t paddr, enum mapping_type type) {
// 检查映射类型与地址范围的一致性
return true; // 简化的检查逻辑
}
private boolean validateMappingPermissions(void* vaddr, enum mapping_type type) {
// 验证映射权限
return true; // 简化的权限检查
}
private void logSecurityEvent(String event) {
securityEvents.add(event);
System.err.println("MAPPING SECURITY: " + event);
}
public List<String> getSecurityEvents() {
return new ArrayList<>(securityEvents);
}
}
// 资源使用观察者
class MappingResourceObserver implements MappingOperationObserver {
private AtomicLong activeMappings = new AtomicLong(0);
private Map<String, AtomicLong> mappingTypeCounts = new ConcurrentHashMap<>();
public void onMappingOperationEvent(MappingOperationEvent event) {
String eventType = event.getEventType();
String mappingType = event.getMappingType().name();
if ("MAPPING_OPERATION".equals(eventType) && event.isSuccessful()) {
activeMappings.incrementAndGet();
mappingTypeCounts.computeIfAbsent(mappingType, k -> new AtomicLong(0)).incrementAndGet();
} else if ("UNMAPPING_OPERATION".equals(eventType)) {
activeMappings.decrementAndGet();
AtomicLong typeCount = mappingTypeCounts.get(mappingType);
if (typeCount != null) {
typeCount.decrementAndGet();
}
}
}
public Set<String> getInterestedEventTypes() {
return new HashSet<>(Arrays.asList("MAPPING_OPERATION", "UNMAPPING_OPERATION"));
}
public boolean isEnabled() {
return true;
}
public long getActiveMappings() {
return activeMappings.get();
}
public long getMappingsByType(String type) {
AtomicLong count = mappingTypeCounts.get(type);
return count != null ? count.get() : 0;
}
}
// 映射监控器
class MappingOperationMonitor {
private List<MappingOperationObserver> observers = new CopyOnWriteArrayList<>();
private Executor notificationExecutor;
public MappingOperationMonitor() {
this.notificationExecutor = Executors.newSingleThreadExecutor();
}
public void addObserver(MappingOperationObserver observer) {
observers.add(observer);
}
public void removeObserver(MappingOperationObserver observer) {
observers.remove(observer);
}
public void notifyMappingOperationEvent(MappingOperationEvent event) {
notificationExecutor.submit(() -> {
for (MappingOperationObserver observer : observers) {
if (observer.isEnabled()) {
Set<String> interestedTypes = observer.getInterestedEventTypes();
if (interestedTypes.contains("*") ||
interestedTypes.contains(event.getEventType())) {
try {
observer.onMappingOperationEvent(event);
} catch (Exception e) {
logObserverError(observer, event, e);
}
}
}
}
});
}
public void mappingOperationPerformed(void* vaddr, phys_addr_t paddr, enum mapping_type type,
String operationType, boolean successful, long duration,
Map<String, Object> eventData) {
MappingOperationEvent event = new MappingOperationEventImpl(operationType, vaddr, paddr,
type, successful, duration, eventData);
notifyMappingOperationEvent(event);
}
public void shutdown() {
notificationExecutor.shutdown();
try {
if (!notificationExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
notificationExecutor.shutdownNow();
}
} catch (InterruptedException e) {
notificationExecutor.shutdownNow();
}
}
private void logObserverError(MappingOperationObserver observer, MappingOperationEvent event, Exception e) {
System.err.println("Mapping operation observer error: " + observer.getClass().getSimpleName() +
" failed to process event " + event.getEventType() + ": " + e.getMessage());
}
}
// 使用观察者模式
class MappingManagementSystem {
private MappingOperationMonitor monitor;
public MappingManagementSystem() {
this.monitor = new MappingOperationMonitor();
// 注册观察者
monitor.addObserver(new MappingPerformanceObserver());
monitor.addObserver(new MappingSecurityObserver());
monitor.addObserver(new MappingResourceObserver());
}
public void* setFixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot) {
long startTime = System.nanoTime();
// 执行固定映射
void* vaddr = __set_fixmap(idx, phys, prot);
long duration = System.nanoTime() – startTime;
// 通知映射事件
Map<String, Object> eventData = new HashMap<>();
eventData.put("index", idx);
monitor.mappingOperationPerformed(vaddr, phys, MAPPING_FIXED,
"SET_FIXMAP", vaddr != null, duration, eventData);
return vaddr;
}
public void* kmapAtomic(struct page* page) {
long startTime = System.nanoTime();
// 执行原子映射
void* vaddr = kmap_atomic(page);
long duration = System.nanoTime() – startTime;
// 通知映射事件
Map<String, Object> eventData = new HashMap<>();
eventData.put("page", page);
monitor.mappingOperationPerformed(vaddr, page_to_phys(page), MAPPING_KMAP,
"KMAP_ATOMIC", vaddr != null, duration, eventData);
return vaddr;
}
}
7. 状态机分析
ARM64 mm fixmap的状态机:
初始状态 -> 映射类型判断 -> 索引分配 -> 页表设置 -> TLB刷新 -> 映射激活
↑ ↓
地址验证 <———————————————————————————+
↑ ↓
权限检查 <———————————————————————————+
↑ ↓
安全审计 <———————————————————————————+
8. 性能优化分析
8.1 固定映射性能优化
固定映射的性能优化:
// 固定映射快速路径
void* fast_fixmap_access(enum fixed_addresses idx)
{
// 检查是否已缓存
if (fixmap_cache_valid[idx]) {
return fixmap_cache[idx];
}
// 慢速路径
return __fix_to_virt(idx);
}
// 批量固定映射设置
int set_fixmaps_bulk(struct fixmap_entry *entries, int count)
{
int i;
int success_count = 0;
// 开始批处理
start_fixmap_batch();
// 批量设置
for (i = 0; i < count; i++) {
if (set_fixmap_single(&entries[i]) == 0) {
success_count++;
} else {
break;
}
}
// 结束批处理
end_fixmap_batch();
// 如果失败,回滚
if (success_count < count) {
rollback_fixmaps(entries, success_count);
return –EFAULT;
}
return 0;
}
// kmap并发优化
void kmap_concurrency_optimize(void)
{
// 使用CPU本地存储
enable_kmap_percpu();
// 减少锁竞争
optimize_kmap_locks();
// 预分配映射槽
preallocate_kmap_slots();
}
// 预取优化
void fixmap_prefetch_optimize(unsigned long addr, size_t size)
{
// 预取页表条目
prefetch_pagetable_entries(addr, size);
// 预取固定映射区域
prefetch_fixmap_region(addr, size);
// 预取TLB
prefetch_tlb_entries(addr, size);
}
8.2 缓存一致性优化
缓存一致性的优化:
// 缓存一致性智能维护
void smart_cache_coherency(void *vaddr, size_t size, enum mapping_operation op)
{
// 分析访问模式
enum access_pattern pattern = analyze_access_pattern(vaddr, size);
switch (pattern) {
case ACCESS_SEQUENTIAL:
// 顺序访问优化
cache_coherency_sequential(vaddr, size, op);
break;
case ACCESS_RANDOM:
// 随机访问优化
cache_coherency_random(vaddr, size, op);
break;
case ACCESS_STRIDED:
// 跨步访问优化
cache_coherency_strided(vaddr, size, op);
break;
default:
// 默认一致性维护
default_cache_coherency(vaddr, size, op);
break;
}
}
// TLB刷新优化
void optimized_tlb_flush(void *vaddr, size_t size)
{
// 检查是否需要全局刷新
if (size > TLB_FLUSH_THRESHOLD) {
flush_tlb_all();
} else {
flush_tlb_kernel_range((unsigned long)vaddr,
(unsigned long)vaddr + size);
}
}
// 内存屏障选择优化
void select_memory_barrier(enum mapping_operation op, enum access_type type)
{
switch (op) {
case MAPPING_SET:
// 设置映射的屏障
if (type == ACCESS_WRITE) {
dsb(ishst); // 存储屏障
} else {
dsb(ish); // 一般屏障
}
break;
case MAPPING_CLEAR:
// 清除映射的屏障
dsb(ish);
break;
case MAPPING_UPDATE:
// 更新映射的屏障
dsb(ish);
isb(); // 指令同步
break;
}
}
9. 安全性考虑
9.1 映射访问控制
映射访问的安全控制:
// 映射访问权限验证
int validate_mapping_access(void *vaddr, size_t size, unsigned long flags)
{
// 验证地址类型
if (!validate_addr_type(vaddr))
return –EINVAL;
// 检查访问权限
if (!check_access_permissions(vaddr, flags))
return –EACCES;
// 验证映射状态
if (!validate_mapping_state(vaddr))
return –EFAULT;
// 安全边界检查
if (!check_security_boundaries(vaddr, size))
return –EPERM;
return 0;
}
// 地址类型验证
static bool validate_addr_type(void *vaddr)
{
unsigned long addr = (unsigned long)vaddr;
// 检查是否为固定映射地址
if (addr >= FIXADDR_START && addr < FIXADDR_TOP)
return true;
// 检查是否为kmap地址
if (is_kmap_addr(addr))
return true;
return false;
}
// 访问权限检查
static bool check_access_permissions(void *vaddr, unsigned long flags)
{
// 检查内核访问权限
if (!capable(CAP_SYS_RAWIO))
return false;
// 检查映射特权
if (!has_mapping_privilege(vaddr, flags))
return false;
return true;
}
// 映射状态验证
static bool validate_mapping_state(void *vaddr)
{
unsigned long addr = (unsigned long)vaddr;
// 检查PTE是否存在
pte_t *pte = virt_to_kpte(addr);
if (!pte || !pte_present(*pte))
return false;
// 检查映射权限
if (!pte_access_permitted(*pte))
return false;
return true;
}
// 安全边界检查
static bool check_security_boundaries(void *vaddr, size_t size)
{
// 检查是否跨越安全区域边界
if (crosses_security_region(vaddr, size))
return false;
// 检查是否访问敏感数据
if (accesses_sensitive_data(vaddr, size))
return false;
return true;
}
9.2 映射完整性保护
映射完整性的保护:
// 映射完整性验证
int verify_mapping_integrity(void *vaddr, phys_addr_t expected_phys)
{
phys_addr_t actual_phys = __virt_to_phys((unsigned long)vaddr);
// 比较物理地址
if (actual_phys != expected_phys) {
// 记录完整性错误
log_integrity_error(vaddr, expected_phys, actual_phys);
return –EFAULT;
}
// 验证页表一致性
if (!verify_pagetable_consistency(vaddr)) {
return –EFAULT;
}
// 验证TLB一致性
if (!verify_tlb_consistency(vaddr)) {
return –EFAULT;
}
return 0;
}
// 页表一致性验证
static bool verify_pagetable_consistency(void *vaddr)
{
unsigned long addr = (unsigned long)vaddr;
pte_t *pte = virt_to_kpte(addr);
if (!pte)
return false;
// 检查PTE标记
if (!pte_present(*pte))
return false;
// 检查权限一致性
if (!pte_flags_consistent(*pte))
return false;
return true;
}
// 映射攻击防护
void prevent_mapping_attacks(void)
{
// 随机化固定映射位置
randomize_fixmap_locations();
// 启用映射访问审计
enable_mapping_audit();
// 设置映射访问限制
setup_mapping_access_limits();
// 监控异常映射模式
monitor_suspicious_mappings();
}
// 映射访问审计
void audit_mapping_access(void *vaddr, size_t size, unsigned long flags)
{
// 记录审计信息
audit_log(AUDIT_MAPPING_ACCESS, current->pid,
(unsigned long)vaddr, size, flags);
}
10. 扩展性分析
10.1 多架构支持
跨架构的固定映射扩展:
// 架构特定的固定映射接口
struct arch_fixmap_ops {
const char *arch_name;
// 固定映射操作
void (*set_fixmap)(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot);
void (*clear_fixmap)(enum fixed_addresses idx);
void *(*__fix_to_virt)(const unsigned int idx);
unsigned long (*__virt_to_fix)(unsigned long vaddr);
// kmap操作
void *(*kmap_atomic)(struct page *page);
void (*kunmap_atomic)(void *vaddr);
void *(*kmap_local_page)(struct page *page);
void (*kunmap_local)(void *vaddr);
// 地址空间定义
unsigned long (*fixmap_start)(void);
unsigned long (*fixmap_end)(void);
unsigned long (*fixmap_size)(void);
};
// ARM64固定映射操作实现
static const struct arch_fixmap_ops arm64_fixmap_ops = {
.arch_name = "arm64",
.set_fixmap = arm64_set_fixmap,
.clear_fixmap = arm64_clear_fixmap,
.__fix_to_virt = arm64__fix_to_virt,
.__virt_to_fix = arm64__virt_to_fix,
.kmap_atomic = arm64_kmap_atomic,
.kunmap_atomic = arm64_kunmap_atomic,
.kmap_local_page = arm64_kmap_local_page,
.kunmap_local = arm64_kunmap_local,
.fixmap_start = arm64_fixmap_start,
.fixmap_end = arm64_fixmap_end,
.fixmap_size = arm64_fixmap_size,
};
// 运行时架构选择
static const struct arch_fixmap_ops *select_arch_fixmap_ops(void)
{
#ifdef CONFIG_ARM64
return &arm64_fixmap_ops;
#else
return NULL;
#endif
}
10.2 功能扩展
固定映射功能扩展:
// 高级固定映射功能扩展
struct advanced_fixmap_features {
bool support_dynamic_fixmap; // 支持动态固定映射
bool support_secure_fixmap; // 支持安全固定映射
bool support_fixmap_caching; // 支持固定映射缓存
bool support_bulk_fixmap_ops; // 支持批量固定映射操作
bool support_fixmap_monitoring; // 支持固定映射监控
bool support_fixmap_auditing; // 支持固定映射审计
};
// 固定映射扩展API
struct extended_fixmap_api {
// 动态固定映射支持
int (*alloc_dynamic_fixmap)(phys_addr_t phys, pgprot_t prot);
int (*free_dynamic_fixmap)(void *vaddr);
int (*query_dynamic_fixmap)(void *vaddr, struct fixmap_info *info);
// 安全固定映射支持
int (*set_secure_fixmap)(enum fixed_addresses idx, phys_addr_t phys,
struct security_context *ctx);
int (*validate_secure_fixmap)(enum fixed_addresses idx);
int (*audit_secure_fixmap_access)(enum fixed_addresses idx);
// 固定映射缓存支持
int (*enable_fixmap_caching)(void);
int (*disable_fixmap_caching)(void);
int (*flush_fixmap_cache)(void);
int (*query_fixmap_cache_stats)(struct cache_stats *stats);
// 批量操作支持
int (*set_fixmaps_bulk)(struct fixmap_entry *entries, int count);
int (*clear_fixmaps_bulk)(enum fixed_addresses *indices, int count);
int (*query_fixmaps_bulk)(enum fixed_addresses *indices,
struct fixmap_info *infos, int count);
// 监控和审计支持
int (*enable_fixmap_monitoring)(struct monitor_config *config);
int (*disable_fixmap_monitoring)(void);
int (*get_fixmap_monitor_report)(struct monitor_report *report);
int (*audit_fixmap_operations)(struct audit_context *ctx);
};
11. 调试和维护
11.1 固定映射调试支持
固定映射调试支持:
// 固定映射调试宏
#define FIXMAP_DEBUG(fmt, ...) \\
pr_debug("FIXMAP: " fmt, ##__VA_ARGS__)
#define FIXMAP_DEBUG_SET(idx, phys) \\
FIXMAP_DEBUG("setting fixmap %d to %pa\\n", idx, &phys)
#define FIXMAP_DEBUG_KMAP(page, vaddr) \\
FIXMAP_DEBUG("kmapping page %p to %p\\n", page, vaddr)
// 详细调试模式
#ifdef CONFIG_FIXMAP_DEBUG
static void fixmap_debug_operation(enum fixed_addresses idx, phys_addr_t phys,
const char *op_type)
{
FIXMAP_DEBUG("=== FIXMAP DEBUG ===");
FIXMAP_DEBUG("Operation: %s", op_type);
FIXMAP_DEBUG("Index: %d", idx);
FIXMAP_DEBUG("Physical: %pa", &phys);
FIXMAP_DEBUG("Virtual: %p", __fix_to_virt(idx));
// 调试页表状态
debug_pagetable_state(__fix_to_virt(idx));
// 调试TLB状态
debug_tlb_state(__fix_to_virt(idx));
FIXMAP_DEBUG("=== END FIXMAP DEBUG ===");
}
#endif
11.2 错误检测和恢复
固定映射错误处理:
// 固定映射错误检测
int detect_fixmap_errors(enum fixed_addresses idx, phys_addr_t phys)
{
void *vaddr = __fix_to_virt(idx);
// 检查地址有效性
if (!virt_addr_valid(vaddr))
return –EINVAL;
// 验证映射一致性
if (!verify_fixmap_consistency(idx, phys))
return –EFAULT;
// 检查页表状态
if (!validate_pagetable_state(vaddr))
return –EFAULT;
return 0;
}
// 错误恢复机制
int recover_fixmap_error(enum fixed_addresses idx, phys_addr_t phys, int error)
{
FIXMAP_DEBUG("Attempting fixmap error recovery: %d\\n", error);
switch (error) {
case –EINVAL:
// 地址错误:验证索引范围
return validate_fixmap_index(idx);
case –EFAULT:
// 映射错误:重新建立映射
return recreate_fixmap_mapping(idx, phys);
default:
FIXMAP_DEBUG("Unrecoverable fixmap error\\n");
return error;
}
}
// 映射一致性验证
static bool verify_fixmap_consistency(enum fixed_addresses idx, phys_addr_t expected_phys)
{
void *vaddr = __fix_to_virt(idx);
phys_addr_t actual_phys = __virt_to_phys((unsigned long)vaddr);
return actual_phys == expected_phys;
}
// 页表状态验证
static bool validate_pagetable_state(void *vaddr)
{
pte_t *pte = virt_to_kpte((unsigned long)vaddr);
if (!pte)
return false;
// 检查PTE存在
if (!pte_present(*pte))
return false;
// 检查权限
if (!pte_access_permitted(*pte))
return false;
return true;
}
12. 总结
ARM64 mm fixmap子模块作为ARM64内存管理子系统中固定映射管理的核心组件,通过完整的编译时固定映射、kmap原子映射和临时映射功能,为ARM64平台提供了稳定高效的固定地址访问。该模块实现了固定地址的静态分配、运行时的动态映射、页表的一致性维护等高级特性,在保证映射稳定性的同时提供了灵活的临时访问接口。源码分析显示,模块采用了单例模式、策略模式和观察者模式等多种设计模式,为固定映射管理提供了灵活可靠的实现框架。



