Why [0x0000fffffff0] f000:fff0 instead of ffff:0000?

以上是计算机加电执行的第一条指令,在该行的左侧,显示了该指令所在的物理内存地址,该地址是用方括号围起来的,你可能会想,他怎么会是0x0000FFFFFFF0呢?
8086有20根地址线,加电启动后,代码段寄存器CS的内容为0xFFFF,指令指针寄存器IP的内容为0x0000,因此第一条指令的物理地址是20位的0xFFFF0。但是8086已经成为历史,它之后的处理器都能够兼容8086的功能,但却拥有超过32根的地址线。在当前的这个Bochs虚拟机上,地址线的数量就是32根,bochs在这里用48位的宽度来显示物理地址,但是它的值应该是0x0000000FFFF0,不是吗?
事情是这样的,和8086不同,现代处理器在加电启动时,段寄存器CS的内容位0xF000,指令指针寄存器IP的内容位0xFFF0,这就是的处理器地址线的低20位同样是0xFFFF0。这还不算完,在刚刚启动时,处理器将其余的(高位部分)地址线强制为高电平,直到遇到并执行了第一个段间指令。因为当前bochs的地址线位32根,所以,初始发出的物理地址内存地址就是0x0000FFFFFFF0了。
之所以这样做,是因为处理器的设计者希望把ROM-BIOS放到4GB(32地址线可选值范围为4GB)的最高端,这样,4GB以下,连同传统的地段1MB都是连续的RAM区,连续的、不间断的RAM能为操作系统管理内存带来方便。
问题在于,计算机制造商们会考虑很多现实问题。老的硬件和软件依赖于地段1MB的ROM-BIOS来工作,这涉及到兼容性。最终,这两个地址区段都指向同一块ROM芯片。
Why 0x7c00?
Why 0100h in com
Why we need rpl?
How does BIOS establish IVT?
你可能会奇怪,BIOS如何建立起低地址1KB的中断向量表和相应的中断例程?它又是怎么知道访问硬件的?毕竟,即使是它,要访问硬件也要通过端口一级的途径。
答案是,BIOS可能会为一些简单的外围设备提供初始化代码和功能调用代码,并填写中断向量表,但也有一些BIOS中断是由外部设备接口自己建立的。
首先,每个外部设备接口,包括各种板卡,如网卡、显卡、键盘接口电路、硬件控制器等,都有自己的只读存储器(ROM),类似于BIOS芯片,这些ROM提供了他自己的功能例程,以及本设备的初始化代码。按照规范,前两个单元的内容是0x55和0xAA,第三个单元是本ROM中以512字节为单位的代码长度;从第四个单元开始,就是实际的ROM代码。
其次,我们知道,从内存物理地址A0000开始,到FFFFF结束,有相当一部分空间是留给外围设备的,如果设备存在,那么,它自带的ROM会映射到分配给它的地址范围内。在计算机启动期间,BIOS程序会以2KB为单位搜索内存地址C0000~E0000之间的区域。当他发现某个区域的头两个字节是0x55和0xAA时,那意味着该区域有ROM代码存在,是有效的。接着对该区域做累加和检查,看结果是否和第三个单元相符,如果相符,则从第四个单元进入。这是处理器执行的是硬件自带的程序指令,这些指令初始化外部设备的相关寄存器和工作状态,最后,填写相关的中断向量表,使他们指向自带的中断处理过程。
