Arch Linux/Windows双系统踩坑记录

由于想使用Linux直接进行开发软件,不考虑使用虚拟机跑IDE等一系列软件(因为虚拟机再怎么样也会存在性能损耗,而且,在虚拟机里写软件有点憋屈)。

当然也不考虑WSL 2。虽然WSL 2我之前用过,其与Windows操作系统的高度集成度值得夸赞,但是WSL 2依然会牵扯到Hyper-V问题。虽然VMware Workstation目前已经可以和Hyper-V共存,但是此时VMware Workstation直接使用虚拟机显示器操作Linux,操作命令行时会产生严重的卡顿感(在使用Arch Linux ISO安装新Arch Linux时会有明显感觉,但是可以用SSH规避此问题)。

所以最后依然是选择了Windows/Arch Linux双系统的方案,即同时维护两套环境,以做到最佳体验。

不过,相比于虚拟机安装Arch Linux,实体机上安装,会踩的坑更多,尤其是在笔记本上安装时。

博主的笔记本配置情况

编写这篇文章的时候使用的是宏碁的暗影骑士擎2020年版游戏本,配置为i5-10300H + GTX1650Ti + 2*16GB内存。

需要说明的是,笔记本原本是2*8GB内存,但是我发现开IDE内存不够用,遂换成了2*16GB内存。

笔记本的三个硬盘位均已被插满,其中两条NVMe SSD(512GB+1TB),均格式化为NTFS。一块2.5英寸512GB SATA SSD用于安装Arch Linux系统。

笔记本上安装了Windows 11+Arch Linux。Windows 11位于512GB NVMe硬盘上,而Arch Linux位于512GB SATA SSD上。

驱动问题

NVIDIA驱动(混合显卡)

Linux下整NVIDIA驱动算是挺折腾的,但是没有之前的nouveau时代折腾(猜猜NVIDIA, f**k you这个梗是怎么来的),不过折腾完之后还是搞好了。

由于我的笔记本没有独显直连,因此NVIDIA驱动这一块,需要考虑的事情比较少。

对于linuxlinux-lts内核的用户,可以直接安装nvidianvidia-lts驱动包。

如果不是这两种Linux内核的用户,比如我使用的是linux-zen内核,则需要使用DKMS。

安装DKMS的具体操作是,安装dkms程序包,并安装你使用的Linux内核的头文件。通常这类软件包的名称都是[linux-name]-headers,比如我的linux-zen内核对应的就是linux-zen-headers软件包。

在安装完DKMS和Linux头文件后,安装nvidia-dkms。之后当Linux内核升级(作为滚动发行版,这种事情在Arch Linux上将会经常发生)时,NVIDIA显卡的相关驱动就会被DKMS重新编译(不会花费很长时间,放心)。

然后启用NVIDIA驱动的DRM功能。创建/etc/modprobe.d/nvidia.conf文件,其中需要包含的内容如下:

options nvidia_drm modeset=1

接下来,对于笔记本混合显卡用户,还有一些需要注意的地方。

首先,记得安装nvidia-prime软件包,该软件包中有个prime-run命令,用于指定某个软件使用NVIDIA显卡运行。

如果你的显卡型号为16xx或更高规格,则可以考虑启用Runtime D3省电优化。需要注意的是,对于30xx系列或更高系列的显卡,该功能可能已经默认开启。

创建/etc/udev/rules.d/80-nvidia-pm.rules,文件内容如下:

# Enable runtime PM for NVIDIA VGA/3D controller devices on driver bind
ACTION==bind, SUBSYSTEM==pci, ATTR{vendor}==0x10de, ATTR{class}==0x030000, TEST==power/control, ATTR{powe
r/control}=auto
ACTION==bind, SUBSYSTEM==pci, ATTR{vendor}==0x10de, ATTR{class}==0x030200, TEST==power/control, ATTR{powe
r/control}=auto

# Disable runtime PM for NVIDIA VGA/3D controller devices on driver unbind
ACTION==unbind, SUBSYSTEM==pci, ATTR{vendor}==0x10de, ATTR{class}==0x030000, TEST==power/control, ATTR{po
wer/control}=on
ACTION==unbind, SUBSYSTEM==pci, ATTR{vendor}==0x10de, ATTR{class}==0x030200, TEST==power/control, ATTR{po
wer/control}=on

创建或编辑/etc/modprobe.d/nvidia.conf,需要添加的内容如下:

options nvidia NVreg_DynamicPowerManagement=0x02
options nvidia NVreg_PreserveVideoMemoryAllocations=1

对于Turing系显卡(GTX 16xx系显卡),还需要加入下面的参数:

options nvidia "NVreg_EnableGpuFirmware=0"

为了防止Wayland程序频繁唤醒NVIDIA显卡,推荐在/etc/environment中追加下述环境变量设置以调整EGL和GLX的显卡优先级。通过调整显卡优先级,还可避免笔记本接入外屏时出现一些诡异问题。

__EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json:/usr/share/glvnd/egl_vendor.d/10_nvidia.json
__GLX_VENDOR_LIBRARY_NAME=mesa

接着,为保证NVIDIA显卡的一些功能,还需要通过systemctl启用NVIDIA的一些服务。

systemctl enable nvidia-persistenced
systemctl enable nvidia-hibernate
systemctl enable nvidia-suspend
systemctl enable nvidia-resume

# 如果你的显卡基于Ampere或之后的架构,还可以启用nvidia-powerd以支持Dynamic Boost
systemctl enable nvidia-powerd

重启电脑,输入下面的命令查看Runtime D3启用状态。如果输出类似内容,则代表启用成功。(下述示例输出所使用的显卡为GTX 1650Ti)

$ cat /proc/driver/nvidia/gpus/0000:01:00.0/power
Runtime D3 status:          Enabled (fine-grained)
Video Memory:               Off

GPU Hardware Support:
 Video Memory Self Refresh: Supported
 Video Memory Off:          Supported

S0ix Power Management:
 Platform Support:          Not Supported
 Status:                    Disabled

此时当NVIDIA显卡没有负载时,显卡将会立刻休眠,当有程序调用时会立刻被唤醒。

声卡

对于部分Intel声卡,在运行Linux时,使用3.5英寸耳机接口可能出现杂音。

如遇到这种情况,创建/etc/modprobe.d/sound.conf,文件内容如下:

options snd_hda_intel power_save=0

启用zram(非必需)

如果你已配置硬盘上的交换空间(如swap分区,swap文件等),此时Arch Linux默认启用的zswap会起效果,就不推荐使用zram了,否则建议配置zram。

需要注意的是,启用zram会阻碍Linux的休眠功能。

安装zram-generator

sudo pacman -S zram-generator

打开/etc/systemd/zram-generator.conf,输入下面的内容,保存。

[zram0]

下次系统启动时,就会自动创建压缩内存,并向系统添加相关的swap选项。

如果你不想重启系统而立刻使用压缩内存,可使用以下命令。

sudo systemctl daemon-reload
sudo systemctl start /dev/zram0
# 上面指令输入完成之后,建议输入swapon确认压缩内存启用情况
swapon

另外还需要注意,启用zram之后需要关闭zswap,方法是添加内核参数zswap.enabled=0。至于如何添加内核参数,ArchWiki有详细的说明方法。

对于GRUB用户,一般都是编辑/etc/default/grub文件,其中的GRUB_CMDLINE_LINUX_DEFAULT就是Linux的内核参数。编辑完这个文件后,记得用grub-mkconfig重新生存配置文件。

Wayland

X11在很长一段时间都占据了Linux桌面环境的基础,不过X11放在现在已经相当老了,有些东西,比如HiDPI,X11就不是支持的很好。

Wayland,更像是Linux桌面环境的未来。越来越多的Linux桌面环境和程序都开始支持Wayland。

对于KDE,之前发布的Arch Linux+KDE安装流程教学已经提过,需要安装plasma-wayland-session软件包。

在安装之后,在sddm登录界面选择Plasma (Wayland),即可进入KDE Wayland。

接下来说一下一些需要注意的地方。

如果你有按照我之前发布的安装教学文章配置过中文UI,则还需要将其中的本地化相关环境变量写入到中~/.config/environment.d/envvars.conf中。

对于Mozilla的部分程序(Firefox,Thunderbird等),为了让其使用Wayland模式运行,需要设置一个环境变量。创建或编辑~/.config/environment.d/envvars.conf,追加下述环境变量内容。

MOZ_ENABLE_WAYLAND=1

如果你的笔记本使用Intel集成显卡进行画面输出,且在Wayland模式下使用KDE Plasma桌面,则建议使用linux-zen内核以优化KDE动画流畅度。 最新版KDE 6.1已经加入三重缓冲功能,因此本条不再适用。

安全启动(Secure Boot)

大部分情况下,关闭Secure Boot后,Windows + Arch Linux双系统依然可以共存的很好。

如果由于某些情况,必须要启用安全启动(比如在Windows 11下游玩无畏契约,或者无感知使用BitLocker),这里也介绍一些方法来启用安全启动。

目前Windows + Linux双系统,并实现安全启动的做法,通常是使用一个微软已经签名的shim,然后通过shim启动本机受信任的引导程序,比如GRUB,rEFInd。

因此,我们首先安装shim-signedAURsbsigntools,以及mokutil

如果你的电脑在打开安全启动的情况,已经可以直接引导Ubuntu或Fedora这些比较知名的发行版,则可以继续。否则,请检查UEFI BIOS的安全启动的相关选项里,是否有“信任第三方CA”或类似的选项,如果有,则需要打开。

然后生成一个用于给引导文件签名的Machine Owner Key:

# 下面的例子均假设MOK Key文件在/etc/efi-keys下。
# 如有需要,可修改MOK Key生成的目标文件夹
openssl req -newkey rsa:4096 -nodes -keyout /etc/efi-keys/MOK.key -new -x509 -sha256 -days 3650 -subj "/CN=My Arch Linux Machine Owner Key/" -out /etc/efi-keys/MOK.crt
openssl x509 -outform DER -in /etc/efi-keys/MOK.crt -out /etc/efi-keys/MOK.cer

给内核的vmlinuz启动文件签名:

# 如果你使用的不是linux内核,比如和我一样是linux-zen,记得修改下面的vmlinuz-linux
sbsign --key /etc/efi-keys/MOK.key --cert /etc/efi-keys/MOK.crt --output /boot/vmlinuz-linux /boot/vmlinuz-linux

如有需要,可以写一个pacman hook,以实现每次内核更新时对内核自动签名。可以在ArchWiki上找到这个pacman hook的具体内容,这里为节省篇幅,就不做过多概述。

接下来配置引导程序的安全启动签名。我这里使用的GRUB。对于使用rEFInd的读者,rEFInd的安全启动相关内容可以去ArchWiki上查阅,感觉写的比较详细。

将由微软签好名的shim的efi启动文件复制到你的EFI分区下,并使用efibootmgr命令向你的UEFI BIOS注册shim的efi启动文件。

# 如果你把EFI分区挂载到了其他位置,记得把下面命令的/efi修改成你的EFI目录!
# 下面的EFI/arch也要改成你自己的Arch Linux启动EFI目录!
cp /usr/share/shim-signed/shimx64.efi /efi/EFI/arch/shimx64.efi
cp /usr/share/shim-signed/mmx64.efi /efi/EFI/arch/mmx64.efi
# 注册shim的efi文件
# /dev/sda记得改为你的EFI分区所在硬盘对应的block文件
# --part后面的1记得改成EFI分区所在分区的位置(以1开始)
efibootmgr --unicode --disk /dev/sda --part 1 --create --label "arch-shim" --loader /EFI/arch/shimx64.efi

接下来,需要重新生成GRUB的启动efi文件,这个GRUB的启动efi文件需要包含一些安全启动的信息,并且包含所有需要加载的模块。这些在ArchWiki中有详细说明。

为了简化之后安装/升级GRUB启动efi的流程,我按照ArchWiki的相关内容,并查阅了一些资料,编写了一个Linux Shell脚本。本文的读者可以直接拿去用(不过还是记得修改其中的一些内容),不过我依然希望读者在使用这个脚本之后去ArchWiki了解其中的运作原理。

#! /bin/bash
BASIC_MODULES="all_video boot btrfs cat chain configfile echo efifwsetup efinet ext2 fat
 font gettext gfxmenu gfxterm gfxterm_background gzio halt help hfsplus iso9660 jpeg 
 keystatus loadenv loopback linux ls lsefi lsefimmap lsefisystab lssal memdisk minicmd
 normal ntfs part_apple part_msdos part_gpt password_pbkdf2 png probe read reboot regexp
 search search_fs_uuid search_fs_file search_label sleep smbios squash4 test true video
 xfs zfs zstd zfscrypt zfsinfo cpuid play tpm usb"

GRUB_MODULES="$BASIC_MODULES cryptodisk crypto gcry_arcfour gcry_blowfish gcry_camellia
 gcry_cast5 gcry_crc gcry_des gcry_dsa gcry_idea gcry_md4 gcry_md5 gcry_rfc2268 gcry_rijndael
 gcry_rmd160 gcry_rsa gcry_seed gcry_serpent gcry_sha1 gcry_sha256 gcry_sha512 gcry_tiger 
 gcry_twofish gcry_whirlpool luks lvm mdraid09 mdraid1x raid5rec raid6rec"

sudo grub-install --target=x86_64-efi --efi-directory=/efi \
    --bootloader-id=arch --modules="${GRUB_MODULES}" \
    --sbat /usr/share/grub/sbat.csv --no-nvram

mok_sign() {
    # sign if not already done so.
    if ! /usr/bin/sbverify --list "$1" 2>/dev/null | /usr/bin/grep -q "signature certificates"; then
        printf 'Signing %s...\n' "$1"
        sudo sbsign --key /etc/efi-keys/MOK.key --cert /etc/efi-keys/MOK.crt --output "$1" "$1"
    else
        printf 'Skip sign: %s\n' "$1"
    fi
}

mok_sign /efi/EFI/arch/grubx64.efi

接下来,需要将我们刚刚生成好的MOK Key注册到我们电脑的MokList中。为了在稍后重启后,能在MokManager中找到我们要注册的Key,需要做一些操作。

# 将生成的MOK Key的证书文件复制到EFI目录中
cp /etc/efi-keys/MOK.cer /efi/EFI/arch/MOK.cer
# 或使用mokutil进行enroll
mokutil --import /etc/efi-keys/MOK.cer

之后,重启电脑,并打开安全启动,使用shim的efi启动系统,在重启后出现的MokManager中注册我们生成的MOK Key,然后再次重启。此时,GRUB和Arch Linux即可使用安全启动功能。

MOKManager

需要注意的是,在较新的GRUB中,启用了安全启动之后,字体文件默认拒绝读取,这会导致GRUB的部分文本的呈现出现问题。若想让字体文件能正常读取,则需要对GRUB所有需要使用的外部文件(grub.cfg,字体文件,linux内核文件,主题相关文件等等)全部进行gpg签名,并且生成GRUB的efi文件时需要指定这个gpg的公钥文件。听着很复杂,对吧?确实是这样的,这是在确保GRUB所有读取到的外部文件都是可信任的。对于大部分人来说,这么做非常吃力不讨好。

因此,为了缓解字体无法加载而导致的文本显示问题,一种办法是在/etc/default/grub中,将GRUB_TERMINAL_OUTPUT=console选项打开。修改后记得执行grub-mkconfig

另外一种办法(极度不推荐,可能产生问题,不到万不得已不要用这个办法)是,可以使用mokutil --disable-validation来禁用掉shim对grub和vmlinuz相关文件的签名检查(可以使用mokutil --enable-validation把相关的签名检查开回来),缺点是每次开机启动都会有一条Booting in insecure mode的提示。

SBAT问题

假如你将证书成功注册到MokList之后,还是提示Verification failed:(0x1A) Security Violation,那么很有可能是你启动过别的Linux发行版,该发行版的shim向你电脑的MokList中写入了SBAT(Secure Boot Advanced Targeting)吊销列表(SBAT Revocations)。

问题的原因也很简单,less /usr/share/grub/sbat.csv,再对比一下FedoraDebian的GRUB SBAT,你就会发现Arch Linux GRUB提供的SBAT信息“太老了”,“老”到会被SBAT吊销列表拦截(实际上Arch Linux的GRUB会跟着上游持续更新,大部分漏洞都得到了及时的修复)。

# 查看SBAT吊销列表
# 若有类似grub,2这个项,则Arch Linux的GRUB会无法引导
mokutil --list-sbat-revocations

第一种解决办法是清除SBAT吊销列表,执行完下面的命令后立刻重启即可。

mokutil --set-sbat-policy delete

第二种办法就是复制/usr/share/grub/sbat.csv到别的位置,自行编辑之后使用编辑好的SBAT重新执行grub-install

cp /usr/share/grub/sbat.csv /etc/user-scripts/grub-sbat.csv
# 编辑/etc/user-scripts/grub-sbat.csv,提高SBAT文件中的grub版本
# 然后grub-install使用的SBAT文件改为你编辑好的grub-sbat.csv

防火墙

因为用RHEL系习惯了,所以我依然选择使用firewalld。

在服务端的firewalld中一般只需要配置public区域(zone)的内容,但对于日用的Linux桌面环境,则可以将不同的网络划分到不同的防火墙区域中。如果你打算这么做,则需要手动使用firewall-cmd对各个zone的防火墙进行分别配置。

NTFS

目前对于NTFS的读取,有两种方案:ntfs-3gntfs3。但是不管你使用什么方案,一般都需要安装ntfs-3g,虽然使用ntfs3并不需要安装ntfs-3g

首先是长久以来已经存在的稳定方案:ntfs-3g。由于使用了fuse层,故大文件读写性能并不是很好。在大部分情况下,一般都能直接使用ntfs-3g

目前最新版本的Linux内核已经自带ntfs3驱动,文件读写性能相当不错,不过由于某些原因,暂时不建议对着安装了Windows的分区使用ntfs3,不过目前可以放心的在存放数据的分区使用ntfs3

不管是ntfs-3g还是ntfs3,在使用时建议附加windows_names挂载选项。

可以使用/etc/fstab来做到开机自动自动挂载NTFS分区。

另外,Linux下进行软件开发时,尽量不要把开发环境放在NTFS分区下!

优化faillock

目前在我的环境下,偶尔会有连续输错3次密码的情况。之后即使输入正确的密码也会提示“密码错误”,此时桌面环境锁屏后,输入任何密码都会收到提示“连续输错3次密码,请10分钟后再试”的提示,并且重启系统后账号的密码锁定状态不会重置。

这个东西就是faillock。我们现在来调整一下faillock中的相关设置,来优化一下我们的使用体验。

打开/etc/security/faillock.conf,编辑其中的deny = 3选项。对于桌面环境,这个选项的值可以设置的稍微大一些(比如20),或者直接关掉(设置成0)。对于服务器环境则推荐设置为6。

其他

还有其他坑的话会继续补充。

评论

  1. ssxx
    1 年前
    2023-7-17 14:28:31

    多系统共存最大的问题还是单硬盘的设备,无法选定最佳的硬盘文件格式,若是有两三块硬盘的话应该没有太大的问题。
    顺便一提,更优先于选择兼容驱动以及拥有官方分发Linux驱动的品牌,我这台Intel好多都是专有驱动根本找不到Linux替代

    • 博主
      ssxx
      1 年前
      2023-7-17 16:23:42

      我笔记本有三块硬盘(

      • ssxx
        Azure Zeng
        1 年前
        2023-7-20 23:23:04

        怎么博客评论的邮件提醒没有开吗还是漏掉了

        • 博主
          ssxx
          1 年前
          2023-7-22 3:30:49

          因为WordPress没有对访客发送“你的评论被回复”相关邮件的功能,我也没装相关的插件

  2. liu
    1 年前
    2023-10-11 18:39:26

    朋友對 bsd 可有興趣?比如 freebsd 或者 openbsd 之類?dragonflybsd 也行。可以致力於 bsd 在中國的發展嘛。

    • 博主
      liu
      1 年前
      2023-10-11 23:03:58

      计划之后试试看,最近没时间

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇