《廉价的家用工作站方案:前篇》一文中,曾提到在 2021 年第三个季度开始,我又购置了一台新的设备,没错,它就是搭载着 Ryzen3 5800u 的笔记本。

然而可惜的是,目前 Ubuntu 社区的发行版并不能够很好的支持搭载 AMD Zen2 / Zen3 芯片的设备。

所以,如果你也希望舍弃掉笔记本设备自带的 Windows 系统,拥抱当前时代 Ubuntu LTS 版本,那么本篇文章,将能帮助你避开“坑”,快速体验这些具备高性能 CPU 的设备。

写在前面:为什么剁手

《廉价的家用工作站方案:前篇》一文中,我提到过,我曾在三个月前购置了一台搭载 AMD Ryzen2 4750u CPU 的设备:ThinkPad L14 Gen1。

AMD 4750u 笔记本开箱全过程

这台设备的最吸引我的,便是在一众同类产品中,支持将内存扩展到 64GB,并搭载了同时期性能非常强的 Zen2 Pro 系列的芯片,机器本身只有集显,价格相对低廉,简直是“程序员之宝”。感兴趣可以围观官方产品规格,或许你也会感兴趣。

时隔几个月,在我希望再次扩充本地计算资源的时候,发现官方在 5月初,居然更新了这个产品线,发布了 ThinkPad L14 Gen2,将 CPU 更新为了 Zen3 R7 PRO 的 5850u(产品详细规格),可以看到 CPU 性能以及缓存大小都有了明显的改进。但可惜的是,在我翻遍全网,也未能找到可以购买这台设备的地方。既然买不到新的,旧的又不是不能用,我再买一台这几个月带来良好体验的 Gen1 就是了,但在我准备下单的时候,发现这台设备居然涨价了,价格直逼其他型号搭载 Zen3 的新设备。

所以,我开始寻找其他型号:“能够支持大内存的笔记本设备,最好具备 Zen3 架构的芯片”。经过两天的资料查找,发现目前搭载 5800u 或者 5800h 的设备,不是锁定 CPU 功耗,就是使用板载内存限制扩展性、限制内存为 16GB,要不就是主打轻薄,谢绝提供 RJ45 网口。

CPU 能否持续稳定输出,决定了编译程序、虚拟化时的效率;RJ45 网卡决定了是否能使用更高性能更稳定的网络,关于这两个功能点是不能妥协的。那么,有没有一台设备能够将内存能尽可能的扩展的大一些呢?或者说,有没有带网口,配备新款 CPU,允许一个内存插槽扩展的设备呢?(别都是板载内存啊)

经过一番查找,最终找到了 ThinkBook 15 这个型号的设备,那么这台设备和我之前的设备的差异有哪些呢?

设备对比:了解设备差异

这台设备的官方产品名称是 ThinkBook 15 G3 ACL,它的产品规格页面中明确展示了它和我之前已经使用了三个月的设备 ThinkPad L14 Gen1 的主要差异:

  • 同样是 8C/16T的CPU,基础和最高频率分别提升了 0.2 / 0.3 GHz,L3 提升了一倍达到了 16MB。
  • 因为板载了一条 8GB 的内存,所以内存上限从 64GB 下调至了 40GB。
  • 这台笔记本允许使用两条 M2 SSD 磁盘,在不使用 USB 和雷电外接存储的情况下,默认的容量会比之前大一些。
  • 因为网卡从 Intel 换成了螃蟹网卡的某个版本,自带“蓝牙”版本从 5.2 下调到了 5.1。
  • 默认电源从 45w 提升到了 65w。

看起来一切还好,美中不足的是内存下调了 24GB 空间。如果遇到实在跑不动的程序,到时候就只好使用 swap 大法或者交给之前的大内存设备来解决啦。

一台“等待处理”的新设备

硬件扩容:扩展内存和存储空间

使用 1622 号螺丝刀进行拆机

在安装系统之前,先对设备进行内存和存储扩充。

5800u拆机

拆掉笔记本背面的螺丝,然后使用塑料卡片将笔记本 D 面一点点撬开,然后就能看到“新鲜的”主板了。

扒开散热罩,替换大容量内存

打开 D 面之后,使用镊子或者螺丝刀,继续将铝制的内存散热罩撬开,可以看到机器自带的一片原装内存,掰一下两侧的内存卡扣,将内存卸掉,使用准备好的 32 GB 新内存进行替换。

扩展容量

接着可以根据自己需求,考虑是否要将原装固态卸掉,我这里选择保留原装固态磁盘,并再添加一条新的固态磁盘,作为数据盘使用,添加磁盘空间以及吞吐能力。

一切就绪后,将笔记本 D 面安装回去,扭好螺丝,接通电源,稍后进行硬件测试。

检查 BIOS 软件版本

在开始硬件测试之前,我们需要先确认机器使用的 BIOS 版本是否需要更新。一般情况下,新版本的 BIOS 软件能够以解决一些基础硬件和功能性问题,翻阅官方支持站点,可以看到最新软件版本为 ** GQCN20WW**。

进入 BIOS 设置界面

连接电源,开机后连续点按 F1,进入 BIOS 设置界面。设备第一次启动会比较慢,这是因为我们改动了默认硬件,机器会进行快速的硬件自检。

关闭 BIOS 提示框,基础信息一览无余

在进入 BIOS 界面后,可以看到目前机器设备的 BIOS 已经是最新版本,那么我们可以直接进入下一个步骤,硬件测试。

硬件测试:验证硬件可用性

联想的 ThinkPad 和 ThinkBook 的 BIOS 中默认带了一个硬件检测的功能,重新开机后连续按 F10 ,即可进入这个功能。

硬件测试

选择“快速机器测试”,大概10分钟左右,就能得到刚刚安装硬件是否能够正常运行的检测报告了。

测试完毕后,关闭机器,等待稍后使用。如果你不关机,重启之后,机器会自动进入大家熟悉的 Windows 系统安装界面,此时想退出过程,可以长按关机键,中止安装。

系统安装

《廉价的家用工作站方案:前篇》 中提到了,如果你希望偶尔带着这台笔记本出行,拥有 GUI 对于你小到切换无线网,大到使用 VSCode 之类的软件都有比较好的体验,所以我们直接访问 Ubuntu 官网获取 Desktop 版本的镜像文件。

建议下载官方原版

制作 USB 启动盘

使用 balenaEtcher ,可以在多种系统平台上,快速制作 Linux 系统的安装引导盘。

使用 Balena Etcher 制作引导盘

当然,因为我们使用的硬件比较新,所以 Ubuntu 系统的安装过程中,会遇到一些问题,稍后我将一一说明。

使用引导程序安装系统

将制作好的 USB 安全引导盘插到新设备的 USB 接口上,重新打开笔记本电源。在启动过程中连续点按 F6,会进入引导设备选择阶段。

因为我们没有格式化设备磁盘,磁盘预装了 Windows,所以界面会提醒我们进入 了 Windows 引导管理程序。选择引导 FEI USB 设备,就能进入 Ubuntu 安装界面啦。

安装 Ubuntu 操作系统

随着 Ubuntu 社区的发展,现如今安装 Ubuntu 系统可以说是一路 Next 就行。

但是在过程中,针对这台设备或者类似设备,在安装步骤选择上,还是有一些推荐策略:

使用正常方式安装

系统安装选择 “Normal Installation”,其他选项中需要选择 “Install third-party software for graphics and Wi-Fi hardware and additional media formats”,安装程序需要我们开启 “Configure Secure Boot”,输入用户自定义密码。这样做可以尽可能让系统安装完毕后,拥有一些常见的驱动程序,节约折腾时间成本。

将预装系统进行全盘擦除

接着选择“Erase Disk and Install Ubuntu”,进行全盘数据擦除,以全新的方式安装系统。避免传统安装全新系统还需要借助其他功能先初始化一遍磁盘和引导分区标记。

初步安装结束

尽管安装简单如此,但是在系统安装完毕之后,你会发现系统显示虽然正常,但是网卡只有有线网卡正常,无线网卡还不能正常使用。而且随着使用的深入,你会发现需要解决的问题不仅仅这一个,在继续解决问题之前,我们先对系统进行一些基础配置。

基础系统配置

参考《NUC 折腾笔记 - Linux 系统篇》一文,先对系统软件源列表 /etc/apt/sources.list 进行更新。

vim /etc/apt/sources.list

将默认软件源替换为清华源,当然,你也可以替换为实际情况中,你访问更快的软件源:

:0,$ s/cn.archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn\/ubuntu/
:0,$ s/security.ubuntu.com/mirrors.tuna.tsinghua.edu.cn\/ubuntu/

为了方便后续操作系统,需要安装 ssh server 以及一些常用工具:

apt install -y openssh-server
apt install -y net-tools htop iftop iotop

在完成了基础配置之后,就能够正式开始,针对系统问题进行解决啦。

问题:系统常规更新后无法运行

当我们使用 apt update && apt upgrade -y 更新系统软件包,并重启设备后。会发现系统出现了下面的错误,卡在了启动界面:“AMD-Vi: Unable to read/write to IOMMU perf counter”。

答案:切换老版本内核版本进行临时启动

出现这个问题的原因主要是因为更新后的 Ubuntu 发行版使用的 Linux 内核并不支持 AMD 5750u 及 5800u,治本的解决方案是切换至更高版本的内核,这些内核中包含了对新款 CPU 的支持。

但是,我们刚刚已经使用过 apt update && apt upgrade -y 执行了升级,官方社区已经没有更加新的 Linux 内核版本可以使用了。

GRUB 引导界面

所以,这里我们需要使用“手动升级内核”的方式来解决问题。以及这里为了正常启动系统,需要在启动进入 Grub 引导界面时,选择 “Advanced options for Ubuntu”,选择 Linux 5.8.0-43 版本的 Linux 内核,让系统能够临时的正常启动。

问题:如何更新系统内核

前文提到,治本的方案是更新系统内核,那么要更新哪个维护渠道的版本,更新到具体哪个内核版本,以及如何进行手动更新呢?

答案1:直接使用 Linux 新版内核

Linux 内核官方页面

Ubuntu 内核官方页面

对比Linux 内核官方网站Ubuntu 内核官方网站,我们可以看到 Ubuntu LTS 使用的 Linux 内核版本比较陈旧:“Based on the upstream 5.4 kernel”,而官方版本已经迭代到了 5.13。

前文提到我们当前使用的版本已经是 5.8.x ,所以 5.8~5.13 都是我们的射程之内,具体使用哪个版本,我们会在下文中细聊。

答案2:使用省事的预编译包

相比较从源码编译,背靠 Ubuntu 社区,我们可以直接使用社区提供的预编译内核软件包。

访问官方地址,可以看到一个 Apache Index 服务,展示了自 v2.6 开始到目前 v5.13 各个版本的内核。

答案3:使用5.10.x版本内核

在依次尝试了 5.13 / 5.12 内核的安装后,我最终选择了 5.10 版本的内核,感兴趣为什么可以参考文末的插曲部分。

访问 https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.11.10/,因为机器架构是 amd64,所以选择相同架构的 Linux 内核安装包:

amd64/linux-headers-5.11.10-051110-generic_5.11.10-*_amd64.deb
amd64/linux-headers-5.11.10-*_all.deb
amd64/linux-image-unsigned-5.11.10-051110-generic_5.11.10-*_amd64.deb
amd64/linux-modules-5.11.10-051110-generic_5.11.10-*_amd64.deb

首先,使用 wget 下载软件包:

wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.11.10/amd64/linux-headers-5.11.10-051110-generic_5.11.10-051110.202103251032_amd64.deb
wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.11.10/amd64/linux-headers-5.11.10-051110_5.11.10-051110.202103251032_all.deb
wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.11.10/amd64/linux-image-unsigned-5.11.10-051110-generic_5.11.10-051110.202103251032_amd64.deb
wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.11.10/amd64/linux-modules-5.11.10-051110-generic_5.11.10-051110.202103251032_amd64.deb

然后下载校验文件,并检查文件下载是否完整,避免安装过程中出现预期之外的错误:

wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.11.10/amd64/CHECKSUMS

# 我们不使用 lowlatency 内核,所以要过滤掉这些文件
cat CHECKSUMS | grep -v lowlatency >> dig.checksum

shasum -c dig.checksum 
linux-headers-5.11.10-051110_5.11.10-051110.202103251032_all.deb: OK
linux-headers-5.11.10-051110-generic_5.11.10-051110.202103251032_amd64.deb: OK
linux-image-unsigned-5.11.10-051110-generic_5.11.10-051110.202103251032_amd64.deb: OK
linux-modules-5.11.10-051110-generic_5.11.10-051110.202103251032_amd64.deb: OK
linux-headers-5.11.10-051110_5.11.10-051110.202103251032_all.deb: OK
linux-headers-5.11.10-051110-generic_5.11.10-051110.202103251032_amd64.deb: OK
linux-image-unsigned-5.11.10-051110-generic_5.11.10-051110.202103251032_amd64.deb: OK
linux-modules-5.11.10-051110-generic_5.11.10-051110.202103251032_amd64.deb: OK

使用 dpkg --install *.deb 安装内核软件包,系统将自动处理安装顺序依赖。如果顺利的话,你将看到类似下面的日志输出:

(Reading database ... 250171 files and directories currently installed.)
Preparing to unpack linux-headers-5.11.10-051110_5.11.10-051110.202103251032_all.deb ...
Unpacking linux-headers-5.11.10-051110 (5.11.10-051110.202103251032) over (5.11.10-051110.202103251032) ...
Preparing to unpack linux-headers-5.11.10-051110-generic_5.11.10-051110.202103251032_amd64.deb ...
Unpacking linux-headers-5.11.10-051110-generic (5.11.10-051110.202103251032) over (5.11.10-051110.202103251032) ...
Preparing to unpack linux-image-unsigned-5.11.10-051110-generic_5.11.10-051110.202103251032_amd64.deb ...
Unpacking linux-image-unsigned-5.11.10-051110-generic (5.11.10-051110.202103251032) over (5.11.10-051110.202103251032) ...
Preparing to unpack linux-modules-5.11.10-051110-generic_5.11.10-051110.202103251032_amd64.deb ...
Unpacking linux-modules-5.11.10-051110-generic (5.11.10-051110.202103251032) over (5.11.10-051110.202103251032) ...
Setting up linux-headers-5.11.10-051110 (5.11.10-051110.202103251032) ...
Setting up linux-headers-5.11.10-051110-generic (5.11.10-051110.202103251032) ...
Setting up linux-image-unsigned-5.11.10-051110-generic (5.11.10-051110.202103251032) ...
Setting up linux-modules-5.11.10-051110-generic (5.11.10-051110.202103251032) ...
Processing triggers for linux-image-unsigned-5.11.10-051110-generic (5.11.10-051110.202103251032) ...
/etc/kernel/postinst.d/initramfs-tools:
update-initramfs: Generating /boot/initrd.img-5.11.10-051110-generic
I: The initramfs will attempt to resume from /dev/dm-2
I: (/dev/mapper/vgubuntu-swap_1)
I: Set the RESUME variable to override this.
/etc/kernel/postinst.d/zz-update-grub:
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.11.10-051110-generic
Found initrd image: /boot/initrd.img-5.11.10-051110-generic
Found linux image: /boot/vmlinuz-5.8.0-59-generic
Found initrd image: /boot/initrd.img-5.8.0-59-generic
Found linux image: /boot/vmlinuz-5.8.0-43-generic
Found initrd image: /boot/initrd.img-5.8.0-43-generic
Adding boot menu entry for UEFI Firmware Settings
done

不论是使用 reboot 命令还是物理方式,进行设备重启。然后,你会发现设备居然无法正常启动了。

问题:无法加载未签名的 Linux 内核

安装了新版内核之后,再次启动系统,会看到一个有趣的报错:

error: /vmlinuz-5.10.11 has invalid signature
error: you need to load the kernel first

这个错误将导致我们新安装的系统内核,无法被引导程序加载,最终导致系统无法启动。

答案:更新 BIOS 设置

引发这个问题的原因,是因为我们使用了未签名的预编译内核安装包 “linux-image-unsigned”。

关闭“Secure Boot”

解决问题的方法也很简单,再次重启机器,连续点按 F1 进入 BIOS 设置,选择 security,将 “Secure Boot” 设置为 “Disabled”,将这个功能关闭后,再次重启设备,系统就能正常运行了。

问题:系统不能使用无线网卡

跟着文章操作到现在,你的系统应该已经能够正常启动,以及能够正常的更新和安装软件了。

同时,设备的 HDMI 接口应该也能够正常使用,但是,你会发现无线网卡目前依旧不能运行,设备无法搜索和连接任何无线网络。

为什么会出现这样的现象呢?原因也很简单,因为缺少无线网卡驱动。

答案:编译无线网卡驱动

绝大多数常见网卡都已经随着内核更新被默认内置,比如 Intel 官方就提供了各个无线网卡硬件和 Linux 内核版本的支持关系。然而这台设备使用的“螃蟹卡”,属于需要“折腾一下”的范畴。

编译无线网卡之前首先要了解设备型号,使用 lspci 命令,可以快速获得网卡类型:

lspci | grep Network
05:00.0 Network controller: Realtek Semiconductor Co., Ltd. Device 8852

在 GitHub 社区,我们能够看到螃蟹网卡的开源实现:https://github.com/lwfinger/rtw89,通过下面的命令,可以快速的对这个网卡驱动进行编译和安装:

apt-get install -y make gcc build-essential git
git clone https://github.com/lwfinger/rtw89.git -b v5
cd rtw89
make
make install

驱动安装完毕,再次重启进入系统后,会发现系统无线网卡已经能够正常使用了。

问题:如何确认我们安装的系统是否稳定

“实践是检验真理的唯一标准。” 对于我们安装的系统也是如此,相对靠谱的方式是通过漫长真实场景的使用,来验证系统是否能够稳定健壮运行,而不是随意崩溃出错。

但是,上面的方式时间上太过于漫长。那么,有没有更有效率的方式呢?这里提供一种相对方便的检测方案:压力/负载测试。

通过持续性的对系统进行压力测试,不限制软件使用的运行资源,最大化的利用系统的 CPU 等硬件,测试系统超过大量预期之外的工作量时的表现,观察系统各硬件的状态和指标(如:温度),来验证系统是否能够正常运行。

那么,怎么进行压力测试呢?

答案:使用经典软件 stress 和 sensors

使用下面的命令安装 stress 和传感器软件 sensors:

apt-get install -y stress
apt-get install -y lm-sensors hddtemp

安装完毕之后,便可以使用 stress 指定 16 个进程满负荷运行30分钟压力测试:

stress -c 16 -t 1800

进行高压力/高负载测试

过程中,会看到 8个核心 16 个线程始终都以满负荷运行。

在过程中,随时使用 SSH 另外一个会话,使用 sensors 命令查询设备状态,能够看的此刻机器各主要硬件的温度,以及 CPU 的功率状态:

# case 1

amdgpu-pci-0600
Adapter: PCI adapter
vddgfx:      774.00 mV 
vddnb:       656.00 mV 
edge:         +56.0°C  
power1:       16.00 W  

nvme-pci-0200
Adapter: PCI adapter
Composite:    +34.9°C  (low  = -273.1°C, high = +80.8°C)
                       (crit = +86.8°C)
Sensor 1:     +34.9°C  (low  = -273.1°C, high = +65261.8°C)

nvme-pci-0300
Adapter: PCI adapter
Composite:    +38.9°C  (low  = -273.1°C, high = +81.8°C)
                       (crit = +84.8°C)
Sensor 1:     +38.9°C  (low  = -273.1°C, high = +65261.8°C)
Sensor 2:     +41.9°C  (low  = -273.1°C, high = +65261.8°C)

BAT1-acpi-0
Adapter: ACPI interface
in0:          17.45 V  

# case 2

amdgpu-pci-0600
Adapter: PCI adapter
vddgfx:      768.00 mV 
vddnb:       762.00 mV 
edge:         +56.0°C  
power1:       19.00 W  

nvme-pci-0200
Adapter: PCI adapter
Composite:    +34.9°C  (low  = -273.1°C, high = +80.8°C)
                       (crit = +86.8°C)
Sensor 1:     +34.9°C  (low  = -273.1°C, high = +65261.8°C)

nvme-pci-0300
Adapter: PCI adapter
Composite:    +38.9°C  (low  = -273.1°C, high = +81.8°C)
                       (crit = +84.8°C)
Sensor 1:     +38.9°C  (low  = -273.1°C, high = +65261.8°C)
Sensor 2:     +41.9°C  (low  = -273.1°C, high = +65261.8°C)

BAT1-acpi-0
Adapter: ACPI interface
in0:          17.45 V  

实际体验过程中,丝毫感觉不到命令卡顿,而且可以观察到满载情况下,这台机器核心温度稳定在了 56 摄氏度。

当半个小时的测试结束之后,设备温度在几分钟内迅速下降,三分钟左右风扇从高速模式转换为零低速模式,片刻之后,设备风扇转换为静音模式运行。

小插曲:尝试高版本的内核

当我们选择高版本的 Linux 内核,执行 dpkg 安装的时候,会看到诸如缺少高版本 glibc 等错误提示。

linux-headers-5.12.14-051214-generic depends on libc6 (>= 2.33); however:
  Version of libc6:amd64 on system is 2.31-0ubuntu9.2.

倘若我们使用 https://pkgs.org/search/?q=libc6 手动寻找和下载这些依赖、以及依赖软件的依赖,并进行安装后,会发现高版本的内核是可以被安装的。

uname -r
5.12.14-051214-generic

然而,一旦在执行 apt install 安装或者更新软件包时,会发现系统会无休止的提醒我们执行 “apt --fix-broken install” 修正依赖,或提示我们刚刚安装的哪些软件包版本的依赖高于了软件在当前发行版下的依赖版本,提示找不到指定依赖而无法继续使用。

所以,为了系统使用上的方便,虽然能够在当前的 LTS 版本上安装比文中版本更高的内核,但是这里强烈不推荐这样操作。

最后,如果在过程中进行了大量尝试,系统包含了一堆冗余的其他版本内核,该怎么处理呢?

答案: 清理不能够正确使用的内核

前文提到过,使用 apt-get upgrade 安装的新版内核,或者手动安装的高版本内核是无法使用的,为了减少冗余,我们可以使用下面的命令对其进行清理:

apt-get purge linux-image-5.8.0-59 linux-image-5.12.14

清理其他版本的内核同理,一般情况下可以使用 tab 来补全具体的内核版本号,如果你希望查看到底安装过哪些内核,可以使用下面的命令:

dpkg --get-selections | grep linux-image

在清理完毕系统内核之后,为了保险,可以手动重新生成 Grub 系统启动内核列表,避免启动时出现错误:

sudo update-grub
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.11.10-051110-generic
Found linux image: /boot/vmlinuz-5.8.0-43-generic
Found initrd image: /boot/initrd.img-5.8.0-43-generic
Adding boot menu entry for UEFI Firmware Settings
done

最后

下一篇这俩 AMD Ryzen CPU 设备的文章,我将继续介绍“廉价的家用工作站”的实践分享。

–EOF