#!/bin/bash # Build planck linux system and generate ISO # Version: 0.0.1 # (C) Chris Dorman, 2020-2021 - GPLv3+ workdir=`pwd` rootdir="/planck" corecount=25 # endtag used for iso filename, and some rootfs configs endtag=`date +"%Y%m%d-%H%M"` # Echo colors NORMAL="\e[0m" RED="\e[0;31m" GREEN="\e[0;32m" BLUE="\e[0;34m" YELLOW="\e[1;33m" MAGENTA="\e[0;35m" CYAN="\e[0;36m" # function to check if errors occurred status() { local CHECK=$? echo -en "\033[68G" if [ $CHECK = 0 ] ; then echo -e "[ \e[0;32mOK\e[0m ]" else echo -e "[ \e[0;31mFAILED\e[0m ]" exit 1 fi } # same as above but doesn't output [ OK ] status_silent() { local CHECK=$? echo -en "\033[68G" if [ $CHECK != 0 ] ; then echo -e "[ \e[0;31mFAILED\e[0m ]" exit 1 fi } if [ "$(id -u)" != "0" ]; then echo -e "[$RED Error $NORMAL] This script needs to be executed by root." exit 1 fi if [ -d $rootdir ]; then rm -r $rootdir fi if [ -d $workdir/src/rootfs ]; then rm -r $workdir/src/rootfs fi # if called, print everything instead of hiding. Debugging purposes case $2 in --verbose|-v) verbose=1;; *) verbose=0; esac # Build linux kernel do_kernel() { echo -e "[$YELLOW Working $NORMAL] Configuring & building Linux kernel" cd $workdir/src/linux-* status echo -n "Configuring..." cp ../../cfg/linux-*.conf .config status echo -n "Building kernel base..." if [ "$verbose" == "1" ]; then make bzImage -j$corecount status else make bzImage -j$corecount > /dev/null 2>&1 status fi #echo -n "Building kernel modules..." #if [ "$verbose" == "1" ]; then # make modules -j20 # status #else # make modules -j20 > /dev/null 2>&1 # status #fi #echo -n "Installing kernel modules..." #make INSTALL_MOD_PATH=`pwd`/_pkg modules_install > /dev/null 2>&1 #status echo -n "Installing kernel headers..." make INSTALL_HDR_PATH=$rootdir headers_install > /dev/null 2>&1 status cd .. } # Build musl-libc for compiler wrapping and OS dependencies do_musl() { #Building musl for planck linux echo -e "[$YELLOW Working $NORMAL] Configuring & building musl-libc" cd $workdir/src cd musl echo -n "Building musl..." if [ "$verbose" == "1" ]; then ./configure --prefix=$rootdir silent_status make -j$corecount status_silent make install status else ./configure --prefix=$rootdir > /dev/null 2>&1 status_silent make -j$corecount > /dev/null 2>&1 status_silent make install > /dev/null 2>&1 status fi cd ../.. #cp -a linux-headers/include $rootdir/. export PATH=$PATH:$rootdir/bin } # Build base system do_base() { echo -e "[$YELLOW Working $NORMAL] Configuring & building system utilities" cd $workdir/src #BUILD PACKAGE: sbase cd sbase echo -n "Building sbase..." if [ "$verbose" == "1" ]; then make -j$corecount status_silent make install status else make -j$corecount > /dev/null 2>&1 status_silent make install > /dev/null 2>&1 status fi cd .. cd ubase echo -n "Building ubase..." if [ "$verbose" == "1" ]; then make -j$corecount status_silent make install status else make -j$corecount > /dev/null 2>&1 status_silent make install > /dev/null 2>&1 status fi cd .. cd sinit echo -n "Building sinit..." if [ "$verbose" == "1" ]; then make -j$corecount status_silent make install status else make -j$corecount > /dev/null 2>&1 status_silent make install > /dev/null 2>&1 status fi cd .. cd sdhcp echo -n "Building sdhcp..." if [ "$verbose" == "1" ]; then make -j$corecount status_silent make install status else make -j$corecount > /dev/null 2>&1 status_silent make install > /dev/null 2>&1 status fi cd .. cd smdev echo -n "Building smdev..." if [ "$verbose" == "1" ]; then make -j$corecount status_silent make install status else make -j$corecount > /dev/null 2>&1 status_silent make install > /dev/null 2>&1 status fi cd .. cd dish echo -n "Building dash..." if [ "$verbose" == "1" ]; then make -j$corecount status_silent make install status else make -j$corecount > /dev/null 2>&1 status_silent make install > /dev/null 2>&1 status fi cd $workdir/src cd tcc echo -n "Building tcc..." if [ "$verbose" == "1" ]; then ./configure --prefix=$rootdir --crtprefix=$rootdir/lib --cc=musl-gcc --elfinterp=$rootdir/lib/libc.so --sysincludepaths=$rootdir/include --libpaths=$rootdir/lib --config-bcheck=no --config-musl=yes status_silent make -j$corecount status_silent make install status else ./configure --prefix=$rootdir --crtprefix=$rootdir/lib --cc=musl-gcc --elfinterp=$rootdir/lib/libc.so --sysincludepaths=$rootdir/include --libpaths=$rootdir/lib --config-bcheck=no --config-musl=yes> /dev/null 2>&1 status_silent make -j$corecount > /dev/null 2>&1 status_silent make install > /dev/null 2>&1 status fi cd .. cd texor echo -n "Building texor..." if [ "$verbose" == "1" ]; then make -j$corecount status_silent cp texor $rootdir/bin/. status else make -j$corecount > /dev/null 2>&1 status_silent cp texor $rootdir/bin/. > /dev/null 2>&1 status fi cd .. cd wgetlite echo -n "Building wgetlite..." if [ "$verbose" == "1" ]; then CC=musl-gcc make -j$corecount status_silent cp wgetlite $rootdir/bin/wget status else CC=musl-gcc make -j$corecount > /dev/null 2>&1 status_silent cp wgetlite $rootdir/bin/wget > /dev/null 2>&1 status fi cd .. # END PACKAGE BUILD # Link libc.so musl linker cd $rootdir cd lib ln -s libc.so ld-musl-x86_64.so.1 cd $workdir/src } # Configure rootfs for live boot configure_system() { echo -e "[$YELLOW Working $NORMAL] Configuring root filesystem" if [ ! -d $workdir/src/rootfs ]; then mkdir $workdir/src/rootfs fi if [ ! -d $rootdir/dev ]; then mkdir $rootdir/dev fi cd $workdir/src/rootfs echo -n "Filling /dev..." cp ../../cfg/mkdevs $rootdir/bin/mkdevs $rootdir/bin/mkdevs $rootdir/dev > /dev/null 2>&1 cp -a $rootdir . status_silent ln -s planck/dev dev status cd planck if [ ! -d etc ]; then mkdir etc fi echo -n "Configuring networking..." echo "127.0.0.1 localhost" > etc/hosts echo "localhost 127.0.0.1" > etc/networks echo "linux" > etc/hostname echo "order hosts,bind" > etc/host.conf echo "multi on" >> etc/host.conf status echo -n "Setting up default users and groups..." echo "root:x:0:0:root:/root:/bin/sh" > etc/passwd echo "root::13525:0:99999:7:::" > etc/shadow echo "root:x:0:" > etc/group echo "root:*::" > etc/gshadow chmod 640 etc/shadow chmod 640 etc/gshadow status #echo -n "Copying kernel modules..." #cp -a ../$kerneldir/_pkg/* . #status #echo -n "Copying kernel headers..." #cp -a ../$kerneldir/_hdr/* . #status echo -n "Compiling termtypes for core terminfo...." tic -o ./share/terminfo ../../../cfg/terminfo/termtypes > /dev/null 2>&1 status echo -n "Finishing up..." echo "# /etc/securetty: List of terminals on which root is allowed to login. # console # For people with serial port consoles ttyS0 # Standard consoles tty1 tty2 tty3 tty4 tty5 tty6 tty7" > etc/securetty echo "/bin/sh" > etc/shells echo "/bin/dash" >> etc/shells echo "Planck Linux\r \l" > etc/issue echo "" >> etc/issue echo "proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0 devpts /dev/pts devpts defaults 0 0 tmpfs /dev/shm tmpfs defaults 0 0" > etc/fstab echo "Welcome to ______________ ______ ___ __ \\__ /_____ ________________ /__ __ /_/ /_ /_ __ \`/_ __ \\ ___/_ //_/ _ ____/_ / / /_/ /_ / / / /__ _ ,< /_/ /_/ \\__,_/ /_/ /_/\\___/ /_/|_| Linux - With no GNU libraries! " > etc/motd echo "[SUID] # Allow command to be run by anyone. su = ssx root.root passwd = ssx root.root loadkmap = ssx root.root mount = ssx root.root reboot = ssx root.root halt = ssx root.root" > etc/busybox.conf echo "# /etc/profile: system-wide .profile file for the Bourne shells PATH=\"/freon/bin:/freon/sbin:/freon/usr/bin:/freon/usr/sbin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bin:/usr/local/sbin\" LD_LIBRARY_PATH=\"/freon/lib:/freon/lib64:/freon/usr/lib:/lib64:/usr/lib:/lib:/usr/local/lib\" TERM=\"xterm\" TERMINFO=\"/share/terminfo\" NORMAL=\"\\[\\e[0m\\]\" RED=\"\\[\\e[0;31m\\]\" GREEN=\"\\[\\e[0;32m\\]\" BLUE=\"\\[\\e[0;34m\\]\" YELLOW=\"\\[\\e[1;33m\\]\" MAGENTA=\"\\[\\e[0;35m\\]\" CYAN=\"\\[\\e[0;36m\\]\" if [ \"\`id -u\`\" -eq 0 ]; then PS1=\"$RED\\u$GREEN@$BLUE\\h [ $MAGENTA\\w$BLUE ]# \$NORMAL\" else PS1=\"$RED\\u$GREEN@$BLUE\\h [ $MAGENTA\\w$BLUE ]\\\$ \$NORMAL\" fi export PATH LD_LIBRARY_PATH PS1 DISPLAY ignoreeof umask 022 export G_FILENAME_ENCODING=iso8859-1 " > etc/profile echo "proc /planck/proc proc defaults 0 0 sysfs /planck/sys sysfs defaults 0 0 devpts /planck/dev/pts devpts defaults 0 0 tmpfs /planck/dev/shm tmpfs defaults 0 0" > etc/fstab status cd $workdir } # generate initramfs for live boot. gen_rootfs() { echo -e "[$YELLOW Working $NORMAL] Generating filesystem..." cd $workdir/src/rootfs ln -s planck/bin bin ln -s planck/lib lib ln -s planck/share share ln -s planck/sbin sbin ln -s planck/etc etc mkdir planck/proc mkdir planck/sys mkdir planck/run if [ ! -d planck/dev/pts ]; then mkdir planck/dev/pts fi ln -s planck/proc proc ln -s planck/sys sys mkdir root echo -n "Stripping build..." strip -g planck/lib/*.so > /dev/null 2>&1 strip -g planck/lib/*.a > /dev/null 2>&1 strip planck/bin/* > /dev/null 2>&1 strip planck/sbin/* > /dev/null 2>&1 cp ../../cfg/planck* planck/etc/. echo -n "Compressing rootfs tree..." find . -print | cpio -o -H newc | gzip -9 > ../../planck.gz 2>&1 status cd $workdir } # setup bootloader for iso do_isolinux() { echo -e "[$YELLOW Working $NORMAL] Setting up bootloader." cd $workdir/src if [ ! -d cdroot ]; then mkdir cdroot mkdir cdroot/boot fi cd syslinux echo -n "Copying isolinux files to iso..." cp bios/core/isolinux.bin ../cdroot status_silent cp bios/com32/elflink/ldlinux/ldlinux.c32 ../cdroot status echo -n "Generating isolinux config..." echo "Planck Linux Press to boot" > ../cdroot/display.txt echo "display display.txt default Planck label Planck kernel /boot/bzImage append initrd=/boot/planck.gz rw root=/dev/null vga=788 implicit 0 prompt 1 timeout 5" > ../cdroot/isolinux.cfg status cd $workdir } # generate complete iso ready for boot gen_iso() { echo -e -n "[$YELLOW Working $NORMAL] Generating bootable ISO image." cd $workdir/src cp ../planck.gz cdroot/boot cp linux-*/arch/x86/boot/bzImage cdroot/boot/bzImage genisoimage -R -o ../planck-$endtag.iso -b isolinux.bin \ -c boot.cat -no-emul-boot -boot-load-size 4 \ -V "Planck Linux" -input-charset iso8859-1 -boot-info-table cdroot > /dev/null 2>&1 status } case $1 in full) do_kernel; do_musl; do_base; configure_system; gen_rootfs; do_isolinux; gen_iso;; rootfs) do_musl; do_base; configure_system; gen_rootfs;; *) echo "Unknown argument: ./build-planck [full|rootfs]";; esac