TLB与《x86汇编语言——从实模式到保护模式》的一个疑似错误

      TLB(Translation Lookaside Buffer)是CPU内部的一个高速缓存,用于最近经常使用的缓存线性地址和物理地址的映射关系。TLB的存在会为程序的编写带来容易忽略的错误。当内存中的目录和页表发生变化时,这些变化并不会立即反映在TLB中。此时,CPU依然依靠TLB完成线性地址到物理地址的映射。所以,一个可靠的方式是更改目录和页表后,将cr3的内容取出,然后重新填入cr3。CR3的赋值操作会导致TLB中所有条目的失效,从而迫使CPU依据内存的目录和页表更新TLB。另外一种方法是特权指令invalpg。给这个指令一个线性地址,它会更新TLB中和那个线性地址对应的条目。
      《x86汇编语言——从实模式到保护模式》在最后给出了invalgp的使用范例。第17章代码的内核代码中,子程序create_copy_cur_pdir,(394行)处有指令:
                                  invlpg [0xfffffff8]
我认为,该指令应该为
                                  invlpg [0xffffe000]
因为涉及到目录、页表之间的反复“循环式”映射(某个目录项指向目录本身从将目录作业表用),作这个修正的原因一言两语难以解释清楚。
      事实上,做出上述修正后,第十七章的程序依然可以正常运行。甚至,删除上述invlpg指令后,所有程序依然正常运行。这是由于子程序load_relocate_program已开始就通过重新写cr3的方式令所有TLB条目失效。上面的invlpg操作,我认为,在cr3重写之后是多余的。另外,我尝试删掉cr3重写的指令,然后试着在load_relocate_program中所有可能因为TLB的不新鲜性而出错的地方利用invlpg令TLB的指定条目失效。第一,create_copy_cur_pdir子程序中,将指令invlpg [0xfffffff8]修改为invlpg [0xffffe000];第二,alloc_inst_a_page子程序中加入指令invlpg [ebx]。结果所有程序都可以正常运行。(我没有仔细筛查子程序load_relocate_program中所有需要增加invlpg的地方,修改这两处后,程序就okay了)。进一步,此时,一旦将子程序create_copy_cur_pdir中的invlpg [0xffffe000]修改回原来的invlpg [0xfffffff8],或者直接删掉该指令,都会导致程序无法正常工作。失去CR3的重写操作后,TLB的更新完全依靠invlpg指令,而此时,错误的指令invlpg [0xfffffff8]所带来的错误结果就表现出来了。这似乎进一步证明了原代码中的invlpg [0xfffffff8]是错误的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值