新机安装笔记 wi/ 调教 Samsung S24C350BL 显示器分辨率

是这样的,我在狗东上买了一台组装机来替换我的 Thinkpad T61 14 inches 装 openSUSE。配置大概是这样:

I5 6400,忘了有没有 K。
华硕 B150M 小板。
NVIDIA GeForce GTX960。
金士顿的 120GB SSD。我自己又加了一块西部数据的 1TB 蓝盘。
没有无线网卡,淘宝了 Linux 神器 Mercury MW150U USB 无线网卡(估计是买的人太多了,水星居然开了官方旗舰店)
声卡什么的就不说了,反正也用不着。
显示器!关键是显示器!狗东的 Samsung S24C350BL,搜下你就造了,不要 998 只要 799!

最开始下的 net install 的 ISO,安装时候等半天以为卡死了,切过去发现原来是要从 download.opensuse.org 下载一堆东西,超慢的。于是又下了 DVD。

刻录 USB 用的是 imageUSB 这个免费工具,SUSE 那个不维护了。

Windows 是整个装在 SSD 上的,我一开始就没打算把 openSUSE 装在 SSD 上,所以阴差阳错避免了很多问题:

华硕 B150M 比较良心,Windows 的 MBR 在 SSD,而 openSUSE 的 secureboot/efi 在 HDD 上(最早弄 UEFI 模式的时候,有个提示大概是 secureboot 让不让 openSUSE 写入,我选了让。反正现在我也不知道是一般的 UEFI 还是真的是 secureboot)。主板可以开机按 F2 进去选择从哪个硬盘启动,而且会记录,下次就不用了。所以避免了 grub2 双启动的各种问题。

而台式机也不存在双显卡问题,因为它的两个显卡有两个物理接口,我的显示器同一时间只能连在一个接口上,连到核载显卡 Windows 点不了显示器,所以连到了 GTX960 上面,相当于单显卡了。

装机唯一坑爹的地方在显示器,可能跟我接线的方式有关,我是用的 DVI 转 VGA 的插头。但是这个显示器是支持 VGA/DVI/HDMI 的。而 VGA 模式下显示器用的信号源不是数字而是模拟。

导致装机的时候分辨率认成了稀奇古怪的东西,简单说就是任何一个窗口都看不见最下面一条。所以各种确定取消的按钮我一律看不见。于是我只简单调教了一下 /home 别用掉全部的 899GB 就继续了。(这里有一个值得研究的问题就是为什么根分区用 BTRFS 最大只让我分 40GB?这可是 1TB 的硬盘啊)

真正装好之后整个人都 233 了,分辨率是 800x600。

这能忍吗?23.6 inches 的显示器分辨率是 800x600!

阅读了一下 /var/log/Xorg.0.log,发现原来是 nouveau 驱动不支持 GTX960,退而求其次到了 Vesa 驱动。于是需要安装闭源驱动。

需要先把 nouveau 驱动扔到驱动黑名单(/etc/modproble.d/50-blacklist.conf)里面,在黑名单的最后加入以下内容:

# Blacklist the open source nouveau nv driver, since NVIDIA Geforce
# GTX960 wasn't supported by the open source driver yet.
blacklist nouveau
blacklist nv
options nouveau modeset=0

我顺手把 nv 驱动也屏蔽了(它支持的显卡估计是 NVIDIA 建厂时候出的那些)。这就搞定了黑名单了。也就是说 NVIDIA 驱动后面给你创建的一些黑名单文件,如果你有洁癖就可以删掉。

下面是重新生成一下 initrd(你可以想象成 android 手机的 rom),因为 nouveau 驱动也在那里面,要把它剔除掉。直接 mkinitrd 命令就好,会自动调用 dracut 来做的。

重启之后装 gcc gcc-c++ make kernel-devel 这四个包,目的是为了编译 nvidia.ko 这个内核模块,也就是闭源驱动啦。

接着发现安装失败了,查 /var/log/nvidia-installer.log 发现是代码问题,于是通过搜索 "nvidia 364.19 kernel 4.6“ 就在 github 上找到了补丁。

你可以用 sh NVIDIA-Linux-x86_64-364.19.run -x 把驱动解压出来去手动改,然后装,也可以:

sh NVIDIA-Linux-x86_64-364.19.run --apply-patch 4.6.patch

来生成一个新的 NVIDIA-Linux-x86_64-364.19-custom.run,直接装生成出来的这个驱动。

装完之后 mkinitrd 重新生成 initrd,把 nvidia.ko 这个模块弄进去。重启。

=。=!640x400 的分辨率!反而更低了…

这绝对绝对不是我的理解能力和操作的问题!

GeForce GTX 960 应该在这个版本就支持了, nvidia.com/download/driverResults.aspx/81252/en-us ,最新的 n 卡驱动版本号在这里, nvidia.com/object/unix.html ,364.19 是 Latest Short Lived Branch,应该是你装的 n 卡驱动版本太新了,有 Bug,换一个长期版本的试试。

于是继续阅读 /var/log/Xorg.0.log,发现有这样一行话:

(**) NVIDIA(0): Using HorizSync/VertRefresh ranges from the EDID for display
(**) NVIDIA(0):     device CRT-0 (Using EDID frequencies has been enabled on
(**) NVIDIA(0):     all display devices.)
(WW) NVIDIA(0): CRT-0 does not have an EDID, or its EDID does not contain a
(WW) NVIDIA(0):     maximum image size; cannot compute DPI from CRT-0's EDID.

别看它只是一条 warning,其实意义可大了。经过漫天的搜索,我觉得用人类可以理解的话应该这么解释:

每一种显示器都有一个 EDID 信息(具体是什么请看 wikipedia),这个 EDID 信息是存在显示器的固件里面的。通过读取它,就能知道它的一些物理限制和建议设置,于是你就知道怎么配置这种显示器了。

也就是说,一旦知道了 EDID,你想配置错都不容易,别说万能的 Linux 了。除非 EDID 本身就是错的。

我一开始看漏了,没有看到 CRT-0 does not have an EDID 这句话。我的思路就是找 EDID,就算为了证明它是错的,你也得先看见它长什么样子。

如果你的显示器有 EDID 的话:

Windows 下面,如果你的显卡是 Quadro 或者 NVX 系列的,它们的驱动内置了一个 EDID 管理程序,所以你在 NVIDIA 控制面板里就能找到 EDID。如果不是的话,可以用 entech taiwan 出的这个 moninfo 软件查看。

Linux 下面可以用 read-edid 这个软件。

但是我的是完全就没有!(也不能断言说是物理意义上的没有,可能跟我接线的方式有关,反正 VGA 接口和模拟信号源是没有或者读取不到)

这就跟开卷考试你没带书一样。

下面继续介绍原理:

每种显示器都有一个物理上的 HorizSync(水平同步率)和 VertRefresh(垂直刷新率)。这两个率共同决定了可以接受多高的分辨率,它们各是一个区间,是没法超频的。举例:

$ cvt 1920 1080 60
# 1920x1080 59.96 Hz (CVT 2.07M9) hsync: 67.16 kHz; pclk: 173.00 MHz
Modeline "1920x1080_60.00"  173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync

看到那个 hsync: 67.16 kHz 了吗?如果你显示器的 HorizSync 是 30 - 81,那么你就能够使用这种分辨率(1920x1080,60 kHz 刷新率)。但要是:

# 2560x1440 59.96 Hz (CVT 3.69M9) hsync: 89.52 kHz; pclk: 312.25 MHz
Modeline "2560x1440_60.00"  312.25  2560 2752 3024 3488  1440 1443 1448 1493 -hsync +vsync

对不起,强撸灰飞烟灭。

Xorg 是这么配置显示器的,首先要有一个设备的配置(Section Device),告诉 Xorg 哪个底层驱动控制哪个监视器。
然后要有一个监视器的配置(Section Monitor),告诉 Xorg 这个显示器的硬件信息。最后要有一个屏幕的配置(Section Screen),
告诉 Xorg 我要用多少分辨率的屏幕。

设备配置比较简单了(/etc/X11/xorg.conf.d/50-device.conf):

Section "Device"
  Identifier "Default Device"
  Driver "nvidia"
  VendorName "NVIDIA Corporation"
  BoardName "GeForce GTX 960"
  Option "monitor-DVI-I-0" "Default Monitor"
EndSection

那个 DVI-I-0 是这么得到的:

$ xrandr -q
Screen 0: minimum 8 x 8, current 1920 x 1200, maximum 16384 x 16384
DVI-I-0 connected primary 1920x1200+0+0 (normal left inverted right x axis y axis) 0mm x 0mm

你看到那个 connected primary 就知道了,不要选那些 disconnected 的。

屏幕的配置也比较简单:

Section "Screen"
  Identifier "Default Screen"
  Device "Default Device"
  Monitor "Default Monitor"
  DefaultDepth 24
  SubSection "Display"
    Depth 24
    Modes "1920x1200" "1600x1200"
  EndSubSection
EndSection

这里需要说明的是 Modes 是有一些预定义的,比如 1024x768。但是如果当你要使用一些没有被检测到的分辨率的时候,你就要在监视器配置的时候做点手脚把这个分辨率通过 Modeline 的方式加进来。

监视器的配置比较难,因为集中了很多你这款显示器的硬件信息,不能添错的。

Section "Monitor"
  Identifier "Default Monitor"
  VendorName "Samsung"
  ModelName "Samsung S24C350BL"
  HorizSync 30.0 - 81.0
  VertRefresh 56.0 - 75.0
  Option "DPMS"
  Modeline "1920x1200_60.00"  193.25  1920 2056 2256 2592  1200 1203 1209 1245 -hsync +vsync
EndSection

至于分辨率,你其实已经知道了你的显示器的最佳分辨率和刷新率了,比如我的在 Windows 里面是 1920x1080,60 kHz。

那用 cvt 命令直接就可以求出 Modeline。

我面对的难点主要是 HorizSync 和 VertRefresh 的值,因为配置错会烧显示器啊!

后来发现是我太相信你们这帮搞 IT 的人的英文水平了,HorizSync 我翻译成水平同步率,VertRefresh 是垂直刷新率。结果你们是叫做”行频“和”场频“的啊!

知道这些,直接在显示器的说明书上就能找到那两个值了。

还有一个更坑爹的地方是,这个显示器其实是 16:10 的(至少在 Linux 下面是),而不是 Windows 和它的厂家说的 16:9。

我用了 1920x1080 的 modeline 结果显示器两边两块黑,直接变成 4:3 的样子了。如果把 modeline 删掉,xorg 会自动使用 1600x1200 的分辨率,也就是 4:3 的(我怀疑可能是 Xorg 的 bug)。

按理我应该去固定高度不变去尝试 1080 高度下的各种更长的分辨率的。但实际上通过百度百科分辨率词条里面那张图你可以看到,没有这样的分辨率,实际上 16:9 最大的分辨率就是 1920x1080。

于是只能用 16:10 的,结果完美显示。

@恋衣之曲

不是显卡驱动的问题,毕竟 GTX960 是全民显卡。我怀疑是硬件方面的,比如 VGA 线就读不到 EDID,或者说 VGA 能读到但 Linux 下面没有这种 implementation。

之前在公司装的一台 dell 小主机就是这样,用 DVI 转 VGA 的头之后分辨率永远都不正确,换了跟双头 DVI 线立刻天下太平;显示器是 dell 的某款准专业屏型号没记住,显卡是 ATI 的忘了什么卡,装的 Leap 42.1

看来以后配置新电脑连接显示器的时候,不要使用各种转接口,尽量使用原生接口。

貌似目前这款显示器只 755。799 贵了。再加 150 就可以买曲面屏了。漂亮的很。

:joy: 所以一开始就用 HDMI 线就好了么

呃,天,看来我还是不要去组装机了,老老实实用自己的华硕老本本,13.2 目前还凑合