[Q] 为什么稳定的内存这么重要 ?
A: 因为,有太多东西需要存放其上了,例如: BIOS code(之后在 shadow部分会提到), 开机之后所需要的 device drivers and OS,etc...假如内存不稳,在存取 memory时无法得到需要的数据,或是根本连 read or write都不行,那么便会发现: 不是 system hang(maybe randomly) during POST ,或是进OS后 blue screen...
所以,"BIOS DRAM sizing不好" 是系统不稳的原因之一. (地基都不稳了,怎能奢求其上的房子可以坚固 ^_^ )
在介绍 DRAM sizing之前,先稍微简单说明 DRAM 的相关知识.
(若有不足或错误之处,请不吝指正...)
1. DRAM chip 可看做是 square array;基本的单位 is cell. 每一个 cell 是由数个晶体管组成(depends on cell width;记得是: 1 bit 由一个晶体管组成,可以记录 0 and 1的信息; 1 cell 可能含 n bits;读取DRAM cell属于破坏性的读取,因此读取的同时常伴随着 "refresh" <- 与 SRAM不同)
2. 要存取 DRAM chip 中的数据,必须提供 row and column address;这两个 address是有先后顺序的;意即: row address先送,然后再送 column address to chip.
(呼应前面所言: square array,类似 x,y 寻址) 最后 指到的 data 将被放到 data bus上,CPU会读走
*若有空可以上网查: 为什么DRAM chip所需的 pins 是减半(half)的 ^_^
3. DRAM controller 现在一般都做在 chipset 中,Ex. NB内(AMD K8 CPU则是将 memory controller做在CPU内 ,for better performance);其工作便是 interfacing DRAM chip;充作其他 devices(Ex. CPU,DMA controller...etc) 与 DRAM chip 之间的桥梁 !
Ex. In BIOS ,写下列的 code 欲 "read", "内存", "位置8处"的数据:
xor ax, ax
mov es, ax
mov edi, 00000008h
mov al, BYTE PTR es:[edi]
[00000008h] 是 programmer所"知"的 linear address,但DRAM chip 只认得 MA0~MAx,BA0~BA1..etc讯号,如何沟通 ? => 靠 DRAM controller 来转换 !!!
4. DRAM access time => 从 DRAM chip 接到 address signals 直到 valid data 出现在 data bus上的时间(assume "read" memory),称之;也是DRAM chip的特性之一.
5. 现今常见的 DRAM is DDR/DDR2 SDRAM. 所谓的 "S"DRAM 指的是 Synchronous DRAM,即 DRAM operation 都是参考一个 clock执行的;即与它同步(synchronous). DDR 指得是 Double Data Rate,亦即在 clock 的 rising and falling edge都可以传数据. 而DDR2指的是: DDR的 "第二代" ! (别想成 DDR2 = DDR x 2 !!! 虽然刚好有些数值是两倍的关系...)
Ex. DDR2 533(or called PC2 4200) =>
1. "2" means DDR2
2. 533 is transfer rate( 每一秒可做 533笔资料 transfer )
3. 4200 means: 533笔资料/s * 每笔 8 bytes( => 64 bit width) ~= 4200MB/s
DRAM Sizing 的程序与chipset design息息相关,不同家chipset其DRAM sizing sequence亦不同.在此只列出 rough sequence以供参考. (真正的 detailed sequence仍须以各家的 code为准)
[假设]:
A. memory controller integrated into NB
=> NB PCI config space有一部份与DRAM相关
B. This chipset support 4 DRAM sockets(max.)
=> 存在 4 registers,分别代表此 4-socket DRAMs' information
=> 存在 4 bits ,分别控制 4-socket's CS(chip select;enable DRAM用的)
[程序]
1. Configure registers by DRAM frequency:
=> 许多DRAM相关的 registers(Ex. tRFC,tRP,tRCD,tWTR,CAS,...etc)都必须根据DRAM operating frequency来设定. (DRAM frequency 可由 CPU freq and CPU/DRAM ratio求得)
2. Execute Initial sequence for DDR(or DDR2)
=> DRAM spec都有列 initial sequence;既定的流程.
3. Set MAX-supported Size of this chipset for 4 sockets !
=> 因为"不知道"插进来的DRAM到底多大,所以假设: 每一个 socket上都有插DRAM,且size 是->此 chipset所 support的最大 size(Ex. 2G)
4. Do the followings for Socket 0/1/2/3 sequentially (<-此时,一次 "只 enable 1 socket"来做事)
1) check DRAM exist or NOT
=> 藉由简单的 write-then-read pattern来判定 socket上是否有 installed DRAM
2) decide DRAM "TYPE" if DRAM exist
=> 假如DRAM有在socket上,则进一步去取得其 "TYPE" information
以DDR2 SDRAM为例,此步骤即:求取该内存的 (Bank,Row,Column,Side) information
Ex. 2x12x9's DRAM 且 double side ,则内存大小为 128MB
* 找DRAM information 有分 MA table & by SPD.
3) write this information to corresponding register
5. Configure registers by DRAM loading
=> 步骤4做完后,所有 installed DRAM已经找到. 此时,需要对一些与 "loading" 相关的DRAM registers做调整(因为: 不同数目的DRAM需要有不同的 driving strength !)
6. Remaining tasks:
=> disable one-page mode
enable dynamic reset
enable refresh cycle ( <- DRAM is ok to use ^_^ )
[注意事项]
1. 至此 Top memory( "可使用的内存上限" 已经...决定了 ^_^)
2. 在此 stage,并没有对 DRAM 做严密的测试. 测试阶段在后面的 tasks
3. 一般若 register config错误,或是 DRAM frequency不对(起因于clockgen config 错误),都会 hang在这个 stage ! 若系统侥幸 passed this stage并进到DOS,则可以再用 memory test utility来 verify DRAM is stable or NOT !!!
[补充]
在此stage(Sizing)完成之前, DRAM is not ready to use. 故撰写此code时得全靠 CPU GPR(general purpose register)来传递参数 or return address ! 因此,得时时注意是否 register content 被改变 ( 因为 GPRs不多...)
但是,若是 activate CAR(Cache as Ram),则在此stage就可以使用 push/pop,所撰写的code将较为模块化及弹性,也不必担心 register content会被破坏了...
Ex. AMD Kx sizing code便是很早便使用 cache 来当作RAM,因此可以写出 module code for sizing !!!
类别:我所知道的bios系列整理(转载小华的部落格) 查看评论