#!/usr/bin/env sh # MIT License, Copyright (c) 2021 Marvin Borner set -e cd "$(dirname "$0")" MAKE=make NPROC=nproc SUDO=sudo TAGS=ctags mode="${1}" no_ask="${2}" build_cross() { if [ ! -d "./cross/" ]; then if [ "$no_ask" != "-y" ]; then echo -n "Do you want to compile a cross compiler (this can take around 20 minutes)? [yn] " read -r answer if ! [ "$answer" != "${answer#[Yy]}" ]; then echo "The compilation of SegelBoot requires a cross compiler!" exit 1 fi fi # Create directory mkdir -p cross cd cross DIR=$(pwd) # Get sources mkdir "${DIR}/src" && cd "${DIR}/src" echo "Downloading..." curl "https://ftp.gnu.org/gnu/binutils/binutils-2.36.1.tar.gz" >binutils.tar.gz tar xzf binutils.tar.gz curl "https://ftp.gnu.org/gnu/gcc/gcc-11.1.0/gcc-11.1.0.tar.gz" >gcc.tar.gz tar xzf gcc.tar.gz # Prepare compiling mkdir -p "${DIR}/opt/bin" export PREFIX="${DIR}/opt" export TARGET=i686-elf export PATH="$PREFIX/bin:$PATH" # Compile binutils mkdir "${DIR}/src/build-binutils" && cd "${DIR}/src/build-binutils" ../binutils-2.36.1/configure --target="$TARGET" --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror $MAKE -j $($NPROC) $MAKE install # Compile GCC mkdir "${DIR}/src/build-gcc" && cd "${DIR}/src/build-gcc" ../gcc-11.1.0/configure --target="$TARGET" --prefix="$PREFIX" --disable-nls --enable-languages=c --without-headers $MAKE -j $($NPROC) all-gcc all-target-libgcc $MAKE install-gcc install-target-libgcc # Remove sources rm -rf "${DIR}/src/" cd "${DIR}/.." fi } # Generate configs for better development experience generate() { ctags -R --exclude=.git --exclude=build --exclude=cross . # Compile commands for ALE in Vim make --always-make --dry-run | grep -wE 'gcc|g\+\+' | grep -w '\-c' | jq -nR '[inputs|{directory:".", command:., file: match(" [^ ]+$").string[1:]}]' \ >compile_commands.json } build() { mkdir -p build/ # Build printf "\nBuilding...\n" $MAKE -j $($NPROC) # Create disk image dd if=/dev/zero of=build/disk.img bs=1k count=32k status=none DEV=$($SUDO losetup --find --partscan --show build/disk.img) PART="p1" $SUDO parted -s "$DEV" mklabel msdos mkpart primary ext2 32k 100% -a minimal set 1 boot on $SUDO mke2fs -b 1024 -q "$DEV$PART" # Write bootsector but jump over partition table (at 440 to 510) $SUDO dd if=build/boot.bin of="$DEV" bs=1 count=440 conv=notrunc status=none $SUDO dd if=build/boot.bin of="$DEV" bs=1 skip=510 seek=510 conv=notrunc status=none # Mount disk and copy files mkdir -p mnt/ $SUDO mount "$DEV$PART" mnt/ $SUDO mkdir -p mnt/boot/ $SUDO cp example/segelboot.cfg mnt/boot/ $SUDO cp build/examples/* mnt/boot/ #$SUDO cp -r "$HOME"/code/melvix/disk/* mnt/ || true #$SUDO cp -r "$HOME"/code/melvix/build/apps/ mnt/apps/ || true $SUDO umount mnt/ || (sync && $SUDO umount mnt/) rm -rf mnt/ $SUDO losetup -d "$DEV" } emulate() { qemu-system-i386 -enable-kvm -d guest_errors -cpu max -serial stdio -m 256M -vga std -drive file=build/disk.img,format=raw,index=1,media=disk } # Always generate updated configurations generate if [ "${mode}" = "cross" ]; then build_cross elif [ "${mode}" = "build" ]; then build_cross $MAKE clean build else build_cross $MAKE clean build emulate fi