How to Use QEMUs “debugcon”-Feature (and Write to a File)

QEMU is a hypervisor often used for low-level OS/kernel development and testing. Especially when you write your own OS/kernel, things can get really hard and difficult to debug. Furthermore, there are not many debug capabilities in the sense, that you can’t write to files or screen in early phases of the boot process due to the lack of an initialized environment with drivers etc. For this case, QEMU has a featured called debugcon. It is barely documented but really handy to debug things and can be used in the earliest phases of the boot already.

What is “debugcon”

The debug connection allows you to write to the x86 I/O-port 0xe9. Practically this means that you can transfer for example ASCII, UTF-8, UTF-16, or UTF-32 via this interface. On the QEMU side, one can connect the I/O port to either a file or a device, like /dev/stdout. When QEMU runs and the binary writes data to the file, you can open it afterwards with an editor of text viewer of your choice.

Due to my research, this feature comes originally from Bochs, a x86 emulator, but QEMU has it for some time now. In my opinion QEMU is not documented very well and especially this feature is hard to use from the official documentation. After some research on Github I found out, how others solved it.

How to Activate it

To connect -debugcon with stdout (the terminal that started your QEMU process), pass -debugcon /dev/stdout to QEMU. To redirect the data to a file, pass -debugcon file:qemu/debugcon.txt to it.

You can use any absolute or relative path behind the :. The file will be created automatically (if QEMU has permission to do that in the given directory).

How to Use in Code

You need the outb instruction from x86. If you are not writing a program in pure assembly, I recommend inline assembly in C or Rust. For Rust, there is a nice abstraction, which can be found in the x86-crate.

Code might look like this:

// Only do this if the app runs in QEMU (or Bochs), otherwise bad things might happen).
// Or to be more specific, only do this, if I/O port 0xe9 is valid.
if runs_inside_qemu() {
    unsafe {
        x86::io::outb(0xe9, b'H');
        x86::io::outb(0xe9, b'e');
        x86::io::outb(0xe9, b'l');
        x86::io::outb(0xe9, b'l');
        x86::io::outb(0xe9, b'o');
        x86::io::outb(0xe9, b'\n');
    }
}

Example QEMU config

The following snippet content from a sh-file, that runs QEMU with the debugcon feature. It’s taken from one of my projects.

QEMU_ARGS=(
          # Disable default devices
          # QEMU by default enables a ton of devices which slow down boot.
          "-nodefaults"
          # Use a standard VGA for graphics
          "-vga"
          "std"
          # Use a modern machine, with acceleration if possible.
          "-machine"
          # "q35" # also works, but slower
          # Interesting to see how this changes CPU-ID
          # Without KVM the Hypervisor is QEMU, else its KVM
          "q35,accel=kvm:tcg"
          # Allocate some memory
          "-m"
          "128M"
          # Set up OVMF
          "-drive"
          "if=pflash,format=raw,readonly,file=${OVMF_FW_PATH}"
          "-drive"
          "if=pflash,format=raw,file=${OVMF_VARS_PATH}"
          # Mount a local directory as a FAT partition
          "-drive"
          "format=raw,file=fat:rw:${QEMU_VOLUME_DIR}"
          # Enable serial
          #
          # Connect the serial port to the host. OVMF is kind enough to connect
          # the UEFI stdout and stdin to that port too.
          "-serial"
          "stdio"
          # https://qemu-project.gitlab.io/qemu/system/invocation.html
          # using this, the program can write to X86 I/O port 0xe9 and talk
          # to qemu => debug output
          "-debugcon"
          # or "/dev/stdout" => it appears in terminal window
          # this is poorly documented! I found out by coincidence, that I can use a file like this
          "file:qemu/debugcon.txt"
          # Setup monitor
          "-monitor"
          "vc:1024x768"
  )
  echo "Executing: qemu-system-x86_64 " "${QEMU_ARGS[@]}"
  qemu-system-x86_64 "${QEMU_ARGS[@]}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值