Linux内核及ARM的内存管理(不厌其烦续)
2009-12-30 11:17
375 查看
一个人勃一次不难,难的是勃一辈子……
最近分心的事很多,勃得越来越少了!
打开mmu是一件神圣的工作,需要仔细、再仔细……
从__v7_setup函数返回来,进入到__enable_mmu过程,做起飞前的最后确认:
__enable_mmu:
#ifdef CONFIG_ALIGNMENT_TRAP
orr r0, r0, #CR_A
#else
bic r0, r0, #CR_A
#endif
根据配置选项,决定是否打开数据对齐检查,一般是要打开的;
#ifdef CONFIG_CPU_DCACHE_DISABLE
bic r0, r0, #CR_C
#endif
根据配置选项,决定是否关闭开数据缓冲区,一般是不需要关闭的;
#ifdef CONFIG_CPU_BPREDICT_DISABLE
bic r0, r0, #CR_Z
#endif
根据配置选项,决定是否要关闭分支预测功能,一般是不需要关闭的;
#ifdef CONFIG_CPU_ICACHE_DISABLE
bic r0, r0, #CR_I
#endif
根据配置选项,决定是否关闭开指令缓冲区,一般是不需要关闭的;
mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | /
domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | /
domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | /
domain_val(DOMAIN_IO, DOMAIN_CLIENT))
结合数据手册,此段是将D0、D1两个域,D1对应于USER域,D0对应于KERNEL和TABLE域,配置为管理模式,对这两个域的访问和执行不受TLB中相应标志位影响,D2域,对应于IO域,配置为客户模式,对此域的访问受TLB中相应标志位的检查;
mcr p15, 0, r5, c3, c0, 0 @ load domain access register
写入域访问控制寄存器,其实和__v7_setup函数中写入的值相同;
mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
__v7_setup函数中也已经写过这个寄存器了;
b __turn_mmu_on
__turn_mmu_on就在后面紧跟着,不明白为何还要b一下;
ENDPROC(__enable_mmu)
再看看紧接着的__turn_mmu_on函数:
/*
* Enable the MMU. This completely changes the structure of the visible
* memory space. You will not be able to trace execution through this.
* If you have an enquiry about this, *please* check the linux-arm-kernel
* mailing list archives BEFORE sending another post to the list.
*
* r0 = cp#15 control register
* r13 = *virtual* address to jump to upon completion
*
* other registers depend on the function called upon completion
*/
.align 5
原来是因为有这个,所以要b过来,但为什么是以5对齐?在网上搜索了一下,原来.align n的语法,有按照n对齐的,也有按照2的n次方对齐的,而arm-linux是按照2的n次方对齐的,即,是以20字节位置对齐的,详见某篇博文:http://www.eetop.cn/blog/html/45/11145-1211.html
__turn_mmu_on:
mov r0, r0
暂时认为这是常规的nop语句……
mcr p15, 0, r0, c1, c0, 0 @ write control reg
终于将寄存器r0的值写入到了mmu控制寄存器中,此时的CPU终于可以“内牛满面”!
mrc p15, 0, r3, c0, c0, 0 @ read id reg
对于Cortex A8处理器来说,此时寄存器r3的值也许是:0x413fc082字样,其中41代表ARM,c08就是Cortex A8;
mov r3, r3
mov r3, r3
继续认为这是nop语句,或者说,在这里是清除流水线,那么,之后的CPU,已经平稳过渡到了虚拟地址空间的环境?(我不敢确认)……
mov pc, r13
无需废话了,很久以前,寄存器r13就准备好了__switch_data的入口地址;
ENDPROC(__turn_mmu_on)
最近分心的事很多,勃得越来越少了!
打开mmu是一件神圣的工作,需要仔细、再仔细……
从__v7_setup函数返回来,进入到__enable_mmu过程,做起飞前的最后确认:
__enable_mmu:
#ifdef CONFIG_ALIGNMENT_TRAP
orr r0, r0, #CR_A
#else
bic r0, r0, #CR_A
#endif
根据配置选项,决定是否打开数据对齐检查,一般是要打开的;
#ifdef CONFIG_CPU_DCACHE_DISABLE
bic r0, r0, #CR_C
#endif
根据配置选项,决定是否关闭开数据缓冲区,一般是不需要关闭的;
#ifdef CONFIG_CPU_BPREDICT_DISABLE
bic r0, r0, #CR_Z
#endif
根据配置选项,决定是否要关闭分支预测功能,一般是不需要关闭的;
#ifdef CONFIG_CPU_ICACHE_DISABLE
bic r0, r0, #CR_I
#endif
根据配置选项,决定是否关闭开指令缓冲区,一般是不需要关闭的;
mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | /
domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | /
domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | /
domain_val(DOMAIN_IO, DOMAIN_CLIENT))
结合数据手册,此段是将D0、D1两个域,D1对应于USER域,D0对应于KERNEL和TABLE域,配置为管理模式,对这两个域的访问和执行不受TLB中相应标志位影响,D2域,对应于IO域,配置为客户模式,对此域的访问受TLB中相应标志位的检查;
mcr p15, 0, r5, c3, c0, 0 @ load domain access register
写入域访问控制寄存器,其实和__v7_setup函数中写入的值相同;
mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
__v7_setup函数中也已经写过这个寄存器了;
b __turn_mmu_on
__turn_mmu_on就在后面紧跟着,不明白为何还要b一下;
ENDPROC(__enable_mmu)
再看看紧接着的__turn_mmu_on函数:
/*
* Enable the MMU. This completely changes the structure of the visible
* memory space. You will not be able to trace execution through this.
* If you have an enquiry about this, *please* check the linux-arm-kernel
* mailing list archives BEFORE sending another post to the list.
*
* r0 = cp#15 control register
* r13 = *virtual* address to jump to upon completion
*
* other registers depend on the function called upon completion
*/
.align 5
原来是因为有这个,所以要b过来,但为什么是以5对齐?在网上搜索了一下,原来.align n的语法,有按照n对齐的,也有按照2的n次方对齐的,而arm-linux是按照2的n次方对齐的,即,是以20字节位置对齐的,详见某篇博文:http://www.eetop.cn/blog/html/45/11145-1211.html
__turn_mmu_on:
mov r0, r0
暂时认为这是常规的nop语句……
mcr p15, 0, r0, c1, c0, 0 @ write control reg
终于将寄存器r0的值写入到了mmu控制寄存器中,此时的CPU终于可以“内牛满面”!
mrc p15, 0, r3, c0, c0, 0 @ read id reg
对于Cortex A8处理器来说,此时寄存器r3的值也许是:0x413fc082字样,其中41代表ARM,c08就是Cortex A8;
mov r3, r3
mov r3, r3
继续认为这是nop语句,或者说,在这里是清除流水线,那么,之后的CPU,已经平稳过渡到了虚拟地址空间的环境?(我不敢确认)……
mov pc, r13
无需废话了,很久以前,寄存器r13就准备好了__switch_data的入口地址;
ENDPROC(__turn_mmu_on)
相关文章推荐
- Linux内核及ARM的内存管理(再续)
- Linux内核及ARM的内存管理(前续)
- Linux内核及ARM的内存管理
- Linux内核及ARM的内存管理 .
- [arm驱动概念篇]Linux内存管理(上)
- 怎样将lua移植到arm平台的linux内核
- ARM学习之内存管理单元(MMU)
- arm-linux内存管理学习笔记(1)-内存页表的硬件原理
- 为Linux内核打ARM补丁
- Linux内核内存管理之内存结构概述(一)
- linux内核高端内存管理之固定内存区与映射
- Linux内核学习笔记——内核内存管理方式
- 【ARM学习笔记】实验四:内存管理单元MMU的虚拟地址映射实验
- Arm-linux内存管理(3)
- arm的2级页表在Linux内核创建过程解析
- 浅析linux内核内存管理之内存池
- linux内核内存管理学习之一(基本概念,分页及初始化)
- [linux内核]ARM-Linux系统调用
- linux内核内存管理子系统概要分析
- 26、(5)Linux内核启动引导阶段之 __arm920_steup函数分析