好文共欣赏------ Gustavo Duarte Linux相关文章翻译之一: 主板芯片组和存储映射

最近在学习Linux memory management的时候, 找到一个很好的blog. 看了几篇博主post的文章, 觉得很受启发.

决心加加油, 做些翻译. 也是加深理解. 有些专业性的词汇, 为了避免歧义, 会直接采用英文原文.图片也会用原文的Po图.

另外, 这些翻译都是经过Gustavo本人允许. 

第一篇题为 主板芯片组和存储映射 (Motherboard Chipsets and the Memory Map) 

[ link: http://duartes.org/gustavo/blog/post/motherboard-chipsets-memory-map ]


我打算写一些有关计算机内部结构的博文, 好解释现代的操作系统内核是如何工作的. 希望能对一些在这方面没有经验, 又非常感兴趣的程序员或爱好者提供一些帮助. 这些专题主要关注在Linux, Windows以及Intel的处理器. 事实上, 研究计算机内部是如何运作, 算是我的爱好之一. 我曾经写过一些类似Kernel的code, 不过已经有段日子没做这些了~ 第一篇文章就来谈谈现代Intel-based的主板上的芯片组是如果排布的, CPU是如何访问Memory, 以及系统的Memory Map.


在开始之前, 我们先来看看当前Intel的计算机是怎么组装起来的好了. 下面的这张图说明了一张主板上的主要组成部分(图作者对色彩的品味似乎不佳哈... 作者原话.... 勿拍 -_- )



正如你所看到的, 有个非常非常非常重要的概念一定要时刻牢记, 那就是:对于CPU而言, 它事实上无法得知连接它身后的究竟都有哪些东西. CPU仅仅能通过它的pin脚(点击可看详情)与外界交流, 不过对CPU来说, 外界环境到底是什么样, 其实一点也不重要. 也许是一整张主板, 也有可能是烤面包机, 网络路由, 脑部移植物等待(o_o).... 或者是CPU测试参照体什么的...总之都对CPU来说都不甚重要. CPU与外界交流通信的方式大体上说来有三种: 内存地址空间(memory address space), I/O地址空间(I/O address Space), 还有中断(Interrupt). 我们目前讨论的内容主要集中在前两种方式.


在主板上CPU都是通过北桥上的前端总线(Front-side Bus)去访问外部环境的. 不论是CPU需要读Memory还是写Memory, 都必须通过这条总线. CPU上某些pin脚被用来传输将被读写的物理内存地址, 有些pin脚则被用来传输或接收需要被读写的数据. 就Intel Core2 QX6600来说, 有33个pin脚是用来传输物理地址的, 因此理论上CPU可以访问的地址空间233 . 同时有64个pin脚用来传输或接收数据, 因此数据可以以64-bit或8-byte作为传输路径来传输. 这样, 从理论上来说, CPU可以访问的Memory的总和是64GiB (233 locations * 8 bytes), 当然现实中的大部分芯片组值只支持处理到8GiB的RAM.


那么现在问题的难点来了: 我们通常所认知的Memory只涉及到RAM, 就是应用程序会不停读写的东西. 而事实上由处理器发出的大部分内存访问请求是通过北桥route到RAM的. 但不是所有的Memory请求都会发给RAM. 物理内存的地址同样也可以被用来跟主板上五花八门的设备进行通信, 这就是所谓的I/O存储映射(Memory-mapped I/O 点击可看详情). 这些设备包括视频卡, 大部分的PCI卡以及存储BIOS的flash Memory.


当北桥收到一个物理地址访问请求的时候, 它会首先判断把应该请求转发给谁: 是RAM吗? 还是视频卡呢? 也就是说当前CPU是想访问RAM还是其他的I/O设备. 究竟是想访问谁实际上是由存储地址怎样映射决定的. 对每一块的物理存储地址来说, 存储映射关系决定该地址归谁所有. 这33个pin脚所携带的地址是属于RAM还是其他I/O设备就是由这些映射关系决定的. 大部分的地址都被Mapping到了RAM上. 一旦发现有地址不在这些RAM的Memory map中时, 表示将有特定的设备去响应访问这些地址的相关请求. 这些RAM之外的Memory Address Mapping就是经典的PC上从640KiB到1MiB的I/O Memory Holes(译者注:I/O Memory Hole这个东东貌似是个历史产物... 涉及到Memory Layout. 还没研究明白 给张图 示意图). 如果需要保留一些内存地址(Memory Address)给视频卡或PCI设备的话, 这个内存洞(Memory Hole)将会变得更大. 在32位操作系统使用4GiB内存的时候, 常常会发现系统报告的内存是小于预期大小的. 其实就是因为内存洞的存在(Windows 4GiB内存所遇问题). 在Linux下输入/proc/iomem 就可以看到这些Memory是怎么映射的. 下图为Intel PC中, 4GiB的内存布局:

        


上图仅仅表示一种典型的内存布局(Memory Layout). 具体的地址范围还以实际中PC的主板和设备为准. 但对大部分的双核系统来说, 基本都是符合上图描述的. 所有灰色的部分表示映射到RAM, 棕色的则对应其他的硬件设备. 有件事请务必牢记:这些都是实际的物理地址(Physical Address), 都是有主板上的总线来对应的. 而那些在CPU内部运行的应用程序, 它们进行直接读写的, 事实上是逻辑地址(Logical Address). 这些逻辑地址会被CPU转换为真正的物理地址, 然后才能通过总线传输, 读写真正的物理内存.


具体怎么把逻辑地址转换为物理地址, 这个过程其实是很非常复杂的. 而且跟CPU的运行模式有很大关系(real mode, 32-bit protected mode, and 64-bit protected mode). 除了逻辑地址到物理地址的转换机制, CPU的运行模式还可以决定有多少物理内存可以访问. 举个例子好了. 比如当前CPU是32-bit mode, 它的最大物理地址就只能到4GiB(当然啦, 其实有个例外叫物理地址扩展(PAE). 不过这里不考虑). 大约有1GiB(数值可以被更改)左右会被Mapping到主板的一些设备, 所以只剩下3GiB的RAM来给CPU使用. 有时候甚至不到3GiB, 我的Vista实际上只有2.4G的内存大小. 如果CPU是在real mode呢? 那么CPU就只能访问1M的物理内存(Physical RAM). 只有早起的Intel处理器才有这种模式. 当CPU在64-bit mode的时候, 就会有64G的地址空间了. 当然目前很少有芯片组支持到这么大的RAM. 在64-bit mode的时候, CPU理论上可以访问的地址空间往往大于实际RAM的大小, 多出来的那些也就理所当然的被主板上林林总总的设备拿去用了. 这就是对芯片组而言非常有用的回收内存(译者注: 芯片组回收内存可以研究这篇: 32-bit系统中的4G内存).


在下篇文章中我们将讨论系统开机流程, 这个过程包括从系统上电开始, 直到bootloader叫起Kernel. 如果你对上述内容很感兴趣, 强烈建议可以参考Intel的手册看看. (译者注: 原文中列出了相关的pdf档案, 有兴趣可以参看).


另外敬请期待下篇: How Computers Boot up.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值