Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1216205
  • 博文数量: 122
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4004
  • 用 户 组: 普通用户
  • 注册时间: 2014-02-20 08:27
文章分类
文章存档

2016年(1)

2015年(21)

2014年(100)

分类: LINUX

2014-03-14 12:43:19


点击(此处)折叠或打开

  1. static inline void flush_write_buffers(void)
  2. {
  3.  __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory");
  4. }

  5. #define dma_cache_inv(_start,_size) flush_write_buffers()
  6. #define dma_cache_wback(_start,_size) flush_write_buffers()
  7. #define dma_cache_wback_inv(_start,_size) flush_write_buffers()

     
1、lock指令:对总线(什么总线?)加锁。为了在多处理器环境中,保证在当前指令执行期间禁止一切中断(只对当前核么?)。
这个前缀仅仅对ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG,DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD,XCHG指令
有效,如果将Lock前缀用在其它指令之前,将会引起异常。
2、 addl $0,0(%%esp)": : :"memory"
表示将0(%%esp)的内存单元加上0,然后再写入相应的内存单元。最后的memory很重要,有两个作用:
1、表示需要强制刷缓存,即同步cache,前面的add操作实际啥也没干,最终就是通过memory限制实现cache的同步。
2、防止编译器编译时对指令顺序进行重排优化。
之前理解错了,以为_start参数会压栈,然后会操作_start相应的内存单元,但实际没有,因为这里的flush_write_buffers
是内联函数,直接展开,没有压栈的过程,所以,实际上,这个函数的参数是没有使用的,无意义的。
另外,这里使用的地址应该是虚拟地址才对。因为保护模式下,汇编指令操作的实际也只能是虚拟地址,虚拟地址经硬件MMU自动转换为物理地址,然后在地址总线上传播。
对于软件来说,保护模式下,只能使用虚拟地址,软件只需准备好页表,并告知页表的位置(通过CR3寄存器),剩余的虚拟地址到物理地址的转换工作,就都由mmu硬件来完成了。

阅读(2265) | 评论(0) | 转发(0) |
0

上一篇:AT&T指令集

下一篇:ioremap相关笔记

给主人留下些什么吧!~~