Guide: Embedded Linux Development in WSL for BeagleY-AI (BYAI)

Installing WSL

Steps taken from MS guide.

  • Open MS PowerShell as administrator
    wsl --install

Installing Debian 11.x or 12.x in WSL

Using the contents of a Debian docker image, create a new WSL install for Debian. Steps taken from MS guide.

Steps for creating TAR file (optional)

You do not need to do these steps if you are able to download a TAR file for your chosen distro. Steps taken from this guide.

  1. Have a Linux distro installed for WSL2.
  2. Install Docker Desktop under Windows, enable WSL integration:
    • Docker > Settings > Docker Engine > Use the WSL 2 based engine
    • Docker > Settings > Resources > WSL Integration > Enabled > select distro.
  3. Launch WSL2's bash
  4. Start the container of interest (may fail, but that's OK)
    docker run -t debian:bullseye bash ls /
    (OK if it gives an error: "/bin/ls: /bin/ls: cannot execute binary file")
  5. Get container ID
    dockerContainerID=$(docker container ls -a | grep -i debian | awk '{print $1}')
    echo $dockerContainerID
  6. Export container to TAR file on C drive:
    docker export $dockerContainerID > /mnt/c/t/debian-bullseye.tar


Import TAR file into WSL

  1. In PowerShell:
    • Create a folder for WSL distro location
      mkdir c:\wslDistroStorage\debian-bullseye
    • Import TAR file (examples use c:\t, but you can use any folder):
      cd c:\t
      wsl --import Debian-Bullseye c:\wslDistroStorage\debian-bullseye .\debian-bullseye.tar
    • Run new distro
      wsl -d Debian-Bullseye
    • Verify correct distro:
      cat /etc/os-release
  2. Update and install sudo and other necessary packages:
    apt update
    apt upgrade
    apt install sudo usbutils lshw iproute2 iputils-ping ssh iptables
    (Critical: ensure you install sudo!)
  3. Setup default user in the newly installed Debian-Bullseye WSL distro:
    • Add new user; add to the sudo group; and set as default WSL user (change to your first name, all lower case, no spaces)
      (choose a password you'll remember; defaults for the rest OK)
      myUsername=yournamehere
      adduser $myUsername
      usermod -aG sudo $myUsername
      echo -e "[user]\ndefault=$myUsername" >> /etc/wsl.conf
  4. Close all WSL instances, set default distro, and restart. In PowerShell:
    wsl --terminate Debian-Bullseye
    wsl --set-default Debian-Bullseye
    wsl
    It should log you in as your new user.
  5. Verify running correct distro:
    cat /etc/os-release

Troubleshooting

  • If something goes wrong, you can remove the WSL distro from PowerShell:
    wsl --unregister Debian-Bullseye

Mapping USB Device to WSL

We must first tell WSL to allow our USB devices to bind to WSL. Then we can tell WSL to take control of the device (attach).

Bind USB Devices to WSL (Once)

Steps drawn from this guide.

  1. Install latest version via its .msi file from usbipd-win project
  2. Connect the BYAI to your computer; allow target to boot (Windows will detect it as a USB device).
  3. Open PowerShell as administrator
  4. Find the USB "BUS ID" for the BYAI:
    usbipd list
    For example:
                    BUS ID    VID:PID    Description
        BYAI:       4-3       1d6b:0104  Remote NDIS Compatible Device, #10, CDC NCM, USB Serial Device...

    Note the "BUS ID" for your BYAI.

  5. Bind BYAI to be shared with WSL:
    usbipd bind --busid 4-3
  6. Verify it now shows as Shared:
    usbipd list

Connect USB Devices to WSL (each time)

  1. Open PowerShell
  2. Find BUS ID for BYAI ("Remote NDIS Compatible Device...")
    usbipd list
    If desired devices show as "Not shared" go back to Bind USB Devices to WSL If desired devices show as "Shared", then attach the USB devices to WSL:
    usbipd attach --wsl --busid 4-3
    usbipd list
    If desired devices show as "Attached", continue to next step.
  3. In WSL, check if USB devices correctly connected:
    • View USB devices:
      lsusb
      (part of usbutils package) should show:
      Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
      Bus 001 Device 002: ID 1d6b:0104 Linux Foundation Multifunction Composite Gadget
      Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    • If any issues, run dmesg.
  4. (Optional) When you want to attach the devices back to Windows, run the following from PowerShell:
    usbipd detatch --busid 4-3

Networking BYAI inside WSL (each time)

  1. Attaching BYAI to WSL, as described above, and launch WSL.
  2. Find the Ethernet adapter for the BYAI:
    sudo lshw -class network
    (shows "Disabled")
  3. Enable device and check status:
    sudo ip link set dev eth1 up
    sudo lshw -class network
    (now does not show disabled)
  4. Manually set IP address for device (note it's 192.168.6.1, not 192.168.7.1)
    sudo ip addr add 192.168.6.1/24 dev eth1
  5. Check connection to target:
    ping 192.168.6.2
    ssh debian@192.168.6.2
  6. Setup internet forwarding between target and WSL Debian
    • Switch WSL Debian to using IP Tables in "legacy" mode:
      sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
    • Setup WSL Debian to route the internet to the target (eth0 connects to the internet; eth1 connects to BYAI):
      sudo iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE
      sudo iptables --append FORWARD --in-interface eth1 -j ACCEPT
      echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
  7. SSH into target and enable internet forwarding to host (WSL):
    sudo route add default gw 192.168.6.1
    ping 8.8.8.8
    • See the networking guide for setting up a nameserver to access google.ca, etc.

NFS Server in WSL

Steps largely based on the NFS guide, plus some ideas from this video:

  1. Create shared folder:
    mkdir -p ~/cmpt433/public
    chmod a+rwx ~/cmpt433/public
  2. Install NFS server:
    sudo apt install portmap nfs-kernel-server
  3. Export the folder for NFS (overwrites any values in /etc/exports):
    echo "/home/$USER/cmpt433/public 192.168.6.0/255.255.255.0(rw,sync,no_subtree_check)" | sudo tee /etc/exports
    sudo exportfs -rav
  4. Start the NFS services (MUST BE DONE EACH BOOT OF THE HOST):
    sudo mkdir -p /run/sendsigs.omit.d
    sudo touch /run/sendsigs.omit.d/rpcbind
    sudo service rpcbind start
    sudo service nfs-kernel-server start
  5. SSH into the target and run:
    sudo mkdir -p /mnt/remote
    sudo chown debian /mnt/remote
    sudo mount -t nfs 192.168.6.1:/home/brian/cmpt433/public /mnt/remote

VS Code to WSL

  1. Run WSL and checkout code into WSL via git. If connecting to SFU's GitHub server, suggest using HTTPS.
  2. Install necessary tools (see Quick Start Guide for details):
    sudo apt install gcc make cmake gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu
  3. Install VS Code into Windows.
  4. Install the "WSL" extension.
  5. Connect to WSL and open a project:
    • Click green "><" button in bottom left.
    • Select "Connect to WSL using Distro..."; select "Debian-Bullseye"
    • Click "Open Folder", and select your folder that is inside WSL.
  6. Install additional extensions into VS Code now that it's connected to WSL:
    • C/C++ Extension Pack
  7. In VS Code, build your project as normal. If running CMake or Makefiles, it may deploy binary to the ~/cmpt433/public folder and therefore be accessible on the target.
  8. Run your code:
    • Open a separate WSL terminal, SSH to the target, mount the NFS folder, and run it.
    • Or, open a WSL terminal within VS Code: Terminal > New Terminal, and run as normal.
  9. Debugging works identically to when using a VM. Note that the IP address of the target/host is now 192.168.6.1 or .2

Browsing to BYAI -- Graphical Linux App in WSL

Use this process to launch a graphical web browser to view a page hosted on the BYAI while connected to WSL.

  1. Launch WSL
    wsl
  2. Install firefox inside WSL
    sudo apt install firefox-esr # The "Extended Support Release"
  3. Launch firefox from within WSL, opening your BYAI at address 192.168.6.2 (port 8088)
    firefox 192.168.6.2:8088 &

Other useful Linux apps to install:

  • Graphical file browser
    sudo apt install nemo
    nemo
  • Gnome-terminal

    sudo apt install dconf-cli dbus-x11 locales gnome-terminal
    
    # Reinstalling terminal
    dconf reset -f /org/gnome/terminal
    sudo apt-get remove gnome-terminal
    sudo apt-get install gnome-terminal
    
    # Reconfiguring locale
    sudo locale-gen --purge
    sudo dpkg-reconfigure locales     # Select en_US.UTF-8 (opt 158?), and then set as default language (opt 3)
    
    # Exit WSL and shut it down
    exit
    wsl --shutdown   # Run in Powershell
    
    # Reload WSL and run
    gnome-terminal

(Optional) Connect to a USB Serial via Screen

  1. Attaching USB serial port to WSL, as described above, and launch WSL.
  2. Install and run screen:
    sudo apt install screen
    sudo screen /dev/ttyUSB0 115200
  3. To close screen press CTRL + A then press \. Then type 'y'.