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,如需转载请自行联系原作者

相关文章
|
2月前
|
C++
MFC编程 -- 记事本项目(大体框架)
MFC编程 -- 记事本项目(大体框架)
12 0
|
2月前
MFC编程 -- 添加菜单
MFC编程 -- 添加菜单
9 0
|
存储 编译器 C语言
STM32第二章-启动过程详解
STM32 的启动过程,启动过程是指从 CPU 上电复位执行第 1 条指令开始(汇编文件)到进入 C 程序 main()函数入口之间的部分。启动过程相对来说还是比较重要的,虽然难但必须了解掌握。
216 0
STM32第二章-启动过程详解