Cavium MIPS的内存布局和映射

Cavium  MIPS的内存布局

 

这里主要想讨论MIPS架构的内存分配问题,对Cavium的了解比较多,所以从熟悉的芯片开始做衍生。Cavium的架构基本上会遵循MIPS的内存分配规则,不会有太大的差异。所以以下讨论均基于Cavium的MIPS架构。

 

一、物理地址的分配

关于物理内存的讨论,也是基于64bit架构的。MIPS的64bit架构在上世纪90年代开始了。其技术一直都领先于其他的架构处理器。MIPS中采用统一编址架构,IO和Memory使用同样的访问方式。在64bit中实际使用49bits来实现物理地址的访问,其中包括system memory(DRAM) 和IO space。PABITS=49,也就是bits<48::0>。

49bits物理地址格式

其中

IO---I/O bit,决定是访问memory 还是IO space

DID---直接访问的hardware block,映射到芯片中的不同的IO 部件上。

Offset –memory或者IO空间的地址值。

 

那么以这种方式实现的设计是如何的呢?下图中可以大概的列出物理地址的分配问题。

IO部分的分配:

 System memory部分的分配:

针对system memory这一块,系统实际上只使用了36bits来寻址16G的system memory,所以,Cavium MIPS只支持到16G的物理内存大小。但是我们从图上可以看到,真正起作用的也只有35bits而已,这个足以实现16G system memory的访问了。

值得注意的是,图中这这16G 物理内存的寻址空间是有非连续的,分成了三部分:

DR0:256MB [0x0 – 0xfff_ffff]

DR1:256MB [0x4_1000_0000 – 0x4_1fff_ffff]

DR2:15.5GB [0x2000_0000 – 0x3_ffff_ffff]

好像是,DR1部分本来该在[0x1000_0000 – 0x1fff_ffff]段的,但是被抠出来放到了高端地址部分了。但是实际上这里有个转换动作,由于在启动的时候bootbus部分bfc0_0000会映射到物理内存的低端地址处,也就是0x1000_0000 –0x1fff_ffff中间一段。所以,system memory不会使用这段地址,而是在等待bootbus的寻址已经完成之后,比如启动稳定之后,系统对memory的访问,Dram controller会将bit[35:34]屏蔽掉,那么对DR1的访问自然就会映射到地址段0x1000_0000 – 0x1fff_ffff部分了。所以这时候DRAM controller看16G的system memory是连续的。

 

二、32bit的虚拟内存的讨论(本节为转载,写的很好,就没有自己另外去写了)

在32位MIPS体系结构下,最多可寻址4GB地址空间。这4GB空间的分配是怎样的呢?让我们看下面这张图:

      +-----------------------------------------------------------------+

      |                       | 0xFFFFFFFF

      |                       |

      |                       |

      | Kernel Space Mapped Cached (kseg2)   |

      |                       |

      |                       |

0xC0000000 |                       |

      +-----------------------------------------------------------------+

      |                       | 0xBFFFFFFF

      | Kernel Space Unmapped UnCached (kseg1)    |

      |                       |

0xA0000000+------------------------------------------------------------------+

      |                       | 0x9FFFFFFF

      | Kernel Space Unmapped Cached (kseg0)         |

      |                       |

0x80000000+------------------------------------------------------------------+

      |                       | 0x7FFFFFFF

      |                       |

      |                       |

      |                       |

      |    User Space               |

      |                       |

      |                       |

      |                       |

      |                       |

      |                       |

0x00000000 +-----------------------------------------------------------------+

         Figure 2-1 MIPS Logical AddressingSpace

 

上图是MIPS处理器的逻辑寻址空间分布图。我们看到,2GB以下的地址空间,也就是从0x00000000到0x7FFFFFFF的这一段空间,为User Space,可以在User Mode下访问,当然,在Kernel Mode下也是可以访问的。程序在访问UserSpace的内存时,会通过MMU的TLB,映射到实际的物理地址上。也就是说,这一段逻辑地址空间和物理地址空间的对应关系,是由MMU中的TLB表项决定的。

  从0x80000000到0xFFFFFFFF的一段为Kernel Space,仅限于KernelMode访问。如果在User Mode下试图访问这一段内存,将会引发系统的一个Exception。MIPS的  Kernel Space又可以划分为三部分。首先是通过MMU映射到物理地址的1GB空间,地址范围从0xC0000000到0xFFFFFFFF。这1GB空间可以用来访问实际的DRAM内存,可以为操作系统的内核所用。

  MIPS的Kernel Space中,还有两段特殊的地址空间,分别是从0x80000000到0x9FFFFFFF的Kernel Space Unmapped Uncached和0xA0000000到0xBFFFFFFF的Kernel Space Unmapped Cached。之所以说它们特殊,是因为这两段逻辑地址到物理地址的映射关系是硬件直接确定的,不通过MMU,而且两段实际上是重叠的,均对应0x00000000到0x20000000的物理地址。那么,为什么一段同样的物理地址有两个逻辑地址对应呢?它们的区别又在哪里呢?

  原来,这是MIPS的设计特色之一。软件在访问Kernel Space Unmapped Uncached这段地址空间的时候,不经过MIPS的Cache。这样,虽然速度会比较慢,但是,对于硬件I/O寄存器来说,就不存在所谓的Cache一致性问题。Cache一致性问题,是指硬件将某个地址的内容跳过软件而改变了,Cache中的内容尚未同步。这样,如果软件读取该地址,有可能从Cache中获取到错误的内容。将硬件I/O寄存器设定在这段地址空间,就可以避免Cache一致性带来的问题。MIPS的程序上电启动地址0xBFC00000,也落在这段地址空间内。——上电时,MMU和Cache均未初始化,因此,只有这段地址空间可以正常读取并处理。

  另一段特殊的地址Kernel Space Unapped Cached,与前者类似,直接映射到0x00000000到0x20000000,与KernelSpace Unmapped Uncached重叠。因为通过Cache,这段地址空间的访问速度比前者为快。一般地,这段内存空间用于内核代码段,或者内核中的堆栈。

  显然地,当工程师们换算Kernel Space中的这两段的物理地址和逻辑地址时,只需要改变地址的高3bit就可以了。

  

三、64bit的虚拟内存的讨论

MIPS的虚拟内存的划分是以‘segments’来实现的,但不是所有的segments都是可以映射的。虚拟地址的转换需要依赖这些条件:

1、 地址空间使用的address bits :64bit 或者32bit 地址空间。

2、 Segment 的选址

3、 权限级别:kernel、supervisor 或者user。

 

对于64bit的虚拟地址映射,虚拟地址的高位的两个bit用来选择四个segment中的一个,当然这些地址位的转换都是由Hardware来完成的。剩下的62bits则有部分bit是忽略被处理器忽略的。如下图所示:

 

在64bit的虚拟地址空间中,可以划分为四个segment:xkseg、xkphys、xsseg、suseg等。如下图所画,分别所处的地址空间为:

Xkseg:0xc000_0000_0000_0000 –- 0xffff_ffff_ffff_ffff                  :kernel mapped

Xkphys: 0x8000_0000_0000_0000  -– 0xbfff_ffff_ffff_ffff               ;kernel  unmapped

Xsseg:  0x4000_0000_0000_0000 -– 0x7fff_ffff_ffff_ffff               ;supervisor mapped

Suseg:  0x0000_0000_0000_0000 -– 0x3fff_ffff_ffff_ffff               ;user mapped

 

而64bit是兼容32bit的,处理方式就是将32bit的虚拟地址的高位进行扩展。比如32地址0x7fff_fff0,最高位是0,扩展到64bit之后,变成了0x0000_0000_7fff_fff0;而比如地址0x8000_fff0,最高位是1,扩展到64bit之后,变成了0xfff_ffff_8000_fff0. 依据这种方式,那么32bit的地址空间扩展到64bit的地址空间是怎么样的呢? 下图也有划分出来。之前的低字节的2G部分user space 依然扩展到64bit地址空间的低字节部分2G。而之前的高字节部分2G kernel space 扩展到64bit空间的最高端2G。

 

 


你可能感兴趣的:(MIPS点滴)