• 2008-04-19

    地址空间小记 - [电路与驱动]

    Tag:

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://hunbalo.blogbus.com/logs/19329948.html

    在clf上看到有人在问地址空间的概念,因为我也是花了些时间的积累才理解的,所以在这里做个总结。这些名词仅凭我的理解描述,或许同学术著作有些不同之处。 
     
    物理地址:是由CPU地址总线[A0…An]时序决定的地址,物理地址空间的大小为2的n+1次方。比如说32bits的总线,这个空间的大小是0x00000000-0xFFFFFFFF。

    总线地址:是由外设(包括RAM, ROM等)地址总线[A0…Am]时序决定的地址,空间大小也
    是2的n+1次方。

    物理地址空间,一部分给物理RAM用,一部分给总线用,这是由硬件设计来决定的,因此在
    32 bits地址线的x86处理器中,物理RAM一般不能上到4GB,因为还有一部分要给总线用。
    当然现在很多x86处理器address bus是36 bits或者更多。所以RAM容量支持还是蛮大的,
    特别是在服务器中。

    有硬件设计经验的都知道,给你一个1G的RAM,你在设计时可以把它译码到地址空间的
    任何一个合适的地址,在PC机中,一般是把低端物理地址给RAM用,高端物理地址给总线用。
    在ISA时代,CPU给出的部分地址(那个时代应该是IO地址)经过缓冲后就直接连到外设,
    但是外设一旦设计完毕,就不可改变,所以你买回一个板卡时,要拨动那些烦人的拨码开关,
    改变主板的译码逻辑,给每个外设分配一个独立的地址空间。

    在PCI时代,物理地址空间经PCI桥处理后才送到外设,在PCI桥这里可以动态分配地址了,
    这样就不会有重叠冲突的可能。

    虚拟地址:是CPU取指令或者取数据逻辑使用的地址,尽管没有打开映射时他们和物理地址是
    相同的。

    为什么要有虚拟地址?
    这个问题在操作系统中已经阐述的很明白,在多任务OS中,如果没有虚拟地址到物理
    地址的映射,比如说在ARM7上跑的ucos ii,那么在编译链接时,每个task的地址空间
    就得固定下来了,也就是说链接后,你想再添加一个task就不可能了,你想删除一个
    task也不可能了,尽管它已经死了,永远不会再执行(或者重新上电复位才会再执行)。

    而有虚拟地址这个概念后,可以给每个task都可以有一个0x00000000-0xFFFFFFFF的
    地址空间(在6.0版本以前的wince中不是这样),程序员在编写程序时,不用考虑链接
    到哪个地址,所有的task都是一样链接的,操作系统在装载task时,先申请一个物理
    空间,再把这个物理空间映射到这个task的0x00000000-0xFFFFFFFF这个虚拟空间中,
    就可以执行这个task了。(在linux,win32中,task高2Gb的虚拟空间每个进程都是重叠的,
    也就是所谓的kernel空间)。这样不执行的task就可以删除,把空间留给别的task用。
    当然虚拟地址的作用远比上述多得多,强得多,灵活得多,这里不展开来说了。

    有了上面的描述,不难理解,CPU发出取指令请求时的地址是当前上下文的虚拟地址,
    MMU再从页表中找到这个虚拟地址的物理地址,完成取指。同样读取数据的也是虚
    拟地址,比如mov ax, var. 编译时var就是一个虚拟地址,也是通过MMU从也表中来
    找到物理地址,再产生总线时序,完成取数据的,这其中还包含了缺页故障怎么处理,
    展开来说,太多了!

    物理空间和虚拟空间可以一样大,也可以比虚拟空间小,也可以比虚拟空间大,MMU的
    页表映射也有些处理器是完全由硬件实现的,比如SHx系列。

    收藏到:Del.icio.us




    评论

  • 个人以为虚实地址的概念用task地址空间解释是可以的,但是说“你想再添加一个task就不可能了”似乎不对