# Raspberry PI + cross compile & build kernel * https://www.raspberrypi.com/documentation/computers/linux_kernel.html * recommend: use another micro SD card for this lab! # topic 1. build kernel ## 先準備VM (ubuntu 20, 64bit) * 使用virtualbox + Ubuntu 20 (64bit) * https://releases.ubuntu.com/focal/ubuntu-20.04.6-desktop-amd64.iso * https://ubuntu.cs.nycu.edu.tw/ubuntu-release/20.04.6/ubuntu-20.04.6-desktop-amd64.iso * 官方文件: https://www.raspberrypi.com/documentation/computers/linux_kernel.html#cross-compiling-the-kernel ## virtualbox setting 1. Install VirtualBox Guest Additions ``` sudo apt update sudo apt upgrade sudo apt install build-essential dkms linux-headers-$(uname -r) ``` * 重開機後, 再執行 Insert Guest Additional CD image ![](https://i.imgur.com/0PWndxd.png) ![](https://i.imgur.com/QaZnimE.png) * 裝完之後, 再重開機 ## Dependencies and Toolchain * Install Required Dependencies and Toolchain `sudo apt install git bc bison flex libssl-dev make libc6-dev libncurses5-dev` * Install the 64-bit Toolchain for a 64-bit Kernel `sudo apt install crossbuild-essential-arm64` * Get the Kernel Sources `git clone --depth=1 https://github.com/raspberrypi/linux` * Omitting the --depth=1 will download the entire repository, including the full history of all branches, but this takes much longer and occupies much more storage. ## Load kernel config and build * Load 64-bit default configs (For Raspberry Pi 3, 3+, 4, 400 and Zero 2 W, and Raspberry Pi Compute Modules 3, 3+ and 4:) ``` cd linux KERNEL=kernel8 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig ``` * Build image for all 64-bit Builds with default config * 第一次跑大約要1小時 (看電腦的性能, 我花了77min) ``` make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbs ``` ### Configuring the Kernel by menuconfig * Preparing to make menuconfig ```sudo apt install libncurses5-dev``` * cross-compiling a 64-bit kernel ```make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig``` * Go to “General setup” -> Select “Local version” -> Put your local version (student id number) ![image](https://hackmd.io/_uploads/HJt0CYGgMg.png) * save and exit, then start to build kernel ```make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbs``` * After building, your image locates: arch/arm64/boot/ ## Install the new kernel * 把micro sd卡連接到虛擬機裡面, 系統會自動掛載磁區, 可以用df -h檢查before/after 的變化 * 下圖例子, 是/media/pi/bootfs 與 /media/pi/rootfs ![image](https://hackmd.io/_uploads/rkeYeqGlMl.png) * install the kernel modules onto the SD card ```sudo make PATH=$PATH ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=/media/pi/rootfs modules_install``` * back up old kernel ``` KERNEL=kernel8 sudo cp /media/pi/bootfs/$KERNEL.img /media/pi/bootfs/$KERNEL-backup.img ``` * copy the kernel and Device Tree blobs onto the SD card ``` KERNEL=kernel8 sudo cp arch/arm64/boot/Image /media/pi/bootfs/$KERNEL-new.img sudo cp arch/arm64/boot/dts/broadcom/*.dtb /media/pi/bootfs/ sudo cp arch/arm64/boot/dts/overlays/*.dtb* /media/pi/bootfs/overlays/ ``` * edit the /media/pi/bootfs/config.txt file, add the following setting ```kernel=kernel8-new.img``` * To restore the original kernel, remove the above setting * remove SD card on VM ``` sudo umount /dev/sdX1 sudo umount /dev/sdX2 ``` * Insert SD card to PI and boot!! check your kernel version ```uname -r ``` ![image](https://hackmd.io/_uploads/BJbNr5fgMe.png) --- --- # topic 2. cross compile 0. 準備一個c code ```` #include <stdio.h> int main() { printf("hello, world\n"); return 0; } ```` 1. 建立流程 ```` nano hello.c // write your code gcc hello.c -o hello.o // compile it, the output file is hello.o ./hello.o // execute hello.o ```` 2. Cross compile, then copy it to PI and execute ```` (@VM) aarch64-linux-gnu-gcc hello.c -o hello.arm (@VM) sudo cp hello.arm /media/pi/rootfs/home/pi/ // 複製hello.arm到PI裡面的家目錄 (@PI) chmod +x hello.arm (@PI) ./hello.arm ```` --- --- ## topic 3. cross compile Tensorflow lite for PI * Install docker on Ubuntu (VM) or WSL * WSL = Windows Subsystem for Linux * Target: Raspberry PI4 (bookworm 64bit) + python 3.11 * 編譯時, 會自動下載相關套件, 建議在網路穩定的地方進行 ### download source code ``` git clone https://github.com/tensorflow/tensorflow.git tensorflow_src cd tensorflow_src git checkout v2.15.1 ``` ### 修改Makefile ```nano tensorflow/lite/tools/pip_package/Makefile``` * 修改: BASE_IMAGE ?= ubuntu:20.04 * 調整為: BASE_IMAGE ?= ubuntu:22.04 ![image](https://hackmd.io/_uploads/HJnuXH7efx.png) ### 修改Dockerfile ``` nano tensorflow/lite/tools/pip_package/Dockerfile.py3``` * 新增參數: `ENV DEBIAN_FRONTEND=noninteractive` * 移除舊有cmake安裝指令, 改由apt安裝 ![image](https://hackmd.io/_uploads/SJl4rBmxzg.png) ### 開始cross compile ``` make -C tensorflow/lite/tools/pip_package docker-build \ TENSORFLOW_TARGET=aarch64 PYTHON_VERSION=3.11 ``` ![image](https://hackmd.io/_uploads/BkyaLSQxzx.png) * 編譯完產生的檔案路徑: `tensorflow/tensorflow/lite/tools/pip_package/gen/tflite_pip/python3.11/dist/tflite_runtime-2.15.1-cp311-cp311-linux_aarch64.whl` #### troubleshooting * If you see "Killed signal terminated program cc1plus", it usually means WSL/Docker ran out of memory. Try BUILD_NUM_JOBS=1 or increase WSL memory/swap. ![image](https://hackmd.io/_uploads/Hy5SYHXxzx.png) ### 複製檔案到PI * 如果使用WSL, 可於本機端使用網路芳鄰進入WSL資料夾 `檔案總管路徑: \\wsl$\Ubuntu\root\tensorflow_src ` * 將編譯完的*.whl複製到PI, 然後在新的虛擬環境安裝 ``` python -m venv tflite_vmtest source tflite_vmtest/bin/activate pip install ./tflite_runtime…..whl pip list ``` ![image](https://hackmd.io/_uploads/B1kcwrmlMl.png)