Chrome OS 设备/Crostini
Crostini 是 Google 提出的一个总括术语,旨在使 Linux 应用程序支持易于使用,并与 Chrome OS 良好集成。
本文介绍如何在 Chromebook 上以容器(通过 Crostini)方式安装 Arch Linux,而无需启用开发者模式,从而允许应用程序与其他 Chrome/Android 应用程序并行运行。
亮点
- 官方支持,无需启用开发者模式 - 保持 Chrome OS 安全,无需刷写 BIOS 等。
- 更佳的电池续航 - 兼具 Chrome 的电池续航和 Linux 的功能。
- 支持音频(输入/输出)和 OpenGL,但 USB 设备仅部分支持,且仍在开发中。
简介
启用 Linux 支持
在“设置”下查找“Linux”并启用它。这将安装一个 Debian Linux 容器,稍后我们将用 Arch Linux 容器替换它。
- 设置 > Linux > 启用
Crostini 仍在向 Chromebook 推广。如果您没有看到启用 Linux 的选项,您可能需要切换到 Beta 或开发者渠道(如果您的笔记本电脑的稳定渠道尚未推出)。这可以通过设置 > 关于 Chrome OS > 渠道 > 开发者/Beta 完成。
将默认 Debian Linux 容器替换为 Arch Linux
以下说明最初基于 https://www.reddit.com/r/Crostini/wiki/howto/run-arch-linux?v=2d4c6b4c-bbb0-11e8-8f2f-0e740b2a8a8c。
可选:删除 Debian 容器
lxc delete penguin
应该不会使空间无法使用。请参阅 [1]如果您不再需要 Debian,则可以通过销毁并重新创建 Termina VM 来节省一些存储空间(这将使您可以跳过稍后重命名/删除现有容器的步骤)。请注意,这也将删除您在 Termina 下可能拥有的任何其他容器。
在 Chrome 中打开 crosh 终端 (Ctrl+Alt+t
)。
vmc destroy termina vmc start termina
创建容器
在 Chrome 中打开一个新的 crosh 终端 (Ctrl+Alt+t
)。使用以下命令进入 termina
vsh termina
现在您需要替换默认的 images
远程仓库
lxc remote remove images lxc remote add images https://images.lxd.canonical.com/ --protocol=simplestreams
然后创建 Arch Linux 容器
lxc launch images:archlinux arch --config security.privileged=true
在 Termina 中打开 shell 并检查 Arch Linux 容器是否存在(可能需要几分钟才能在列表中显示)
lxc list
如果容器未启动,请启动它
lxc start arch
在容器中启动 bash shell
lxc exec arch -- bash
设置用户
容器在安装时会根据用于登录 Chrome OS 的电子邮件创建一个默认用户。可以使用以下命令查看用户名
grep 1000:1000 /etc/passwd|cut -d':' -f1
您可以选择重命名用户/组,默认情况下以您的 GMail ID 命名
# pkill -9 -u old-username # groupmod -n new-username old-username # usermod -d /home/new-username -l new-username -m -c new-username old-username
需要为用户设置密码
# passwd username
您可能还需要安装 sudo 并将用户添加到 wheel 组。安装后使用
# visudo
取消注释以下行以允许 wheel 组使用 sudo
# %wheel ALL=(ALL) ALL
将您的用户添加到 wheel 组
# usermod -aG wheel username
离开容器
# exit
设置容器以便在 Chrome OS 中使用
使用您刚刚配置的常规用户帐户登录到容器
lxc console arch
验证容器中的网络连接。命令
$ ip -4 a show dev eth0
应返回一个非空输出,其中包含容器的已分配 IP 地址。如果它不为空,您可以继续,否则您将面临 #容器中没有网络 中描述的问题 - 按照那里列出的说明解决该问题。
安装 Crostini 容器工具、用于 GUI 应用程序支持的 Wayland 和用于 X11 应用程序支持的 Xwayland
安装 cros-container-guest-tools-gitAUR 软件包。此外,安装 wayland 和 xorg-xwayland 以便能够使用 GUI 工具。
启动/启用 以下用户单元
模板实例 | 目的 |
---|---|
sommelier@0.service |
Wayland |
sommelier-x@0.service |
X11 |
sommelier@1.service |
Wayland (低密度) |
sommelier-x@1.service |
X11 (低密度) |
通过检查它们的单元状态,确保这些用户服务成功运行。现在,当在 Arch Linux 中安装应用程序时,它们将自动出现在 Chrome OS 启动器中。按 Ctrl+a
q
从容器 shell 退出到 Termina shell。
将默认 Debian 容器替换为 Arch Linux
默认的 Debian 容器名为 penguin。将上面创建的“arch”容器重命名为它将导致 Chrome OS 从 arch 容器启动 Linux 应用程序。停止 Arch Linux 容器
lxc stop --force arch
停止 Debian 容器并将其重命名为“debian”(如果您已删除 Debian 容器,则可以跳过此步骤)
lxc stop --force penguin lxc rename penguin debian
将 Arch 容器重命名为“penguin”并启动它
lxc rename arch penguin lxc start penguin
重启 Linux 子系统以应用更改。重启后,验证是否没有列出失败的系统或用户单元。
以下命令应报告为容器分配的 IP 地址
ip -4 a show dev eth0
故障排除
journalctl --user -u cros-garcon
) 以查找主机集成问题,例如“Linux 文件在文件应用中为空”或“应用程序未出现在 Chrome OS 上”。更新到 Chrome OS 81 后 Arch 容器无法启动
大多数自定义容器在 Chrome OS 81 更新后停止工作。根本原因是 LXC 版本更新,因此,容器启动失败并显示以下错误
lxc penguin 20200411193357.312 WARN initutils - initutils.c:setproctitle:324 - Invalid argument - Failed to set cmdline lxc penguin 20200411193357.395 WARN conf - conf.c:lxc_map_ids:2919 - newuidmap is lacking necessary privileges lxc penguin 20200411193357.395 WARN conf - conf.c:lxc_map_ids:2925 - newgidmap is lacking necessary privileges lxc penguin 20200411193357.400 WARN conf - conf.c:lxc_map_ids:2919 - newuidmap is lacking necessary privileges lxc penguin 20200411193357.400 WARN conf - conf.c:lxc_map_ids:2925 - newgidmap is lacking necessary privileges lxc penguin 20200411193357.477 ERROR conf - conf.c:run_buffer:335 - Script exited with status 32 lxc penguin 20200411193357.477 ERROR conf - conf.c:lxc_setup:3589 - Failed to run mount hooks lxc penguin 20200411193357.477 ERROR start - start.c:do_start:1263 - Failed to setup container "penguin" lxc penguin 20200411193357.478 ERROR sync - sync.c:__sync_wait:62 - An error occurred in another process (expected sequence number 5) lxc penguin 20200411193357.478 WARN network - network.c:lxc_delete_network_priv:2561 - Failed to rename interface with index 17 from "eth0" to its initial name "veth421fa9d1" lxc penguin 20200411193357.478 ERROR lxccontainer - lxccontainer.c:wait_on_daemonized_start:842 - Received container state "ABORTING" instead of "RUNNING" lxc penguin 20200411193357.479 ERROR start - start.c:__lxc_start:1939 - Failed to spawn container "penguin" lxc penguin 20200411193357.701 WARN conf - conf.c:lxc_map_ids:2919 - newuidmap is lacking necessary privileges lxc penguin 20200411193357.701 WARN conf - conf.c:lxc_map_ids:2925 - newgidmap is lacking necessary privileges lxc 20200411193357.706 WARN commands - commands.c:lxc_cmd_rsp_recv:132 - Connection reset by peer - Failed to receive response for command "get_state" lxc 20200411193357.707 WARN commands - commands.c:lxc_cmd_rsp_recv:132 - Connection reset by peer - Failed to receive response for command "get_state"
解决方案
导航到 crosh 并执行以下命令
vmc start termina vsh termina lxc file delete penguin/var/lib/lxc lxc file delete penguin/var/lib/lxcfs
重启 Linux 子系统,容器应该可以正常启动。
容器中没有网络
正如多方报道,systemd-244.1 中的 systemd-networkd 和 systemd-resolved 服务对于非特权 LXC 容器无法正常工作,这最终导致 Crostini 容器内部缺少网络连接。用户可能只会看到 arch
容器的 IPv6 地址,但没有 IPv4 地址(例如,使用 ip a
命令)。
一个可能的解决方案在此处说明:LXD#systemd-networkd 没有 IPv4。
或者,另一种解决方案是完全禁用 systemd-networkd/systemd-resolved,并通过 dhclient 服务执行网络配置。首先,安装 dhclient,然后,以 root 用户身份运行
dhcpcd eth0 systemctl disable systemd-networkd systemctl disable systemd-resolved unlink /etc/resolv.conf touch /etc/resolv.conf systemctl enable dhclient@eth0 systemctl start dhclient@eth0
NetworkManager 和 dhcpcd 也可用于解决此问题,如果您更喜欢它们而不是 dhclient
解决方案。
ping 权限被拒绝
如果您收到
ping: socket: permission denied
当尝试从 root
以外的用户 ping 时,您需要设置 /usr/bin/ping
文件上的capability 标志来修复它。
# setcap cap_net_raw+ep /usr/bin/ping
这应该可以解决问题。请参阅 FS#63710。
应用在 Chrome OS 中无法打开(无限旋转)
我发现启动控制台 (lxc console penguin) 会话会阻止应用程序在 Chrome OS 中启动。启动会导致无限旋转。在这种情况下,我必须停止并启动容器才能使 Chrome OS 启动器工作
lxc stop penguin lxc start penguin
我没有使用 lxc 控制台会话,而是使用了从 Chrome OS 启动的常规 Linux 终端 GUI,这可以避免此问题。
音频播放/输入
Crostini 从 Chrome OS 74 开始支持音频播放。安装 cros-container-guest-tools-gitAUR 后,在 PulseAudio 配置之后,ALSA 和 PulseAudio 播放都应该可以工作。音频输入从 Chrome OS 79 开始支持。
在容器中输入以下命令(如果您尚未输入)
$ cp -rT /etc/skel/.config/pulse ~/.config/pulse
也可以使用 PipeWire 代替 PulseAudio。将以下文件放入 /etc/pipewire/pipewire.conf.d
/etc/pipewire/pipewire.conf.d/crostini-audio.conf
context.objects = [ { factory = adapter args = { factory.name = api.alsa.pcm.sink node.name = "Virtio Soundcard Sink" media.class = "Audio/Sink" api.alsa.path = "hw:0,0" audio.channels = 2 audio.position = "FL,FR" } } { factory = adapter args = { factory.name = api.alsa.pcm.source node.name = "Virtio Soundcard Source" media.class = "Audio/Source" api.alsa.path = "hw:0,0" audio.channels = 2 audio.position = "FL,FR" } } ]
视频播放
mpv 可以使用软件渲染播放视频,无需任何额外配置,但这对于现代视频编解码器(如 H265)来说,CPU 消耗量大且体验卡顿。对于硬件加速播放,需要 GPU 加速。请注意,Crostini 的 GPU 加速基于 VirGL,因此不会执行真正的 GPU 设备直通,并且硬件特定的 API(如 VA-API 或 VPDAU)不可用。但是可以使用 OpenGL 加速,例如,以下是 mpv.conf
的示例,它在 Chrome OS 77 及更高版本上启用了 Google Pixelbook 的加速视频和音频播放
vo=gpu ao=alsa
GPU 加速
在 Google Pixelbook 上,GPU 加速在 Chrome OS 77 及更高版本上开箱即用地适用于 Arch。在最新发布的 Chrome OS 版本上也不需要启用任何标志
$ glxinfo -B
name of display: :0 display: :0 screen: 0 direct rendering: Yes Extended renderer info (GLX_MESA_query_renderer): Vendor: Red Hat (0x1af4) Device: virgl (0x1010) Version: 19.1.4 --> Accelerated: yes <-- Video memory: 0MB Unified memory: no Preferred profile: core (0x1) Max core profile version: 4.3 Max compat profile version: 3.1 Max GLES1 profile version: 1.1 Max GLES[23] profile version: 3.2 OpenGL vendor string: Red Hat OpenGL renderer string: virgl OpenGL core profile version string: 4.3 (Core Profile) Mesa 19.1.4 OpenGL core profile shading language version string: 4.30 OpenGL core profile context flags: (none) OpenGL core profile profile mask: core profile OpenGL version string: 3.1 Mesa 19.1.4 OpenGL shading language version string: 1.40 OpenGL context flags: (none) OpenGL ES profile version string: OpenGL ES 3.2 Mesa 19.1.4 OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20
在启动容器时解锁密钥环
如果您在使用 gnome-keyring-daemon 的程序时遇到问题,则需要编写一个用户 systemd 守护程序(请参阅 Systemd/User#编写用户单元),该守护程序将在容器启动时运行密钥环守护程序。
创建以下两个文件
/etc/systemd/user/gnome-keyring.service
[Unit] Description=Keyring [Service] ExecStart=/usr/local/bin/export-keys KillUserProcesses=no [Install] WantedBy=default.target
echo random-password
替换为 cat ~/.password
。/usr/local/bin/export-keys
#!/bin/bash killall gnome-keyring-daemon echo random-password | gnome-keyring-daemon --components=secrets,ssh,pkcs11 --unlock --foreground
授予文件启动权限
# chmod a+x /usr/local/bin/export-keys
然后,启动/启用 gnome-keyring.service
用户单元并运行
$ echo -n login > ~/.local/share/keyrings/default
全屏视频、游戏和鼠标捕获
目前,Crostini 从 Chrome OS 79 开始对鼠标捕获提供有限的支持。您必须启用 chrome://flags/#exo-pointer-lock 标志才能获得鼠标捕获。与鼠标捕获相关的已关闭问题是 https://bugs.chromium.org/p/chromium/issues/detail?id=927521。
主机上的“Linux 文件”为空
如果您发现主机上的“Linux 文件”目录始终为空,并且在访客 Arch Linux 中看到以下日志,则您可能受到影响。
Feb 24 21:18:23 penguin garcon[183]: [183]: sftp: accepted connection from vsock:2:3162708311 Feb 24 21:18:23 penguin garcon[183]: [183]: Failed to execute requested program in child process: No such file or directory Feb 24 21:18:23 penguin garcon[183]: [183]: sftp: failed to spawn child process: No child processes (10)
自 2022-06 起,garcon 使用 /usr/lib/openssh/sftp-server
启动 sftp 服务器,而 openssh 软件包将二进制文件安装在 /usr/lib/ssh/sftp-server
。一种解决方法是将 garcon 期望的路径链接到已安装的路径
# mkdir /usr/lib/openssh/ # ln -s /usr/lib/ssh/sftp-server /usr/lib/openssh/sftp-server
Firefox 点击、滚动和视频卡顿
如果 firefox 在点击地址栏、滚动、选择文本等操作时表现出极其卡顿的行为,并且或播放滞后或断断续续的视频,则使用 MOZ_ENABLE_WAYLAND=1 运行 firefox 可能会解决此问题。在此之后,在 firefox 内部,about:support 应该显示“窗口协议”为 wayland。
MOZ_ENABLE_WAYLAND=1 firefox