转自:http://blog.csdn.net/u011461299/article/details/10199989
版权声明:本文为博主原创文章,未经博主允许不得转载。
在驱动程序的设计中,我们可能会用到flush_cache_all将ARM cache的内容刷新到RAM,这是因为ARM Linux中cache一般会被设定为write back的。而通常象DMA是访问不了cache,所以如果我们需要启动DMA将RAM中的内容写到Flash中或LCD framebuffer,那么我们就需要调用flush_cache_all将cache中最新的内容刷新到RAM中。如果不这样做在LCD中可能会出现花屏。本文主要分析在ARM平台上到底如何实现的。
1.1 flush_cache_all在ARM Linux中的实现
在include/asm-arm/cacheflush.h中:
#define flush_cache_all() __cpuc_flush_kern_all()
#define __cpuc_flush_kern_all cpu_cache.flush_kern_all
在setup_processor():
list = lookup_processor_type(processor_id);
//根据processor id找到对应ARM CPU(常见的如ARM926)相关的信息,存在list中。如果想把事情彻底搞清楚,必然要问processor_id是怎么来。它是在Linux Kernel启动时候从ARM chip中读出来。如果以后有机会大家一起讨论ARM Linux的启动全过程,可以详细分析。
…
cpu_cache = *list->cache;
而lookup_processor_type定义在arch/arm/kernel/head-comman.S中:相应的assembler code如下:
.type __lookup_processor_type, %function
__lookup_processor_type:
adr r3, 3f
ldmda r3, {r5 - r7}
sub r3, r3, r7 @ get offset between virt&phys
add r5, r5, r3 @ convert virt addresses to
add r6, r6, r3 @ physical address space
1: ldmia r5, {r3, r4} @ value, mask
and r4, r4, r9 @ mask wanted bits
teq r3, r4
beq 2f
add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
cmp r5, r6
blo 1b
mov r5, #0 @ unknown processor
2: mov pc, lr
/*
* This provides a C-API version of the above function.
*/
ENTRY(lookup_processor_type)
stmfd sp!, {r4 - r7, r9, lr}
mov r9, r0
bl __lookup_processor_type
mov r0, r5
ldmfd sp!, {r4 - r7, r9, pc}
/*
* Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
* more information about the __proc_info and __arch_info structures.
*/
.long __proc_info_begin
.long __proc_info_end
3: .long .
.long __arch_info_begin
.long __arch_info_end
它其实就是到__proc_info_begin开始的section中去找到对应当前SOC中用的CPU Cache相关的operation list
再由arch/arm/kernel/vmlinux.lds.S可以__proc_info_begin就是section *(.proc.info.init)的开始地址。
__proc_info_begin = .;
*(.proc.info.init)
__proc_info_end = .;
而我们知道我们所用是ARM926,所以其定义在arch/arm/mm/proc-arm926.S:
.section ".proc.info.init", #alloc, #execinstr
.type __arm926_proc_info,#object
__arm926_proc_info:
.long 0x41069260 @ ARM926EJ-S (v5TEJ)
.long 0xff0ffff0
.long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
PMD_BIT4 | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
.long PMD_TYPE_SECT | \
PMD_BIT4 | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
b __arm926_setup
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
.long cpu_arm926_name
.long arm926_processor_functions
.long v4wbi_tlb_fns
.long v4wb_user_fns
.long arm926_cache_fns
.size __arm926_proc_info, . - __arm926_proc_info
arm926_cache_fns定义在同一个文件中,如下:
ENTRY(arm926_cache_fns)
.long arm926_flush_kern_cache_all
.long arm926_flush_user_cache_all
.long arm926_flush_user_cache_range
.long arm926_coherent_kern_range
.long arm926_coherent_user_range
.long arm926_flush_kern_dcache_page
.long arm926_dma_inv_range
.long arm926_dma_clean_range
.long arm926_dma_flush_range
它所对应的struct的定义:(include/asm-arm/cacheflush.h)
struct cpu_cache_fns {
void (*flush_kern_all)(void);
void (*flush_user_all)(void);
void (*flush_user_range)(unsigned long, unsigned long, unsigned int);
void (*coherent_kern_range)(unsigned long, unsigned long);
void (*coherent_user_range)(unsigned long, unsigned long);
void (*flush_kern_dcache_page)(void *);
void (*dma_inv_range)(const void *, const void *);
void (*dma_clean_range)(const void *, const void *);
void (*dma_flush_range)(const void *, const void *);
};
所以其实flush_cache_all 在我们的项目中就是arm926_flush_kern_cache_all:其实现在同一个文件中:
/*
* flush_kern_cache_all()
* Clean and invalidate the entire cache.
*/
ENTRY(arm926_flush_kern_cache_all)
mov r2, #VM_EXEC
mov ip, #0
__flush_whole_cache:
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
#else
1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate
bne 1b
#endif
tst r2, #VM_EXEC
mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
mcrne p15, 0, ip, c7, c10, 4 @ drain WB
mov pc, lr
最后我们它不仅仅flush 所有的cache(包括ICache和DCache),也flush了Write Buffer。
Linux Kernel之flush_cache_all在ARM平台下是如何实现的【转】的更多相关文章
-
[转]ARM平台下独占访问指令LDREX和STREX
参考:ARM平台下独占访问指令LDREX和STREX的原理与使用详解 全文转载如下: 为了实现线程间同步,一般都要在执行关键代码段之前加互斥(Mutex)锁,且在执行完关键代码段之后解锁.为了实现所谓 ...
-
4G通信模块在ARM平台下的应用
4G模块是连接物与物的重要载体,是终端设备接入物联网的核心部件之一.随着4G的普及,许多新兴市场对4G通信模块的需求都在日益扩大,那么在ARM平台的嵌入式设备上如何快速的应用4G模块呢? 4G通信模块 ...
-
4G 通信模块在ARM 平台下的应用
收藏 评论(0) 分享到 微博 QQ 微信 LinkedIn 4G模块是连接物与物的重要载体,是终端设备接入物联网的核心部件之一,随着4G的普及,许多新兴市场对4G通信模块的需求都在日益扩大,那么在A ...
-
NDK编程的一个坑—Arm平台下的类型转换
最近在做DNN定点化相关的工作,DNN定点化就是把float表示的模型压缩成char表示,虽然会损失精度,但是由于DNN训练的模型值比较接近且范围较小,实际上带来的性能损失非常小.DNN定点化的好处是 ...
-
Mplayer ARM平台下交叉编译
下载MPlayer http://www.mplayerhq.hu/design7/dload.html 编译环境 系统 : ubuntu 11.04 交叉编译器版本 : Sourcery G++ L ...
-
ARM 平台下的 SSHD 配置
sshd_config 文件中 允许 root 用户登录 PermitRootLogin yes 配置为内部的 sftp Subsystem sftp internal-sftp key 配置 ssh ...
-
Linux kernel的中断子系统之(六):ARM中断处理过程
返回目录:<ARM-Linux中断系统>. 总结:二中断处理经过两种模式:IRQ模式和SVC模式,这两种模式都有自己的stack,同时涉及到异常向量表中的中断向量. 三ARM处理器在感知到 ...
-
Linux Kernel代码艺术——系统调用宏定义
我们习惯在SI(Source Insight)中阅读Linux内核,SI会建立符号表数据库,能非常方便地跳转到变量.宏.函数等的定义处.但在处理系统调用的函数时,却会遇到一些麻烦:我们知道系统调用函数 ...
-
Linux Kernel空指针引用本地拒绝服务漏洞(CVE-2013-5634)
漏洞版本: Linux kernel 漏洞描述: BUGTRAQ ID: 61995 CVE(CAN) ID: CVE-2013-5634 Linux Kernel是Linux操作系统的内核. 适用于 ...
随机推荐
-
【原】git如何删除本地和远程的仓库
今天操作git时遇到一个小问题:如何删除本地和远程的仓库,在网上巴拉一番解决了这个问题. 方法1: $rm testfile$git add -u $git commit -m "delet ...
-
SwitchCompat 修改颜色
Ok, so I'm sorry but most of these answers are incomplete or have some minor bug in them. The very c ...
-
gulp安装
1. npm install gulp -g 全局安装 npm install gulp --save-dev 安装文件内,纪录于package.json 接著安装插件,完成下列任务 ...
-
SourceTree 将本地已有的git项目推送到远程git仓库
1.在远程git仓库创建对应的项目: 2.用命令行生成本地的ssh key; 3.把公钥粘贴远程仓库对应的位置: 4.SourceTree 设置远程仓库的地址: 5.把本地对应的分支推送到远程仓库: ...
-
iOS 任务的依赖操作
-(void)dependency{ /** 假设有A.B~C三个操作,要求: 1. 3个操作都异步执行 2. 操作C依赖于操作B 3. 操作B依赖于操作A */ //创建一个队列 NSOperati ...
-
本地创建yum源并安装lnmp
注意:安装系统时,文件类型要未xfs类型,root要分配最多的空间 1.挂载安装光盘mount -t iso9660 -o loop CentOS-7-x86_64-DVD-1511.iso /mnt ...
-
【日记】一次程序调优发现的同步IO写的问题,切记
众所周知,我们在写程序的时候,好习惯是在重要的代码打上日志.以便监控程序运行的性能和记录可能发生的错误. 但是,如果日志是基于同步IO文件操作,那么就必须考虑到访问总次数或并发数目. 如果总次数或并发 ...
-
dva-quickstart 与 create-react-app 比较(一)
最近在学习 React , 现对 dva-quickstart 与 create-react-app 比较 1. 安装, 两个都需要安装工具包:npm install -g create-re ...
-
textarea不能使用maxlength
知道文本框有个maxlength属性,有次开发项目中使用了textarea标签,没去看文档,直接加了maxlength属性,且有效果没有报错,喜滋滋的用了,结果没两天就测试出了bug 问题描述:文本域 ...
-
【代码笔记】Web-JavaScript-Javascript对象
一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...