Chinaunix

标题: 关于ROM BIOS的启动问题 [打印本页]

作者: daidongly    时间: 2008-02-27 23:56
标题: 关于ROM BIOS的启动问题
最近看了一本书,提到ROM中的系统BIOS程序在系统启动时的处理过程,看过以后不是很明白,希望大侠能够指点一二。

1,文中提到,为使PC/AT计算机向上兼容,系统会产生一个影子区域,即BIOS代码会被复制到这个区域,而另一方面原来系统ROM中的基本输入输出程序BIOS一直处于CPU能寻址的内存最高端位置处。
     不太明白的是,保证ROM中BIOS程序一直处于CPU能寻址的内存的最高端位置处是在什么时候完成的?

2,文中提到,PC/AT微机的BIOS有可能大于64KB。而我们在内存中留出的影子区域(shadow)也就是ROM BIOS的映射区只有64KB。
那么我们是怎么选择复制哪些BIOS程序呢?

3,文中提到,BIOS程序会使用一种称作32位大模式的技术把数据寄存器的访问范围设置为4G(原来是64KB)。而BIOS在执行一些列硬件检测和初始化操作后,就会把于原来PC机兼容的64KB BIOS代码和数据复制到内存低端1MB末端的64KB处,然后跳转到这个地方应且让CPU进入真正的实地址模式工作。
     请问上面这个过程具体是怎么实现的?什么叫做真正的实地址模式呢?

第一次提问,不知道是不是太小白了,不过确实想不明白,谢谢关注的人,希望能有人帮忙~
作者: zx_wing    时间: 2008-02-28 01:15
原帖由 daidongly 于 2008-2-27 23:56 发表
最近看了一本书,提到ROM中的系统BIOS程序在系统启动时的处理过程,看过以后不是很明白,希望大侠能够指点一二。

1,文中提到,为使PC/AT计算机向上兼容,系统会产生一个影子区域,即BIOS代码会被复制到这个 ...

1. BIOS代码的copy很常见。即在启动过程中,BIOS的代码会被拷贝到一个指定的虚拟地址,其主要用途多用于OS在运行过程中实时的调用BIOS提供的接口。是否拷贝到虚拟地址的高端部分应该是操作系统决定的,例如windows就是如此,估计LZ看的书是以windows为例。

2.第二个不懂哦,这里为bios留出的shadow区域是什么意思,估计是leagcy bios的规定。bios不一定是只有64k,例如intel的EFI就可以达到2M多的大小。

3.这里说的是IA32架构的big real mode。有人认为这是cpu的一个bug。其过程是进入保护模式后,将各个段寄存器设置恰当后再退回到实模式,就可以在实模式下访问和保护模式下一样的4G地址空间。LZ可以google其详细流程。
作者: daidongly    时间: 2008-02-28 02:07
谢谢!

第二个问题估计是我自己没说清楚,现在回过头来自己看看都觉得不知所言。
我到网上Google了下,看到了些文章。不过还是有不少地方不懂~我尽量表述的清楚点呵

开机后,CPU重置,从地址FFFFFFF0取第一个命令,这个地址正好落在ROM BIOS中。该地址内容一定是一个JMP指令,系统便跳转到该JMP指令所指的地方。

1,而这里之后我开始不明白了。JMP要跳转到的位置是在高地址(4G末端)Flash Rom BIOS中还是在低地址(1M末端)的shadow BIOS呢?

2,位于低地址(1M处)的(BIOS shadow)是从Flash BIOS拷贝而来呢,还是没有任何拷贝过程仅仅利用地址映射到原Flash BIOS中的呢?

3,无论是拷贝还是映射,内存地址空间上ROM BIOS映射区只有 0xF0000~0x100000之间的64KB。而ROM本身有可能大于2M。那映射的应该是原BIOS程序的一部分,那么是哪一部分呢?

我很头大,不知道有没有问到点子上,盼解答。


作者: zx_wing    时间: 2008-02-28 12:48
原帖由 daidongly 于 2008-2-28 02:07 发表
谢谢!

第二个问题估计是我自己没说清楚,现在回过头来自己看看都觉得不知所言。
我到网上Google了下,看到了些文章。不过还是有不少地方不懂~我尽量表述的清楚点呵

开机后,CPU重置,从地址FFFFFFF0取 ...

恩,这部分我不感确定说的正确,mik对开机流程很清楚的,说错了请纠正,还有版主哈:wink:
>>1,而这里之后我开始不明白了。JMP要跳转到的位置是在高地址(4G末端)Flash Rom BIOS中还是在低地址(1M末端)的shadow BIOS呢?

肯定跳转的目标在1M+64k以下,不会到4G末端。因为这个时候还处于实模式,无法寻址到4G末端去。
注意,big real mode是必须执行到保护模式再退回实模式才行,这个时候离开机已经走了很远了。

>>2,位于低地址(1M处)的(BIOS shadow)是从Flash BIOS拷贝而来呢,还是没有任何拷贝过程仅仅利用地址映射到原Flash BIOS中的呢?

是拷贝到内存中的。如果是直接映射的BIOS的flash的话,那就是做I/O,效率就很低了。
这个应该不叫拷贝,应该说是加载。通常说BIOS拷贝是指下面的内容

在实模式时,执行的都是未拷贝的BIOS代码(还位于被加载到内存中的位置)。拷贝通常应该是OS为了在运行过程中调用BIOS代码,而把BIOS代码“挪”到其它的地方,例如4G末端;或者是OS要使用BIOS占用的地址空间,而进行“挪”。发生拷贝的时候离启动已经很远了。所以开机时执行的仍然是未拷贝前的BIOS代码。

>>3,无论是拷贝还是映射,内存地址空间上ROM BIOS映射区只有 0xF0000~0x100000之间的64KB。而ROM本身有可能大于2M。那映射的应该是原BIOS程序的一部分,那么是哪一部分呢?

leagcy BIOS,也就是传统的BIOS大小应该都在64K之下。ROM本身大于2M,并非ROM就全部是用来装BIOS代码,例如用于存储设置的NVRAM,应该也包含在ROM之中。其次,ROM本身比BIOS例程大,也有提供给OEM商做扩展的用途。例如现在很流行的linux-BIOS项目就是把一个裁剪过的linux放在BIOS中(听说华硕都出产品了 )。
此外,如果BIOS代码本身大于64K,那么它在地址空间中的布局就会有变化,例如我所用的平台上BIOS代码就位于4G-16M而非0xF0000~0x100000

个人的一些看法,欢迎大家指正。

[ 本帖最后由 zx_wing 于 2008-2-28 17:27 编辑 ]
作者: zx_wing    时间: 2008-02-29 12:39
原帖由 zx_wing 于 2008-2-28 12:48 发表

恩,这部分我不感确定说的正确,mik对开机流程很清楚的,说错了请纠正,还有版主哈:wink:
>>1,而这里之后我开始不明白了。JMP要跳转到的位置是在高地址(4G末端)Flash Rom BIOS中还是在低地址(1M末端)的 ...

第二个问题我应该说错了。
如果第一次执行的时候不是用的映射,那么把代码加载到内存中的动作应该是谁做的呢?那就应该用的是映射。
我查查资料先。惭愧
作者: cainiao911    时间: 2008-02-29 19:59
楼主是不是在看BIOS研发技术剖析?
作者: zx_wing    时间: 2008-02-29 21:54
关于第二个问题,我想应该是用map的,我没找到具体资料,但有一份关于BIOS启动时的option rom的资料。opition rom是映射的,所以BIOS应该也是映射的。
希望了解的朋友讲一下。
这份spec也不错,如果LZ在研究BIOS,我想对你有益,作为附件上传

BIOS_Boot_Spec_v1.01.pdf

178.89 KB, 下载次数: 1369


作者: cainiao911    时间: 2008-02-29 22:40
我看过一些资料,可能是错误的,仅供参考,切勿笑话。
1,386以后的cpu没有什么真正的实模式,执行第一条指令时,也就是"jmp far f000:e05b"的时候就是所谓32位的分段机制(就是用GDT,IDT来分段的那个什么来着),32位CPU在实模式下的分段机制其实就是加了一些限制的32位分段机制,很明显,执行第一条指令的时候A20是开启的。这个问题说起来话长,这里就不多说了,就此打住。我的观点是这个跳转是跳到1M以下的那个BIOS,在bochs里面就可以看到,第一条指令的地址是0xFFFFFFFF0,而第二条则位于0x000FE0FD.


2,据我了解,应该是拷贝的, 在bochs源代码中,有一个BIOS的实现,包括rombios.c,rombois32.c等文件,大致流程是,先切换到32位模式,然后把flash rom中的bios拷贝到一个临时区域,再告诉北桥芯片组将原先分配给flash BIOS的地址重新分配给DRAM bios.关于这一点,我们可以在rombios32.c的源代码中看到:

static int find_bios_table_area(void)
{
    unsigned long addr;
    for(addr = 0xf0000; addr < 0x100000; addr += 16) {
        if (*(uint32_t *)addr == 0xaafb4442) {
            bios_table_cur_addr = addr + 8;
            bios_table_end_addr = bios_table_cur_addr + *(uint32_t *)(addr + 4);
            BX_INFO("bios_table_addr: 0x%08lx end=0x%08lx\n",
                    bios_table_cur_addr, bios_table_end_addr);
            return 0;
        }
    }
    return -1;
}

static void bios_shadow_init(PCIDevice *d)
{
    int v;

    if (find_bios_table_area() < 0)
        return;

    /* remap the BIOS to shadow RAM an keep it read/write while we
       are writing tables */
    memcpy((void *)BIOS_TMP_STORAGE, (void *)0x000f0000, 0x10000);  //将BIOS拷贝到临时区域
    v = pci_config_readb(d, 0x59);
    v = (v & 0x0f) | (0x30);               
    pci_config_writeb(d, 0x59, v); //这里估计就是所谓的重新映射
    memcpy((void *)0x000f0000, (void *)BIOS_TMP_STORAGE, 0x10000);   //从临时区域拷贝到刚映射的DRAM中。
   
    i440_pcidev = *d;
}
作者: zx_wing    时间: 2008-02-29 23:01
原帖由 cainiao911 于 2008-2-29 22:40 发表
我看过一些资料,可能是错误的,仅供参考,切勿笑话。
1,386以后的cpu没有什么真正的实模式,执行第一条指令时,也就是"jmp far f000:e05b"的时候就是所谓32位的分段机制(就是用GDT,IDT来分段的那个什么来着 ...

嗯,第一个问题已经论述过好多次了,版内也有不少帖子,反正就是所谓开机的混沌模式了。

第二个问题,我有一点看法。
不管是bochs还是QEMU,由于它们是模拟器,所以这个bios的拷贝动作是把bios代码拷贝到客户机地址空间中对应的位置,例如1M以下。这个是可以理解的。因为对于虚拟技术来说,其中的实现可以和真实的不一样,只要结果一样就行。所以它可以直接把代码拷贝到地址空间中对应的位置以代替映射这个操作,反正对于BIOS来说只要它执行对应地址上的代码,而不管这个地址是映射过来的,还是在内存中有真正的物理页与之对应。
但是在真实平台上,如果是拷贝的话,这个拷贝的动作是谁执行的,我就是这点没想通,也没找到资料。
作者: cainiao911    时间: 2008-02-29 23:25
我还是认为应该是拷贝,我又找了一些证据。
award源代码:
  ;-------------------------------;
  ;  Switch to Proctected Mode ;
  ;-------------------------------;
      cli   
      lgdt    fword ptr cs:A_GDTR ; Load descriptor table
      mov     eax,cr0                 ; Enter protected mode
      or      al,1
      mov     cr0,eax
      jmp short $+2
      mov     ax,B_DATA1_INDEX
      mov     ds,ax                   ; DS = 00000000h

      mov esi,0f0000000H  ; ROM location
      cmp word ptr [esi],0AA55H ; ROM signature
      jne short NoVideoRom
      mov edi,0000C0000h  ; shadow RAM address
      mov ecx,64*1024/4  ;copy 64Kb video ROM
      cld
      db 67h
      rep movsd   ;copy ROM to shadow RAM
      NoVideoRom:
  ;-------------------------------;
  ;  Leave Proctected Mode ;
  ;-------------------------------;

首先声明我是菜鸟啊,刚研究这些东西没多久,我找证据只是为了寻找寻找答案,学习技术,呵呵。

[ 本帖最后由 cainiao911 于 2008-2-29 23:26 编辑 ]
作者: zx_wing    时间: 2008-03-01 15:46
原帖由 cainiao911 于 2008-2-29 23:25 发表
我还是认为应该是拷贝,我又找了一些证据。
award源代码:
  ;-------------------------------;
  ;  Switch to Proctected Mode ;
  ;-------------------------------;
      cli   
      lgdt    f ...

这段代码是拷贝VGA bios到0xc0000。VGA bios确实是拷贝的,它用于提供INT 10中断的处理函数,操作系统要拷调用这个中断切换模式,例如从640*480的分辨率切换到高分辨率。
我的意思是开机上电的时候,BIOS本身的代码是不是被拷贝到内存的,如果是,谁做的这个拷贝工作。
唉,还是没找到相关文章。


PS:CU讨论技术问题不会有人生攻击的,说的对就是对,错就是错。所以兄台不必太在意自己是不是刚开始研究,大家讨论而已嘛:wink:

[ 本帖最后由 zx_wing 于 2008-3-1 15:48 编辑 ]
作者: zx_wing    时间: 2008-03-01 21:17
找到证据了,先看一段:

ROM Shadowing

As described in the section on UMA ROM and RAM, in most PCs, there is a full 384 KB area of RAM in the UMA. When any addresses in the UMA region are used by ROMs, the RAM underlying them is hidden. However, that doesn't mean that it has to be wasted.

One problem with ROMs such as those used for the system BIOS and video BIOS, is that it is relatively slow. The access time of ROMs is usually between 120 and 200 ns, compared to system RAM which is typically 50 to 70 ns. Also, system RAM is accessed 32 bits at a time, while ROMs are usually 16 bits wide. The result of this is that accesses to the BIOS code are very slow relative to accesses to code in the system memory.

I'm sure you can see where this is heading. Since there is RAM hiding underneath the ROMs anyway, most systems have the ability to "mirror" the ROM code into this RAM to improve performance. This is called ROM Shadowing, and is controlled using a set of BIOS parameters. There is normally a separate parameter to control the shadowing of the system BIOS, the video BIOS and adapter ROM areas.

When shadowing of a region of memory is enabled, at boot time the BIOS copies the contents of the ROM into the underlying RAM, write-protects the RAM and then disables the ROM. To the system the shadow RAM appears as if it is ROM, and it is also write-protected the way ROM is. This write-protection is important to remember, because if you enable shadowing of memory addresses that are being used for RAM, the device using it will cease to function when the RAM can no longer be written to (it is locked out by the shadowing). Some network cards for example use parts of the memory region they occupy for both ROM and RAM functions. Enabling shadowing there will cause the card to hang up due to the write-protection. Similarly, you should never turn on shadowing of the regions of memory being used for an EMS frame buffer or for UMBs.

In normal circumstances, the system BIOS and video BIOS are the only areas shadowed. This can in theory cause problems with some operating systems, though I have never personally encountered this. I have also heard rumors of video cards that don't function correctly when video BIOS shadowing is off, but I haven't encountered that myself either.



从上面的论述我们可以看到,BIOS在最初阶段是被映射的。BIOS代码放到ROM里面,以write-protects的形式被映射执行。为了提高效率,ROM里的代码被允许拷贝到内存(RAM)中执行,并同时禁止调ROM的映射。这个就是ROM shadow的作用和原因。所以可以看出,最初上电执行时,BIOS代码是被映射执行的,而不是拷贝。
作者: mik    时间: 2008-03-02 02:10
偶的看法:
在整个物理地址空间中, 可以被划分给 BIOS 的有4个:

FFE00000 ~ FFFFFFFF: 被映射到 flash 类型的存储介质的 ROM,存放 BIOS
000F0000 ~ 000FFFFF: 在 1M 范围下,典型被映射到 RAM,若想从 flash 拷贝到 RAM ,就拷贝到此区域
000E0000 ~ 000EFFFF: 这个地址空间可以映射到 RAM 或 ROM,典型地可以复制 BIOS 中扩展代码
000C0000 ~ 000DFFFF: 某些 PCI 设备的 BIOS 可以映射到这个区域。

对于 000F0000 ~ 000FFFFF 这个区域是比较有疑问的。processor 复位后执行第一条的指令 [FFFFFFF0] 就是一条跳转指令,结果就是跳转到 000F0000 ~ 000FFFFF 这个区域里,偶不太认可 bios 复制到这里一说。偶倾向于bios代码映射到这里这种观点。
偶想花时间好好研究BIOS代码,希望能有更清晰的答案
作者: zx_wing    时间: 2008-03-02 12:41
原帖由 mik 于 2008-3-2 02:10 发表
偶的看法:
在整个物理地址空间中, 可以被划分给 BIOS 的有4个:

FFE00000 ~ FFFFFFFF: 被映射到 flash 类型的存储介质的 ROM,存放 BIOS
000F0000 ~ 000FFFFF: 在 1M 范围下,典型被映射到 RAM,若想从 ...

赞同。mik研究好了把成果发出来共享哈
作者: cainiao911    时间: 2008-03-02 14:58
不好意思各位,可能我前面的一些回答,表达方式不对。下面再次予以阐述。
1,首先CPU执行第一条指令(jmp far f000:e05b)的时候,0xFFFFFFFF---FFFF0000, 0xFFFFF---0xF0000的都是映射的,并且都是映射到相同的Flash Rom,关于这一点我们可以在Intel的MCH DataSheet的System Address Map这一章节看到。
2,Cpu执行这条指令后,将导致CS隐藏寄存器中基地址从0xFFFF0000变成000F0000。所以物理地址将落在0x000FE05B,也就是在1M以下那个Bios。
3,地址的映射是可以通过配置PCI总线来完成的,可以配置给Flash Rom, 也可以是DRAM.
4,Memory Shadow肯定是发生在第一条指令之后,到底是在之后的什么时候我暂时不清楚。
5这条可能假设性比较强,抱歉,我只是谈谈看法。在Shadow之前,肯定要映射一部分DRAM(记为DRAM1),这样我们才可以将flash bios拷贝到临时区域,拷贝到临时区域之后,我们命令pci总线将0xFFFFF---0xF0000分配给另一部分DRAM(记为DRAM2),分配之后,因为DRAM2中没有数据,所以我们将临时区域中的BIOS拷贝到DRAM2)中。至于为什么不从4G高地址拷贝,而是使用临时区域,或者4G那个部分是否和Shadow有关,暂时不知道。

有一篇在2007韩国poc大会上发表的文档(BIOS Boot Hijacking And VMware Vulnerabilities Digging),估计是国人写的,有关于Memory Shadow的一些信息,有兴趣的可以看看。

下面摘录几句:
Right after machine power-on and the very beginning of the Boot
stage, the E_segment (0xE0000~0xEFFFF) and F_segment
(0xF0000~0xFFFFF) are not claimed by North Bridge, and all
accesses to these ranges are actually forwarded to South Bridge
and decoded by Firmware Hub (FWH) until subsequently North
Bridge RAM shadowing function will be enabled by BIOS code.

&#1048708; E_segment/F_segment and their counterparts in High BIOS Area
(topmost 2M in the whole accessible 4G physical memory space)
are both decoded by FWH into the last two 64k of BIOS ROM chip,
so we can say that E_segment and F_segment alias to
0xFFFE0000~0xFFFEFFFF and 0xFFFF0000~0xFFFFFFFF respectively.

&#1048708; The first instruction that CPU executes upon power-on is at
0xFFFFFFF0 (alias to 0xFFFF0 and both are within BIOS ROM chip)
where usually a far jump instruction resides (mostly JMP
F000:E05B, and after this jump CS base 0xFFFF0000 will get
flushed) , so the next instruction will be fetched from 0xFE05B
(alias to 0xFFFFE05B) which is also decoded into BIOS ROM.


作者: cainiao911    时间: 2008-03-02 15:21
下面再摘录一点东西。出处:http://www.programmer-club.com/p ... ssembly&id=6277

[Why shadow BIOS ?]
在此之前所提的BIOS tasks,都是循着 CPU->NB->SB->SIO->ROM的路径来达成的;意即: CPU是去BIOS ROM里面抓code来执行 ! 明显的一件事是: ROM access time > DRAM access time ! 且RAM access width is 32bits,而 ROM access width 通常为 16 bits. 因此,便有了所谓" BIOS Shadowing"的观念产生 ! <- "performance consideration" !!!

[What is shadowing]
意即: 将部分BIOS CODE(in ROM)拷贝至DRAM中 ! (此后, CPU将从DRAM中抓code来执行...)这样的动作便称做 "Shadowing" ! 而该处的DRAM即称为 shadow memory.

Shadowing 在BIOS 中是极为复杂的 kernel code part ! 想深入了解的人最好有 source code可 trace.

[When to shadow BIOS]
=> 当然是等内存稳定了,可以使用后,才做 ^_^

*因此,假如 DRAM sizing 有问题, BIOS shadowing必定有问题 !!!


以下是之前在其他文章中发表关于 shadow 的文章,再次节录以供参考 !

[System Behavior before & after shadow]
说 的更白话一点就是 : 当 Power On后, 跑完 system power-on sequence后, CPU会被 reset ( reset 指的是 CPU 的 内容会回到 "初始值" ); 而 CPU内部的 EIP (32-bit )的初值是 FFFFFFF0h, 所以, CPU的 第一个 code read 就是到 FFFFFFF0h fetch code...

这个 memory cycle 从 CPU发出, 先会经过 North bridge ; 此时, north bridge会说 "这不是我的"...然后,往 south bridge 丢 ; south bridge 会说, "这是我的",收下后丢给 ROM ! 所以, FFFFFFF0h 会被 ROM 接走 !!! ( 所以 前人才说 "硬件初始值要把0xFFFFFFF0 和 0x000FFFF0 要mapping到同一个地方", 这个地方就是.....ROM !!! )

之后, CPU所发的 cycle 都会照上述的方式一路抵达 ROM...由 CPU循着 fetch, decode, execute, store的顺序作事情...

但 到某一个阶段前, BIOS的 code 会指示 " 要将 BIOS data 从 ROM 搬到 DRAM" ! 而在此阶段之后, BIOS会设定 north bridge 缓存器, 告诉 north bridge "之后 CPU所发的 cycle 不可以不收而传到 south bridge"....

自此之后, CPU 所发的 cycle 全部转到 DRAM 中,由 CPU循着 fetch, decode, execute, store的顺序作事情...

<Summary> 总而言之, BIOS 一开始是CPU读取 ROM content来执行,之后是CPU 读取 DRAM content 执行 ^_^










-------------------------------------------------------------------------------------------------------------------------------------------------

[补充][以提问的方式^_^]

[Q]: shadow memory到底是那一块 ?
[A]: 以现在的计算机系统而言, shadow memory 是在UMA(upper memory area;传统内存 640K以上至1M之间) "里面"(part of it) ;在此UMA内可以分为 6 segments(64kB/each), total 384KB.

其中 C0000h~DFFFFh: for VGA BIOS and other devices' Option ROMs
     E0000h~FFFFFh: BIOS ROM code

这两个 blocks 本质是 memory;之后会被载以ROM content;因此,便称为 shadow memory(好像: ROM在上面, memory在下面,是ROM的 "shadow"...)

[Q]: shadow memory 的内容 完全 "=" ROM content ?
[A]: of course NOT ! 除了 UMA不大以外,BIOS ROM因为必须support more and more functions/features,size已经越长越大;除此之外,BIOS ROM中也有部分module是经过压缩的.(UMA不够放...)

当BIOS shadow时,只会 copy necessary code(Ex. run-time要用的...etc)至 shadow memory ! 另外,已经执行过后的code也不会被加载. 因此,不是 1-1的copy...

[Q]: what Shadow enabled/disable mean in chipset ?
[A]: 前面提过, CPU要 fetch的code由 shadow memory 提供 or ROM提供,其根本关键在于 chipset's behavior ! 意即,NB必须做此决定 ! 所以,这机制一般是由NB来实现的.

NB内有所谓的 shadow registers. 当 shadow register enable时, memory cycle由 shadow memory 来回应;若 shadow disable,则由ROM回应.

意即:
000E0000h~000FFFFFh由 shadow memory replies if (shadow enabled)
000E0000h~000FFFFFh由 ROM chip replies if (shadow disabled)

若FFFE000h~FFFFFFFFh呢 ? 必定由ROM chip来回应(不然一开机怎么办?). 与 shadow disable/enable无关 !!!

*若使用 ru.exe 并检视 memory space,可发现上述的情况.

[Q]: shadow有何好处 ?
[A]: 因为 slower ROM v.s faster RAM,所以放在RAM可以增加 system performance.

*各位可以发现,同样的code放在 rom & dram中执行速度将大不相同 !

[Q]: shadow memory的 issue ?
[A]: 被 shadowed 的 memory area都会被设成 write-protected ! 因此,这块area是不能 write 的.所以,若有程序会 "write"这块,则会有问题 !!!

其实, BIOS shadow这段code大家不太会碰触到...了解基本information即可.

有错误请指正 !!!
作者: mik    时间: 2008-03-02 15:27
原帖由 cainiao911 于 2008-3-2 14:58 发表
不好意思各位,可能我前面的一些回答,表达方式不对。下面再次予以阐述。
1,首先CPU执行第一条指令(jmp far f000:e05b)的时候,0xFFFFFFFF---FFFF0000, 0xFFFFF---0xF0000的都是映射的,并且都是映射到相同的F ...


要彻底明白这些问题,看 Intel 北桥芯片 datasheet 是不够的。 intel 的 mch 的 datasheet 也没能说得明白。

搞清问题只有结合二个途径: pci 总线规范和 BIOS 代码(或者 BIOS 的开发手册),研究 BIOS 相关的开发手册犹为重要,会提及 PCI 总线的初始配置情况。从而得出 pc 系统未上电时的初始配置。
作者: cainiao911    时间: 2008-03-02 15:44
Intel的MCH DataSheet确实只是说到了映射,没说过程。
不知阁下有无PCI System Architecture电子版,能否共享?

[ 本帖最后由 cainiao911 于 2008-3-2 15:50 编辑 ]
作者: mik    时间: 2008-03-02 16:43
原帖由 cainiao911 于 2008-3-2 15:44 发表
Intel的MCH DataSheet确实只是说到了映射,没说过程。
不知阁下有无PCI System Architecture电子版,能否共享?

给个邮箱,发给你吧
作者: cainiao911    时间: 2008-03-02 17:22
mytoolsdisk1@126.com,先行谢过!
作者: mik    时间: 2008-03-02 23:49
标题: 回复 #20 cainiao911 的帖子
已发
作者: albcamus    时间: 2008-03-03 09:42
原帖由 cainiao911 于 2008-3-2 15:44 发表
Intel的MCH DataSheet确实只是说到了映射,没说过程。
不知阁下有无PCI System Architecture电子版,能否共享?


这种书上emule搜索,我有这些,都是emule来的:

2002-10-03_2002-09-06_pci中文规范.pdf                                                   PCI Bus Demystified.pdf
Addison.Wesley,.MindShare,.PCI.System.Architecture.pdf                                  PCI_Express_Base_11.pdf
build_history.pdf                                                                       PCI.Express.Base.Specification.v2.0.pdf
conventional_pci_2_3.pdf                                                                PCI Express Complete Core.pdf
ECN-Interrupt_Line_Register_Usage_061605.pdf                                            PCI Express System Architecture.chm
ECN_PCI_Connector_Finish.pdf                                                            PCI Firmware Specification - Revision 3.0-2005.pdf
ECN_SATA_Class_Code.pdf                                                                 PCI Local Bus Specification-Revesion 3.0-2004.pdf
Introduction to PCI Express - A Hardware and Software Developers Guide.Intel.Press.pdf  PCI Local Bus Specification Revision 3.0.pdf
msi-x_ecn.pdf                                                                           PCI System Architecture, 4th Chinese-English Edition.pdf
PCI_2_3_Errata_9_08_03.pdf                                                              PCI局部总线.pdf
pci30_faq.pdf                                                                           prd_msc_pcitech.pdf
PCI BIOS Specification -Revision 2.1, 1994.pdf                                          SATA_CAP_Ptr_ECN_-_final.pdf
作者: cainiao911    时间: 2008-03-03 09:53
Mindshare的书比较好。我有ISA System Architecture,80486 System Architecture
但找不到《Pentium Processor System Architecture》,《Protected Mode Software Architecture》,《Pentium Pro and Pentium II System Architecture》
作者: zx_wing    时间: 2008-03-03 12:41
原帖由 cainiao911 于 2008-3-3 09:53 发表
Mindshare的书比较好。我有ISA System Architecture,80486 System Architecture
但找不到《Pentium Processor System Architecture》,《Protected Mode Software Architecture》,《Pentium Pro and Pentium  ...

mindshare的书不求多,一本本的看,看懂一本就不错了。
我老大当时读P4那本,我靠,一个星期2000页的书就读完了,然后给我们讲前端总线。而且讲的非常之清楚。
不过他说了,很多东西都是知道的,读这些书只是总结,我想我去读一本,怕是一年都看不完。

晕,变资料交换帖了,大哥们继续研究这个启动的过程啊,研究好了发个总结帖。我人懒啊,想捡个现成。
作者: cj_ict    时间: 2008-03-04 13:52
标题: 回复 #3 daidongly 的帖子
谢谢!

第二个问题估计是我自己没说清楚,现在回过头来自己看看都觉得不知所言。
我到网上Google了下,看到了些文章。不过还是有不少地方不懂~我尽量表述的清楚点呵

开机后,CPU重置,从地址FFFFFFF0取第一个命令,这个地址正好落在ROM BIOS中。该地址内容一

定是一个JMP指令,系统便跳转到该JMP指令所指的地方。

1,而这里之后我开始不明白了。JMP要跳转到的位置是在高地址(4G末端)Flash Rom BIOS中还是

在低地址(1M末端)的shadow BIOS呢?

2,位于低地址(1M处)的(BIOS shadow)是从Flash BIOS拷贝而来呢,还是没有任何拷贝过程仅

仅利用地址映射到原Flash BIOS中的呢?

3,无论是拷贝还是映射,内存地址空间上ROM BIOS映射区只有 0xF0000~0x100000之间的64KB。而

ROM本身有可能大于2M。那映射的应该是原BIOS程序的一部分,那么是哪一部分呢?

对这个问题的回答需要阐明机关概念:
1.机器加电时,内存控制器还没有初时化,内存是不可用。
2.机器加电时,对CPU的指令的解码不是北桥,CPU发出的地址被传递到南桥并由FHW(Firmware

Hub)解码到BIOS ROM芯片(Flash)。在加电时一直到引导进程初,BIOS的E段(0xE0000~0xEFFFF)和F

段(0xF0000~0xFFFFF)和4G内存顶端的对应段0xFFFE0000~0xFFFEFFFF和0xFFFF0000~0xFFFFFFFF都

被FWH解码到BIOS的ROM芯片的两个64区域。即在启动阶段访问0xE0000~0xEFFFF和

0xFFFE0000~0xFFFEFFFF是同一个BIOS区域,访问0xF0000~0xFFFFF和0xFFFF0000~0xFFFFFFFF是同

一个BIOS区域。
3.机器加电时,CS段寄存器值为0xF000,EIP值为0x0000FFF0,但CPU的取的地址是段寄存器不可见

的部分(影子寄存器)加上偏移部分,此时影子寄存器的值为0xFFFFFFF0。所以CPU执行的第一条指

令是0xFFFFFFF0(复位向量),通常在BIOS ROM对应的指令是一个跳转指令JMP F000:E05B,当取出跳

转完成后,由于CS段的影子寄存器刷新并重新加载,下一条指令地址是0xFE05B。不过这条指令仍

然从BIOS ROM里取得。
4.关于shadow BIOS,BIOS程序通常是压缩的,在系统初始化阶段,BIOS会解压BIOS Image到RAM中

,然后编程北桥控制器对0xE0000~0xFFFFF置为write only,这样对该区域的写被传递到DRAM里,

然后把解压的BIOS拷贝到E段和F段。最后重新编程北桥控制器对0xE0000~0xFFFFF置为read only。
对于PCI ROM BIOS,BIOS会把每个卡上的ROM拷贝到0xC0000~0xDFFFF然后执行他们的初时化代码。
5.BIOS ROM可以很大,但不都是可执行的,如含有ACPI Table等,开始解压到0xE0000~0xFFFFF只

是其中一部分,在启动过程中还需要从BIOS ROM解压代码到RAM中,并覆盖其中不需要的代码。这

个就好像BIOS ROM是硬盘(不过可用直接访问),真正执行的代码在RAM中一样。硬盘可以很大但RAM

小,这也就是程序的局部性原理。

其它对开机过程的误识也会从我的回答中得到答案。
作者: zx_wing    时间: 2008-03-04 14:12
原帖由 cj_ict 于 2008-3-4 13:52 发表
谢谢!

第二个问题估计是我自己没说清楚,现在回过头来自己看看都觉得不知所言。
我到网上Google了下,看到了些文章。不过还是有不少地方不懂~我尽量表述的清楚点呵

开机后,CPU重置,从地址FFFFFFF0取 ...

有几个问题没弄明白,想请教一下

2.机器加电时,对CPU的指令的解码不是北桥,CPU发出的地址被传递到南桥并由FHW(Firmware

Hub)解码到BIOS ROM芯片(Flash)。在加电时一直到引导进程初,BIOS的E段(0xE0000~0xEFFFF)和F

段(0xF0000~0xFFFFF)和4G内存顶端的对应段0xFFFE0000~0xFFFEFFFF和0xFFFF0000~0xFFFFFFFF都

被FWH解码到BIOS的ROM芯片的两个64区域。即在启动阶段访问0xE0000~0xEFFFF和

0xFFFE0000~0xFFFEFFFF是同一个BIOS区域,访问0xF0000~0xFFFFF和0xFFFF0000~0xFFFFFFFF是同

一个BIOS区域。


这么说BIOS拷贝到高端内存是架构决定的?也就是说所有操作系统都是这样的?
我认为是操作系统决定的。而且我认为开机的时候4G末端是没有BIOS的映射的,而是系统启动中BIOS被操作系统拷贝的到这个位置去的。
希望能看到出处,最好是有BIOS的specification之类的权威规范。

另外还有个问题就是我们讨论的“开机时BIOS是否是被映射执行的?这个映射过程是如何的?”希望这个问题能得到解答。
作者: cainiao911    时间: 2008-03-04 16:06
原帖由 zx_wing 于 2008-3-4 14:12 发表

我认为是操作系统决定的。而且我认为开机的时候4G末端是没有BIOS的映射的,而是系统启动中BIOS被操作系统拷贝的到这个位置去的。


我谈谈我的看法。
先不管映不映射。至少在执行第一条指令的时候,4G末端Bios是存在的。
还是拿bochs来举例。
1,启动bochsdbg.
2,执行disasm 0xFFFFFF00 0xFFFFFFFF
3,执行disasm 0x000FFF00 0x000FFFFF
可以看到两个地方反汇编出来的代码是一样的。
虚拟机的具体实现可能与现实中有区别,但这个BIOS是个独立模块,可以用于Bochs,Plex86,QEMU,具有一定的可信度。

梁肇新先生的书《编程高手箴言》讲到“在DOS实模式下读取4GB内存”,用代码证实了BIOS在两个地方同时出现,我想,我们
直接将代码写在硬盘或软盘第一个扇区应该可以达到同样的效果。

cj_ict 貌似是高手,不会不来了吧!?
作者: zx_wing    时间: 2008-03-04 17:06
原帖由 cainiao911 于 2008-3-4 16:06 发表


我谈谈我的看法。
先不管映不映射。至少在执行第一条指令的时候,4G末端Bios是存在的。
还是拿bochs来举例。
1,启动bochsdbg.
2,执行disasm 0xFFFFFF00 0xFFFFFFFF
3,执行disasm 0x000FFF00 0x000FFFF ...

cainiao911兄不要怪我多疑,实在是因为这种情况导致我有几个地方想不通。

1.  为什么4G末端会有BIOS的映射?
兄台和cj_ict看来应该是做BIOS相关工作的,那肯定就知道BIOS的服务可以分为boottime和runtime两种。我对4G末端有BIOS映射的解释是操作系统为了在运行期间调用BIOS的runtime服务,而把BIOS拷贝到这个区域。并且是操作系统决定的,并非所有操作系统遵守这个情况。
我想问一下兄台用bochsdbg看的时候,操作系统启动没有?还是刚开机的时候?

2. 4G末端的映射什么时候被使用到?
对4G末端的访问前面说过,只有在big real mode下才可能访问,不可能在一上电的时候就访问到。如果是通过big real mode访问,那就是开机后很久的事情的。那么如果4G末端的映射一开机就存在,那么它有什么用?什么时候会被用到。

所以我想看到有权威的spec来解释这个东西。
作者: cainiao911    时间: 2008-03-04 17:34
4G那部分在刷BIOS的时候要用到,具体不清楚。
我前面的帖子里面有个链接,里面有讲到。
BIOS Boot Hijacking And VMware Vulnerabilities Digging
你还可以用google搜索 "TOP_SWAP"看看。
作者: zx_wing    时间: 2008-03-04 21:22
综合看了cainiao911发的PDF文档,又根据里面的内容查阅了ICH9的spec,看了TOP_SWAP的相关章节,有一点看法。写出来大家讨论一下。
首先一个概念要先区分一下,我认为这个是问题的关键。即,这里的4G末端是个映射,所指向的不是RAM,而是BIOS ROM,这时的BIOS根本没有被拷贝。

为什么这样说。有几点原因:1)此时MCH没有参与地址地址访问,而内存还未初始化,此时RAM不可用 2)从TOP_SWAP的讲述来看,此时ICH的A16被invert,所有访问0xFFFF0000 ~ 0xFFFFFFFF的访问变成对0xFFFE0000~0xFFFEFFFF的访问。我认为这里A16就是一个地址线引脚,所谓invert就是被拉低了。所以这时ICH在参与地址访问。3)还是老原因,实模式无法寻址到4G。

综上3个原因,我认为问题JMP要跳转到的位置是在高地址(4G末端)Flash Rom BIOS中还是在低地址(1M末端)的shadow BIOS呢?”的实际解释是:0xF0000~0xFFFFF和0xFFFF0000~0xFFFFFFFF都是指向BIOS ROM的两个映射而已,BIOS的拷贝只有一份,在BIOS ROM里,这两个映射都指向它。所以无论跳转到哪儿,都是指向BIOS ROM,在跳转后CS被flush掉,这个时候使用低地址映射执行BIOS代码。

所以在这个过程中根本就没有RAM的参与,所谓4G末端只是个地址空间上的概念,BIOS也没有被拷贝。

我原先理解成BIOS被拷贝到RAM中,而这个RAM的在地址地址空间中位于4G末端。把OS拷贝BIOS例程到高端内存和这里的高端地址映射BIOS ROM混淆了。各位可能早就清楚上述事实,多半被我的问题搅晕了o" />ps:" />

但还有一个问题没想通,上电的时候CS位于0XFFFF0000,但执行完一个long jmp后CS会被flush掉,按理说后面就不会有高于1M+64K的地址出现了,那么在4G末端映射整个BIOS ROM又有什么用呢?我想这样做的原因是可以让long jmp跳到BIOS ROM里的任何地址,而非是特定的某个地方。不知道对不对。

[ 本帖最后由 zx_wing 于 2008-3-4 21:25 编辑 ]
作者: abutter    时间: 2008-03-07 20:25
CPU出的地址线是特定的,但是过了南桥芯片就会发生变化,从芯片的角度取理解就容易了。
作者: zt52952    时间: 2008-03-12 23:59
标题: 回复 #1 daidongly 的帖子
1,文中提到,为使PC/AT计算机向上兼容,系统会产生一个影子区域,即BIOS代码会被复制到这个区域,而另一方面原来系统ROM中的基本输入输出程序BIOS一直处于CPU能寻址的内存最高端位置处。
     不太明白的是,保证ROM中BIOS程序一直处于CPU能寻址的内存的最高端位置处是在什么时候完成的?

X86 CPU的地址空间在实模式下是00000H-FFFFFH,保护模式下是00000000H-FFFFFFFFH
实模式和保护模式是CPU的一个寄存器决定,查看一下Intel 64  and IA-32 Architectures Software Developer's Manual
无论是在实模式还是保护模式下,有一段地址空间即可以寻址到ROM也可以寻址以RAM,比如E0000-F0000可以访问ROM也可以访问RAM,访问RAM的也就是所谓的影子区域,个体访问哪个区域由北桥或南桥决定,不同的芯片组处理的不一样,如VIA,Sis,Intel,nVidia。BIOS执行过程中由BIOS决定存取什么地方。


2,文中提到,PC/AT微机的BIOS有可能大于64KB。而我们在内存中留出的影子区域(shadow)也就是ROM BIOS的映射区只有64KB。
那么我们是怎么选择复制哪些BIOS程序呢?
现在的BIOS,至少也有512KB,一般是1MB到2MB,EFI的话至少也会是2MB吧,
开机时执行ROM,然后把整个程序解压复制到RAM中,shadow一般是中断服务程序、ACPI、DMI的一些入口数据。

3,文中提到,BIOS程序会使用一种称作32位大模式的技术把数据寄存器的访问范围设置为4G(原来是64KB)。而BIOS在执行一些列硬件检测和初始化操作后,就会把于原来PC机兼容的64KB BIOS代码和数据复制到内存低端1MB末端的64KB处,然后跳转到这个地方应且让CPU进入真正的实地址模式工作。
     请问上面这个过程具体是怎么实现的?什么叫做真正的实地址模式呢?
BIOS实现,需要设置CPU的GDT表,
Intel网站上可以下载到北桥如G33,南桥如ICH9的一些Spec,可以参考一下。
作者: JJSTU    时间: 2008-03-18 10:24
不知对不对,我记得在实模式下对段寄存器赋值,是不能改变其隐藏部分的。
如果在实行第一句跳转后,cs从FFFF0000到F0000 应该不能算是正真的实模式吧,

问题是 如果是这样Cs被flush,那其他的段寄存器又是如何?
4.25
今天回来再看,终于明白了。
另外,自己上面的描述有错误,现在做一下更正,在实模式下并非不能改变其隐藏部分,
而是有些属性位不可改变。
最后,其实这个问题在上面的十五、十六楼已经把答案说的差不多了,而自己没有明白有几点原因,现在写下来:
1 上面关于隐藏部分记错了,以为在实模式下不能改变
2 将alias与shadow混淆了,以为是一回事

[ 本帖最后由 JJSTU 于 2008-4-25 14:31 编辑 ]




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2