使用qemu -nographic在文本终端打印字符串的问题
问题原因与解决方法
你当前的汇编代码是往VGA文本模式显存(通过GS段指向0xB8000区域)写入字符和颜色属性,这种方式依赖QEMU启用VGA显卡输出。而-nographic参数的作用是禁用VGA显卡,将串口(COM1)作为默认输入输出设备,把终端和虚拟机的串口绑定,所以原来的VGA输出方式自然看不到内容。
要在-nographic模式下的终端看到输出,需要修改代码,改成通过串口(COM1)发送字符,以下是修改后的MBR代码:
org 0x7c00 ; 初始化串口COM1(波特率9600,8位数据,无校验,1位停止位) init_serial: mov dx, 0x03FB ; 线路控制寄存器 mov al, 0x80 ; 置位DLAB,允许设置波特率 out dx, al mov dx, 0x03F8 ; 波特率除数低字节(9600对应0x000C) mov al, 0x0C out dx, al mov dx, 0x03F9 ; 波特率除数高字节 mov al, 0x00 out dx, al mov dx, 0x03FB ; 线路控制寄存器,恢复DLAB,设置数据格式 mov al, 0x03 ; 8位数据,无校验,1位停止位 out dx, al mov dx, 0x03FC ; 调制解调器控制寄存器 mov al, 0x03 ; 使能DTR和RTS out dx, al ; 发送字符串"hello"到串口 send_string: mov si, msg send_char: lodsb or al, al jz hang ; 字符串结束则进入死循环 call send_serial_char jmp send_char send_serial_char: push dx push ax wait_tx_empty: mov dx, 0x03FD ; 线路状态寄存器 in al, dx test al, 0x20 ; 检查发送缓冲区是否为空(第5位为1表示空) jz wait_tx_empty mov dx, 0x03F8 ; 数据寄存器,发送字符 pop ax out dx, al pop dx ret msg: db 'hello', 0 hang: jmp near $ times 510-($-$$) db 0 dw 0xAA55
使用说明
- 将这段代码编译写入MBR(和你之前的操作一致)
- 用原来的命令启动QEMU:
qemu-system-i386 -m 32 -smp 2 -enable-kvm -hda $(DISK) -nographic,此时终端会直接输出hello
补充说明
- 如果不想改代码,也可以在启动QEMU时保留VGA输出同时映射串口,但
-nographic本身就是禁用图形界面的参数,所以最直接的方式还是改用串口输出。 - 串口输出是BIOS/裸机环境下,终端交互的标准方式,适合无图形界面的场景。
内容的提问来源于stack exchange,提问作者MEssa
相关产品推荐
相关产品推荐

