PS3 上 Linux 安装的默认显示配置取决于您的安装方法。如果您正在使用一个普通的 NTSC 或 PAL 电视机(而不是 HDTV 或连接到监视器的 VGA 转换器),就无法使用 YDL 的图形安装模式,因为它会试图设置一个更高的扫描分辨率。
因此,默认的 Linux 安装是没有提供 X 包的,它使用的是 TV 分辨率的屏幕。对于本系列文章来说,您可以通过编辑 /etc/kboot.conf — 来修改这种行为,您可能会希望在 RGB 模式中运行,对于 NTSC 用户来说是 480i,对于 PAL/SECAM 用户来说是 576i。对于这两种设置所给出的屏幕大小,freamebuffer 设备都会报告分辨率为 576×384 像素;稍后会对此作更多介绍。
这个引导时特定的 framebuffer 视频模式可以通过引导启动程序 kboot 传递给内核的参数进行设置。(注意这种视频模式设置只有在 ps3fb framebuffer 设备加载之后才会进行检查,因为这是一个内核参数。启动和初始化 ps3fb 设备这两个时刻之间的视频模式是您在 Sony GameOS 菜单中设置的;默认情况下,它采用的是您的 PS3 购买地的交错式 SDTV 分辨率)。kboot 的设置保存在 /etc/kboot.conf 中 — 下面介绍我是如何对自己的系统进行配置的。这些配置都是直接从 YDL 安装程序所生成的配置中取过来的,我只是修改了视频模式:
default=ydl
timeout=10
root=/dev/sda1
ydl=’/dev/sda1:/vmlinux-2.6.16-20061110.ydl.2ps3
initrd=/dev/sda1:/initrd-2.6.16-20061110.ydl.2ps3.img root=/dev/sda3
init=/sbin/init video=ps3fb:mode:33 rhgb’
对 kboot.conf 所做的修改会在下次重新启动时立即生效;您不需要执行任何特殊操作将新配置告诉引导程序。
如果您正在使用电视机,并且所在的位置是欧洲,那么就可能希望以 38 模式运行;这样可以在上面的清单中简单地将 mode:33 修改为 mode:38 即可。如果感兴趣,可以使用 ps3videomode -h 命令查看所有的可用模式清单。您也可以使用 ps3videomode -v <number> 命令动态地体验各种模式。
现在我们已经完成了将像素写入空白显存所需要执行的操作了。
PS3 视频子系统受到了 Sony GameOS “系统管理程序” 的严格保护,它不能在其他 Linux 上显示出来。尚不清楚它们之所以这样做有多大程度是由于害怕有人会在某些特定情况下复制 PS3 游戏,或者能够看到一个 HD 视频内容的未加密字节;或者有多大程度上是由于 Sony 需要开发一种方法向 Linux 公开视频接口,而不需要对外公布有关 GPU 的任何注册表级文档(研究标明这可能会产生 GPL 的副作用,例如需要公布与 nVidia 达成的非公开协议所隐藏的代码)。
不管动机如何,ps3fb 视频设备的工作方式与其他 Linux framebuffer 都有些不同,这既是一个缺点,又是一个优点。参考资料 中给出了有关它的工作方式的详细文档,不过上面对讨厌的 bug 却只字未提。您需要了解的内容简单总结如下:
* 通常,framebuffer 设备都会让您直接访问显卡内存。
* 使用 ps3fb 设备,您的应用程序会写入主存(offscreen)缓冲区。对于垂直方向上的每个空格来说,管理程序都会采用 DMA 方式将自己的缓冲区读到 GPU 的内存中,然后将 GPU 的可视页刷新为与垂直空格信号同步的数据。
* 对于这个系统来说,优点是您永远都不需要担心更新屏幕内容时在一帧中间导致动画产生 “撕裂” 效应。
* ps3fb 还提供了一些 ioctl 命令,让您可以按照一种单缓冲区模式来显示自己的屏幕,此时您可以停止周期性的中断,并在应用程序认为合适的时机显式地将新的视频数据写入 GPU(当然,这依然要通过系统管理程序)。X 就使用了这种模式。
我刚才提到的那个讨厌的 bug 是指标准模式信息查询 ioctl 并不能正常工作,至少对于电视分辨率来说是如此。正如前面介绍的一样,NTSC 和 PAL 分辨率都会报告 576×384 像素的虚拟/物理大小。这甚至都不正确;NTSC 屏幕的实际宽度是 720 像素,而高度(由映射和日益累积变大的 RAM 边缘决定)实际上大约是 480 行,不过 framebuffer 控制台看起来在 400 行就停止了,480 行距离整个扫描区域的屏幕底部还有一段距离,至少对于默认的视频配置来说是如此。
因此,如果您简单地编译并运行通用 framebuffer 代码,它并不能显式地理解 PS3 会这样中断。我的解决方案是强制代码相信自己是在一个 720×400 像素的屏幕上运行的,这看起来似乎可以很好地工作。如果您正在使用 NTSC 电视机之外的其他设备作为输出设备,可能会希望进行这种修改;不过尽管代码能够正常操作,但是可能不会产生一个清晰的显示输出。
PS3 输出的另外一点非常怪异的事情是整个扫描区域的颜色是上一次扫描线的最后一个像素的输出颜色。关于这一点,我认为是 RAMDAC 对于每个 DMA 循环都有一个像素插销,当光栅超过 framebuffer 区域时,这个插销就会闭合,直到垂直空白间隔出现位置,此时会重新加载一个黑色的像素值。另外一种可能是这种现象是由于系统管理软件中的某种竞争所导致的。
本文提及这个问题的惟一原因是如果您在屏幕上画了一个矩形,它触及了屏幕的左边缘,就会看到这个矩形的颜色扩展到了整个扫描区域,而矩形的左上角却不是这样(由于这个角是从上一条扫描线的末尾继承的颜色)。即使在低分辨率的电视机上,这种现象也很容易注意到;我不希望您将这个问题报告为我代码的一个 bug,因为这根本不是我的 bug!