diff --git a/.gitignore b/.gitignore index 496ee2c..2f096d7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,10 @@ -.DS_Store \ No newline at end of file +.DS_Store +raspberrypi/kernel-qemu +raspberrypi/raspios_lite_armhf +raspberrypi/raspios_lite_armhf.img +raspberrypi/raspios_lite_armhf.qcow2 +raspberrypi/raspios_lite_armhf.img.xz +raspberrypi/raspios_lite_armhf.xz +raspberrypi/versatile-pb.dtb +raspberrypi/kernel.img +raspberrypi/bcm2708-rpi-zero-w.dtb diff --git a/raspberrypi/Makefile b/raspberrypi/Makefile new file mode 100644 index 0000000..0353e01 --- /dev/null +++ b/raspberrypi/Makefile @@ -0,0 +1,109 @@ +SHELL := /bin/bash + +# Variables +IMAGE_URL = https://downloads.raspberrypi.org/raspios_lite_armhf_latest +IMAGE_NAME = raspios_lite_armhf +IMAGE_EXT = .img +KERNEL_URL = https://github.com/raspberrypi/firmware/raw/master/boot/kernel.img +KERNEL_NAME = kernel.img +DTB_URL = https://github.com/raspberrypi/firmware/raw/master/boot/bcm2708-rpi-zero-w.dtb +DTB_NAME = bcm2708-rpi-zero-w.dtb +PLAYBOOK = playbook.yml + +.PHONY: all +all: check-dependencies download-image extract-image resize-image download-kernel download-dtb boot-qemu run-playbook ## Run all steps + +.PHONY: check-dependencies +check-dependencies: ## Check required dependencies + @command -v qemu-system-arm > /dev/null 2>&1 || { echo >&2 "QEMU is not installed. Aborting."; exit 1; } + @command -v xz > /dev/null 2>&1 || { echo >&2 "Xz is not installed. Aborting."; exit 1; } + @command -v wget > /dev/null 2>&1 || { echo >&2 "Wget is not installed. Aborting."; exit 1; } + @command -v ansible-playbook > /dev/null 2>&1 || { echo >&2 "Ansible-playbook is not installed. Aborting."; exit 1; } + +.PHONY: download-image +download-image: ## Download Raspberry Pi OS image + @if [ ! -f $(IMAGE_NAME)$(IMAGE_EXT) ]; then \ + echo "Downloading Raspberry Pi OS image..."; \ + wget $(IMAGE_URL) -O $(IMAGE_NAME)$(IMAGE_EXT).xz; \ + fi + +.PHONY: extract-image +extract-image: ## Extract the downloaded image + @if [ ! -f $(IMAGE_NAME)$(IMAGE_EXT) ]; then \ + echo "Extracting Raspberry Pi OS image..."; \ + xz -v -d -k -f $(IMAGE_NAME)$(IMAGE_EXT).xz; \ + fi + +.PHONY: resize-image +resize-image: ## Resize the image + @echo "Resizing the Raspberry Pi OS image..." + @qemu-img resize -f raw $(IMAGE_NAME).img 4096M + +.PHONY: download-kernel +download-kernel: ## Download a compatible kernel for QEMU + @if [ ! -f $(KERNEL_NAME) ]; then \ + echo "Downloading Raspberry Pi OS kernel..."; \ + wget $(KERNEL_URL) -O $(KERNEL_NAME); \ + fi + +.PHONY: download-dtb +download-dtb: ## Download the compatible Device Tree Blob (DTB) + @if [ ! -f $(DTB_NAME) ]; then \ + echo "Downloading Raspberry Pi OS dtb..."; \ + wget $(DTB_URL) -O $(DTB_NAME); \ + fi + +.PHONY: mount-image +mount-image: ## Mount the Raspberry Pi OS image + @echo "Mounting the Raspberry Pi OS image..." + @sudo mkdir -p /mnt/rpi + @sudo mount -o loop,offset=272629760 $(IMAGE_NAME).img /mnt/rpi + +.PHONY: unmount-image +unmount-image: ## Unmount the Raspberry Pi OS image + @echo "Unmounting the Raspberry Pi OS image..." + @if mountpoint -q /mnt/rpi; then \ + sudo umount /mnt/rpi; \ + fi + @sudo rmdir /mnt/rpi + + +.PHONY: copy-scripts +copy-scripts: mount-image ## Copy the setup and optimization scripts to the image + @echo "Copying setup and optimization scripts to the image..." + @sudo cp setup.sh /mnt/rpi/root/ + @sudo cp optimize_boot.sh /mnt/rpi/root/ + @echo "Attempting to enable SSH" + @sudo touch /mnt/rpi/boot/ssh + @echo '#!/bin/bash' | sudo tee /mnt/rpi/etc/init.d/boot-start.sh + @echo 'date +%s > /boot/start.txt' | sudo tee -a /mnt/rpi/etc/init.d/boot-start.sh + @echo '#!/bin/bash' | sudo tee /mnt/rpi/etc/init.d/boot-end.sh + @echo 'date +%s > /boot/end.txt' | sudo tee -a /mnt/rpi/etc/init.d/boot-end.sh + @sudo chmod +x /mnt/rpi/etc/init.d/boot-start.sh + @sudo chmod +x /mnt/rpi/etc/init.d/boot-end.sh + @if [ ! -L /mnt/rpi/etc/rcS.d/S01boot-start.sh ]; then \ + sudo ln -s ../init.d/boot-start.sh /mnt/rpi/etc/rcS.d/S01boot-start.sh; \ + fi + @if [ ! -L /mnt/rpi/etc/rc6.d/S99boot-end.sh ]; then \ + sudo ln -s ../init.d/boot-end.sh /mnt/rpi/etc/rc6.d/S99boot-end.sh; \ + fi + @echo "Disabling Raspberry Pi OS setup wizard..." + @if [ -f /mnt/rpi/etc/xdg/autostart/piwiz.desktop ]; then \ + sudo rm /mnt/rpi/etc/xdg/autostart/piwiz.desktop; \ + fi + @make unmount-image + + +.PHONY: boot-qemu +boot-qemu: copy-scripts ## Boot the image in QEMU + @echo "Booting Raspberry Pi OS in QEMU..." + @qemu-system-arm -machine raspi0 -kernel $(KERNEL_NAME) -dtb $(DTB_NAME) -netdev user,id=net0,hostfwd=tcp::5022-:22 -device usb-net,netdev=net0 -no-reboot -append "earlycon=pl011,0x20201000 console=ttyAMA0,115200 dwc_otg.fiq_fsm_enable=0 dwc_otg.fiq_enable=0 dwc_otg.nak_holdoff=0 root=/dev/mmcblk0p2 initcall_blacklist=bcm2835_pm_driver_init arm_boost=1 rootwait" -drive "file=$(IMAGE_NAME).img,format=raw,index=0,media=disk" + +.PHONY: run-playbook +run-playbook: ## Run the Ansible playbook + @echo "Running the Ansible playbook..." + @ansible-playbook $(PLAYBOOK) + +.PHONY: help +help: ## Display this help + @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) \ No newline at end of file diff --git a/raspberrypi/playbook.yml b/raspberrypi/playbook.yml new file mode 100644 index 0000000..7545610 --- /dev/null +++ b/raspberrypi/playbook.yml @@ -0,0 +1,15 @@ +- hosts: raspi + gather_facts: no + vars: + ansible_user: pi + ansible_password: raspberry + ansible_port: 5022 + ansible_host: localhost + ansible_become: yes + ansible_become_method: sudo + tasks: + - name: Update and install raspberrypi-kernel + apt: + update_cache: yes + pkg: + - raspberrypi-kernel