博客主题

MIPS体系结构 Q & A Part 0x04 系统异常篇
由 帅云霓 在 周一, 2010-09-06 15:02 提交 内核研究31.
Q: 异常和中断有什么区别?
A: 中断是异常的一种,占用0号异常。中断是异步发生的,一般由硬件事件触发(如某GPIO引脚的电平跳变),和指令执行阶段无关。而异常是指令触发发生的,也就是同步发生的。
32.
Q: 什么叫“精确异常”?
A: "精确异常" 的原文是precise exception。precise这个词其实有“穷讲究”的意思。在这里指的就是:当异常发生时,已经执行完memory阶段操作的指令均有效,未执行到该阶段的指令,在流水线中一律丢弃。该异常的触发者为该条指令。
33.
Q: 对于TLB miss/Address error这样的异常,实际上为什么不会写入指令中的地址呢?
A: 因为这个时候指令只执行完ALU阶段,还没到Memory,所以被丢弃了。从处理器设计的角度来看,这种非法指令本身也不该生效。
34.
Q: 发生异常的时候,是不是会进入内核态?
A: 是的。当然如果原本就在内核态,那么还是会在内核态。一般来说,操作系统通用的进入内核,是通过一条syscall指令,产生类型为0x08的异常来实现的。
35.
Q: 我想知道,breakpoint, syscall和trap三种异常都是特殊指令触发的,它们有什么区别?
A: 一般说来,syscall指令是用于一般性的系统调用进入内核,类似于x86的调用门。
breakpoint是程序错误处理,例如,mips的除法指令,如果除数为0,会造成不确定的结果。编译器在对除法表达式进行处理的时候,就做一个判断,如果除数为0,则执行指令:break 0x07。如果运行时出现了除以0,那么,break 0x07这条指令会抛出一个breakpoint异常,子类型为0x07——这样,程序员在debug的时候看见这个异常信息,就可以判断,程序中除数出现了0。

MIPS体系结构 Q & A Part 0x03 CP0篇
由 帅云霓 在 周三, 2010-09-01 16:31 提交 内核研究20.
Q: CP0是干嘛的?
A: CP0是协处理器0,Co-Processor 0的缩写,MIPS最多可以支持4个协处理器,其中CP0是强制要求实现的,用于处理器的状态控制等。它包括MMU、异常控制、Cache控制等功能。
21.
Q: MIPS的其他协处理器都有什么呢?
A: 这个和具体厂商的实现有关系了。CP1是浮点协处理器,是可选的,CP2和CP3是厂家自定义的。
22.
Q: CP0里面都有哪些寄存器?一般用在什么场合?
A: CP0有32个寄存器,一般操作系统的内核才会接触到它们。主要有MMU类、异常控制类、断点控制类等。
23.
Q: 这几类寄存器各有哪些呢?
A: MMU相关的,有Index,Random, EntryLo0, EntryLo1, Context, EntryHi, MageMask和Wirds几个。具体用途介绍MMU的时候会提到。
异常控制相关的有Status, Cause, EPC, BadVaddr等。
断点控制的有Count, Compare, WatchLo, WatchHi等。
此外,还有PRId,用于确定CPU的类型;
LLAddr, 用于原子锁指令;
Config, 用于配置处理器。
24.
Q: 对CP0寄存器如何访问呢?
A: 有专门的指令访问。32bit读:
mfc0 rs, /*Move from co-processor 0*/
64bit读:
dmfc0 rs, /*Double move from co-processor 0*/
32bit写:
mtc0 rs, /*Move to co-processor 0*/
64bit写:
dmtc0 rs, /*Double move to co-processor 0*/
25.
Q: 对于CP0寄存器,如果只想修改其中的几个bit,该怎样做?
A: 只能先读取到GPR中,修改后写回。
如:
mfc0 t0, SR
nop
and t0, BIT_MASK_ALPHA
or t0, BIT_MASK_BETA
mtc0 t0, SR
nop
26.
Q: 为什么要在mfc和mtc后面插入一个nop指令?
A: 这是为了避免CP0 hazard,简单地说就是执行完mfc或mtc指令之后,有可能要等待一条指令的时间,数据才真正读取或写入到寄存器之中,在这个过程中如果修改相应寄存器会导致错误的结果。
27.
Q: 为什么会有hazard现象?

MIPS体系结构 Q & A Part 0x02 地址空间
由 帅云霓 在 周二, 2010-08-31 13:24 提交 内核研究11.
Q: MIPS的内存空间有多大?
A: 在32-bit模式下是4GB,用户态可以使用的空间是2GB。
12.
Q: 用户态是使用哪部分内存?
A: 虚拟地址0x00000000-0x7fffffff的2GB,叫做user space, mapped & cached.
13.
Q: 什么是用户态,还有哪些别的状态呢?
A: MIPS除了用户态还有内核态,在内核态下可以访问全部资源,但用户态只能访问部分,如CP0、MMU等,用户态是不可以访问的。
14.
Q: 那么,怎样从用户态进入内核态呢?
A: 一般的正常渠道是执行syscall指令。另外还有trap/brackpoint等指令,会引发相应的异常,进入内核态。当然程序错误引起的异常(如非对齐地址访问、未映射的地址访问)也会引发异常,进入内核态。
15.
Q: 在内核态下可以访问多大的内存空间呢?
A: 4GB,但是从0x80000000到0xBFFFFFFF有特殊用途。0x80000000到0x9FFFFFFF,和0xA0000000到0xBFFFFFFF这两段地址,硬件上指向同一段物理地址,0x00000000到0x1fffffff。
16.
Q: 为什么要这样做?
A: 0xA0000000到0xBFFFFFFF是不经过Cache访问的,可以保证在上电时就可用,并且,作为硬件IO寄存器映射地址时,不会被cache 扰乱。MIPS的上电启动地址,0xBFC00000就在这段内存中。而0x80000000到0x9FFFFFFF这段地址是经过Cache映射的,内核代码段和堆栈往往放在这一段内存,以保证访问和执行速度。
17.
Q: 我的硬件工程师将bootrom连接到总线的0xBFC00000地址了,为什么系统不能启动?
A: 0xBFC00000是逻辑地址(程序中的地址),对应的物理地址(将逻辑分析仪连接在总线上,捕捉到的地址)是0x1FC00000。
18.
Q: 那么,0xC0000000到0xFFFFFFFF的地址空间是干嘛的?
A: 可以作为内核使用的内存,比如kmalloc之类的函数分配使用。这段内存是通过MMU和TLB映射的。
19.

MIPS体系结构 Q & A Part 0x01 寄存器与内存访问
由 帅云霓 在 周日, 2010-08-29 21:53 提交 内核研究最近问我MIPS体系结构相关问题的人越来越多,在这里小结一下。
一般在职业有段者水平的MIPS体系结构问题,都能在这里找到答案。
1.
Q: MIPS有多少一般用途的寄存器?
A: 32个。
2.
Q: 我在看反汇编代码的时候,看到一些寄存器名叫zero, a1, a2...还有sp, ra这样的名字。为什么给他们起这些名字呢?
A: MIPS的通用寄存器中,按照编译器的通常的约定,某些寄存器是做专门用途的,比如sp就是堆栈指针,ra是函数调用的返回地址等等。当然你也可以不按照这些约定编程,例如用$2存放堆栈指针,$3存放返回地址,但这样的程序,和标准库链接就不能工作了。
3.
Q: 为什么MIPS的SP寄存器也是通用寄存器呢?而且MIPS似乎没有专门的压栈/出栈指令啊。
A: 这是MIPS这样的RISC处理器,同x86为代表的CISC处理器的重大区别之一。RISC没有专门的硬件实现的堆栈寄存器/指令,改为软件实现,在函数入口堆栈指针递减,堆栈向低地址生长,返回处恢复堆栈值,销毁堆栈帧。
4.
Q: MIPS的堆栈用软件实现,那么,MIPS的函数调用开销会更大吗?
A: 这是x86为首的CISC支持者,经常诟病RISC的一点。但是,实际上,我们知道,MIPS使用了4个GPR(一般用途寄存器)来传递前4个Word的函数参数,而x86只有EAX一个寄存器用于传递函数参数。所以,如果函数的参数小于或等于4个word,那就不需要使用栈。我们知道,大多数函数的参数都在4 个word以内。——所以,这一点不比太担心。另外,写太多参数的函数时,建议使用结构体传递这些参数。
5.
Q: MIPS的lh, lb这样的指令,会改变寄存器里的前2个/1个字节,还是后2个/1个字节?
A:一般来说是低位。
6.
Q: MIPS是大端(Big-endian)的,还是小端的(Little-endian)?

关于spinlock的二三事
由 droplet 在 周五, 2010-08-20 18:33 提交 编程实践spinlock是multicore编程里面最基本的一个同步机制,关于spinlock,有以下事实
1) 为什么需要spinlock?
spinlock需要忙等待,thread不能切换出去做其他事,这与其他一下同步机制,比如semaphore不太
一样。所以spinlock的用途和其他同步机制不同,比如从网卡收包,假设多个thread都可以从网卡收包,
并把收到的包放入一个队列,队列是用spinlock保护的,如果不忙等待,而是可以切换出去,就需要保存
当前thread的状态可以参数,也就是当前这个包需要找一个地方保存起来,然后这个thread才能切换出去
做其他事情,而新的thread调度进来之后,才能继续原来的工作(thread可以放到等待队列,然后被唤醒),
这个在realtime系统是不行的,因为packet需要被及时处理。如果处理的时间不能确定,latency就会很大,
会影响其他应用。
2) spinlock的各线程是相互竞争的,谁能获取锁是不确定的,但是机会是平等的。一个release lock,然后再
获取锁的thread,机会就比忙等待的线程小一点,因为cache flush也load instruct都需要时间。
3) 需要lock哪些东西?
使用spinlock的目的是为了在访问某个数据结构时,数据结构的状态是确定的,比如多个CPU同时执行
a += 1
这段代码不是原子的,如果没有spinlock,每个CPU在访问a是,它的状态都不是确定的,那么,最后的结果就是
不确定的。所以需要这个动作顺序地执行。如果程序的执行不依赖于数据结构的状态,那么就不需要锁。比如在
一个数组里面查找某个数
+--2--+--3--+-4---+-4---+

FORWARD
由 stonezhang 在 周四, 2010-08-19 21:50 提交 IT人生近来在做Firewall方面的一些事情,对filter 中的 FORWARD时 -i/-o interface不太明白。
对于-i, 它只用于 input and prerouting .
对于-o, 它只用与 output and postrouting.
这些都容易理解。
惟独对forward, -i/-o都可以,怎么来区分何时用-i, 何时用-o.

Toy vs tool
由 droplet 在 周四, 2010-08-12 18:57 提交 业界评论最近在www.youxia.org上看许多安全产品的介绍,感觉产品太多了,每一种都有许多厂家在做,而且还有很多oem等等。
很热闹,也很混乱。但是在这个行业能够立足,并且发展的,是那些做tool的公司,而不是做toy的公司。如果只是个玩具,
当然只要有基本的功能就可以了,但是要做在用户那里能够工作的产品,就需要很多产品化的东西。所谓的产品化,需要考虑
以下几个问题:
1)提供哪些功能,哪些是真正有用的功能?并不是功能越多就越厉害,多并不代表能用;在实验室里能用,并不代表在真实环境
里面能用;在小流量的情况下能用,并不代表在大流量下也能用。做出来的功能,不是为了当摆设,需要哪些,舍弃哪些,需要产品
定义的人好好考虑。
2)是否有可持续的roadmap。如果一个产品没有roadmap,那么认真的客户是不会考虑这个产品的。因为一个产品不可能一次就
做得很完美,不需要增加新的功能,不需要改善性能等等。出产品需要一个周期,在这个周期里面,需要给客户一些promise,一些
confidence,也就是说产品在不断改进之中。产品的未来是可预见的,这样用起来才放心。
3)持续改进的措施。需要从过去的错误或者经验里面学习。没一次产品升级,都能改进原来的不足和缺陷。在产品生命周期里面,对
bug/issue等等,有持续的跟踪。只有这样,才能学习和积累。否则当前做的事对未来一点帮助都没有,做了有什么意义。任何一个在
行业内领先的公司,都有比其他公司更多,更深的积累。不单是技术,也包括市场,服务等等。

关于big-endian 和 little-endian
由 Avenue 在 周三, 2010-08-11 18:18 提交 编程实践和大家share一下最近在网上收集到的资料和自己的体会,同时自己添加一个例子。
一、基础知识
1、位(bit)
来自英文bit,音译为“比特”,表示二进制位。位是计算机内部数据储存的最小单位,11010100是一个8位二进制数。一个二进制位只可以表示0和1两种状态(21);两个二进制位可以表示00、01、10、11四种(22)状态;三位二进制数可表示八种状态(2^3)……。
2、字节(byte)(可以理解为物理单位)
字节来自英文Byte,音译为“拜特”,习惯上用大写的“B”表示。 字节是计算机中数据处理的基本单位。计算机中以字节为单位存储和解释信息,规定一个字节由八个二进制位构成,即1个字节等于8个比特(1Byte=8bit)。八位二进制数最小为00000000,最大为11111111;通常1个字节可以存入一个ASCII码,2个字节可以存放一个汉字国标码。
3、字 (可以理解为逻辑单位)
计算机进行数据处理时,一次存取、加工和传送的数据长度称为字(word)。一个字通常由一个或多个(一般是字节的整数位)字节构成。例如286微机的字由2个字节组成,它的字长为16;486微机的字由4个字节组成,它的字长为32位机。 计算机的字长决定了其CPU一次操作处理实际位数的多少,由此可见计算机的字长越大,其性能越优越。
另一种说法:
字
在计算机中,一串数码作为一个整体来处理或运算的,称为一个计算机字,简称宇。字通常分为若干个字节(每个字节一般是8位)。

Optimizing for instruction caches
由 droplet 在 周一, 2010-08-09 10:35 提交 编程实践
What is ALG for?
由 droplet 在 周三, 2010-08-04 14:47 提交 编程实践ALG(application level gateway)的作用是什么?
1)connectivity,也就是允许application的traffic 通过。特别是在application使用动态端口的情况下,policy/acl一般是
无法静态配置的,所以需要ALG动态地打开协议端口,允许traffic通过。
2)NAT aware,如果application是穿过nat box,需要ALG改动payload里面的地址,并建立地址与地址直接的映射,否则
application还是无法建立连接。这里无法连通的原因是地址不匹配,而不是access control。
3) security,这里面有几个含义。一是protocol验证,对非法的协议验证;二是防止DoS攻击。网络层是不知道具体的协议
是什么,而application层知道,所以可能控制的更精细。网络层的access control/dos等等,是第一道门,在application层,
可以更精确,也更准确。让ALG做这个事是勉为其难,不过到了application level,功能都是相通的,谁做都一样。

最新评论
16 小时 18 分钟 前
1天 1 分钟 前
1天 19 小时 前
2 天 17 小时 前
5 天 15 小时 前
5 天 15 小时 前
5 天 20 小时 前
1周 20 小时 前
1周 23 小时 前
2 周 1天 前