diff --git a/fpga/README.md b/fpga/README.md index 9151782e..306ded76 100644 --- a/fpga/README.md +++ b/fpga/README.md @@ -66,6 +66,14 @@ Linux running on the ARM cores of the ZYNQ. 4. Prepare the SD card and the ZedBoard for booting via SD card. To prepare the card, follow the Xilinx guide [1]. + Alternatively, you can run `make install SD_DEV=/dev/your_sd_card` + in the `fpga/sw` directory. This will automatically partition the + given block device and copy the files of step 5 and 6. If `SD_DEV` + is not given `/dev/mmcblk0` will be used. + After running the script you can inspect the resulting file systems + in `/mnt/pulpino_...`. When done call `make umount` and continue with + step 7. Attention: this removes all `/mnt/pulpino_*` directories. + 5. Copy the BOOT.BIN, uImage and devicetree.dtb files to the first partition of the SD card. Those files can be found inside the `fpga/sw/sd_image` folder. diff --git a/fpga/sw/Makefile b/fpga/sw/Makefile index 80c63a76..3293448d 100644 --- a/fpga/sw/Makefile +++ b/fpga/sw/Makefile @@ -140,3 +140,19 @@ clean: make -C buildroot clean rm -f hsi/pulpemu_top.sysdef rm -f sd_image/* + + +################################################################################ +# SD card handling/installation +################################################################################ +MOUNT_POINT_BASE:=/mnt/pulpino_ +export MOUNT_POINT_BASE + +.PHONY: install +install: + @sudo ./install.sh $(SD_DEV) + +.PHONY: umount +umount: + @sudo umount -Rl "$(MOUNT_POINT_BASE)"* 2>/dev/null || true + @sudo rm -rf "$(MOUNT_POINT_BASE)"*/ diff --git a/fpga/sw/install.sh b/fpga/sw/install.sh new file mode 100755 index 00000000..ebd4e037 --- /dev/null +++ b/fpga/sw/install.sh @@ -0,0 +1,107 @@ +#!/bin/bash +# We need bash for $EUID, =~, arrays and trap ERR +# +# First and only parameter gives the block device to be prepared. +# If not given then /dev/mmcblk0 is used. +# +# The environment variable MOUNT_POINT_BASE can be set to provide +# the path to the base name of the mount point. +# The default is /mnt/pulpino_ + +# Minimum SD card size is 128 MiB +# The script creates a small fixed-sized boot partition and uses the remainder for /. +BOOT_BLOCKS=131072 # 64 MiB + +ROOTTAR="rootfs.tar" +SOURCE_DIR="sd_image/" +BOOTFILES=(BOOT.BIN devicetree.dtb uImage) + +# Check input files +for f in ${BOOTFILES[*]} $ROOTTAR; do + if [ ! -r "${SOURCE_DIR}${f}" ] || [ ! -s "${SOURCE_DIR}${f}" ]; then + echo "\"${SOURCE_DIR}${f}\" is missing/not readable/empty.">&2 + exit 1 + fi +done + +# Sanity check for block device +sd_dev="${1:-/dev/mmcblk0}" +if [ ! -b "$sd_dev" ]; then + echo "Path \"$sd_dev\" does not point to a block device.">&2 + exit 1 +fi + +# Check size of target +minsize=$((2*${BOOT_BLOCKS})) +if [ $(blockdev --getsz "${sd_dev}") -lt $minsize ]; then + echo "${sd_dev} is too small. Where did you find such a small card!?">&2 + exit 1 +fi + +# Let the user confirm +echo "This will re-partition \"$sd_dev\" and void all data on it." +read -r -p "Are you sure? [y/N] " rep +if [ "$rep" != "y" ]; then + echo "Aborted.">&2 + exit 1 +fi + +# Test for root rights +if [ $EUID -ne 0 ]; then + echo "This script must be run as root.">&2 + exit 1 +fi + +# Set up clean up hooks +return_value=0 +cleanup () { + rm -f "$sfdisk_file" + exit $return_value +} +bailout () { + local cmd="$BASH_COMMAND" rc=$? + echo "Command \"$cmd\" exited with code \"$rc\".">&2 + return_value=1 + cleanup +} +trap bailout ERR SIGINT SIGTERM +trap cleanup EXIT + +# Cleanup old partitions +oldparts=( $(lsblk -po KNAME -n "${sd_dev}" | grep -v "^${sd_dev}$" || true) ) +for p in ${oldparts[*]} ; do + umount "$p" 2>/dev/null || true + wipefs -a "$p" >/dev/null 2>&1 || true +done +wipefs -a "${sd_dev}" >/dev/null 2>&1 || true + +# Create temporary files and directories +sfdisk_file="$(mktemp pulpino_sfdisk_XXX)" +rootdir="$(mktemp -d ${MOUNT_POINT_BASE:-/mnt/pulpino_}XXX)" +bootdir="$(mktemp -d ${MOUNT_POINT_BASE:-/mnt/pulpino_}XXX)" + +# Partition, format and mount target partitions +cat >"$sfdisk_file" </dev/null +mkfs.ext4 -q -F -L root -E nodiscard "${parts[1]}" +mount "${parts[1]}" "${rootdir}" +mount "${parts[0]}" "${bootdir}" + +# Copy files to target +for f in ${BOOTFILES[*]} ; do + cp --preserve=timestamps "${SOURCE_DIR}${f}" "${bootdir}" +done +tar --one-top-level="${rootdir}" -xf "${SOURCE_DIR}${ROOTTAR}" +sync -f "${rootdir}/bin" "${bootdir}/${BOOTFILES[0]}" + +echo "Done. Check out ${bootdir} (boot) and ${rootdir} (root)." +echo "Execute \"make umount\" before removing the card."