跳转至内容

Chrome OS 设备/Crostini

来自 ArchWiki

Crostini 是 Google 的总称,用于轻松使用 Linux 应用程序支持并使其与 Chrome OS 良好集成。

本文介绍如何在 Chromebook 上通过容器(通过 Crostini)安装 Arch Linux,无需启用开发者模式,允许应用程序与其他 Chrome/Android 应用程序并行运行。

亮点

  • 官方支持,无需启用开发者模式 - 保持 Chrome OS 安全,无需刷新 BIOS 等。
  • 更长的电池续航 - 拥有 Linux 功能的 Chrome 电池续航。
  • 支持音频(输入/输出)和 OpenGL,但 USB 设备仅部分支持,并且仍在开发中。

简介

启用 Linux 支持

在“设置”中查找 Linux 并启用它。这将安装一个 Debian Linux 容器,然后我们将用 Arch Linux 容器替换它。

设置 > Linux > 启用

Crostini 仍在向 Chromebook 推出。如果您看不到启用 Linux 的选项,您可能需要切换到 beta 或开发者频道,如果它尚未在稳定频道中为您的笔记本电脑推出。这可以通过 _设置 > 关于 Chrome OS > 频道 > Dev/Beta_ 完成。

将默认的 Debian Linux 容器替换为 Arch Linux

以下说明最初基于 https://www.reddit.com/r/Crostini/wiki/howto/run-arch-linux?v=2d4c6b4c-bbb0-11e8-8f2f-0e740b2a8a8c

可选:删除 Debian 容器

警告 在 Chrome 87 版本期间,使用自定义 lxc 映像启动 vmc 会使 Termina 认为其无效并将其删除。lxc delete penguin 不应使空间无法使用。请参阅 [1]

如果您不再需要 Debian,可以通过销毁并重新创建 Termina VM 来节省一些存储空间(这将使您可以跳过重命名/删除现有容器)。请注意,这也将删除您可能在 Termina 下拥有的任何其他容器。

警告 销毁现有的 Termina 也可能禁用 Android 应用和 Play 商店。

在 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

注意:截至 2025 年 10 月,Canonical 不再为 x86_64 提供 Arch Linux 容器映像,仅提供 aarch64。如果您使用的是 x86_64,请参阅 #请求的架构不受此主机支持

在容器中启动 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 容器工具、Wayland 以支持 GUI 应用程序,以及 Xwayland 以支持 X11 应用程序。

安装 cros-container-guest-tools-gitAUR 包。另外,安装 waylandxorg-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

故障排除

提示 检查 Chromium OS Garcon Bridge(journalctl --user -u cros-garcon)是否存在主机集成问题,例如“文件应用中的 Linux 文件为空”或“应用程序未出现在 Chrome OS 中”。

Arch 容器启动失败

容器存在但状态为已停止。

$ lxc list
+---------+---------+------+------+-----------+-----------+
|  NAME   |  STATE  | IPV4 | IPV6 |   TYPE    | SNAPSHOTS |
+---------+---------+------+------+-----------+-----------+
|  arch   | STOPPED |      |      | CONTAINER | 0         |
+---------+---------+------+------+-----------+-----------+

尝试通过 lxc start arch 启动容器但未成功。

原因:systemd 版本 258 需要 cgroup v2,而 Crostini 目前不支持

Detected cgroup v1 hierarchy at /sys/fs/cgroup/, which is no longer supported by current version of systemd.
Please instruct your initrd to mount cgroup v2 (unified) hierarchy,
possibly by removing any stale kernel command line options, such as:
 systemd.legacy_systemd_cgroup_controller=1
 systemd.unified_cgroup_hierarchy=0
[!!!!!!] Detected unsupported legacy cgroup hierarchy, refusing execution.
Exiting PID 1...
Error: write /dev/pts/ptmx: file already closed

目前没有解决方案,只能将容器中的 systemd 降级到 257 版本。

请求的架构不受此主机支持

lxc launch images:archlinux archlinux --config security.privileged=true
Creating archlinux
Error: Failed instance creation: Failed creating instance record: Requested architecture isn't supported by this host

Canonical 不再为 x86_64 提供 Arch Linux 容器映像。您可以使用以下命令查看支持哪些架构:

lxc image list images: | grep archlinux | grep CONTAINER

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 v249 中,问题似乎已经消失,一切正常。然而,在 systemd v250 中,问题似乎再次出现。以上关于 v249 和 v250 的说法需要更多用户报告来确认。(请参阅 Talk:Chrome OS devices/Crostini 讨论)

正如多个来源报告的那样,systemd-244.1 中的 systemd-networkd 和 systemd-resolved 服务在非特权 LXC 容器中工作不正常,这导致 Crostini 容器内缺乏网络连接。用户可能只看到 IPv6 地址,而没有 arch 容器的 IPv4 地址(例如,使用 ip a 命令)。

一个可能的解决方案在这里:LXD#No IPv4 with systemd-networkd

或者,另一个解决方案是完全禁用 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

如果您更喜欢 dhclient 解决方案,也可以使用 NetworkManagerdhcpcd 来解决此问题。

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

我使用从 Chrome OS 启动的常规 Linux 终端 GUI,而不是使用 lxc 控制台会话,这可以防止此问题。

音频播放/输入

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 设备直通,并且 VA-API 或 VPDAU 等硬件特定 API 不可用。但是可以使用 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#Writing user units),以便在容器启动时运行密钥环守护程序。

创建以下两个文件:

/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 才能获得鼠标捕获。与鼠标捕获相关的已关闭的 issue 是 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 会显示“Window Protocol”为 wayland。

MOZ_ENABLE_WAYLAND=1 firefox

参见