Introduction:
Raspberry Pi is a very popular development platform based on ARM processors. Recently a fantastic IMU/GPS combo shield was released for such platform by EMLID. While source code of several components is available by their git-hub, additional software components (for example ROS) could be interesting to develop your robotic application… As first step, to get confident with the Raspberry environment, my personal suggestion consists into running the Raspbian (the Raspberry operating system) through an emulator, for example QEMU.
In this article, we are going to show how to download, setup and manage Raspbian images with Ubuntu and QEMU. For your convenience, all the steps are combined into bash scripts. You may download freely and without any warranty.
Because the robotic platform developed by our group is named CalaTronics you may find some reference to this name in the script logs 🙂
1) Downloading the EMLID image of Raspbian: getRTRpi.sh
#!/bin/bash echo "Downloading kernel-qemu" wget http://xecdesign.com/downloads/linux-qemu/kernel-qemu echo "Downloading image" wget http://emlid.com/files/Raspbian-SEP-2014-RT-B+.img.tar.bz2 -c echo "Unzipping image" tar jxvf Raspbian-SEP-2014-RT-B+.img.tar.bz2 echo "Renaming image" mv Raspbian-SEP-2014-RT-B+.img ccrpi.img echo "Cleaning up" rm -f Raspbian-SEP-2014-RT-B+.img.tar.bz2
Once that this file is executed, you should find two new files named ccrpi.img and kernel-qemu.
Note that you may want to adjust some of the links in case are corrupted or updated.
2) Initialize the image by adjusting some of the default params: initrpi.sh
#!/bin/bash echo -en "\ec" echo echo "CalaTronics Init RPi Firmware Manager" echo if [ -z $1 ]; then echo echo "Use initrpi.sh file.img" echo echo " file.img is the RPi image" echo exit fi if [ ! -f $1 ]; then echo "Invalid image file." echo exit fi IMG_DEV="$1" MEMORY="256" echo "Selected Image : ${IMG_DEV}" echo "Login/Password should be pi/raspberry" echo echo "a) /etc/ld.so.preload" echo " comment #/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so" echo echo "b) /etc/udev/rules.d/90-qemu.rules" echo " KERNEL==\"sda\", SYMLINK+=\"mmcblk0\"" echo " KERNEL==\"sda?\", SYMLINK+=\"mmcblk0p%n\"" echo " KERNEL==\"sda2\", SYMLINK+=\"root\"" echo echo "c) /etc/network/interfaces" echo " auto eth0" echo " iface eth0 inet static" echo " address 10.0.0.2" echo " network 10.0.0.0" echo " netmask 255.255.255.0" echo " broadcast 10.0.0.255" echo " gateway 10.0.0.1" echo echo "Running initial" echo sudo qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m ${MEMORY} -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw init=/bin/bash" -hda ${IMG_DEV} echo
All the necessary steps and instructions required to adjust the default parameters will be displayed on the screen. Just do it…
In case you are not familiar with these instructions, we are going to comment out a library link, change some udev options and fix the ethernet address to 10.0.0.2.
3) Manage the images: ccrpi.sh
One important, sometime required, step during development is to make periodic updates. You may consider to develop on your emulator or directly on the Raspberry… it is your choice. But how to keep this two deviced (virtual/real) synchronized?
A possible solution is to run the SD card image of the Raspberry through the emulator. Then each modification will be done on the SD card and the Raspberry will use the fresh image.
Another possibility is to work without SD card and flash it when necessary (for example using dd).
We made a simple script which will provide you all these options: the ccrpi.sh.
#!/bin/bash echo -en "\ec" echo echo "CalaTronics RPi Firmware Manager" echo if [ -z $1 ]; then echo echo "Use ccrpi.sh file.img [/dev/sdX]" echo echo " file.img is the RPi image" echo " /dev/sdX is the (optional) device to perform firmware operations" echo exit fi if [ ! -f $1 ]; then echo "Invalid image file." echo exit fi IMG_DEV="$1" MEMORY="256" HOST_IP="10.0.0.1" HOST_NET="10.0.0.0/8" HOST_PORT="2222" GUEST_PORT="22" GUEST_IP="10.0.0.2" echo "Selected Image : ${IMG_DEV}" if [ -z $2 ]; then echo echo "Pure simulation mode active" echo "Running CalaTronics SD (Firmware) [${HOST_IP}:${HOST_PORT}->${GUEST_IP}:${GUEST_PORT}]" echo sudo qemu-system-arm \ -kernel kernel-qemu -cpu arm1176 -m ${MEMORY} -M versatilepb -no-reboot -serial stdio \ -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" -hda ${IMG_DEV} -net nic -net user,net=${HOST_NET},host=${HOST_IP},hostfwd=tcp:127.0.0.1:${HOST_PORT}-${GUEST_IP}:${GUEST_PORT} exit fi echo "Device: ${SD_CARD} SELECTED" echo "Device: $2" if [[ $2 =~ (/dev/.+) ]]; then echo "Device: $1 PATH OK" else echo "Device: $1 PATH INVALID" echo "Use ccrpi.sh /dev/sdX" exit; fi if [[ $2 =~ .*[^0-9]$ ]]; then echo "Device: $1 DEVICE OK" else echo "Device: $1 DEVICE INVALID" echo "Use ccrpi.sh /dev/sdX" exit; fi SD_CARD="$2" echo echo "Check SD Card: ${SD_CARD}" sudo fdisk -l ${SD_CARD} | grep ${SD_CARD} echo echo "Choosing the wrong HD could cause data loss." echo read -p "Continue (y/n)? " choice case "$choice" in y|Y ) ;; n|N ) echo "If the device is wrong, select a new one." exit;; * ) echo "No option was selected, aborting." exit;; esac echo echo "Select the operation:" echo echo "1) IMG -> SD (Flash)" echo "2) SD -> IMG (Backup)" echo "3) Run IMG (Simulator)" echo "4) Run SD (Firmware)" echo read -p "?> " choice echo case "$choice" in 1 ) if [ -f ${IMG_DEV} ]; then echo "Flashing CalaTronics Firmware" echo echo "> dd bs=1M if=${IMG_DEV} of=${SD_CARD}" sudo dd bs=1M if=${IMG_DEV} of=${SD_CARD} else echo "ERROR: CalaTronics Firmware not available offline (${IMG_DEV})." fi ;; 2 ) echo "Saving CalaTronics Firmware" echo echo "> dd bs=1M if=${SD_CARD} of=${IMG_DEV}" sudo dd bs=1M if=${SD_CARD} of=${IMG_DEV} ;; 3 ) echo "Running CalaTronics IMG (Simulator) [${HOST_IP}:${HOST_PORT}->${GUEST_IP}:${GUEST_PORT}]" echo sudo qemu-system-arm \ -kernel kernel-qemu -cpu arm1176 -m ${MEMORY} -M versatilepb -no-reboot -serial stdio \ -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" -hda ${IMG_DEV} -net nic -net user,net=${HOST_NET},host=${HOST_IP},hostfwd=tcp:127.0.0.1:${HOST_PORT}-${GUEST_IP}:${GUEST_PORT} ;; 4 ) echo "Running CalaTronics SD (Firmware) [${HOST_IP}:${HOST_PORT}->${GUEST_IP}:${GUEST_PORT}]" echo sudo qemu-system-arm \ -kernel kernel-qemu -cpu arm1176 -m ${MEMORY} -M versatilepb -no-reboot -serial stdio \ -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" -hda ${SD_CARD} -net nic -net user,net=${HOST_NET},host=${HOST_IP},hostfwd=tcp:127.0.0.1:${HOST_PORT}-${GUEST_IP}:${GUEST_PORT} ;; * ) echo "No option was selected, aborting." exit;; esac echo
If you already perform an initialization through the previous scripts, you may consider to flash the SD card with the image (you have in your PC).
4) Connecting to the Emulator!
Once you run the image with the simulator (by NOT passing the device option to the ccrpi.sh or by selecting the mode 3/4) you may want to connect to the system using ssh…
#!/bin/bash echo -en "\ec" echo echo "CalaTronics RPi Firmware SSH Connection" echo echo "Login: pi" echo "Password: raspberry" HOST_PORT="2222" echo ssh -lpi 127.0.0.1 -p${HOST_PORT}
Note that the selected SSH host is localhost while the port is 2222. This port forward rule is the result of the ccrpi.sh script options.
5) Enjoy your Raspberry Emulator!
Hope you enjoyed this fantastic journey into emulators, images and bash scripts… Now you are ready for a new challenge… install ROS??