计算机底层是如何访问显卡的?
知乎地址http://www.zhihu.com/question/20722310
里面提到了一个显存地址的东西,B8000H 到 C7FFFH,通过计算,此地址区间的大小为3.5M左右。
本人计算机windows10 64位集成显卡,显示的显存地址空间为C0000000-C03FFFFF,以及B0000000-BFFFFFFF,大小差不多是4M+256M,同文中给的显存地址空间差距较大。
个人理解的显存使用流程:
数据地址空间(内存空间?)以及IO地址空间的操作集合,合作完成
集成显卡:
系统在内存中分配一块区域为共享显存,显存地址可能为实际的内存地址,或者从0位开始再映射到实际内存地址上。
此外,系统还会分配一些显卡的控制/数据寄存器的地址,到IO地址空间(同内存地址空间是不一样的)上。IO地址空间应该是控制总线,可读可写,可写需看硬件是否支持。在《程序是怎样跑起来的》[2]一书中,有对IO寄存器的读取操作。
内存有专门的IO控制器(北桥),其余的设备,比如硬盘、USB、网卡等,由南桥作为IO控制器。每个设备的控制总线的地址,由控制器确定,CPU发出控制指令后,由控制器打通CPU和设备的地址总线和数据总线,执行硬件操作。
不同的显示分辨率以及显示颜色,会有不同的显存大小要求。
显存若是太小的话,需要多次写满显存才能显示一帧或少数的几帧,画面显示会不流畅。显存较大时,可以预先缓存多帧的数据,显示会更加流畅。同时由于显示设备目前会有矢量图绘制的需要,因此显存不再仅仅保存显示的位图数据了,还会保存绘图素材的数据。
操作系统通过读写IO寄存器以及显存,显卡定时根据IO寄存器的指令完成读取显存并显示画面的功能。
独立显卡:
同集成显卡一样,系统在内存中分配一块区域为共享显存,显存地址可能为实际的内存地址,或者从0位开始再映射到实际内存地址上。
此外,系统还会分配一些显卡的控制/数据寄存器的地址,到IO地址空间上。
系统分配的共享显存大小会低于独立显卡的独立显存大小,此时系统通过操作IO寄存器,控制独立显卡将共享显存(Linux中的Frame Buffer?DMA?)中的内容拷贝到独立显存中,或者使用IO寄存器指令,反复操作共享显存,并填满独立显存的剩余空间,显卡即可根据独立显存的内容显示图像。
个人理解造成这个结果的原因:
好像显存还会分为两部分,一部分是即将显示的图像信息,一部分是需要处理的显示素材信息。因为一般需要的显存大小,即即将显示的图像信息,同显示的分辨率以及显示的颜色位数相关,比如2160×1440*32/8,显存大小约是12M,系统中为了操作方便会变为16M。此外显卡还可能会绘制质量图一类的东西,并为其进行图片渲染,会有一些缓存存储显示素材信息。
运行XP最低需要16MB显存,想让win7能够运行的比较流畅的话最低需要128MB。这是打开Aero的最低配置。卡吧有测试显存占用的,开启Aero之后显存占用会高数十MB,然后多开网页之后,128MB也就所剩无几了,因此即使是在win7下进行一般的文字处理,128MB显存都是必不可少的。如果是高分屏,显存应该更大一些。当然,就算是现在的集成显卡,共享显存也很少低于128MB这个数字了。[1]
无论是集成显卡的共享内存还是独立显卡的独立显存,都需要在地址空间上开辟一个区域,供CPU往里面写显示的数据(显示器的分辨率,以及每个像素的颜色信息,以及显示素材)。
但是此地址空间不能占用左右的计算机内存地址空间,不然系统无法获得内存,便无法运行了,因此系统会在显存地址空间以及系统可使用的内存地址空间做一个权衡。
集成显卡的显存可以手动指定,但应有最小显存限制。
如果系统为32位系统,显存是不可能超过4G的,即使使用独立显存,独立显存的大小超过了4G,最终分配的显存地址空间,可能只有几百兆左右,这就需要操作系统不停的改变内存映射地址,或者控制寄存器内容,来操作所有的独立显存。当系统达到64位时,就可以利用更大的显存了。
硬件控制方法
IO端口号,IRQ,DMA,内存范围。
IO端口号,有独立模块管理,同外围硬件协商,避免IO端口号冲突。CPU通过IO端口号,访问硬件的寄存器,完成硬件的控制功能,比如要求硬件读取数据到指定内存空间、将内存空间的数据写入到硬件存储设备。此部
IRQ,需要交互的硬件设备,通过发送IRQ,引起中断,CPU根据终端号确定何种硬件的终端,并执行相应的终端程序。比如键盘按键,发送中断到CPU,CPU保存正在执行的程序,根据IRQ号确定为键盘中断,然后使用相应的终端程序,到指定的数据地址读取键盘的按键信息。
DMA,有时硬件需要有大量的数据同内存进行传输,经过CPU会降低计算机性能,因此,通过专门开辟的内存空间,硬件直接将数据写入到指定内存,完成后通过中断通知CPU,提高了性能。
内存范围,硬件设备需要同CPU进行大量数据的传输,仅仅使用IO寄存器的形式,效率很低(完成一次写地址以及数据的任务,可能需要比写内存更多的指令),因此通过划分内存范围供硬件独享,这样当有数据传输时,CPU可以先写到内存中,然后通知硬件读取,提高了效率。需同DMA一起工作。磁盘以及独立显存,应该都是这样操作的。
[1]http://tieba.baidu.com/p/1896763297
[2]程序是怎样跑起来的.【作者】 [日] 矢泽久雄 【ISBN】 978-7-115-38513-0 【日期】 2015-04
[3]http://blog.csdn.net/xport/article/details/1387928。PC架构系列:CPU/RAM/IO总线的发展历史!