WinCE6.0学习之EBoot源码分析----startup.s(五)

简介:
               ; Comment: 
                ; The following loop is to direct map RAM VA == PA. i.e. 
                ;     VA == 0x50XXXXXX => PA == 0x50XXXXXX for S3C6410 
                ; Fill in 8 entries to have a direct mapping for DRAM 

                ldr                    r10, =PT_1ST_BASE                    ; Restore address of 1st level page table 
                ldr                    r0,    =DRAM_BASE_PA_START
这部分开始建立虚拟地址到相等的物理地址的映射,因为是S3C6410,所以是0x50000000,如果是2410,则为0x30000000。首先将R10指向页表首地址(验证了前面那句减去0x30000000语句是没用的),R0存储的是0x50000000,既可以当做物理地址操作,也可以当做虚拟地址操作(因为是相等的地址映射)。
                add                    r10, r10, #PTR_1ST_PTE         ; (r10) = ptr to 1st PTE for 0x50000000
    这条语句用来计算虚拟地址 0x50000000 对应的页表的存储地址,并赋值给 R10 PTR_1ST_PTE 在文件最开始处已经进行了定义,其实定义相当于将 0x50000000>>18 ,用高 14 位计算相对于页表基地址的偏移量。
                add                    r0, r0, #0x1E                             ; 1MB cachable bufferable 
                orr                    r0, r0, #0x400                    ; set kernel r/w permission 
                mov                    r1, #0 
;                    mov                    r3, #64                                        ; 64MB DRAM 
                mov                    r3, #128                                        ; 128MB DRAM
    前两条语句用来设置页表对应页的缓冲读写属性,第四条语句,将 DRAM 的大小赋值给 R3 寄存器,该值的大小选择就是根据全局内存映射表中的 DRAM 设置的大小。该值不会大于 512 ,因为 WinCE 最大支持 512MB 的物理内存。
45 
                mov                    r2, r1                                        ; (r2) = virtual address to map Bank at 
                cmp                    r2, #0x20000000:SHR:BANK_SHIFT 
                add                    r2, r10, r2, LSL #BANK_SHIFT-18
    第一条和第二条语句要结合起来看, R2 开始是 0 cmp 的比较就是为了保证 DRAM 的大小不超过 512M ,注释中的 Bank 大小就是 1MB BANK_SHIFT 在最开始定义,大小为 20 ,而 0x20000000>>20=512 cmp 指令影响的状态位,在后面的代码判断时使用。第三条语句其实还是计算对应的页表的存储地址的, LSL #BANK_SHIFT-18 结合前面一条语句,相当于将 R2>>18 ,这下就回到了前面介绍的,将高 14 位作为页表基地址的偏移量。
                strlo                    r0, [r2] 
                add                    r0, r0, #0x00100000         ; (r0) = PTE for next physical page 
                subs                    r3, r3, #1 
                add                    r1, r1, #1 
                bgt                    %B45
    第一条语句是将 R0 中的页表项写入 R2 指向的地址,但是没有 str 指令,而是 strlo 指令,因为这里有不同的地方, strlo 实现的效果是,如果还没有超过 512MB ,那么像 str 指令一样,如果超过 512MB ,则不会往地址中写数据,忽略此次操作。个人认为,这样写的用意在于,当以后 DRAM 大小变化的时候,只需要该一个值,其他部分不变,而且如果设置的大于 512MB ,可以实现保护。第二条到第四条语句和前面介绍的部分类似。最后一条语句就是根据上面 cmp 的比较结果进行跳转的, bgt 表示如果大于则跳转。
ldr                    r10, =PT_1ST_BASE         ; (r10) = restore address of 1st level page table
    该语句重新将 R10 指向页表基地址,因为下面会用到它。
                ; The page tables and exception vectors are setup. 
                ; Initialize the MMU and turn it on. 
                mov                    r1, #1 
                mcr                    p15, 0, r1, c3, c0, 0         ; setup access to domain 0 
                mcr                    p15, 0, r10, c2, c0, 0
    前面设置好页表以后,这里开始初始化 MMU ,并打开 MMU 。上面代码设置的是域 0 的访问控制属性,同时将页表的基地址存储到 CP15 协处理器的 C2 寄存器中。
mcr                    p15, 0, r0, c8, c7, 0         ; flush I+D TLBs
         这条代码用来无效整个指令 Cache 、数据 Cache TLB ,相当于清空所有 MMU 的相关空间。 
                mrc                    p15, 0, r1, c1, c0, 0 
                orr                    r1, r1, #0x0071                    ; Enable MMU 
                orr                    r1, r1, #0x0004                    ; Enable the Data Cache
     第一条语句读取 CP15 C1 寄存器的数据到 R1 中,下面两条用来设置 MMU 的标志,使能 MMU ,使能数据 Cache
                ldr                    r0, =VirtualStart 

                cmp                    r0, #0                                        ; make sure no stall on "mov pc,r0" below 
                mcr                    p15, 0, r1, c1, c0, 0 
                mov                    pc, r0                                        ; & jump to new virtual address 
                nop

    首先R0存储标号VirtualStart的地址,它是一个虚拟地址,因为它出现在启用虚拟地址之后。确保标号VirtualStart的虚拟地址不为0,因为下面有mov pc r0,语句,不可以给pc赋值0。第三天语句将R1中的数据写入CP15C1寄存器中,设置MMU标志,并启用MMU,最后通过直接给PC赋值,跳转到VirtualStart标号处。



本文转自jazka 51CTO博客,原文链接:http://blog.51cto.com/jazka/572649,如需转载请自行联系原作者

相关文章
|
Java 数据库连接 数据安全/隐私保护
利用开源工具实现轻量级上网行为审计(来源ispublic.com)
来源ispublic.com Google上貌似找不到利用开源软件实现上网行为审计的文章——这也难怪,开源在国内并不流行,而上网行为审计在国外也不流行。
1774 0
|
12月前
|
数据采集 人工智能 缓存
腾讯混元又来开源,一出手就是最大MoE大模型
腾讯混元团队近日发布了开源Transformer-based MoE模型Hunyuan-Large,参数量达3890亿,激活参数520亿,处理tokens高达256K。该模型在多个基准测试中超越LLama3.1-70B,在某些方面媲美更大规模的LLama3.1-405B。其成功源于合成数据集、混合专家路由策略、键值缓存压缩及专家特定学习率等创新技术。尽管面临训练成本高和数据质量等挑战,Hunyuan-Large仍为AI行业注入新活力,并推动技术进步与应用创新。
213 13
|
IDE PHP 开发工具
【PHP开发专栏】Xdebug在PHP调试中的应用
Xdebug 是一个功能强大的 PHP 扩展,提供调试、代码分析和性能分析等功能。本文介绍了 Xdebug 的基本概念、安装配置方法及在 PHP 调试中的应用技巧,包括断点调试、堆栈跟踪、远程调试和性能分析等。通过合理使用 Xdebug,可以显著提高调试效率和代码质量。
284 3
|
人工智能 算法
AI 写歌词,会让歌词创作变得更容易吗?
在科技迅猛发展的今天,AI已渗透至多个领域,包括歌词创作。《妙笔生词智能写歌词软件》通过强大算法与海量数据,为新手提供创作指导,快速生成多风格歌词片段,降低创作门槛,节省时间。尽管如此,优秀作品仍需创作者的情感与思考,AI辅助下的歌词创作正逐渐变得更为便捷。
|
编解码 安全 Unix
数据导入与预处理-第4章-数据获取python读取pdf文档
数据导入与预处理-第4章-数据获取Python读取PDF文档 1 PDF简介 1.1 pdf是什么 2 Python操作PDF 2.1 pdfplumber库
数据导入与预处理-第4章-数据获取python读取pdf文档
|
存储 分布式计算 Kubernetes
【混沌工程】什么是混沌工程? 介绍、定义及更多
软件和系统开发是创新和解决未知问题的练习。 软件和系统是容易出错的,因为它们是由具有不同观点和技能的人(很可能是多人)制作的。 技术变得越来越分散和复杂,尤其是随着微服务的推动。 很少有人拥有完整的端到端知识 […]
|
弹性计算
阿里云AMD EPYC Genoa 9T24 处理器2.7 GHz主频计算性能稳定睿频3.7 GHz
阿里云AMD EPYC Genoa 9T24 处理器2.7 GHz主频计算性能稳定睿频3.7 GHz
835 0
|
数据采集 存储 运维
CDP客户数据管理平台体系化搭建
客户数据平台通过采集多方客户数据(主体与线索)等,从而进行精准的客户分析和人群细分,进而实现高效的客户维系和发掘以及日常营销运营。
976 0
CDP客户数据管理平台体系化搭建
EMQ
|
存储 Prometheus 监控
Mria + RLOG 新架构下的 EMQX 5.0 如何实现 1 亿 MQTT 连接
大规模分布式物联网MQTT消息服务器EMQX的5.0 版本在发布前的性能测试中达成了1亿 MQTT 连接。本文将对使EMQX水平扩展能力得到指数级提升的全新底层架构进行详细解析,同时帮助大家理解在不同的实际应用场景中如何选择合适的部署架构,实现更加可靠的设备接入与消息传输。
EMQ
615 0
Mria + RLOG 新架构下的 EMQX 5.0 如何实现 1 亿 MQTT 连接
|
负载均衡 网络安全
VRRP、VGMP 和 HRP 之间有什么区别?这篇文章给你答案!
作为USG防火墙最重要的功能之一,双机热备极大地提高了设备的可靠性,当主用设备发生故障时,备用设备可以立即接管受影响的业务,从而显着减少业务中断的持续时间。
1136 0