This page describes how to setup a VirtualBox to be used for cross-compilation and how to initialise the Raspberry Pi (RPi). A VirtualBox is used to ensure we can experiment with compilation and installation of the necessary tools without pushing or messing up our main system to an unfixable state.
Both the Raspberry Pi (RPi) and VirtualBox (aka “Cross-Compile Server” or XCS) will be configured to run headless, that is, without graphical interface (GUI). The XCS will be configured with a shared folder so you can develop your code in any program on your main machine, while able to cross-compile it in a controlled setup.
Throughout this guide the following prefixes for commands are used:
HOST~$
commands executed on the Host, our main system.XCS~$
commands executed on the Cross-Compilation Server / VirtualBox.RPI~$
commands executed on the Raspberry PiWhen running ROS2 20.04 is required.
Exact value depends on your system capabilities. My Host contains 8 CPU’s, hence 2 can be used for the XCS
This rule will be used to connect to the XCS via SSH from the Host
My Host does not support the USB2 controller.
The same username and password as in a default Raspbian setup are used to simplify this guide.
You can pretty much leave all options to the default setting.
After installation, update XCS (if omitted during installation)
XCS~$ sudo apt-get update
XCS~$ sudo apt-get dist-upgrade
Install SSH-server (if omitted during installation)
XCS~$ sudo apt-get install openssh-server
After reboot of the XCS, you should be able to connect to it from the Host via SSH on port 2222 :
HOST~$ ssh -p 2222 pi@localhost
or, when using X-server:
HOST~$ ssh -X -p 2222 pi@localhost
For use of X-server ensure that
X11Forwarding yes
in/etc/ssh/sshd_config
in the XCS is configured and thatForwardX11 yes
is set in~/.ssh/config
on the Host. When changed, restart ssh:sudo service ssh restart
.
To eliminate the need for entering your password each time you open a shell to connect to XCS, we can automate the login process with the use of ssh-keys. On your Host, generate the ssh-keys:
HOST~$ cd ~/.ssh
HOST~$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/XXX/.ssh/id_rsa): xcs_rpi_rsa
Enter passphrase (empty for no passphrase): <empty>
Enter same passphrase again: <empty>
Your identification has been saved in xcs_rpi_rsa.
Your public key has been saved in xcs_rpi_rsa.pub.
...
Optionally you can choose a different rsa-name (required if you are planning to use multiple keys for different systems) and set a passphrase (increasing security). In my setup I left the passphrase empty (just hitting enter).
Set correct permissions of the key-set
HOST~$ chmod 700 xcs_rpi_rsa xcs_rpi_rsa.pub
Send a copy of the public key to the XCS so the XCS can verify the automated connection upon request.
HOST~$ cat ~/.ssh/xcs_rpi_rsa.pub | ssh -p 2222 pi@localhost "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
Setup ssh connection in ssh_config
so we can login by only using a reference (e.g xcs-rpi
)
HOST~$ sudo nano ~/.ssh/config
Add the following lines:
# connect to XCS-rpi via hostname
Host xcs-rpi
HostName localhost
IdentityFile ~/.ssh/xcs_rpi_rsa
User pi
Port 2222
For Windows users the location should be
C:\Users\username\.ssh
or%USERPROFILE%\.ssh
Test connection:
HOST~$ ssh xcs-rpi
You should now be logged in onto the XCS via SSH, without entering your password. Type exit
to terminate connection.
XCS-rpi
Install required packages
XCS~$ sudo apt-get install make gcc linux-headers-$(uname -r)
Install the additions
XCS~$ sudo mkdir -p /media/cdrom
XCS~$ sudo mount /dev/cdrom /media/cdrom
XCS~$ sudo /media/cdrom/VBoxLinuxAdditions.run
XCS~$ sudo adduser pi vboxsf
<FolderName>
You can use any name, but note that you need to remember it to setup a symbolic link later on.
Reboot XCS to mount shared folder
XCS~$ sudo reboot now
Create link to home-folder so we can access our (user-)code easily.
XCS~$ ln -s /media/sf_<FolderName> /home/pi/<FolderName>
the XCS should be turned off before you can execute this command successfully.
HOST~$ VBoxManage modifyvm "XCS-rpi" --natdnshostresolver1 on
In Ubuntu versions > 16.04 we need to set the name-server address manually to the VirtualBox DNS ip (10.0.2.3
) to ensure the DNS will be picked up properly.
XCS~$ sudo apt-get install resolvconf
XCS~$ sudo nano /etc/resolvconf/resolv.conf.d/head
Update the name-server:
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "systemd-resolve --status" to see details about the actual nameservers.
nameserver 10.0.2.3
Now that we have SSH-access to the XCS, booting and powering down from the Host-shell would allow us to skip almost all (mouse)handling of VirtualBox (and the activation of extra windows). To do so, we add some aliases to .bashrc
on the Host:
HOST~: sudo nano ~/.bashrc
Add the following lines:
# XCS-Management
alias xcs-rpi-start='VBoxManage startvm XCS-rpi --type headless'
alias xcs-rpi-stop='VBoxManage controlvm XCS-rpi poweroff'
As .bashrc
is only activated when opening a new shell, so we need to do a reload:
HOST~: source ~/.bashrc
You can now start the XCS with xcs-rpi-start
:
HOST~: xcs-rpi-start
Waiting for VM "XCS-rpi" to power on...
VM "XCS-rpi" has been successfully started.
And stop with xcs-rpi-stop
:
HOST~: xcs-rpi-stop
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
In our setup several folders will be used for different purposes. To keep the setup as generic as possible, these folder-references will be set in environment-variables so you can customise them to your need.
Edit .bashrc
on the XCS:
XCS~: sudo nano ~/.bashrc
Add the following lines:
# Base directory of the rpi-setup. It contains all cross-compile dependencies,
# toolchains, examples, scripts, source&build directories, git-repos, etc
export XC_RPI_BASE=$HOME/rpi
# ROOTFS of the RPi on the XCS.
export XC_RPI_ROOTFS=$XC_RPI_BASE/rootfs
# Folder at which we mount de SDCard.
export XC_RPI_MNT=$XC_RPI_BASE/mnt
# Contains img-files for backup and the downloaded raspbian.
export XC_RPI_IMG=$XC_RPI_BASE/img
# Where we download the source-code of libraries which we want to build.
export XC_RPI_SRC=$XC_RPI_BASE/src
# Here we build our own code.
export XC_RPI_BUILD=$XC_RPI_BASE/build
You can change the directories as you wish, however, using the home-dir shortcut (
~/
) will not not work. So make sure that you either use full, absolute paths, or the$HOME
reference.
As .bashrc
is only activated when opening a new shell, so we need to do a reload:
XCS~: source ~/.bashrc
Lets create al folders:
XCS~: mkdir -p $XC_RPI_ROOTFS $XC_RPI_MNT $XC_RPI_IMG $XC_RPI_SRC $XC_RPI_BUILD $XC_RPI_GUIDE
Source: https://www.raspberrypi.org/documentation/installation/installing-images/linux.md
Download and Unzip the latest Raspbian Lite
XCS~$ cd $XC_RPI_IMG
XCS~$ wget wget https://downloads.raspberrypi.org/raspios_lite_armhf_latest
XCS~$ sudo apt-get install unzip
XCS~$ unzip raspios_lite_armhf_latest
This download is the Lite version of raspbian and hence does not include a GUI or commonly used application. If a GUI is required, you can add it later via
apt-get
or download a different raspios version.
VBoxManage
:
HOST~$ VBoxManage controlvm XCS-rpi usbattach 6f73773c-5558-4e06-8de5-d7fdb74b43bf ```
Detect SDCard
XCS~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 25G 0 disk
├─sda1 8:1 0 487M 0 part /boot
├─sda2 8:2 0 1K 0 part
└─sda5 8:5 0 24.5G 0 part
├─XCS--rpi--vg-root 252:0 0 20.5G 0 lvm /
└─XCS--rpi--vg-swap_1 252:1 0 4G 0 lvm [SWAP]
sdb 8:16 1 7.3G 0 disk <=== Our SDCard!
├─sdb1 8:17 1 63M 0 part
└─sdb2 8:18 1 7.3G 0 part
sr0 11:0 1 55.7M 0 rom
Install Raspbian (this might take a while..)
XCS~$ sudo dd bs=4M if=$XC_RPI_IMG/2021-10-30-raspios-bullseye-armhf-lite.img of=/dev/sdb
[sudo] password for pi:
441+0 records in
441+0 records out
1849688064 bytes (1.8 GB, 1.7 GiB) copied, 71.1205 s, 26.0 MB/s
OPTIONAL: Validate that the image is properly copied
XCS~$ sudo dd bs=4M if=/dev/sdb of=from-sd-card.img
XCS~$ sudo truncate --reference 2021-10-30-raspios-bullseye-armhf-lite.img from-sd-card.img
XCS~$ sudo diff -s from-sd-card.img 2021-10-30-raspios-bullseye-armhf-lite.img
Files from-sd-card.img and 2021-10-30-raspios-bullseye-armhf-lite.imgg are identical
Remove images, we do not need these anymore
XCS~$ sudo rm *.img
Having installed the basic components, lets configure the network/ssh settings of our RPi!