Chinaunix首页 | 论坛 | 博客
  • 博客访问: 809442
  • 博文数量: 296
  • 博客积分: 5376
  • 博客等级: 大校
  • 技术积分: 2298
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-14 19:02
文章分类

全部博文(296)

文章存档

2023年(2)

2020年(2)

2018年(2)

2017年(26)

2016年(4)

2015年(19)

2014年(12)

2013年(26)

2012年(84)

2011年(50)

2010年(41)

2009年(28)

分类: LINUX

2013-01-15 09:50:48

   

Bit[1:0]

页描述符类型标识。00:无效;01:大页;10:小页;11:极小页

CB

该二级描述符对应的存储空间的cacheWrite Buffer特性控制位,如表4-5所示

APx

访问权限控制位,详见前面“MMU中的域”说明

TEX

ARMv5以上版本处理器中有定义,如果TEX等于1,表示系统支持写时分配cache

大页基地址:

该描述符对应的大页存储空间的物理基地址,64KB对齐

小页基地址:

该描述符对应的小页存储空间的物理基地址,4KB对齐

极小页基地址:

该描述符对应的极小页存储空间的物理基地址,1KB对齐

 

C

B

写通类型cache

写回类型cache

可选择写通属性的写回类型cache

0

0

Uncached/unbuffered

Uncached/unbuffered

Uncached/unbuffered

0

1

Uncached/buffered

Uncached/buffered

Uncached/buffered

1

0

cached/unbuffered

不可预测

写通cached/buffered

1

1

Cached/buffered

Cached/buffered

写回cached/buffered

二、ADS初始化中建立二级页表;

;**************************************************************************************

;* 初始化页表

;**************************************************************************************

; 初始化MMU,Cache以及WB

       mov        r0,          #0                  ; r0寄存器置0,用于后续对CP15寄存器赋值

       mcr        p15, 0, r0, c7, c7, 0                    ; 失效I/DCache

;      mcr        p15, 0, r0, c7, c10, 4                   ; 挤干WB

       mcr        p15, 0, r0, c8, c7, 0                    ; 失效I/D TLBs

       mrc        p15, 0, r0, c1, c0, 0                    ; 加载控制寄存器C1R0

       bic          r0,          r0,#0x000f            ; R0W(WB)C(Cache)A(Align)M(MMU)位清零

       bic          r0,          r0,#0x1100            ; R0I(ICache)S(System Protection)位清零

       mcr        p15, 0, r0, c1, c0, 0                    ; R0写到控制寄存器C1

 

       ldr          r5,         =0x30004000                ; 加载页表基址0x4000R5,该值不能低于0x4000,因为C2寄存器近31:14位有效,低于该值则1级页表项将从0x0开始,这将和中断向量表以及中断处理函数冲突

       mcr        p15, 0, r5, c2, c0, 0                    ; R5写到翻译表CP15协处理器的基址寄存器C2

 

; 0.0x4000000映射到0x4000000 得到并写入1级页表

       ;ldr         r0,          =0x30004100                ; R0寄存器加载1级页表描述符地址,具体配置如下:

       ;ldr         r1,          =0x4000c0e             ;这里的0x30004100是根据0x4000000在整个4GB的一级页表内的偏移序号

       ;str         r1,          [r0]             ;0x4000c0eesram的一级页表描述符,映射1MB

      

; 1.0x0(虚地址)映射到0x24000000(实地址即CSB 得到并写入1级页表

 

       ldr          r0,          =0x30004000                ; R0寄存器加载1级页表描述符地址,具体配置如下:

       ldr          r1,          =0x24000c0e               ;这个是将0x30000000映射到页表的第一项

       str          r1,          [r0]

      

; 2.0x11000000映射到0x11000000(映射SEP4020相应的寄存器空间) 得到并写入1级页表

 

       ldr          r0,          =0x30004440                ; R0寄存器加载1级页表描述符地址,具体配置如下:

       ldr          r1,          =0x11000c02                ;这个是将4020的寄存器虚实映射起来(0x11000c02表示不cache)

       str          r1,          [r0]

      

 

;3.先建立0x30000000映射到0x30000000的段地址描述符,在这里只建立了4M的映射空间, 得到并写入1级页表

 

       ldr          r0,          =0x30004c00                ; 一级页表项存放的位置为0x0000,4c00~0x0000,4c10  R0寄存器加载1级页表描述符地址,具体配置如下:

 

; Address of First-Level Descriptor:

;           0,           0,           0,           0,           4,           0,           0,           4

; 31 30 29 28, 27 26 25 24, 23 22 21 20, 19 18 17 16, 15 14 13 12, 11 10 09 08, 07 06 05 04, 03 02 01 00

;  0  0  0  0,  0  0  0  0,  0  0  0  0,  0  0  0  0,  0  1  0  0,  0  0  0  0,  0  0  0  0,  0  1  0  0

 

       ldr          r1,          =0x30008011                ; 二级页表存放的位置为0x3000,8000~0x3000,a000               

      

; First-Level Descriptor:(一级页表中包含256项二级页表项)

;           0,           0,           0,           0,           8,           0,           1            1

; 31 30 29 28, 27 26 25 24, 23 22 21 20, 19 18 17 16, 15 14 13 12, 11 10 09 08, 07 06 05 04, 03 02 01 00

;  0  0  0  0,  0  0  0  0,  0  0  0  0,  0  0  0  0,  1  0  0  0,  0  0  0 |0,  0  0  0 |1,  0  0 |0  1

; Page Table Address                                                     |S |Domain      |IMP      |0  1

       add         r6,          r0, #0x10

first1

       str          r1,         [r0], #4          ; 写入映射1级页表页描述符

       add         r1,          r1, #0x400

       teq          r0,          r6

       bne         first1

      

                     ;

 

; 4.再建立SDRAM的二级页表描述符,这个是存放在得到并写入2级页表,这里先统一建立4M

       ldr          r0,          =0x30008000                ;  二级页表项存放的位置在0x30008000~0x30009000          

       ldr          r1,          =0x30000FFE               ;  二级页表映射的物理地址范围是0x3000,0000 ~~0x3040,0000映射的虚拟地址为0x3000,0000 ~~0x3040,0000    准备第2MB2级页表项,具体配置为:

     

; Second-level descriptor:

;           3,           0,           0,           0,          0,         F,       F,       2

; 31 30 29 28, 27 26 25 24, 23 22 21 20, 19 18 17 16, 15 14 13 12, 11 10 9 8, 7 6 5 4, 3 2 1 1

;  0  0  1 1,  0  0  0  0,  0  0  0  0,  0  0  0  0,  0 0  0  0, |1  1|1 1,|1 1|1 1,|C|B|1 1

; 256B page base address                                           |AP  |AP  |AP |AP  |1|1|1 0

 

       ldr          r5,          =0x1000       ;映射的大小为0x2,c000大小

       add         r6,          r0, r5                    ; 2级页表描述符初始地址R0和总的页数(4K)所占页表项空间大小(16K=0x4000)并扣除不在该1级描述符映射的区域,得到2级页表结束地址,保存到R6

second_one                                                     ;

       str          r1,          [r0], #4          ; 循环装载2级页表

       add         r1,          r1, #0x1000           ; 每次加0x1000,为了页号每次自加(偏移)1

       teq          r0,          r6                  ; 0x8000对比,等于则意味着完成虚地址0x3040,0000~0x3040,00004MB的映射

       bne         second_one                                ;

 

; 5.在这里再将页表项存放的位置0x3000,4000~0x3000,a000将他们改为不可cache的,因为页表项不可cache,得到并写入2级页表

       ldr          r0,          =0x30008010                ;  二级页表项存放的位置在0x8010~0x8028        

       ldr          r1,          =0x30004FF2               ;  二级页表映射的物理地址范围是0x3000,4000 ~~0x3000,a000映射的虚拟地址为0x3000,4000 ~~0x3000,a000    准备第2MB2级页表项,具体配置为:

     

; Second-level descriptor:

;           0,           0,           0,           0,           4,         F,       F,       2

; 31 30 29 28, 27 26 25 24, 23 22 21 20, 19 18 17 16, 15 14 13 12, 11 10 9 8, 7 6 5 4, 3 2 1 1

;  0  0  0  0,  0  0  0  0,  0  0  0  0,  0  0  0  0,  0  1  0  0, |1  1|1 1,|1 1|1 1,|C|B|1 1

; 256B page base address                                           |AP  |AP  |AP |AP  |0|0|1 0

 

       ldr          r5,          =0x18       ;映射的大小为0x2,c000大小

       add         r6,          r0, r5                    ; 2级页表描述符初始地址R0和总的页数(4K)所占页表项空间大小(16K=0x4000)并扣除不在该1级描述符映射的区域,得到2级页表结束地址,保存到R6

second_two                                                     ;

       str          r1,          [r0], #4          ; 循环装载2级页表

       add         r1,          r1, #0x1000           ; 每次加0x1000,为了页号每次自加(偏移)1

       teq          r0,          r6                  ; 0x8000对比,等于则意味着完成虚地址0x3001,0000~0x3070,00007MB的映射

       bne         second_two                         ;

 

; 开启MMU并跳转到主程序开始执行

       ldr          r0,          =0x0                     ;

       ldr          r1,          =0x400000ff          ; 准备填写Domain,由于上面用到03两个域,所以需要给0x55,最前面的4问题不大

       mcr        p15, 0, r1, c3, c0, 0                    ; 写入Domain

       ldr          r1,          =0x4005147D        ; 准备填写C1控制寄存器

      

;**************************************************************************************

;* 跳转到主函数 main()

;**************************************************************************************

      

       IMPORT MAIN_DO

      

    ldr r5,=MAIN_DO

       mcr        p15, 0, r1, c1, c0, 0                    ; 打开MMUCache

       add         pc,          r5,#0x0                 ; PC到刚才准备的__main的虚地址地址继续执行

 

       mov        r0,          r0                  ; 填充流水线

       mov        r0,          r0                  ; 填充流水线

       mov        r0,          r0                  ; 填充流水线

;**************************************************************************************

这上面的过程就是建立二级页表的过程,其中需要注意的几个问题是:

(1)       页表建立的地方的虚实映射一定要提前建立好,否则在最好打开cacheMMU的时候就会死掉;

(2)       一定要提前建立好虚地址0的映射,否则会在

mcr        p15, 0, r1, c1, c0, 0                    ; 打开MMUCache

这句话死掉,会怎么也过不过去的。

(3) 页表描述符存放的位置不要做成cache,这个是MMU规定的,因为mmu会直接从sdram中去页表描述符的,而不会从cache中取描述符的。

4)注意要使我们的程序跑起来还需要注意程序连接的地址应该是程序运行起来的虚地址,而不是实地址,另外还需要注意的是,程序的堆栈一定要改到我们已经映射的虚地址当中,否则程序会直接跑飞的。

阅读(890) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~