meta-winedev
is a meta layer for OpenEmbedded / Yocto build environments.
This layer provides support to cross-compile and run Wine on different target architectures using the Yocto project's Poky reference distribution.
For an introduction to the Yocto project have a look here:
Compatibility with Yocto releases:
- Dunfell (3.1)
Supported target architectures/platforms:
- ARMv8 QEMU machine with virtio and virgl support using Virgil 3D GPU project
- ARMv8 HiKey960 SoC 96boards.org HiKey960 board support
Features:
- X11/XFCE target image with full 64-bit and 32-bit multi-lib support (aarch64 + armv7)
- Yocto SDK containing GCC 9.x and Clang 10.x toolchains for aarch64 and armv7hf with full 64-bit and 32-bit multi-lib support
Typical disk space usage for multilib/bi-arch image target winedev-image-xfce
, MACHINE=hikey960
- DL_DIR (tarball downloads): 10G
- Yocto build directory including Yocto SDK (cross-toolchain): 236G
- Yocto SDK (cross-toolchain) installed: 25G
Clone Yocto and required layers:
git clone -b dunfell git://git.yoctoproject.org/poky.git
cd poky
git clone -b dunfell git://git.openembedded.org/meta-openembedded.git
git clone -b dunfell https://github.com/rmi1974/meta-winedev.git
git clone -b master git://github.com/kraj/meta-clang.git
Optional HiKey960 Board support:
git clone -b dunfell https://github.com/96boards/meta-96boards.git
# edk2-hikey960 fork requires Python 2.x
git clone -b dunfell git://git.openembedded.org/meta-python2.git
Source one of the scripts to initialize BitBake environment (MACHINE
, DISTRO
and IMAGE
variables):
# for QEMU ARM64
source meta-winedev/scripts/winedev-image-xfce-qemuarm64.env
# for HiKey960 Board
source meta-winedev/scripts/winedev-image-xfce-hikey960.env
NOTE: The above script sources oe-init-build-env
as well.
Register the needed layers within BitBake environment:
bitbake-layers add-layer \
../meta-openembedded/meta-oe \
../meta-openembedded/meta-python \
../meta-openembedded/meta-perl \
../meta-openembedded/meta-multimedia \
../meta-openembedded/meta-filesystems \
../meta-openembedded/meta-networking \
../meta-openembedded/meta-gnome \
../meta-openembedded/meta-xfce \
../meta-winedev \
../meta-clang
Optional HiKey960 Board support:
bitbake-layers add-layer \
../meta-96boards \
../meta-python2
To support SSH-based authentication for automated cross-development, a new key pair has to be generated and embedded in the target image:
Generate the key pair:
ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/winedev
Copy the keys into the meta-winedev
layer at the following location:
mkdir ../meta-winedev/recipes-common/ssh-keys/files/
cp ~/.ssh/winedev* ../meta-winedev/recipes-common/ssh-keys/files/
Run BitBake to build 64-bit kernel and multilib userland rootfs image:
bitbake $IMAGE
Run BitBake to build the Yocto SDK (cross-Canadian toolchain) for host:
bitbake $IMAGE -c populate_sdk
The Yocto SDK toolchain for 32-bit userland will be generated by previous step as well.
Install Yocto SDK cross-toolchain that has been built:
tmp/deploy/sdk/*-$MACHINE-toolchain-*.sh -y
The default installation location is /opt/winedev/
directory.
The SDK installer prints the available cross-toolchain environment scrips after installation.
Source the desired cross-toolchain in the shell environment:
For 64-bit ARM:
source /opt/winedev/*/environment-setup-aarch64*
echo $CC
For 32-bit ARM:
source /opt/winedev/*/environment-setup-armv7*
echo $CC
Start Wine build process using the cross-toolchain environment. Example by using buildwine.py script for building Wine with shared WoW64 support:
./buildwine.py --cross-compile-prefix=$CROSS_COMPILE \
--disable-mingw --enable-clang --clean --force-autoconf
If real hardware is used you need to flash the generated artifacts to the target storage (eMMC, SD-card, ...).
Prepare an SD-Card as follows:
Export some environment vars for convenience in shell as follow-up commands reference it:
export BOOT_PART=/dev/mmcblk0p1
export ROOTFS_PART=/dev/mmcblk0p2
Write boot partition disk (UEFI) image to block device:
sudo dd if=tmp/deploy/images/hikey960/boot-hikey960.uefi.img \
of=$BOOT_PART bs=1M status=progress conv=fdatasync
Write rootfs partition disk (ext4) image to block device:
gunzip < tmp/deploy/images/hikey960/winedev-image-xfce-hikey960.ext4.gz | \
sudo dd of=$ROOTFS_PART bs=1M status=progress conv=fdatasync
or use the rootfs tarball extract method (a bit faster):
# Format the rootfs partition as 'ext4' and label it 'rootfs'
sudo mkfs.ext4 -F -m 0 -L rootfs $ROOTFS_PART
# Mount the target rootfs
udisksctl mount -b $ROOTFS_PART
# Unpack the rootfs tarball contents to mounted fs
# NOTE: You will need 'pv' tool installed with your host distro for progress indicator
ROOTFS_MOUNTPOINT=$(lsblk -nro MOUNTPOINT $ROOTFS_PART)
pv winedev-image-xfce-hikey960.tar.gz | sudo tar xpzf - -C $ROOTFS_MOUNTPOINT
# Unmount the target rootfs
udisksctl unmount -b $ROOTFS_PART
Start the terminal app and power cycle the board.
Make sure the local user is part of dialout
group to access serial devices without root:
sudo usermod -a -G dialout $USER
sudo reboot
picocom /dev/ttyUSB0 -b 115200 -f x
Run target image with qemu:
runqemu
By default, the target login user is the current host user $USER
(password equals username).
The host user $USER
was automatically added during the build step (the user BitBake was running under).
See recipes-core/images/winedev-image-xfce.bb for details.
Add the previously generated SSH host key to the ssh-agent:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/winedev
Now you can login using SSH without password:
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
$USER@192.168.7.2
Mount directories from the host via SSHFS. To ease debugging with Wine (symbols lookup), the user and mapped base path should be the same for host and target.
mkdir projects
sshfs -o StrictHostKeyChecking=no -o idmap=user \
$USER@192.168.7.1:/home/$USER/projects $HOME/projects
Unmount as needed:
fusermount -u projects
Run 64-bit Wine on 64-bit ARM:
export PATH=$HOME/projects/wine/mainline-install-aarch64/bin/:$PATH
# wipe existing prefix
rm -rf ~/.wine
wine64 --version
wineboot
Run 32-bit Wine on 64-bit ARM:
export PATH=$HOME/projects/wine/mainline-install-arm/bin/:$PATH
# wipe existing prefix
rm -rf ~/.wine
wine --version
wineboot
On the target:
dmesg | grep drm
glxgears -info
vblank_mode=0 glxgears
The main bottleneck is QEMU CPU emulation (Intel host <-> ARM64 target) compared to running KVM on real hardware - even with multi-threaded TCG.
QEMU monitor access is configured via UNIX socket. To connect use socat
tool:
socat -,echo=0,icanon=0 unix-connect:qemu-monitor-socket
For scripting:
echo "info status" | socat - unix-connect:qemu-monitor-socket | tail --lines=+2 | grep -v '^(qemu) '
All metadata is MIT licensed unless otherwise stated. Source code included in tree for individual recipes is under the LICENSE stated in each recipe (.bb file) unless otherwise stated.
Links
- OpenEmbedded / Yocto
- Getting Started: The Yocto Project Overview
- Yocto Project Docs Overview: What I Wish I’d Known
- Yocto releases
- Virgil 3D GPU project
- openembedded-core: virglrenderer support for QEMU
- buildwine.py script for building Wine with shared WoW64 support
- 96boards.org HiKey960 board support