- Published on
Getting Started with Yocto QEMU on Windows Using WSL
- Authors
- Name
- Mai H. Son (Mason)
Working with Yocto on Windows can be challenging, but thanks to the Windows Subsystem for Linux (WSL), the process has become much more accessible. In this guide, I will walk you through the steps required to set up Yocto QEMU on WSL.
Prerequisites
Before you begin, ensure you have the following prerequisites:
[Optional] A machine with ample RAM and CPU cores. Yocto builds can be resource-intensive, especially for complex projects. A powerful machine will significantly reduce build times. My system has 32 GB of RAM and 20 cores at 4.3 GHz, but even with this setup, builds can be lengthy. For this example, 8 to 16 GB of RAM should suffice.
Windows 10 or later: WSL is available on Windows 10 version 2004 and above.
WSL installed: If you have not installed WSL, run the following command in PowerShell as an administrator:
wsl --install
Ensure WSL is set to use WSL 2. You can verify this by running:
wsl --list --verbose
If your default version is not WSL 2, set it with:
wsl --set-default-version 2
Ubuntu distribution: Install Ubuntu from the Microsoft Store or use any other Linux distribution compatible with Yocto.
Step-by-Step Guide to Setting Up Yocto QEMU on WSL
Install Required Packages
First, open your WSL terminal (Ubuntu) and update the package list:
sudo apt update
sudo apt upgrade -y
sudo apt install -y build-essential git wget diffstat unzip texinfo gcc-multilib \
chrpath socat cpio python3 python3-pip python3-pexpect python3-venv xz-utils debhelper \
libncurses5-dev libssl-dev libelf-dev libxml2-utils bc zstd liblz4-tool
Clone the Simplest Yocto Example
cd ~
git clone [email protected]:bootlin/simplest-yocto-setup.git
The example repository is configured for the BeagleBone Black board. We will reuse this and add QEMU support. In this example, we use the kiss
distribution, a minimal Yocto distribution.
You can connect VS Code to your WSL instance for a more convenient development experience.
Create a Python Virtual Environment
cd simplest-yocto-setup
python3 -m venv venv
source venv/bin/activate
# If you do not have kas installed (required once only):
pip install kas
Add QEMU Support
Edit the .config.yaml
file to change the machine to qemux86
:
header:
version: 11
- machine: dogboneblack
+ machine: qemux86
distro: kiss
target:
- kiss-image
Add the machine configuration for the meta layer:
# Simple QEMU x86 machine configuration for Yocto
# Enables simulation with QEMU using a generic 32-bit x86 target.
# require conf/machine/include/tune-i586.inc
require ../../../openembedded-core/meta/conf/machine/include/x86/tune-i586.inc
MACHINE_FEATURES = "pcbios efi usbhost ext2 vfat"
SERIAL_CONSOLES = "115200;ttyS0"
KERNEL_IMAGETYPE = "bzImage"
# Use the default kernel and bootloader from OE-Core
PREFERRED_PROVIDER_virtual/kernel ?= "linux-yocto"
PREFERRED_PROVIDER_virtual/bootloader ?= "grub-efi"
# Set root device for QEMU
APPEND = "root=/dev/vda rw console=ttyS0"
# Image types
IMAGE_FSTYPES = "wic.gz"
# QEMU binary
QB_SYSTEM_NAME = "qemu-system-i386"
QB_DEFAULT_KERNEL = "bzImage"
QB_DEFAULT_FSTYPE = "wic.gz"
QB_MEM = "512M"
QB_MACHINE = "-machine pc"
QB_CPU = "-cpu qemu32"
QB_OPT_APPEND = "console=ttyS0"
Add the root user to the recipe:
# Build a simple, minimal root filesystem.
#
# This recipe is a simplified form of core-image-minimal.
SUMMARY = "A simple, minimal image"
IMAGE_INSTALL = "packagegroup-core-boot dropbear sl"
IMAGE_LINGUAS = " "
- inherit core-image
+ inherit core-image extrausers
+ # user: root; password: 1234
+ # The hash can be generated with the command `openssl passwd -1 1234 | sed -e 's/[$`"\\]/\\&/g'`. In production, this should be set via the environment.
+ EXTRA_USERS_PARAMS = "usermod -p '\$1\$HYUAtT4V\$egIyAfSQoAveUkttkzJLl0' root;"
Build the Image
You can now build the image using the following commands:
# Use kas to download the required third-party repositories
# (required the first time, or after changes to .config.yaml)
kas checkout
# Set up the build environment
source openembedded-core/oe-init-build-env
# Build the image
bitbake kiss-image
The initial build may take some time, depending on your system's resources.
Run the Image with QEMU
Once the build is complete, you can run the image using QEMU. Ensure QEMU is installed in your WSL environment. If not, install it with:
runqemu qemux86 nographic
You should see the console output in your terminal. Log in with the username root
and the password root
.
INIT: version 3.01 booting
Starting udev
[ 2.885841] udevd[157]: starting version 3.2.10
[ 2.946600] udevd[158]: starting eudev-3.2.10
[ 3.361589] EXT4-fs (vda): re-mounted. Opts: (null). Quota mode: disabled.
INIT: Entering runlevel: 5
Configuring network interfaces... ip: RTNETLINK answers: File exists
Starting Dropbear SSH server: dropbear.
Starting syslogd/klogd: done
Keep-it-simple,stupid Linux 1.0 qemux86 /dev/ttyS0
qemux86 login: root
Password:
root@qemux86:~#
To exit QEMU, use the key combination: Ctrl + A, X.
[Bonus] Add a New Helloworld Recipe
Let's add a simple "Hello World" program from local source files.
# If you are in the build directory, return to the root of the project
pwd # /home/youruser/simplest-yocto-setup
mkdir -p meta-kiss/recipes-example/helloworld/files
Add the following content to each file:
#include <iostream>
int main() {
std::cout << "Hello, world!" << std::endl;
return 0;
}
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SUMMARY = "Simple Hello World C++ application"
LICENSE = "MIT"
# The checksum is calculated from the LICENSE file using the command: md5sum meta-kiss/recipes-example/helloworld/files/LICENSE | awk '{print $1}'
LIC_FILES_CHKSUM = "file://LICENSE;md5=5d584f75c9dac80816984cad5f09d576"
SRC_URI = "file://helloworld.cpp file://LICENSE"
S = "${WORKDIR}"
# Work around QA error due to the over-simplistic Makefile:
INSANE_SKIP:${PN} += "ldflags"
FILES:${PN} += "${datadir}/licenses/helloworld/LICENSE"
do_compile() {
${CXX} helloworld.cpp -o helloworld
}
do_install() {
install -d ${D}${bindir}
install -m 0755 helloworld ${D}${bindir}/
install -d ${D}${datadir}/licenses/helloworld
install -m 0644 ${WORKDIR}/LICENSE ${D}${datadir}/licenses/helloworld/
}
Add the Recipe to the Build
- IMAGE_INSTALL = "packagegroup-core-boot dropbear sl"
+ IMAGE_INSTALL = "packagegroup-core-boot dropbear sl helloworld"
Rebuild the Image
bitbake kiss-image
Run the Image with QEMU Again
qemux86 login: root
Password:
root@qemux86:~# helloworld
Hello, world!
root@qemux86:~#
Voilà! You have successfully set up Yocto QEMU on WSL and created a simple "Hello World" application.