Zircon 可以使用 QEMU 进行模拟运行。您可以通过以下任一方式安装 QEMU: 预构建二进制文件或本地构建的
预构建 QEMU
jiri
会下载 QEMU(作为 jiri update
或 jiri run-hooks
的一部分)。
将 QEMU 提取到 //prebuilt/third_party/qemu
中。你可以
fx qemu
来轻松实现(见下文)。
构建 QEMU
cd $SRC
git clone --recursive https://fuchsia.googlesource.com/third_party/qemu
cd qemu
./configure --target-list=aarch64-softmmu,x86_64-softmmu
make -j32
sudo make install
如果您不想安装在 /usr/local(默认设置)中,此时安装 是 root 权限,请添加 --prefix=/path/to/install(可能是 $HOME/qemu)。然后,您需要 需要将 /path/to/install/bin 添加到 PATH 中,或者使用 -q /path/to/install 调用 run-zircon-{arch} 时。
在 QEMU 下运行 Zircon
# for aarch64
fx set bringup.arm64
fx build
fx qemu
# for x86
fx set bringup.x64
fx build
fx qemu
如果 QEMU 不在您的路径中,请使用 -q
-h 标志将列出许多选项,包括用于重建的 -b 等内容 必要时,先运行 -g,使用图形帧缓冲区运行。
要退出 qemu,请按 Ctrl-a x。使用 Ctrl-a h 查看其他命令。
在 QEMU 下启用网络
run-zircon 脚本在给定 -N 参数时将尝试创建 使用名为“qemu”的 Linux tun/tap 网络设备的网络接口。QEMU 不需要以任何特殊权限运行,但需要 提前创建一个持续的 Tun/tap 设备(需要 root 权限):
sudo ip tuntap add dev qemu mode tap user $USER
sudo ip link set qemu up
这足以启用链路本地 IPv6(与 loglistener 工具所用的相同)。
在 QEMU 下使用模拟磁盘
使用基于核心的版本(实际上就是初启的任何产品)
自动暗示为 fvm
分区提供磁盘
包含一个用于可变存储的 minfs 分区,以及一个用于存储可变存储的 blobfs 分区
软件包数据存储
您可以使用标志附加额外的图片,如下所示:
fx qemu -d [-D <disk_image_path (default: "blk.bin")>]
使用 GDB 调试内核
示例会话
此处提供了一个示例会话,帮助您入门。
在运行 QEMU 的 shell 中:
shell1$ fx qemu -- -s -S
[... some QEMU start up text ...]
这样会启动 QEMU,但会在启动时冻结系统, 正在等待你通过“continue”恢复。 如果您想在不使用 GDB 的情况下运行 QEMU,但之后能通过 GDB 挂接 然后在不带“-S”键的情况下启动 QEMU例如:
shell1$ fx qemu -- -s
[... some QEMU start up text ...]
然后,您需要在 out
目录中找到 zircon.elf
。
然后在 shell 中运行 GDB:
shell2$ gdb path-to-zircon.elf -x ${FUCHSIA_DIR}/zircon/kernel/scripts/zircon.elf-gdb.py
Reading symbols from /fuchsia/out/default/kernel_x64-clang/zircon.elf...
Loading zircon.elf-gdb.py ...
Zircon extensions installed for /fuchsia/out/default/kernel_x64-clang/zircon.elf
(gdb) target extended-remote :1234
Remote debugging using :1234
0x000000000000fff0 in ?? ()
Thread 1 hit Breakpoint -1, 0x0000000000100050 in ?? ()
Watchpoint set on KASLR relocated base variable
Thread 1 hit Hardware read watchpoint -2: *0x767ca0
Value = 0
0x00000000001000ef in ?? ()
Update symbols and breakpoints for KASLR
KASLR: Correctly reloaded kernel at 0xffffffff00000000
(gdb) # Don't try to do too much at this point.
(gdb) # GDB can't handle architecture switching in one session,
(gdb) # and at this point the architecture is 16-bit x86.
(gdb) break lk_main
Breakpoint 1 at 0xfffffffff010cb58: file kernel/top/main.c, line 59.
(gdb) continue
Continuing.
Breakpoint 1, lk_main (arg0=1, arg1=18446744071568293116, arg2=0, arg3=0)
at kernel/top/main.c:59
59 {
(gdb) continue
此时 Zircon 启动,并在 shell1 中返回,您将位于 Zircon 提示。
mxsh>
如果此时在 shell2 中按 Ctrl-C,可以返回到 GDB。
(gdb) # Having just done "continue"
^C
Program received signal SIGINT, Interrupt.
arch_idle () at kernel/arch/x86/64/ops.S:32
32 ret
(gdb) info threads
Id Target Id Frame
4 Thread 4 (CPU#3 [halted ]) arch_idle () at kernel/arch/x86/64/ops.S:32
3 Thread 3 (CPU#2 [halted ]) arch_idle () at kernel/arch/x86/64/ops.S:32
2 Thread 2 (CPU#1 [halted ]) arch_idle () at kernel/arch/x86/64/ops.S:32
* 1 Thread 1 (CPU#0 [halted ]) arch_idle () at kernel/arch/x86/64/ops.S:32
对于每个 CPU,QEMU 会向 GDB 报告一个线程。
zircon.elf-gdb.py 脚本
zircon/kernel/scripts/zircon.elf-gdb.py
脚本应由 gdb 自动加载。如果
则您可能需要将其路径添加到 gdb 的 auto-load-safe-path 中。
或者,您也可以在 gdb 的命令行标志中添加手动设置:
$ gdb path-to-zircon.elf -x ${FUCHSIA_DIR}/zircon/kernel/scripts/zircon.elf-gdb.py
它提供以下几项功能:
gdb 的 KASLR 重定位,允许您在函数中正确设置断点。
用于锆石物体的漂亮打印机(毕竟目前还没有任何一台设备)。
一些特定于 zircon 的命令,所有命令都带有一个“zircon”前缀。要查看这些建议,请执行以下操作:
(gdb) help info zircon
(gdb) help set zircon
(gdb) help show zircon
- 增强了对展开程序的支持(通过内核故障自动展开)。
注意:此脚本并不总是随着 Zircon 的变化而更新。
注意:由于 bug 67893,如果将 qemu 与 kvm 搭配使用,KASLR 部分可能无法正常工作。 如需解决此问题,您可以在 gdb 中执行以下命令:
(gdb) # before attaching to qemu
(gdb) mem 0 0xffffffffffffffff ro
(gdb) target extended-remote :1234
(gdb) ...
(gdb) # after the script performed the kaslr relocations
(gdb) mem auto
终止会话
要终止 QEMU,您可以从 GDB 向 QEMU 发送命令:
(gdb) monitor quit
(gdb) quit
与 Gdb 中的 QEMU 交互
如需查看您可以从 GDB 执行的 QEMU 命令列表,请执行以下操作:
(gdb) monitor help
保存系统状态以进行调试
如果您遇到了难以调试的崩溃或需要帮助 可以保存类似于核心转储文件的系统状态。
bash$ qemu-img create -f qcow2 /tmp/my_snapshots.qcow2 32M
将创建一个“3200 万”块存储设备接下来启动 QEMU 并告诉它 但不要求它将设备连接到访客系统。 没关系;我们不打算用它来备份磁盘状态 核心转储文件注意:如果您已在进行模拟,则可以跳过 并且使用的是 qcow2 格式
bash$ qemu <normal_launch_args> -drive if=none,format=qcow2,file=/tmp/my_snapshots.qcow2
当您需要保存核心状态时,直接切换到 QEMU
使用
(qemu) savevm my_backup_tag_name
稍后,在相同的机器(一台以与之前相同的参数启动)上, 您可以拖放到控制台并运行以下命令:
(qemu) loadvm my_backup_tag_name
来恢复状态。或者,您也可以在 cmd 行中使用以下命令:
bash$ qemu <normal_launch_args> -drive if=none,format=qcow2,file=/tmp/my_snapshots.qcow2 -loadvm my_backup_tag_name
从理论上讲,您可以将 qcow2 映像与构建输出打包在一起 这样其他人就能够恢复你的状态并开始 与 QEMU 控制台有关的内容