Skip to content

Yocto project layer for Wine cross-development targeting ARM architectures

License

Notifications You must be signed in to change notification settings

rmi1974/meta-winedev

Repository files navigation

meta-winedev

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:

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

System requirements

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

Set up development workspace

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

Host and Target authentication prerequisite

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/

Building target images

Run BitBake to build 64-bit kernel and multilib userland rootfs image:

bitbake $IMAGE

Building Yocto SDK for cross-development

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.

Set up Yocto SDK for use with Wine

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

Flashing build artifacts

If real hardware is used you need to flash the generated artifacts to the target storage (eMMC, SD-card, ...).

Hikey960 board support

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

Run the target and set up Wine

Hikey960 board support

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

QEMU

Run target image with qemu:

runqemu

Login

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 host directories

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

Wine environment

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

Miscellaneous

Validate that virgl is working

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.

Access to QEMU monitor

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) '

LICENSE

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