diff --git a/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/figures/ARM_tool_config.png b/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/figures/ARM_tool_config.png new file mode 100644 index 0000000000000000000000000000000000000000..4ad5a243dd5be20643917a052539e2fef445983b Binary files /dev/null and b/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/figures/ARM_tool_config.png differ diff --git a/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/figures/ARM_tools.png b/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/figures/ARM_tools.png new file mode 100644 index 0000000000000000000000000000000000000000..ebda0d82e905f79d3a9d06b437f3a4a86e610d5e Binary files /dev/null and b/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/figures/ARM_tools.png differ diff --git a/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/figures/brk-hello-main.png b/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/figures/brk-hello-main.png index 73406a41265165ef792b946b8f9fdb2aa78a1739..ba05cab7405b511f0411c6ddd2588f7d95eabf2d 100644 Binary files a/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/figures/brk-hello-main.png and b/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/figures/brk-hello-main.png differ diff --git a/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/figures/run_debug.png b/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/figures/run_debug.png new file mode 100644 index 0000000000000000000000000000000000000000..b835be2574257bc3ebe6e3828f76d9651e36a8ae Binary files /dev/null and b/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/figures/run_debug.png differ diff --git a/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/qemu-arm-linux.md b/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/qemu-arm-linux.md index 9b8a83f5c78116beea3c7343ec766e63734c45aa..33a882b61c15f879e30d9245dcce827089f898b1 100644 --- a/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/qemu-arm-linux.md +++ b/rt-thread-version/rt-thread-smart/debug/qemu-arm-linux/qemu-arm-linux.md @@ -1,20 +1,15 @@ # 使用 VSCode 调试用户态应用 (arm-Linux) -本教程的内容是如何在 Ubuntu 上使用 VSCode 调试 RT-Smart 内核及用户态应用,基于 qemu-vexpress-a9 BSP 完成。 +本教程的内容是如何在 Ubuntu 上使用 VSCode 调试 RT-Smart 内核及用户态应用,基于 qemu-virt64-aarch64 BSP 完成。 ## 准备工作 1. 下载源码: - - rt-thread(https://github.com/RT-Thread/rt-thread.git) 切换到 rt-smart 分支。 + - rt-thread (https://github.com/RT-Thread/rt-thread.git) 。 ```bash $ git clone https://github.com/RT-Thread/rt-thread.git - $ - $ git checkout rt-smart - $ - # update kernel's rt-smart branch to the latest version - $ git pull origin rt-smart ``` - 用户态应用程序 (https://github.com/RT-Thread/userapps.git) @@ -30,7 +25,7 @@ $ sudo apt-get update $ sudo apt-get install ubuntu-make $ umake ide visual-studio-code - + # 提示输入 a 即可 ``` @@ -42,7 +37,7 @@ $ sudo tar xf gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2 -C /opt ``` - 然后设置 GDB 环境变量设置,打开 ~/.bashrc + 然后设置 GDB 环境变量设置,打开~/.bashrc ```bash $ sudo gedit ~/.bashrc @@ -51,22 +46,80 @@ ![image-20221026140628406](figures/gdb-path.png) +4. 安装内核编译工具链 + +编译内核的时候需要用到 aarch64-linux-musleabi- 工具链,可在 userapps/apps 目录下通过 `xmake smart-rootfs --export=all` 命令导出。导出的目录为 `userapps/apps/build/packages/a/aarch64-smart-musleabi/176897/efeb359e05d0431ea1fd8843dccf6d8f/bin` + +![](figures/ARM_tools.png) + +环境变量配置为: + +```shell +export RTT_CC="gcc" +export RTT_EXEC_PATH="/opt/aarch64-linux-musleabi/bin/" +export RTT_CC_PREFIX="aarch64-linux-musleabi-" +export PATH="$RTT_EXEC_PATH:$PATH" +export PATH="/opt/gcc-arm-none-eabi-10-2020-q4-major/bin/:$PATH" +``` + +![](figures/ARM_tool_config.png) + +1. 安装 xmake 和 scons 工具 + + - 安装 scons + + ```bash + sudo apt-get install scons + ``` + + - 安装 xmake + + 请根据 [xmake 官方文档](https://xmake.io/#/zh-cn/guide/installation?id=ubuntu) 进行安装 + + 以下为 ubuntu 安装方式 + + ```bash + sudo add-apt-repository ppa:xmake-io/xmake + sudo apt update + sudo apt install xmake + ``` + + - 安装 gdb-multiarch + + ```bash + sudo apt-get install gdb-multiarch + ``` + + + ## 编译 userapps 与内核 -在 userapps 中,配置 gcc 工具链并编译 app: -1. 在 `userapps\tools` 目录下,使用如下 python 命令 `python get_toolchain.py arm` 下载工具链(若之前执行过则无需再次执行); -2. 在 `userapps` 目录下,使用命令 `source smart-env.sh arm` 设置工具链路径; -3. 在 `userapps` 目录下,使用命令 `scons` 编译。编译顺利的话,将在 `userapps\root` 文件夹中得到一系列可执行 elf 文件。 +在 userapps 中,编译 app: + +``` +cd apps +xmake f -a aarch64 # 配置为 aarch64 平台 +xmake -j8 +``` + +制作镜像: + +``` +xmake smart-rootfs +xmake smart-image -o ../prebuilt/qemu-virt64-aarch64-ext4/ext4.img # 将镜像输出至 qemu-virt64-aarch64-ext4 目录 +``` + +编译系统内核: -在 `\rt-thread\bsp\qemu-vexpress-a9` 目录下,编译系统内核: -1. 使用命令 `scons` 编译,会生成 rtthread.elf 与 rtthread.bin; -2. 使用命令 `./qemu-nographic.sh`,测试 qemu 正常运行后,使用 ctrl a,x 结束运行。 +1. 进入 `rt-thread/bsp/qemu-virt64-aarch64` 目录使用命令 `scons` 编译,会生成 rtthread.elf 与 rtthread.bin; +2. 将 rt-thread 编译生成的 rtthread.bin 和 rtthread.elf 文件拷贝到 userapps/prebuilt/qemu-virt64-aarch64 中 +3. 使用命令 `./run.sh`,测试 qemu 正常运行后,使用 ctrl a,x 结束运行。 ## VSCode 配置 要想使用 VSCode 调试用户态应用,需要先在工程路径下添加调试配置。 -1. 首先在终端使用命令 `code . `,使用 VSCode 打开该目录。 +1. 首先在终端使用命令 `code .`,使用 VSCode 打开该目录。 2. 修改 `\rt-thread\bsp\qemu-vexpress-a9` 目录下 `.vscode` 文件夹中的 `launch.json` 配置,如下所示(需要更新实际的 gdb 路径): ```json @@ -103,38 +156,56 @@ } ``` -### 将待调试的 app 拷贝到 sd.bin +如果上述配置 launch.json 的文件无法进行调试,那就使用以下配置: -如果 sd.bin 不存在,可以通过下面方法创建并格式化: +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "aarch64-debug", + "type": "cppdbg", + "request": "launch", + "miDebuggerPath": "/usr/bin/gdb-multiarch", + "program": "${workspaceFolder}/rtthread.elf", + "setupCommands": [ + { + "description": "为 gdb 启用整齐打印", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "text": "target remote localhost:1234" + }, + { + "text": "restore ${workspaceFolder}/rtthread.elf" + } + ], + "launchCompleteCommand": "None", + "cwd": "${workspaceFolder}" + } + ] +} -```bash -$ dd if=/dev/zero of=sd.bin bs=1024 count=65536 -$ mkfs.vfat sd.bin ``` -然后后拷贝 app 到 sd.bin 中 (调试过程中每次修改重新编译 app 后,都需要更新 sd.bin 里面的 app 文件): - -```bash -$ sudo mount sd.bin /mnt -$ sudo cp ../../../userapps/root/bin/hello.elf /mnt/hello.elf -$ sudo umount /mnt -``` +launch.json 配置文件中的 `rtthread.elf`,改为自己要调试的应用。 ## 调试用户态应用 -这部分开始正式调试用户态应用,先进入内核的调试界面,然后添加用户态应用的符号表,再在内核中运行用户态应用即可进入用户态应用调试,具体步骤如下: +这部分开始正式调试用户态应用,具体步骤如下: -1. 在 VSCode 终端输入 `./qemu-dbg.sh`,此时弹出 qemu 窗口。可以看到启动过程被挂起,等待调试前端来连接。 +1. 修改 `run.sh` 脚本,在脚本里添加 `-s -S`。 -2. 在 VSCode 中按下 F5 开始调试内核,运行的代码将停在 main 断点处,并且控制台打印 rt-thread logo,表示系统已经正常启动,文件系统也已经成功挂载。 + ![](figures/run_debug.png) - ![image-20221026104404817](figures/vsc-debug.png) +2. 在 VSCode 终端输入 `./run.sh`,此时弹出 qemu 窗口。可以看到启动过程被挂起,等待调试前端来连接。 -3. 断点在 main 处时,可以加载待调试应用程序的符号,如调试 hello.elf,在 VSCode 调试控制台输入如下命令后回车(注意调整 elf 文件的正确的相对路径) `-exec add-symbol-file ../../../userapps/root/bin/hello.elf`,之后输入 `-exec b main` 命令并回车,这将会在 app main 上打断点。 +3. 在 VSCode 中按下 F5 开始调试内核,运行的代码将停在 main 断点处,并且控制台打印 rt-thread logo,表示系统已经正常启动,文件系统也已经成功挂载。 - ![image-20221026103535098](figures/debug.png) + ![image-20221026104404817](figures/vsc-debug.png) -4. 按下 F5 全速运行程序,这时系统正常运行,可以在终端输入 MSH 调试命令。在终端输入用户态应用的文件路径执行相应的用户态应用,如 `mnt/hello.elf`。应用会被加载运行,并自动停在应用程序入口处。从 VSCode 可以看到应用的源码文件被打开,并且断点停在应用入口 main 处。 +4. 按下 F5 全速运行程序,这时系统正常运行,应用会被加载运行。从 VSCode 可以看到应用的源码文件被打开,并且断点停在应用入口 main 处。 ![image-20221026104738963](figures/brk-hello-main.png) diff --git a/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/ARM_tool_config.png b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/ARM_tool_config.png new file mode 100644 index 0000000000000000000000000000000000000000..4ad5a243dd5be20643917a052539e2fef445983b Binary files /dev/null and b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/ARM_tool_config.png differ diff --git a/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/ARM_tools.png b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/ARM_tools.png new file mode 100644 index 0000000000000000000000000000000000000000..ebda0d82e905f79d3a9d06b437f3a4a86e610d5e Binary files /dev/null and b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/ARM_tools.png differ diff --git a/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/build_app-res.png b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/build_app-res.png index 93d137086202eb475f58dbcf7b73eb6a906e1852..73997569b85994babed62bd4115893d327369a52 100644 Binary files a/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/build_app-res.png and b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/build_app-res.png differ diff --git a/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/build_app.png b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/build_app.png index 8c19c1b3f4563c1282cc8c7bcd7ebb59d732a7cc..f0238be87d0a94a60423379bf8db3de8a033a6ab 100644 Binary files a/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/build_app.png and b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/build_app.png differ diff --git a/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/build_kernel1.png b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/build_kernel1.png index 4c55cc32c8ff03f3faaeb465688ecebeb569a92b..e291c1a7d9a15b89f972b045e3f7c257c3af3deb 100644 Binary files a/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/build_kernel1.png and b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/build_kernel1.png differ diff --git a/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/build_kernel2.png b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/build_kernel2.png index 464916b0324f266fd06369c8f5b211befa8198ae..d1701bab2b73137f5561ee9b38999e3b57d0b99e 100644 Binary files a/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/build_kernel2.png and b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/build_kernel2.png differ diff --git a/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/image.png b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/image.png new file mode 100644 index 0000000000000000000000000000000000000000..12069c19c2ab1cdd8f0d7266ee009c669aa20fb4 Binary files /dev/null and b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/image.png differ diff --git a/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/qemu_run.png b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/qemu_run.png index c0deb1290a10929024165b0546e5e11ae90d61e9..18ebbbe014efed0cf7c40ec780d20f82fc47dbcc 100644 Binary files a/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/qemu_run.png and b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/figures/qemu_run.png differ diff --git a/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/quickstart.md b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/quickstart.md index 1d95acf42beee61ccf23651394df3db809c89821..054d7e312c2e71c08c89b5c4cda94477f3376aaf 100644 --- a/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/quickstart.md +++ b/rt-thread-version/rt-thread-smart/quick-start/qemu-linux/quickstart.md @@ -1,8 +1,8 @@ # QEMU 快速上手 (Linux) -本教程在 Ubuntu 平台上使用 QEMU 快速上手 RT-Smart,运行 RT-Smart 用户态应用,内核基于 qemu-vexpress-a9 ,其他内核可以用同样的方式运行。 +本教程在 Ubuntu 平台上使用 QEMU 快速上手 RT-Smart,运行 RT-Smart 用户态应用,内核基于 qemu-virt64-aarch64 ,其他内核可以用同样的方式运行。 -> 注意:运行环境的 QEMU 版本太低会导致执行脚本后终端无输出。 +> 注意:运行环境的 QEMU 版本太低会导致执行脚本后终端无输出。 ## 如何构建用户态应用 @@ -19,50 +19,72 @@ git clone https://github.com/RT-Thread/userapps.git ``` . ├── apps ---- app 体验示例 -├── configs ---- 不同平台 app 的通用配置 -├── linker_scripts ---- 编译 app 使用的链接脚本 ├── prebuilt ---- 预编译好的内核镜像 -├── rtconfig.h ---- app 使用的公共配置文件 +├── repo ---- packages 配置 ├── sdk ---- 开发 app 使用的 sdk -├── smart-env.bat ---- 配置 Win 上环境变量的脚本 -├── smart-env.sh ---- 配置 Linux 上环境变量的脚本 -└── tools ---- 开发 app 使用的脚本工具 - ├── get_toolchain.py ---- 下载工具链的脚本 - └── gnu_gcc ---- 下载下来的工具链存放的路径 +├── env.sh ---- 配置 Linux 上环境变量的脚本 +└── tools ---- 编译好的工具包 +``` + +### 安装 xmake 和 scons 工具 + +```bash +sudo add-apt-repository ppa:xmake-io/xmake +sudo apt update +sudo apt install xmake + +sudo apt-get install scons ``` ### 配置工具链 -在 userapps\tools 目录下运行 get_toolchain.py 的脚本,会下载对应的工具链并展开到 userapps\tools\gun_gcc 目录。后面的工具链名称可以是 arm | riscv64。 +工具链可以通过 [Downloads | GNU-A Downloads – Arm Developer](https://developer.arm.com/downloads/-/gnu-a) 网址下载,(aarch64 位) -本文以 ARM 平台为例,输入下面的命令: +下载完成之后,解压,然后打开 `~/.bashrc` 文件,添加环境变量: ``` -python get_toolchain.py arm +export PATH="/opt/gcc_tool/gcc-arm-10_3_2021_07_x86_64-aarch64-none-elf/bin:$PATH" ``` -在 userapps 目录下, 运行 smart-env.sh 配置工具链路径,配置完会显示配置好的工具链路径。(这一步包括后面步骤编译内核都需要保留的工具链路径,重开一个终端都要重新source一次) +编译内核的时候需要用到 aarch64-linux-musleabi- 工具链,可在 userapps/apps 目录下通过 `xmake smart-rootfs --export=all` 命令导出。导出的目录为 `userapps/apps/build/packages/a/aarch64-smart-musleabi/176897/efeb359e05d0431ea1fd8843dccf6d8f/bin` -``` -source smart-env.sh arm +![](C:\Users\RTT\Desktop\source_code\docs-online\rt-thread-version\rt-thread-smart\quick-start\qemu-linux\figures\ARM_tools.png) + +环境变量配置为: + +```shell +export RTT_CC="gcc" +export RTT_EXEC_PATH="/opt/aarch64-linux-musleabi/bin/" +export RTT_CC_PREFIX="aarch64-linux-musleabi-" +export PATH="$RTT_EXEC_PATH:$PATH" +export PATH="/opt/gcc-arm-none-eabi-10-2020-q4-major/bin/:$PATH" ``` -![image-20221021144625013](figures/set.png) +![](C:\Users\RTT\Desktop\source_code\docs-online\rt-thread-version\rt-thread-smart\quick-start\qemu-linux\figures\ARM_tool_config.png) ### 编译用户态应用 -在 userapps 目录下使用 scons 编译,编译顺利的话,将在 root 文件夹中得到一系列可执行 elf 文件。 +在 userapps/apps 目录下使用 `xmake -j8` 编译,生成的可执行文件在 userapps/apps/build/cross/aarch64 目录中的 debug 和 release 目录下。 ![img](figures/build_app.png) ![image-20221021145335403](figures/build_app-res.png) +### 制作 img 镜像 -## 构建内核镜像 +执行以下命令制作镜像: + +``` +xmake smart-rootfs +xmake smart-image -o ../prebuilt/qemu-virt64-aarch64-ext4/ext4.img # 将镜像输出至 qemu-virt64-aarch64-ext4 目录 +``` + +![](figures/image.png) -rt-thread 中默认的镜像并非 Smart 需要先编译替换 -下载 rt-thread 源码(如有则跳过),之后切换到 rt-smart 分支并从远端同步更新。(RT-Thread 版本大于等于 5.0.0 时,直接查看下面的注意事项) +## 构建内核镜像 + +下载 rt-thread 源码(如有则跳过)。(RT-Thread 版本大于等于 5.0.0 时,直接查看下面的注意事项) ``` git clone https://github.com/RT-Thread/rt-thread.git @@ -78,7 +100,7 @@ git pull origin rt-smart ![image-20221021153136199](figures/build_kernel2.png) -将生成的内核镜像 rtthread.bin 更新到 userapps\prebuilt\ qemu-vexpress-a9 目录即可。 +将生成的内核镜像 rtthread.bin 更新到 userapps\prebuilt\ qemu-virt64-aarch64 目录即可。 > 注意事项: > @@ -86,11 +108,11 @@ git pull origin rt-smart > > ``` > git clone https://github.com/RT-Thread/rt-thread.git -> cd ./rt-thread/bsp/qemu-vexpress-a9/ #打开rt-thread项目目录中的 bsp/qemu-vexpress-a9目录 +> cd ./rt-thread/bsp/qemu-virt64-aarch64/ #打开 rt-thread 项目目录中的 bsp/qemu-virt64-aarch64 目录 > scons --menuconfig > ``` > -> 基于 rt-thread 仓库的 qemu-vexprss-a9 BSP 构建内核镜像: +> 基于 rt-thread 仓库的 qemu-virt64-aarch64 构建内核镜像: > > 1. 选择 RT-Thread Kernel 选项 > @@ -108,57 +130,20 @@ git pull origin rt-smart > > ![image-20221021153136199](figures/build_kernel2.png) > -> 将生成的内核镜像 rtthread.bin 更新到 userapps\prebuilt\qemu-vexpress-a9 目录即可。 +> 将生成的内核镜像 rtthread.bin 更新到 userapps\prebuilt\qemu-virt64-aarch64 目录即可。 ## 运行用户态应用 -在本仓库的 prebuilt 目录下存放有预构建好的针对 QEMU ARM 平台的内核镜像 qemu-vexpress-a9\rtthread.bin,可以直接运行体验。 - -### 将待调试的 app 拷贝到 sd.bin - -如果 sd.bin 不存在,可以通过下面方法创建并格式化: - -``` -dd if=/dev/zero of=sd.bin bs=1024 count=65536 -mkfs.vfat sd.bin -``` - -然后后拷贝 app 到 sd.bin 中 (调试过程中每次修改重新编译 app 后,都需要更新 sd.bin 里面的 app 文件): - -``` -sudo mount sd.bin /mnt -sudo cp root/bin/hello.elf /mnt/hello.elf -sudo umount /mnt -``` - -![image-20221021153444835](figures/sd.png) +在本仓库的 prebuilt 目录下存放有预构建好的针对 QEMU ARM 平台的内核镜像 qemu-virt64-aarch64\rtthread.bin,可以直接运行体验。 ### 运行 QEMU -将 sd.bin 复制到 userapps\prebuilt\qemu-vexpress-a9 中,终端也切换到该目录下 - -![image-20221021152537185](figures/prebuilt-file.png) - -在 userapps\prebuilt\qemu-vexpress-a9 目录下创建 qemu-nographic.sh 文件,写入以下命令(如果当前目录已有 qemu-nographic.sh 请忽略) -``` -#!/bin/bash -SHELL_FOLDER=$(cd $(dirname ${BASH_SOURCE[0]}); pwd) - -if [ ! -f ${SHELL_FOLDER}/"sd.bin" ]; then -qemu-img create -f raw ${SHELL_FOLDER}/sd.bin 64M -fi -qemu-system-arm -M vexpress-a9 -kernel rtthread.bin -nographic -sd sd.bin -``` -然后执行 `./qemu-nographic.sh`。 +执行 `./run.sh` ![image-20221024180626302](figures/qemu_run.png) -Smart 运行起来后输入 ls 可以看到我们存储到 QEMU SD 卡里的文件和文件夹了。 - -![image-20221024180816610](figures/qemu_run2.png) - 在最后执行了 hello 示例,输出 "hello world!"。 执行 ctrl a,x 可退出 QEMU。