单龙芯3A3000-7A1000PMON研究学习-(17)撸起袖子干-分析代码前的准备工作4-地址映射

1.地址映射是搞得我最懵逼的地方,我也不知道我现在看懂没,先写上吧,有错误再改。

地址映射涉及到访问内存,访问外设(寄存器)啊。。。。不搞清楚,真的是程序看不懂。

2.首先物理地址吧。声明一下,龙芯3A3000启动就是使用虚拟地址。

2.1 上图《user1.pdf》

 这个图片显示龙芯支持48位地址,但是实际只用了44位(单芯片的情况下)

44位能访问的空间也是足够大了,16TB。(这是内存空间,应该目前够用了吧。硬盘的空间不占用在这个地址范围哈。)

每一片龙芯3A3000的物理地址范围地址就是0-0xfff,ffff,ffff 共16T

44位的最高位,为0表示共享Cache模块

                        为1 表示4个方向的端口设备。(如下图,只有两个端口(6,7)有效,4,5已省略。)

其中[42:41] 还要进一步划分为4个部分(结合[44],总共划分8个部分)。如下图:

 HT用于连接桥片(我的是7A1000),或者多片3A3000互联

根据实际的原理图,我的连接是在HT1上,所以访问桥片的物理地址是0xe00,0000,0000开始的地址。

2.2 一级XBAR和二级XBAR

这是龙芯的特色,机会都会涉及到这个话题。

 这个图中,一级XBAR每个master(共有6个master)有8个地址窗口,每个窗口有3个64位寄存器,分别位BASE,MASK,MMAP

还有命中公式(重要):输入的地址 & MASK 要与BASE相等才行,否则就是没命中。

注意:

2.3 有XBAR之后,7A1000的桥片地址也一同映射。

 这个是《7A1000user.pdf》中的截图。

 这里5个区域使用了一级XBAR进行映射。主要都是桥片的地址。

在2.1节中,我们看到桥片的空间就是要0xe00开头的这样44位的地址(使用HT1桥接口)

以下我只是根据印象猜测,可能仍不正确请多多指教:

比如图中的1,当cpu准备访问0x1000,00xx的时候,XBAR会自动转为0xe00,1000,00xx这样的地址(转换是有规则的!!!后面讲),实际访问的也是后面的这个地址。其他依次类推。

注意,这里仍然是物理地址。

3.虚拟地址,这也必须要用啊。

龙芯3A3000使用64位虚拟地址。这里需要说的是cpu一开始就是使用的虚拟地址。(其中有一段是不需要MMU参与地址转换的)。

0xbfc0,0000   --> 对应的物理地址正好是0x1fc0,0000. 这是启动地址,无需MMU参与。

之前接触的arm,在没有使能mmu之前,使用的是物理地址,使能之后,使用的是虚拟地址。

而龙芯是没使能mmu,也能使用部分虚拟地址。

3.1首先分用户态和核心态,用户态访问受限,核心态无限制。

kuseg : 0x00000000 ------ 0x7fffffff (2G)      user space
kseg0 : 0x80000000 ------ 0x9fffffff (512M)    unmapped, cached
kseg1 : 0xa0000000 ------ 0xbfffffff (512M)    unmapped, uncached
kseg2 : 0xc0000000 ------ 0xffffffff (1G)      mapped,   cached

32CPU下(32位早于64位设计,后来64位出来之后,仍然要兼容32位cpu),程序地址空间划分为4个大区域。每个区域有一个传统的名字。对于在这些区域的地址,各自有不同的属性:

kuseg: 虚拟空间0x0000 0000 - 0x7FFF FFFF (低端2G):这些地址是用户态可用的地址。在有MMU的机器里,这些地址将一概被MMU作转换,除非MMU的设置被建立好,否则这2G地址是不可用的。对于没有MMU的机器,存取这2G地址的方法依具体机器相关,你的CPU具体厂商提供的手册将会告诉你关于这方面的信息。如果想要你的代码在有或没有 MMUMIPS处理器之间有兼容性,尽量避免这块区域的存取。

kseg0: 虚拟空间0x8000 0000 - 0x9FFF FFFF(512M): 这些地址映射到物理地址简单的通过把最高位清零,然后把它们映射到物理地址低段512M(0x0000 0000 - 0x1FFF FFFF)。因为这种映射是很简单的,通常称之为非转换的地址区域。几乎全部的对这段地址的存取都会通过快速缓存(cache)。因此cache设置好之前,不能随便使用这段地址。通常一个没有MMU的系统会使用这段地址作为其绝大多数程序和数据的存放位置。对于有MMU的系统,操作系统核心会存放在这个区域。

kseg1: 虚拟空间0xA000 0000 - 0xBFFF FFFF(512M): 这些地址通过把最高3位清零的方法来映射到相应的物理地址上,与kseg0映射的物理地址一样。但kseg1是非cache存取的kseg1是唯一的在系统重启时能正常工作的地址空间这也是为什么重新启动时的入口向量是0xBFC0 0000。这个向量相应的物理地址是0x1FC0 0000。你将使用这段地址空间去存取你的初始化ROM。大多数人在这段空间使用I/O寄存器。如果你的硬件工程师要把这段地址空间映射到非低段512M 空间,你得劝说他。

kseg2: 虚拟空间0xC000 0000 - 0xFFFF FFFF (1G): 这段地址空间只能在核心态下使用并且要经过MMU的转换。在MMU设置好之前,不能存取这段区域。除非你在写一个真正的操作系统,一般来说你不需要使用这段地址空间。

综上可以看到,MIPS32 CPU下面的不经过MMU转换的内存窗口只有kseg0kseg1 512M的大小,而且这两个内存窗口映射到同一512M的物理地址空间。其余的3G虚拟地址空间需要经过MMU转换成物理地址,这个转换规则是由CPU 厂商实现的。还句话说,在MIPS32 CPU下面访问高于512M的物理地址空间,必须通过MMU地址转换。

在核心态下(CPU启动时)CPU可以作任何事情。在用户态下,2G之上的地址空间是非法的,任何存取将会导致系统异常处理。注意的是,如果一个 CPUMMU,这意味着所有的用户地址在真正访问到物理地址之前必须经过MMU的转换, 从而使得OS可以防止用户程序随便乱用。对于一个没有内存映射的OSMIPS CPU的用户态其实是多余的。在核心态下,CPU可以存取低段地址空间,这个存取也是通过MMU的转换。

3.2下面来谈谈MIPS64 CPU的虚拟地址空间。

64CPU的地址空间的最低2G和最高2G区域是和32位情况下一样的,64位扩展的地址部分在这两者之间。64位下那些大块的不需要MMU转换的窗口可以克服kseg0kseg1 512M的局限,但是32位下我们可以通过对MMU编程来同样达到这一点。

 在这个图中,右边出现的字母n表示结点号,我实际只有1个节点,所以n等于0;

0x90开头的虚拟地址(不使用cache的方式)和0x98开头的虚拟地址(使用cache的方式)可以映射整个物理地址空间,大小为2T(44位中还有3位要拿出来做设备选择,剩下41位)

 除了这两段之外,0xffff,ffff,8000,0000开始的那段地址的映射,与32位映射一致,只是(32转64的时候)高位补充的是符号位。

3.3 用户空间0x0-0x7fff,ffff,ffff这段需要MMU映射才能使用。

PMON阶段不使用,此时处于内核态。但是仍然会初始化TLB,为操作系统的使用做准备

4.cpu访问地址空间的行为

CPU拿到地址(虚拟地址),其转换过程如下步骤:
(1) 判断当前是kernel mode还是user mode
(2) 如果是kernel mode
      (A) 访问的地址是kuseg或者kseg2,进行 TLB 查找;如果查找不成功,exception。如果查找成功,得到物理地址
      (B) 如果访问的地址是 kseg0/kseg1,不进行TLB 查找;通过减去一个偏移量得到物理地址
(3) 如果是user mode
      (A) 访问地址kuseg,进行TLB 查找。如果查找不成功,exception。如果查找成功,得到物理地址
      (B) 访问kseg0/1/2,exception

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大智兄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值