Apple Silicon 上 Cirros 控制台VNC打不了字

Apple Silicon 上 Cirros 控制台VNC打不了字

前置:本地学习:用 DevStack 安装 OpenStack创建第一台实例 目标:分清哪些是苹果芯片的问题、哪些是这张 aarch64 镜像的问题,并把 noVNC 修到能登录、能打字。

引言

在 Apple Silicon 的 DevStack 上开 Cirros,控制台经常不是「坏了」一种样子,而是连着变三次:先完全没画面,再能看到登录行但打不了字,换成另一块显卡后又停在三行 EFI 日志上。

这不全是苹果芯片的问题。没有 KVM、CPU 型号被认错,才是芯片这边的事。后面画面不刷新、键盘没反应,是 Cirros 这张 aarch64 镜像把对应驱动裁掉了。换一台 ARM 服务器、用同一张镜像,后半段一样会遇到。

本文按现象写修复,环境是 Multipass 里的 DevStack,镜像 cirros-0.6.3-aarch64-disk,虚机内核 5.15.0-117-generic


先分清卡在哪一层

你看到的 虚机实际状态 原因
一直是 Display output is not active,串口日志 0 字节 固件没跑起来 CPU 被选成 32 位 cortex-a15
GRUB:error: out of memory 卡在引导器 m1.nano 只有 192MB
看得到 vm1 login:,打什么都没反应 系统已起来,画面冻住 virtio-gpu 不再刷新
停在 EFI stub: Exiting boot services... 系统已起来,显存没人接 ramfb 缺少 simplefb,USB 键盘缺少 xhci

第三、第四种不要在 noVNC 里反复点。先用串口看它是不是已经在登录提示上:

bash 复制代码
multipass exec devstack -- sudo virsh console <instance名>

退出按 Ctrl+]。Cirros 默认用户 cirros,密码 gocubsgo(输入时不显示)。实例名用下面这条看,不要猜编号:

bash 复制代码
openstack server show vm1 -c OS-EXT-SRV-ATTR:instance_name -f value

上图是第四种。固件把这三行画出来就退出了,后面没有驱动继续写这块显存,所以光标停住。同一时刻串口上已经是 vm1 login:


1. 完全没画面:指定 64 位 CPU

Apple Silicon 上没有 KVM,virt_type 必须是 qemu。安装篇里如果只写了 cpu_mode = none,libvirt 认不出这颗主机 CPU,会退到 32 位的 cortex-a15,而 AAVMF 固件是 64 位的。虚机起不来,VNC 一直空。

/etc/nova/nova-cpu.conf[libvirt]

ini 复制代码
cpu_mode = custom
cpu_models = cortex-a72
virt_type = qemu
bash 复制代码
sudo systemctl restart devstack@n-cpu.service

已经创建的虚机不会跟着变,CPU 型号写在创建时的 domain 里。删掉重建。


2. GRUB 内存不够

aarch64 上这份 Cirros 的 GRUB 2.06,用 m1.nano(192MB)会报 error: out of memory。规格用 m1.tiny:1 vCPU、512MB 内存、1GB 磁盘。


3. 看得到登录行,但不是焦点问题

Nova 在 AArch64 上默认显卡是 virtio。x86 上这块显卡还能退回 VGA 文本模式,aarch64 的 virt 机器没有这条退路。

这张镜像带了 virtio-gpu.ko,所以能画出第一帧,vm1 login: 会出现在 noVNC 上。紧接着内核日志里有:

text 复制代码
virtio_gpu virtio5: [drm] drm_plane_enable_fb_damage_clips() not called

这之后的画面更新不再发给 QEMU,noVNC 停在那一帧。点上方灰条、点黑色区域,都不会出现字符。

也不要改成 bochs。Nova 允许这个名字,但这张镜像里没有 bochs.ko,控制台会直接黑。


4. 显卡改成 ramfb

ramfb 就是一块普通显存:客人往里写,VNC 就能看到,不依赖 virtio-gpu 那次刷新。这台机器上的 QEMU 和 libvirt 10 都认识它。挡住的是 Nova:VideoModel 的允许列表里没有 ramfb,AArch64 默认仍返回 virtio

编辑 /opt/stack/nova/nova/objects/fields.py

python 复制代码
class VideoModel(BaseNovaEnum):

    CIRRUS = "cirrus"
    QXL = "qxl"
    VGA = "vga"
    VMVGA = "vmvga"
    XEN = "xen"
    VIRTIO = 'virtio'
    GOP = 'gop'
    NONE = 'none'
    BOCHS = 'bochs'
    RAMFB = 'ramfb'

    ALL = (CIRRUS, QXL, VGA, VMVGA, XEN, VIRTIO, GOP, NONE, BOCHS, RAMFB)

这是 DevStack 学习环境里的改动,生产集群不要手改计算节点源码。驱动齐全的云镜像(例如 Ubuntu)通常不必走这条路。

创建实例时,API、调度器、conductor、compute 各自用自己进程里 的允许列表做校验。只重启 nova-compute,创建会报:

text 复制代码
Invalid image metadata. Error: Field value ramfb is invalid

这几个都要重启。conductor 会等手头任务结束,停服务要一两分钟是正常的。

bash 复制代码
sudo systemctl restart \
  devstack@n-api.service \
  devstack@n-sch.service \
  devstack@n-cond-cell1.service \
  devstack@n-super-cond.service \
  devstack@n-cpu.service

然后把属性写到镜像上,删掉旧实例再创建。正在跑的虚机不会热更新显卡;从卷启动的实例更是在创建时就把型号写进 domain 了,改 Glance 对它无效。

bash 复制代码
source ~/devstack/openrc admin admin

openstack image set --property hw_video_model=ramfb cirros-0.6.3-aarch64-disk

openstack server delete vm1
openstack server create --flavor m1.tiny \
  --image cirros-0.6.3-aarch64-disk \
  --network shared --wait vm1

确认两处都是 ramfb:镜像属性,以及这台虚机的 domain XML。instance-00000005 只是这次的编号。

到这里,固件阶段的输出应该已经出现。如果仍停在下面这三行,继续第 5 节,不要再改显卡型号:

text 复制代码
EFI stub: Booting Linux Kernel...
EFI stub: Using DTB from configuration table
EFI stub: Exiting boot services...

5. 停在 EFI stub:补帧缓冲和 USB 键盘

ramfb 只保证固件能画。进内核之后,这张镜像把对应驱动裁掉了,所以是两件独立的事。

画面。 客人里有平台设备 simple-framebuffer.0,但没有 simplefb.ko / simpledrm.ko。内核把 EFI 帧缓冲转成了 simple-framebuffer,没有模块就绑不上,/sys/class/graphics 里只有 fbcon、没有 fb0。VNC 永远停在固件最后一帧。

键盘。 libvirt 给的是 USB 3 控制器 qemu-xhci 和 USB 键盘。这个内核编进了 EHCI / OHCI / UHCI,没有把 xHCI 编进去,Cirros 又把 xhci-pci.ko 裁掉了。/proc/bus/input/devices 里只有电源按钮。noVNC 的按键和 virsh send-key 都到不了虚机。

先在串口里看内核版本,模块包必须和它一致:

bash 复制代码
uname -r
# 5.15.0-117-generic

在 DevStack 那台 Ubuntu 上下这个 arm64 包并解开:

bash 复制代码
curl -fsS -o /tmp/linux-modules.deb \
  http://ports.ubuntu.com/pool/main/l/linux/linux-modules-5.15.0-117-generic_5.15.0-117.127_arm64.deb
mkdir -p /tmp/linux-modules
dpkg-deb -x /tmp/linux-modules.deb /tmp/linux-modules

要用的三个文件,都在 /tmp/linux-modules/lib/modules/5.15.0-117-generic/kernel/ 下面:

文件 作用
drivers/usb/host/xhci-pci-renesas.ko xhci-pci 的依赖,必须先加载
drivers/usb/host/xhci-pci.ko 认出 qemu-xhci 和 USB 键盘
drivers/video/fbdev/simplefb.ko 把 ramfb 的显存接成 fb0

拷到虚机里的同一相对路径(/lib/modules/5.15.0-117-generic/kernel/...)。图形控制台还不能用时,用 virsh console 登录再拷;虚机关机后,也可以用 libguestfs 的 virt-copy-in 写进那块磁盘。

Cirros 开机时会跑 /etc/init.d/rcS,它执行 /etc/init.d/S??*。放一个真实文件,不要只放指向别处的符号链接:

bash 复制代码
sudo tee /etc/init.d/S15console-fix >/dev/null << 'EOF'
#!/bin/sh
insmod /lib/modules/5.15.0-117-generic/kernel/drivers/usb/host/xhci-pci-renesas.ko
insmod /lib/modules/5.15.0-117-generic/kernel/drivers/usb/host/xhci-pci.ko
insmod /lib/modules/5.15.0-117-generic/kernel/drivers/video/fbdev/simplefb.ko
EOF
sudo chmod 755 /etc/init.d/S15console-fix
sudo reboot

顺序不能反:先 renesas,再 xhci-pci,最后 simplefb。重启后打开控制台,先点一下黑色画面。用户名 cirros,密码 gocubsgo


哪些算苹果芯片,哪些不算

现象 是不是 Apple Silicon 特有
没有 KVM,必须用 qemu;CPU 要指定 cortex-a72,否则会变成 cortex-a15 是。普通 x86,或带 KVM 的 ARM 服务器,不会走这条
aarch64 的 virt 机器没有 VGA 兼容显卡 是这套架构的事,不是 M 系列独有
virtio-gpu 画出一帧后不再刷新 这张 Cirros 内核的问题。同一镜像在别的 ARM 机器上一样
ramfb 停在 EFI stub,USB 键盘不存在 镜像裁掉了 simplefbxhci-pci,同样不是芯片特有

CPU 型号和「不能用 KVM」按苹果芯片处理。显卡不刷新、键盘没有驱动,按这张 aarch64 Cirros 镜像处理。

相关推荐
JudithHuang1 天前
OpenStack 是什么:一张图看懂在干什么
openstack
SeanQhl4 天前
基于华为云ARM架构ECS平台的OpenStack Wallaby All-in-one 完整部署指导
openstack·all-in-one
JudithHuang6 天前
从零安装 OpenStack:DevStack + Multipass 本地可复现指南
openstack
小马同学-7 天前
OpenStack 使用实战:Web 界面与 CLI 命令行实验
运维·云计算·openstack
小马同学-7 天前
OpenStack 镜像管理:Glance 镜像服务实验
运维·云计算·openstack
闲云自留地7 天前
Neutron 实战教程:物理 vs 虚拟网络,OVN 环境创建网络与安全策略
服务器·网络·openstack
Lysander.Jovian7 天前
OpenStack使用_网页版
php·openstack
闲云自留地8 天前
动手玩 Nova:Hypervisor、主机聚合、可用分区、虚拟机生命周期实操
运维·架构·openstack
闲云自留地8 天前
存储实验室:Cinder 多后端配置、卷挂载实例,Swift 对象存储实操教程
openstack