xps13(9370) Linux之路
简介
我希望通过戴尔xps13的实例让喜欢爱折腾的玩家加入Linux,出现的代码可以在我的Github仓库xps-13-conf查找。
选择发行版和桌面环境分别是ArchLinux和GNOME。
新手强烈建议Manjaro起步,不要碰ArchLinux,不要碰ArchLinux,不要碰ArchLinux。哪怕给你安装了ArchLinux,你后续的时间成本也很重。
文章更新于2020-04-05
选择ArchLinux的原因
- 滚动更新,ArchLinux Wiki和社区论坛可以解决大部分入坑者的问题;
- 通过Arch Build System(ABS)和Arch User Repository(AUR)安装维护软件十分方便,享受前人的成果,我使用yay安装各种软件和工具;
- 自定义程度极高,例如我就是从Manjaro转到ArchLinux,遇到个别问题可以参考Manjaro是如何实现和解决的;
选择GNOME的原因
- Ubuntu是目前最多人使用的Linux的发行版,桌面环境默认是GNOME,如果一个UI界面使用群体低的话,会有非常多的坑;
- GNOME界面风格最接近现代操作系统,如macOS;
- 扩展能力非常强,有Gnome shell extensions;
简述ArchLinux启动过程
在安装前简述ArchLinux我认为还是很有必要的,方便后续理解。
如今BIOS已经被UEFI取代,这里就略过过时的技术了,直接使用UEFI。
通电后,一个完整的Linux启动过程大致如下:
- UEFI:选择启动Bootloader,双/多系统就是从这里选择的;
- Bootloader:初始化硬件(内存和磁盘驱动等)并加载Kernel镜像;
- Kernel:系统核心调度和驱动硬件,初始化后引导initramfs;
- initramfs:本质是一个最小镜像,最主要用途是挂载真实文件系统,最终调用init;
- init最后调用getty或者Display Manger服务,也就是我们正常操作的界面;
这里安装的ArchLinux中,Bootloader实例是GRUB,Kernel的镜像是vmlinuxz-linux-lts,initramfs是initramfs-linux-lts.img,init是systemd。
参考来源:
安装预备
下载镜像
到Arch Linux Downloads选择中国镜像并下载。
制作USB启动盘
- Windows下可使用Rufus,按照官方教程即可;
- Linux下使用dd命令:
sudo dd if=/path/to/archlinux-date-x86_64.iso of=/dev/sdX bs=4M && sync
,请修改镜像的实际路径和U盘实际设备号;
修改boot menu
按F2进入bios修改:
- Change the SATA Mode from the default “RAID” to “AHCI”;
- Disable secure boot to allow Linux to boot;
如果没有修成上述的设置,xps13进入引导程序后可能无法发现ssd。
参考来源:
如果是其他笔记本,可以在ArchLinux选择对应型号搜索即可。
安装过程
以下的安装流程都是离不开Installation guide。这里的安装目标是可以登录GNOME Display Manager(GDM)。
如果没有意外,通过引导USB启动盘能进入到终端。
我的显示器分辨率为4K,默认的字体太小,需要设置终端字体:
执行setfont latarcyrheb-sun32
,这是终端自带字体包目前最大的字体。
参考来源:
在/root/install.txt
有一个离线安装指导,离线的情况下可以参考。
检验UEFI启动
通过ls /sys/firmware/efivars
命令检验这个文件是否存在,存在则代表UEFI启动。
配置网络
我使用笔记本,这里使用Wi-Fi连接网络,步骤会比有线网络稍微复杂。
- 获取笔记本网卡的设备名称:
ip link
,我的机器是wlan0
; - 使网卡上线:
ip link set wlan0 up
; - 获取局域网的Wi-Fi的帐号:
iw dev interface scan | grep 'SSID'
; - 如今一般的Wi-Fi的帐号都是WPA/WPA2密码,需要用
wpa_supplicant
这个命令连上Wi-Fi。执行:wpa_supplicant -B -i wlan0 -c <(wpa_passphrase MYSSID passphrase)
; - 检验Wi-Fi是否连接上:
iw dev wlan0 link
; - 自动获取动态ip地址:
dhcpcd
; - 检验是否获取ip地址:
ip a wlan0
;
参考来源:
配置系统时钟
执行timedatectl set-ntp true
。
磁盘分区并格式化
因为是UEFI启动,所以需要GPT分区表,而不能使用MBR分区表。
磁盘分区
- 通过
lsblk
显示磁盘名称,这里我的ssd是nvme0n1; - 用fdisk对ssd分区:
fdisk /dev/nvme0n1
fdisk用到的快捷键:
m
:帮助信息;p
:打印分区表;g
:创建一个空的GPT分区表;d
:删除一个分区;n
:创建新的分区,对于指定大小可以输入+<size>{M,G,...}
;l
:查看文件类型,1=EFI,19=Swap,20=filesystem;t
:为分区分配对应类型;w
:保存设置;
分区流程如下:
- 按
g
创建GPT分区表; - 按
n
创建分区,我这里分别创建300MB EFI,375GB的Root和SWAP 20GB(我的内存是16GB)的分区; - 按
t
给已经创建的分区分配类型; - 按
w
保存设置;
因为我需要深度休眠Hibernation,所以SWAP需要20GB左右,划分SWAP分区的大小可以参考下面的链接。
参考来源:
格式化分区
每一种分区类型对应的命令稍有不同。
- 格式化EFI分区:
mkfs.vfat /dev/nvme0n1p1
; - 格式化Root分区为ext4格式:
mkfs.ext4 /dev/nvme0n1p2
; - 格式化SWAP分区:
mkswap /dev/nvme0n1p3
; - 激活SWAP分区:
swapon /dev/nvme0n1p3
;
挂载系统文件
这里要挂载刚才创建的EFI和Root分区,挂载EFI分区是为了安装引导程序,挂载Root分区当然是为了安装最小的镜像。
- 挂载Root分区到
/mnt
,mount /dev/nvme0n1p2 /mnt
; - 创建
/mnt/boot/efi
目录,mkdir -p /mnt/boot/efi
; - 挂载EFI分区,
mount /dev/nvme0n1p1 /mnt/boot/efi
;
EFI的分区可能有部分人是
/mnt/efi
,因为我是Manjaro入门,所以这里参考Manjaro的目录路径。
制作最小镜像
更换镜像源
默认的镜像源是国外的,速度对国内用户极度不友善,国内用户需要手动更新源文件。编辑/etc/pacman.d/mirrorlist
,选择一个China服务器移放到顶部或者注释其他国家的服务器。
pacman是ArchLinux的Arch Build System(ABS)包的管理工具。
pacstrap脚本安装包
pacstrap只是一个安装包的工具到指定目录上,安装包类似于pacman。
不建议安装linux
这个包,除非你的驱动需要最新内核,否则建议linux-lts
长期支持的内核版本。
pacstrap /mnt base base-devel linux-lts linux-lts-headers linux-firmware
最终要安装到系统的包都可以通过pacstrap预先安装。
生成Fstab
生成fstab:genfstab -U /mnt >> /mnt/etc/fstab
,并确认分区cat /mnt/etc/fstab
。
通电后启动GRUB的时候(GRUB配置内已经记录Root分区信息),会把Root分区信息以参数形式传递到Kernel,Kernel以只读的方式挂载Root分区,然后读取fstab的信息,最后init的时候重新挂载fstab内容的分区。
参考来源:
配置镜像
Chroot
Chroot大体用途是改变你当前的根目录为指定目录并加载指定目录镜像,非常有用。特别是你可以在系统无法正常启动的时候,利用USB引导盘执行chroot进入故障根目录并排查问题。
chroot到刚才我们已经基本完善的根目录镜像/mnt
:arch-chroot /mnt
,此后我们犹如进入预装系统,后续一切操作都是真实操作,对系统是真实生效的。
配置终端字体
4K分辨率默认的字体太小,下载稍微好看的终端字体包,并设置终端字体。
- 下载终端字体:
pacman -Sy terminus-font
- 设置终端字体:
setfont ter-132n
配置时区时间
执行ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && hwclock --systohc
。
设置locale
- 编辑
/etc/locale.gen
,取消en_US.UTF-8 UTF-8
的注释并保存; - 执行
locale-gen
; - 设置环境变量LANG:
echo 'LANG=en_US.UTF-8' > /etc/locale.conf
;
配置网络
我的hostname是kevin-pc,可以根据自己喜好命名。
趁现在已经联网,执行pacman -S networkmanager
安装networkmanager,不然后续重启后没办法上网。
配置hostname
配置/etc/hostname
:echo 'kevin-pc' > /etc/hostname
配置hosts
编辑/etc/hosts
,内容如下:
1
2
3
127.0.0.1 localhost
127.0.1.1 kevin-pc
::1 localhost ip6-localhost ip6-loopback
更改root的密码
执行passwd
,后面就可以输入自定义的密码。
配置Bootloader
目前大部分发行版都是GRUB作为Bootloader,这里随大流,少踩坑。遇上多系统无法引导的问题,可以利用配置Bootloader的这小节的步骤进行修复。
安装GRUB
- 安装必要的包:
pacman -S grub efibootmgr
; - 在EFI分区生成Bootlaoder文件:
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=ArchLinux
,–efi-directory是EFI分区的文件路径,–bootloader-id就是id,随你喜欢; - 检查是否生成
/boot/efi/EFI/ArchLinux/grubx64.efi
文件和/boot/grub/x86_64-efi
目录;
配置GRUB
- 编辑
/etc/default/grub
,保存你所需要的设置; - 生成
grub.cfg
文件:grub-mkconfig -o /boot/grub/grub.cfg
参考来源:
到这里配置镜像基本完成了,按ctrl-d
退出chroot,执行umount -R /mnt
并reboot
后便可以拔掉USB启动盘了。
进入图形界面的前置配置
添加普通用户
登录root帐号后,不可能以root角色使用Linux桌面,需要一个普通权限的用户。
添加名为kevin的用户,并设置zsh
为默认的shell:
- 安装zsh:
pacman -S zsh
; - 添加普通用户:
useradd -m -U -G sys,power,wheel,input,network -s /bin/zsh kevin
; - 修改密码:
passwd kevin
,后面就可以输入自定义的密码;
添加完用户后需要验证用户是否创建成功,直接切换到新的用户:su kevin
,输入密码完成登录。
参考来源:
配置网络
此时是没办法上网的,利用之前安装的networkmanager
,现在可以直接执行:
- 启动NetworkManager服务,可以动态获取IP地址:
systemctl start NetworkManager.service
; - 激活NetworkManager服务,开机自动启动:
systemctl enable NetworkManager.service
;
启动NetworkManager服务后,需要用nmcli
命令行连接上具体的Wi-Fi,这个命令在日常使用Linux中也是非常有用,推荐使用。
- 检测网络连接状态:
nmcli radio
; - 若Wi-Fi连接状态是off可以:
nmcli radio wifi on
打开Wi-Fi; - 重新刷新并列出Wi-Fi:
nmcli device wifi rescan && nmcli detail wifi list
; - 选择一个Wi-Fi连接:
nmcli device wifi connect 'ssid' password 'password'
;
参考来源: nmcli_examples
安装显卡
通过lspci | grep VGA
查看显卡信息,我的显卡是uhd 620。
在KMS下默认已经有modesetting驱动,xf86-video-intel
这个包问题还是比较多,不建议在uhd620下安装。如果用其他显卡,请自行搜索资料。
安装GNOME桌面
如果喜欢默认的GNOME全家桶可以直接:sudo pacman -S gnome
安装以gnome为group的所有包。
我喜欢一个较为纯净的GNOME,根据自身需求安装,如下:
sudo pacman -S gdm gnome-control-center gnome-keyring gnome-disk-utility xdg-user-dirs xorg-init
这里会根据依赖安装GNOME被依赖的包,所以并没有罗列全部包。
gnome-keyring
:密码相关的包,没有的话无法持久化和GNOME相关软件的密码,如evolution;gnome-disk-utility
:磁盘工具,主要是为了自动挂载外部磁盘;xdg-user-dirs
:创建用户默认的目录,如Desktop,Pictures等;xorg-init
:保证在tty里面执行startx
直接进入GNOME;
安装完GNOME会根据依赖自动安装蓝牙服务,这里启动蓝牙服务:
- 启动bluetooth服务:
systemctl start bluetooth.service
; - 激活bluetooth服务,开启自动启动:
systemctl enable bluetooth.service
;
至此已经基本把ArchLinux和GNOME安装完毕,执行reboot
重启进入GDM登录界面选择kevin登录即可以进入GNOME。
调教系统
安装yay
默认pacman不太好用,例如一定要在pacman
前面加sudo
,并且不能安装Arch User Repository(AUR)的包。所以需要一款工具,这里使用yay。
git clone https://aur.archlinux.org/yay.git
;cd yay && makepkg -si
;
yay受pacman的配置影响,我偏好开启颜色和包的详细信息。编辑/etc/pacman.conf
并注释掉Color
和VerbosePkgLists
即可。
参考来源:
配置sudo
sudo输入正确密码后,默认的超时时间是5分钟,这个时间太短,并且我使用的是tmux,默认配置在不同窗口下是不能共享正确密码,一旦超时,需要繁琐且不断重复输入密码,这里可以适当延长超时时间和把超时时间设置成全局。
在root权限下(su root或者sudo),编辑/etc/sudoers.d/10-installer
文件如下:
1
2
3
%wheel ALL=(ALL) ALL
Defaults timestamp_timeout=60
Defaults timestamp_type=global
参考来源:
电源节能
笔记本有续航的需求,需要一款节能的软件,TLP可以解决这个问题。
- 安装TLP:
yay -S tlp tlp-rdw
; - 启动并激活tlp服务:
sudo systemctl start tlp.service && sudo systemctl enable tlp.service
; - 屏蔽systemd-rfkill:
sudo systemctl mask systemd-rfkill.service && sudo systemctl mask systemd-rfkill.socket
;
参考来源:
配置深度休眠
配置Hibernation
在安装系统的时候虽然为SWAP分区预留出空间,但initramfs引导起来后并不能利用这个空间,需要重新生成initramfs。
- 编辑
/etc/mkinitcpio.conf
,在HOOKS=(base ......)
基础上修改成HOOKS=(base ...... resume)
; - 生成initramfs:
sudo mkinitcpio -p linux-lts
;
参考来源:
修复无法进入深度睡眠
当晚上睡觉前合上盖子休眠,早上醒来打开会掉电20%,原因是未进入深度休眠。
可以通过cat /sys/power/mem_sleep
查看输出是[s2idle] deep
,还是s2idle [deep]
,若是后者请自行查找相关资料。
- 编辑’/etc/default/grub’,修改GRUB_CMDLINE_LINUX_DEFAULT添加内核启动参数
mem_sleep_default=deep
,如GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
更改成GRUB_CMDLINE_LINUX_DEFAULT="quiet splash mem_sleep_default=deep"
; - 执行
sudo grub-mkconfig -o /boot/grub/grub.cfg
更新grub; - 重启系统后,执行
cat /sys/power/mem_sleep
确保输出是s2idle [deep]
;
参考来源:
解锁AC电源模式下的CPU性能
XPS 9370在下CPU封装的限制温度是95摄氏度,而Linux却是80摄氏度,应该算是一个Bug,这极大限制了CPU的性能,需要安装throttled解除限制。
- 安装s-tui测试CPU数据
yay -S s-tui
,安装后root权限打开s-tui,在Modes栏中选中Stress进行压力测试,看稳定温度是否超过80摄氏度,不能则执行下面步骤; - 安装throttled:
yay -S throttled
; - 开启并激活throttled服务
sudo systemctl enable lenovo_fix.service && sudo systemctl start lenovo_fix.service
; - 在s-tui压力模式下稳定温度是否超过80摄氏度;
- 修改
/etc/lenovo_fix.conf
可以调整参数;
性能对比
没有启动lenovo_fix.service
CPU功耗很难突破15W和稳定温度无法超过80摄氏度。
在默认配置的条件下开启后
CPU可以稳定保持在2.8-3.0Ghz并且功耗在27W左右,稳定温度在95摄氏度左右。
修改undervolt的配置
1
2
3
4
5
6
7
8
9
10
11
[UNDERVOLT.AC]
# CPU core voltage offset (mV)
CORE: -95
# Integrated GPU voltage offset (mV)
GPU: -125
# CPU cache voltage offset (mV)
CACHE: -95
# System Agent voltage offset (mV)
UNCORE: 0
# Analog I/O voltage offset (mV)
ANALOGIO: 0
以上是我的xps13修改的undervolt参数,每台笔记本参数不一致,需要在Windows的intel xtu下调优适合的参数(使用双系统)。
修改参数后CPU可以稳定保持在3.1-3.2Ghz并功耗在27W左右,稳定温度在95摄氏度左右。
参考来源:
降低热量
- 更换CPU和散热器间的硅脂,我用的是信越7921的硅脂。
- xps13是金属背壳,通过散热垫片把热量导到背壳,使用1.5mm厚度的散热垫片(每款笔记本厚度间隙不一致)。
通过更换硅脂和添加散热垫后,温度从95摄氏度变成81摄氏度,CPU频率有所提升。
参考来源:
改变风扇特性
默认情况下是bios控制主板的风扇。不得不说这控制逻辑真的很奇葩。如果按照默认的bios控制风扇,xps13这部笔记本绝对是不建议购买的。CPU温度在50+摄氏度风扇就会猛转。
正确安装风扇驱动
用lm_sensors(yay -S lm_sensors
),看不到主板风扇的sensors。因缺少或者加载错误驱动。对于xps13而言就是加载dell_smm_hwmon驱动错误。
执行sudo modprobe dell_smm_hwmon ignore_dmi=1
后,再运行sensors
查看是否有风扇的参数或者cat /proc/i8k
是否运行正确。
modinfo dell-smm-hwmon
可以查看驱动信息,包括参数的含义。
参考来源:
安装驱动工具
只要加载驱动成功就可以继续安装i8kutils,执行yay -S i8kutils
。
i8kfan只可以调控左右两个风扇3档调速,分别是0 0,1 1, 2 2。执行i8kfan 2 2
发现不能工作。重新加载驱动执行sudo modprobe dell_smm_hwmon ignore_dmi=1 restricted=0
后,可以控制风扇的3档调速。
- 避免每次开机都要手动加载驱动,可以创建
echo 'options dell-smm-hwmon ignore_dmi=1 restricted=0' > /etc/modprobe.d/dell-smm-hwmon.conf
; - 开启并激活i8kmon服务
sudo systemctl enable i8kmon.service && sudo systemctl start i8kmon.service
;
禁止bios控制风扇
虽然可以手动或开启服务控制风扇的转速,但bios仍然参与风扇控制。这导致风扇的控制特性不符合预期,需要禁止bios控制风扇。
- 执行
yay -S dell-bios-fan-control-git
安装禁止bios控制风扇的命令。 - 安装后执行
sudo dell-bios-fan-control 0
,终端输出BIOS CONTROL DISABLED
。
禁用bios控制风扇是在应用态而不是内核态(driver)。当系统进入休眠再次唤醒的时候,bios将会重新接管风扇的控制。这里有两种方案:
- 修改内核,为其添加禁用bios控制风扇的driver(例如Wi-Fi休眠后唤醒可正常工作)。
- 在应用态添加服务,触发时机是在休眠前后。
方案1对于ArchLinux是很危险的,滚动更新内核。最好别自行更改内核,所以这里选择方案2。方案2最佳的例子就是TLP,参照TLP的版本是1.22以前的,最新版对sleep的策略已经略有不同。
已经制作Makefile适合懒人:fan。
参照tlp.service
和tlp-sleep.service
,分别编写dell-fan-control.service
和dell-fan-control-sleep.service
并放置到/etc/systemd/system/
路径下。
dell-fan-control.service代码如下:
[Unit]
Description=Disables BIOS control of fans at boot.
Before=i8kmon.service
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/bin/dell-fan-control 1
ExecStop=/usr/bin/dell-fan-control 0
[Install]
WantedBy=multi-user.target
dell-fan-control-sleep.service代码如下:
[Unit]
Description=Enable BIOS control of fans at sleep.
Before=sleep.target
StopWhenUnneeded=yes
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/dell-fan-control 0
ExecStop=/usr/bin/dell-fan-control 1
[Install]
WantedBy=sleep.target
dell-fan-control是封装了dell-bios-fan-control
的简单可执行shell,把其放置到/usr/bin/
路径下,其代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env bash
if [ "$(whoami)" != root ]; then
echo 'You need to be root.'
exit
fi
if [[ ! -x "$(command -v dell-bios-fan-control)" ]]; then
echo 'dell-bios-fan-control is not found.'
exit
fi
if [[ ! -x "$(command -v i8kfan)" ]]; then
echo 'dell-bios-fan-control is not found.'
exit
fi
if (($1 == 1)); then
dell-bios-fan-control 0 >/dev/null
i8kfan 0 0 >/dev/null
echo 'User control fan is enabled.'
else
dell-bios-fan-control 1 >/dev/null
echo 'User control fan is disabled.'
fi
- 执行
sudo dell-fan-control 1
,终端输出User control fan is enabled.
表示成功。 - 分别开启dell-fan-control.service和dell-fan-control-sleep.service服务
sudo systemctl enable dell-fan-control.service && sudo systemctl enable dell-fan-control-sleep.service
并start。
参考来源:
自定义温度vs风扇转速曲线
i8kutils默认配置文件是/etc/i8kutils/i8kmon.conf
,修改部分的代码如下:
1
2
3
4
5
6
set config(acpi) "acpi -a"
set config(0) { {0 0} -1 75 -1 60 }
set config(1) { {1 1} 70 85 55 70 }
set config(2) { {2 2} 75 92 60 80 }
set config(3) { {2 2} 90 128 75 128 }
- 控制风扇特性曲线有两种状态分别是电源和电池。i8kutils依赖acpi判断是电源还是电池状态。发现电源状态曲线失效,查看
/usr/bin/i8kmon
的代码,发现默认配置的acpi命令有误,无法正确匹配,添加set config(acpi) "acpi -a"
就能正确匹配(怀疑是用了老版本的acpi,这里不深究); - 简单解释一下怎么自定义曲线的参数。如{ {1 1} 70 85 55 70 },{1 1}代表左右风扇的档速,这里是左右风扇的第一档(0关闭,2转速最大)。70 85代表电源状态下的滞回温度,低于70摄氏度左右风扇调节0档,高于85摄氏度左右风扇调节到2档。55 70则是电池状态下的滞回温度;
- 这个参数是追求风扇噪声低的前提下配置出来的。电池状态的温度比电源状态低的缘故就是怕放在膝盖的时候烫人= =!不过测试过CPU在85摄氏度的时候,背壳也就55摄氏度左右;
- 修改完毕后重启i8kmon.service即可生效;
修复蓝牙音频漏洞
在蓝牙音频设备与XPS 9370连接成功后,在sound settings声音选项中大概率无法找到该蓝牙设备选项,也就是无法切换音源。
原因是系统启动的时候,蓝牙服务会初始pulseaudio蓝牙音频模块,pulseaudio需要X-server(图形界面)启动后才能正常初始化,但实际情况蓝牙服务早于X-server初始化完成,导致pulseaudio初始化失败。
只需要把初始化pulseaudio的代码放到X-server后面即可。
- 编辑
/etc/pulse/default.pa
,注释掉蓝牙服务初始化pulseaudio的代码;1 2 3
# .ifexists module-bluetooth-discover.so # load-module module-bluetooth-discover # .endif
- 编辑
/usr/bin/start-pulseaudio-x11
,找到以下代码段1 2 3
if [ x”$SESSION_MANAGER” != x ] ; then /usr/bin/pactl load-module module-x11-xsmp “display=$DISPLAY session_manager=$SESSION_MANAGER” > /dev/null fi
,修改为
1 2 3 4 5
if [ x”$SESSION_MANAGER” != x ] ; then /usr/bin/pactl load-module module-x11-xsmp “display=$DISPLAY session_manager=$SESSION_MANAGER” > /dev/null /usr/bin/pactl load-module module-bluetooth-discover /usr/bin/pactl load-module module-switch-on-connect fi
- 重启机器即可正常工作;
参考来源:
休眠停止音乐播放
在图书馆或者其他安静的公共场合佩带着蓝牙耳机听音乐的时候,休眠(合盖)再唤醒,蓝牙接收不及时导致音乐外放。可以通过休眠/锁屏就关闭音乐播放。
原理是利用dbus监控锁屏事件(没禁用锁屏则休眠会产生锁屏事件)并通过playerctl暂停音乐。
已经制作Makefile适合懒人:audio。
把pause-audio-on-lock
放置到$PATH
路径下,其代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env bash
if [[ ! -x $(command -v playerctl) ]]; then
exit 1
fi
DBUS_LOCK="interface='org.gnome.ScreenSaver',member='ActiveChanged'"
LOCK_SIGNAL='true'
dbus-monitor --session "type='signal',$DBUS_LOCK" |
(
while read -r line; do
if grep $LOCK_SIGNAL <<<$line 2>/dev/null; then
for player in $(playerctl --list-all); do
if [[ $(playerctl --player=$player status) == Playing ]]; then
playerctl --player=$player pause
fi
done
fi
done
)
编写和dbus相关的user service,这里并不是系统级别的,因为dbus跟每个用户绑定,所以service也要和用户绑定。
把pause-audio-on-lock.service
放置到$HOME/.config/systemd/user
路径下,其代码如下:
[Unit]
Description=Pause audio on lock
BindsTo=graphical-session.target
After=graphical-session.target
[Service]
Type=simple
ExecStart=请修改成pause-audio-on-lock的绝对路径
[Install]
WantedBy=graphical-session.target
启动并激活服务:sudo systemctl --user start pause-audio-on-lock.service && sudo systemctl --user enable pause-audio-on-lock
;
测试:可以开启音乐锁屏,重新进入是否音乐停止播放。
参考来源:
为触摸板添加自定义手势
默认触摸板可以只有普通的双击,三击和双手滑动的手势,这里可以添加2-4指缩放,3-4上下左右滑动的自动以手势。
可以通过libinput-gestures实现。
- 安装
yay -S libinput-gestures
; - 添加你的用户到input group
sudo gpasswd -a $USER input
,完成后登出或者重启机器; - 启动libinput-gestures守护线程
libinput-gestures-setup autostart && libinput-gestures-setup start
; - 理解阅读xdotool和wmctrl,是实现手势的方法,可以参考
/etc/libinput-gestures.conf
; - 编辑
~/.config/libinput-gestures.conf
;
我的配置如下:
1
2
3
4
5
gesture: swipe left 3 xdotool key XF86Back
gesture: swipe right 3 xdotool key XF86Forward
gesture: swipe up 4 xdotool key super+alt+8
gesture: swipe left 4 xdotool key super+alt+minus
gesture: swipe right 4 xdotool key super+alt+equal
更改按键映射
我是一位vim用户,按键映射是必须更换的,更改的键位比较复杂,可以描述为:
- Esc->CapsLock
- ~/`->Esc
- CapsLock->LeftCtrl
- LeftCtrl->~/`
主要是为了让左小指按压Esc和LeftCtrl更轻松,代码比较冗余,就不贴了,具体代码可以查看xkb和kbd。
- 对于X-server而言,修改
/usr/share/X11/xkb/symbols/pc
和/usr/share/X11/xkb/symbols/us
; - 对于Vconsole而言,复制
/usr/share/kbd/keymaps/i386/qwerty/us.map.gz
到/usr/share/kbd/keymaps/
路径下并修改其按键映射。同时更改/etc/vconsole.conf
的KEYMAP=对应的名字。(如我添加的文件名是personal.map,那么KEYMAP=personal);
参考来源:
外置显卡
硬件环境
- 笔记本:XPS 9370@ArchLinux GNOME
- 显卡坞:Mantiz
- 显卡:Nvidia GTX 1060 3GB
需求
外置显卡驱动内置4k显示器和两块外置4显示器或者两块外置4k显示器工作使用(非游戏玩家)。
选卡
因eGPU.io大部分Linux系统的Build案例是N卡,所以这里直接选择N卡,驱动3个4K分辨率的显示器保守一点还是选择了1060 3GB。
安装N卡私有驱动
- 连接好硬件,通过
lspci | grep VGA
查看显卡信息,确认nvidia的显卡出现在输出; - 安装nvidia-dkms:
yay -S nvidia-dkms
;
解决无法启动外置显卡
按照A script to change Xorg config,无法启动外置显卡,通过GDM登录帐号的时候进入死循环,无法进入GNOME。
通过journalctl -b
发现无法正确检测到Nvidia显卡,动态切换回Intel显卡渲染X-server。通过以下手段得知是时序问题:
- 禁用动态切换
/etc/X11/xorg.conf
,默认用Nvidia的配置,开机一段时间后,通过虚拟终端登录并startx可以成功登录并用Nvidia渲染X-server。 - 用机械硬盘安装系统并启动,连接外置显卡。eGPU提供的脚本能正确用Nvidia渲染X-server。
- xps13 9370用的是nvme存储,比机械硬盘快得多。对比两者启动的日志,发现Thunderbolt加载之间的时间差异。
- 在nvme启动情况下,修改脚本,延时检测动态切换的代码。eGPU提供的脚本能正常用Nvidia渲染X-server。
基于eGPU提供的脚本,我编写了一个异步延时检测切换显卡的脚本gxs,使用查看README。
启动脚本后,在GDM界面输入账户密码这段时间内,会异步延时检测动态的显卡,使得用户看起来不会闪屏卡顿。
未解决的问题
外置显卡真的遇到挺多的问题,有些问题至今仍未解决,如以下问题:
- 无法在X-server下动态切换显卡。只有重新配置并重启X-server,才能切换Intel和Nvidia显卡。
- 用Nvidia外置显卡同时渲染内置和外置显示器将会卡顿不流畅,并且会撕裂。这可能是时序同步问题和外置显卡渲染内屏损耗导致。
- Intel和Nvidia显卡不能在同一个X-server同时渲染。如内置显示器用Intel,而外置显示器用Nvidia。
解决tmux被杀掉的问题
切换显卡的时候按道理可以保留tmux的程序(X-server肯定要重启的)。现实情况是切换显卡过了10+秒后不重新登录X-server,整个tmux session消失了。
原因是当用户登出后,系统会在一定时间内杀掉用户启动的服务,例如tmux。这里解决的办法是让tmux作为一个systemd系统服务,这样就可以解决因为Xserver退出导致tmux也被强制退出。
tmux@service内容如下:
[Unit]
Description=Start tmux server, require to set server option exit-empty off
[Service]
Type=forking
User=%I
ExecStart=/usr/bin/zsh -i -c 'source ~/.zshrc; /usr/bin/tmux start-server'
ExecStop=/usr/bin/tmux kill-server
[Install]
WantedBy=multi-user.target
- 启动服务的时候并没有启动tmux的session,所以需要
.tmux.conf
内设置set -sg exit-empty off
; - 把
[email protected]
放置到/etc/systemd/system
下; - 启动并激活服务:
sudo systemctl start [email protected] && sudo systemctl enable [email protected]
,这里的用户名是kevin,根据你自己的实际情况替换;
参考来源: