Enabling USB for Cubieboard QEMU
- April 17, 2025

Embedded systems support various serial or parallel interfaces for communication. In some of the posts in MistraSolutions blog interfaces like SPI and I2C were covered.
Today, one more serial interface will be covered, which is USB (Universal Serial Bus). We will not go into details of creating a custom USB device, but into using the USB bus on the Cubieboard emulated in QEMU.
USB support in QEMU provides instructions on some of the features supported by QEMU, like adding a virtual USB storage or HID device (mouse, keyboard, tablet).
The practical thing about USB is that it is a standard protocol and that even a real (physical) device can be connected to a QEMU instance.
Enabling USB for Cubieboard QEMU
QEMU Cubieboard supports for USB emulation, but it is not enabled by default. This can be observed by starting QEMU emulation, where following messages will be printed in the U-Boot and Linux boot log:
[ U-Boot log ]
...
starting USB...
Bus usb@1c14000: USB EHCI 0.00
Bus usb@1c14400: USB OHCI 0.0
Bus usb@1c1c000: USB EHCI 0.00
Bus usb@1c1c400: USB OHCI 0.0
scanning bus usb@1c14000 for devices... 1 USB Device(s) found
scanning bus usb@1c14400 for devices... 1 USB Device(s) found
scanning bus usb@1c1c000 for devices... 1 USB Device(s) found
scanning bus usb@1c1c400 for devices... 1 USB Device(s) found
scanning usb for storage devices... 0 Storage Device(s) found
...
Starting kernel ...
...
[ 0.736588] ehci-platform 1c14000.usb: EHCI Host Controller
[ 0.737300] ehci-platform 1c14000.usb: new USB bus registered, assigned bus number 1
[ 0.739015] ehci-platform 1c1c000.usb: EHCI Host Controller
[ 0.739360] ehci-platform 1c1c000.usb: new USB bus registered, assigned bus number 2
[ 0.741614] ohci-platform 1c14400.usb: Generic Platform OHCI controller
[ 0.742047] ohci-platform 1c14400.usb: new USB bus registered, assigned bus number 3
[ 0.743662] clk: Disabling unused clocks
[ 0.748461] ohci-platform 1c1c400.usb: Generic Platform OHCI controller
[ 0.748792] ohci-platform 1c1c400.usb: new USB bus registered, assigned bus number 4
[ 0.750701] ohci-platform 1c14400.usb: irq 107, io mem 0x01c14400
[ 0.751755] ohci-platform 1c1c400.usb: irq 108, io mem 0x01c1c400
[ 0.755512] ehci-platform 1c1c000.usb: can't setup: -110
[ 0.755924] ehci-platform 1c1c000.usb: USB bus 2 deregistered
[ 0.756801] ehci-platform: probe of 1c1c000.usb failed with error -110
[ 0.760776] ehci-platform 1c14000.usb: can't setup: -110
[ 0.761187] ehci-platform 1c14000.usb: USB bus 1 deregistered
[ 0.761841] ehci-platform: probe of 1c14000.usb failed with error -110
[ 0.816298] ohci-platform 1c1c400.usb: init err (00000000 0000)
[ 0.817222] ohci-platform 1c1c400.usb: can't start
[ 0.819682] ohci-platform 1c1c400.usb: startup error -75
[ 0.820272] ohci-platform 1c1c400.usb: USB bus 4 deregistered
[ 0.821419] ohci-platform: probe of 1c1c400.usb failed with error -75
[ 0.822710] ohci-platform 1c14400.usb: init err (00000000 0000)
[ 0.823681] ohci-platform 1c14400.usb: can't start
[ 0.824342] ohci-platform 1c14400.usb: startup error -75
[ 0.824998] ohci-platform 1c14400.usb: USB bus 3 deregistered
[ 0.825782] ohci-platform: probe of 1c14400.usb failed with error -75
...
Luckily, USB can be enabled for any board (that has support for emulation of USB controller) by passing -usb
when
starting the QEMU emulation. The command to enable USB emulation is
qemu-system-arm \
-M cubieboard \
-m 1G \
-net nic \
-net tap,ifname=qemu-tap0,script=no,downscript=no \
-sd sd.img \
-nographic \
-usb
In the U-Boot and Linux logs we can see that the USB is now recognized.
[ U-Boot log ]
...
starting USB...
Bus usb@1c14000: USB EHCI 1.00
Bus usb@1c14400: USB OHCI 1.0
Bus usb@1c1c000: USB EHCI 1.00
Bus usb@1c1c400: USB OHCI 1.0
scanning bus usb@1c14000 for devices... 1 USB Device(s) found
scanning bus usb@1c14400 for devices... 1 USB Device(s) found
scanning bus usb@1c1c000 for devices... 1 USB Device(s) found
scanning bus usb@1c1c400 for devices... 1 USB Device(s) found
scanning usb for storage devices... 0 Storage Device(s) found
...
Starting kernel ...
...
[ 0.776150] ehci-platform 1c14000.usb: EHCI Host Controller
[ 0.776700] ehci-platform 1c14000.usb: new USB bus registered, assigned bus number 1
[ 0.780998] ehci-platform 1c14000.usb: irq 105, io mem 0x01c14000
[ 0.785543] ehci-platform 1c1c000.usb: EHCI Host Controller
[ 0.786053] ehci-platform 1c1c000.usb: new USB bus registered, assigned bus number 2
[ 0.787271] ohci-platform 1c14400.usb: Generic Platform OHCI controller
[ 0.787815] ohci-platform 1c14400.usb: new USB bus registered, assigned bus number 3
[ 0.789564] ohci-platform 1c1c400.usb: Generic Platform OHCI controller
[ 0.790236] ohci-platform 1c1c400.usb: new USB bus registered, assigned bus number 4
[ 0.792127] ohci-platform 1c14400.usb: irq 107, io mem 0x01c14400
[ 0.793064] ohci-platform 1c1c400.usb: irq 108, io mem 0x01c1c400
[ 0.793743] ehci-platform 1c1c000.usb: irq 106, io mem 0x01c1c000
[ 0.807429] ehci-platform 1c14000.usb: USB 2.0 started, EHCI 1.00
[ 0.812146] hub 1-0:1.0: USB hub found
[ 0.812780] hub 1-0:1.0: 6 ports detected
[ 0.837361] ehci-platform 1c1c000.usb: USB 2.0 started, EHCI 1.00
[ 0.839332] hub 2-0:1.0: USB hub found
[ 0.840711] hub 2-0:1.0: 6 ports detected
[ 0.858951] hub 4-0:1.0: USB hub found
[ 0.859470] hub 4-0:1.0: 3 ports detected
[ 0.861435] hub 3-0:1.0: USB hub found
[ 0.861778] hub 3-0:1.0: 3 ports detected
USB Storage device
The posts so far provided instructions on how to use SD card connected to Cubieboard in QEMU. Sometimes it is useful to use some extra memory storage types, like a USB drive.
If we want to add a USB drive to the QEMU emulated Cubieboard, first we need to create a USB drive image file usb.img
,
as well as partition and format it.
In this example we will create a 1GB USB drive with one FAT32 partition.
# Create a USB drive image
dd if=/dev/zero of=usb.img bs=1M count=1024
# Use sfdisk to partition it (single FAT32 partition)
sfdisk usb.img << EOF
,,c
EOF
Once partition is made, it needs to be formatted. In order to do it, the image should be made available to the system
using kpartx
. Running the kpartx
command with -v
will print the loop mapper partition that is assigned.
sudo kpartx -av ./usb.img
add map loop0p1 (252:0): 0 2095104 linear 7:0 2048
Based on this output, we can format the partition using
sudo mkfs.vfat /dev/mapper/loop0p1
Use the correct path based on the
kpartx
output.
We will also place file test.txt
in the newly created partition, with the following content
Hello from USB drive in QEMU Cubieboard
In order to do it, the partition needs to be mounted. Following code can be used to do it
mkdir -p /tmp/usb
sudo mount /dev/mapper/loop0p1 /tmp/usb
sudo tee /tmp/usb/test.txt << EOF
Hello from USB drive in QEMU Cubieboard
EOF
After the file is created, the partition should be umounted, and image removed from the system
sudo umount /tmp/usb
sudo kpartx -d ./usb.img
The QEMU can now be started with a USB drive attached using
qemu-system-arm \
-M cubieboard \
-m 1G \
-net nic \
-net tap,ifname=qemu-tap0,script=no,downscript=no \
-usb \
-device usb-storage,bus=usb-bus.0,drive=stick \
-drive if=none,id=stick,file=usb.img \
-sd sd.img \
-nographic
U-Boot 2024.01-g (Jan 08 2024 - 15:37:48 +0000) Allwinner Technology
...
starting USB...
Bus usb@1c14000: USB EHCI 1.00
Bus usb@1c14400: USB OHCI 1.0
Bus usb@1c1c000: USB EHCI 1.00
Bus usb@1c1c400: USB OHCI 1.0
scanning bus usb@1c14000 for devices... 2 USB Device(s) found
scanning bus usb@1c14400 for devices... 1 USB Device(s) found
scanning bus usb@1c1c000 for devices... 1 USB Device(s) found
scanning bus usb@1c1c400 for devices... 1 USB Device(s) found
scanning usb for storage devices... 1 Storage Device(s) found
...
[ 1.373968] usb-storage 1-1:1.0: USB Mass Storage device detected
[ 1.375835] scsi host1: usb-storage 1-1:1.0
[ 2.436405] scsi 1:0:0:0: Direct-Access QEMU QEMU HARDDISK 2.5+ PQ: 0 ANSI: 5
[ 2.438455] sd 1:0:0:0: Attached scsi generic sg0 type 0
[ 2.508795] sd 1:0:0:0: [sda] 2097152 512-byte logical blocks: (1.07 GB/1.00 GiB)
[ 2.513932] sd 1:0:0:0: [sda] Write Protect is off
[ 2.521230] sd 1:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[ 2.538341] sda: sda1
[ 2.541121] sd 1:0:0:0: [sda] Attached SCSI disk
...
Kernel should be built with CONFIG_USB_STORAGE option enabled.
After QEMU is started, the USB drive can be mounted using
mkdir -p /tmp/usb
mount /dev/sda1 /tmp/usb
This will provide access to the files and we can confirm that the test.txt
is present with the predefined content.
USB passthrough
USB passthrough is a very interesting feature, where a physical device can be passed from the host to the QEMU system that is being emulated. The passthrough can be done on the VID:PID, or on the explicit USB port on the host.
For example, if a USB drive is attached to the host, the lsusb
output could be
lsusb
Bus 002 Device 002: ID 0781:5597 SanDisk Corp. Cruzer Glide 3.0
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
The VID:PID for the USB drive is 0781:5597, so in order to pass this device to QEMU a following command can be used
qemu-system-arm \
-M cubieboard \
-m 1G \
-net nic \
-net tap,ifname=qemu-tap0,script=no,downscript=no \
-usb \
-device usb-host,vendorid=0x0781,productid=0x5597 \
-sd sd.img \
-nographic
[ 2.033214] usb-storage 2-1:1.0: USB Mass Storage device detected
[ 2.094059] scsi host1: usb-storage 2-1:1.0
[ 3.148767] scsi 1:0:0:0: Direct-Access SanDisk Cruzer Glide 3.0 1.00 PQ: 0 ANSI: 6
[ 3.157951] sd 1:0:0:0: Attached scsi generic sg0 type 0
[ 3.187860] sd 1:0:0:0: [sda] 30605312 512-byte logical blocks: (15.7 GB/14.6 GiB)
[ 3.206973] sd 1:0:0:0: [sda] Write Protect is off
[ 3.224366] sd 1:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
[ 3.455618] sda: sda1
[ 3.503294] sd 1:0:0:0: [sda] Attached SCSI removable disk
Again, the USB drive can be mounted and file test.txt
can be accessed to validate the expected content.
Summary
QEMU has built-in support for USB device emulation, with some of the common classes implemented.
This post provides a short overview of steps needed to enable and use USB for QEMU Cubieboard. Using these commands more features can be added to the emulated system.
These commands are also applicable to other systems that can be emulated in QEMU, which have support for the USB controller.