FreonLinux/build-freon

890 lines
18 KiB
Bash
Executable File

#!/bin/bash
# Build linux system and generate ISO
# Version: 0.5.0
# (C) Chris Dorman, 2014-2020 - GPLv3+
workdir=`pwd`
freondir="/freon"
corecount=25
# Common mirror (now self hosted)
mainmirror="https://mirror.freonlinux.com/source"
# Download mirrors
syslinuxmirror="https://www.kernel.org/pub/linux/utils/boot/syslinux"
kernelmirror="https://cdn.kernel.org/pub/linux/kernel/v5.x"
busyboxmirror="http://busybox.net/downloads"
libcmirror="http://ftp.gnu.org/gnu/libc"
grubmirror="http://alpha.gnu.org/gnu/grub"
xzmirror="https://tukaani.org/xz"
dropbearmirror="https://matt.ucc.asn.au/dropbear/releases"
zlibmirror="https://zlib.net"
# endtag used for iso filename, and some rootfs configs
endtag=`date +"%Y%m%d-%H%M"`
hostbuild="Debian 10"
# Source code filenames
kernel="linux-5.9.1.tar.xz"
syslinux="syslinux-6.03.tar.gz"
busybox="busybox-1.32.0.tar.bz2"
libc="glibc-2.28.tar.xz"
grub="grub-2.02~rc2.tar.xz"
xz="xz-5.2.4.tar.xz"
dropbear="dropbear-2019.78.tar.bz2"
zlib="zlib-1.2.11.tar.xz"
# Source directory names
kerneldir=${kernel//.tar.xz}
busyboxdir=${busybox//.tar.bz2}
syslinuxdir=${syslinux//.tar.gz}
libcdir=${libc//.tar.xz}
grubdir=${grub//.tar.xz}
xzdir=${xz//.tar.xz}
dropbearsrcdir=${dropbear//.tar.bz2}
zlibsrcdir=${zlib//.tar.xz}
# 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 "src" ]; then
echo -e "[$YELLOW Warning $NORMAL] No source directory!"
echo -n "Creating source directory..."
mkdir src > /dev/null 2>&1
status
fi
# check to see if source dir exists, if not create
if [ ! -d src ]; then
mkdir src
status_silent
fi
# if called, print everything instead of hiding. Debugging purposes
case $2 in
--verbose|-v) verbose=1;;
*) verbose=0;
esac
# Download source code
get_files()
{
cd $workdir/src
if [ -d "rootfs" ]; then
echo -e "[$YELLOW Warning $NORMAL] Rootfs tree still exists."
echo -n "Cleaning build tree..."
rm -r rootfs > /dev/null 2>&1
status
fi
#echo " " # This is used to keep next echo from moving around
echo -e "[$YELLOW Working $NORMAL] Downloading needed files..."
if [ ! -f $kernel ]; then
echo -n "$kernel..."
wget $mainmirror/$kernel > /dev/null 2>&1
status
fi
if [ ! -f $busybox ]; then
echo -n "$busybox..."
wget $mainmirror/$busybox > /dev/null 2>&1
status
fi
if [ ! -f $syslinux ]; then
echo -n "$syslinux..."
wget $mainmirror/$syslinux > /dev/null 2>&1
status
fi
if [ ! -f $xz ]; then
echo -n "$xz..."
wget $mainmirror/$xz > /dev/null 2>&1
status
fi
if [ ! -f $libc ]; then
echo -n "$libc..."
wget $mainmirror/$libc > /dev/null 2>&1
status
fi
if [ ! -f $grub ]; then
echo -n "$grub..."
wget $mainmirror/$grub > /dev/null 2>&1
status
fi
}
# Build linux kernel
do_kernel()
{
cd $workdir/src
echo -e "[$YELLOW Working $NORMAL] Configuring & building Linux kernel"
if [ ! -d $kerneldir ]; then
echo -n "Unpacking..."
tar xf $kernel > /dev/null 2>&1
status
fi
echo -n "Configuring..."
cd $kerneldir
cp ../../files/$kerneldir.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=`pwd`/_hdr headers_install > /dev/null 2>&1
status
cd ..
}
# Build busybox
do_base()
{
echo -e "[$YELLOW Working $NORMAL] Configuring & building system utilities"
cd $workdir/src
if [ ! -d $busyboxdir ]; then
echo -n "Unpacking..."
tar xf $busybox > /dev/null 2>&1
status
fi
echo -n "Configuring..."
cd $busyboxdir
cp ../../files/$busyboxdir.conf .config
status_silent
make oldconfig > /dev/null 2>&1
status
echo -n "Building..."
if [ "$verbose" == "1" ]; then
make -j$corecount
status
else
make -j$corecount > /dev/null 2>&1
status
fi
if [ "$verbose" == "1" ]; then
make install
status
else
make install > /dev/null 2>&1
status
fi
echo -n "Finishing up..."
chmod 4755 _install/bin/busybox
cp -a _install/* /freon
status
cd $workdir
cd system/ii
make -j$corecount; make install
status_silent
cd ../chttpd
cp inc/chttpd ../../rootfs/etc/init.d/chttpd
make -j$corecount; make install
status_silent
cd ../sic
make -j$corecount; make install
status_silent
cd $workdir
}
# Build system wide dependencies
do_libc()
{
echo -e "[$YELLOW Working $NORMAL] Configuring & building libc"
cd $workdir/src
if [ ! -d $libcdir ]; then
echo "Unpacking..."
tar xf $libc > /dev/null 2>&1
status
fi
if [ ! -d rootfs ]; then
mkdir rootfs
cd rootfs/
echo -n "Laying out filesystem tree..."
mkdir -p dev root etc home proc media mnt sys tmp var
mkdir -p usr/{lib,local,share,games} \
var/{cache,lib,lock,log,games,run,spool,www} \
media/{cdrom,flash,usbdisk} \
etc/{init.d,conf.d}
cd ..
fi
if [ ! -d $libcdir-build ]; then
mkdir $libcdir-build
fi
if [ ! -d /freon/lib ]; then
mkdir /freon/lib
fi
cd $libcdir-build
echo -n "Configuring..."
if [ "$verbose" == "1" ]; then
`pwd`/../$libcdir/configure \
--prefix=$freondir \
--build=$MACHTYPE \
--host=x86_64-linux \
--target=x86_64-linux
--with-headers=_hdr/include
status
else
`pwd`/../$libcdir/configure \
--prefix=/freon \
--build=$MACHTYPE \
--host=x86_64-linux \
--target=x86_64-linux > /dev/null 2>&1
--with-headers=_hdr/include > /dev/null 2>&1
status
fi
echo -n "Building..."
if [ "$verbose" == "1" ]; then
make install-bootstrap-headers=yes install-headers
status
make -j$corecount csu/subdir_lib
status
install csu/crt1.o csu/crti.o csu/crtn.o /freon/lib
status
gcc \
-nostdlib \
-nostartfiles -shared -x c /dev/null -o $freondir/lib/libc.so
status
make -j$corecount
status
else
make install-bootstrap-headers=yes install-headers > /dev/null 2>&1
status_silent
make -j$corecount csu/subdir_lib > /dev/null 2>&1
status_silent
install csu/crt1.o csu/crti.o csu/crtn.o $freondir/lib > /dev/null 2>&1
status_silent
gcc \
-nostdlib \
-nostartfiles -shared -x c /dev/null -o $freondir/lib/libc.so 2>&1
status_silent
make -j$corecount > /dev/null 2>&1
status
fi
echo -n "Copying to rootfs..."
if [ "$verbose" == "1" ]; then
make install
status
else
make install > /dev/null 2>&1
status
fi
echo -n "Cleaning files..."
#strip -v lib/* > /dev/null 2>&1
mkdir $workdir/src/rootfs/lib64
cd $workdir/src/rootfs/lib64
ln -s $freondir/lib/ld-2.28.so ld-linux-x86-64.so.2
status
cd $freondir
if [ ! -d "lib64" ]; then
mkdir lib64
fi
cd lib64
ln -s $freondir/lib/ld-2.28.so ld-linux-x86-64.so.2
cd $workdir
}
# Build grub legacy bootloader and install
do_grub()
{
echo -e "[$YELLOW Working $NORMAL] Configuring & building bootloader"
cd $workdir/src
echo -n "Extracting..."
if [ ! -d "$xzdir" ]; then
tar xf $xz > /dev/null 2>&1
status_silent
fi
if [ ! -d "$grubdir" ]; then
tar xf $grub > /dev/null 2>&1
status
fi
cd $grubdir
echo -n "Configuring..."
./configure --prefix=`pwd`/../rootfs \
--disable-efiemu \
--disable-werror > /dev/null 2>&1
status_silent
cd ../$xzdir
./configure --prefix=`pwd`/../rootfs \
--disable-static > /dev/null 2>&1
status
cd ../$grubdir
echo -n "Compiling..."
make -j$corecount > /dev/null 2>&1
status_silent
cd ../$xzdir
make -j$corecount > /dev/null 2>&1
status
cd ../$grubdir
echo -n "Copying to rootfs..."
make install > /dev/null 2>&1
status_silent
cd ../$xzdir
make install > /dev/null 2>&1
status
cd ../$grubdir
echo -n "Installing patched grub-mkconfig..."
rm ../rootfs/sbin/grub-mkconfig > /dev/null 2>&1
status_silent
cp ../../files/sbin/grub-mkconfig ../rootfs/sbin > /dev/null 2>&1
status
cd ../rootfs
#echo -n "Stripping grub..."
#strip -s rootfs/bin/grub-* > /dev/null 2>&1
#strip -s rootfs/sbin/grub-* > /dev/null 2>&1
cd ..
#status
}
# Install Freon utilities
do_utilities() {
echo -e "[$YELLOW Working $NORMAL] Installing Freon utilities"
echo -n "Copying files..."
cd $workdir/src
cp -a ../files/bin/* rootfs/bin
status
}
# Configure rootfs for live boot
configure_system()
{
echo -e "[$YELLOW Working $NORMAL] Configuring root filesystem"
echo -n "Linking init..."
cd $workdir/src/rootfs
if [ -f linuxrc ]; then
rm linuxrc
fi
if [ ! -f init ]; then
ln -s $freondir/bin/busybox init
fi
status
echo -n "Filling /dev..."
cp ../../files/bin/mkdevs $freondir/bin/mkdevs
$freondir/bin/mkdevs dev > /dev/null 2>&1
status
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
mkdir etc/network
mkdir etc/network/if-up.d
mkdir etc/network/if-down.d
mkdir etc/network/if-pre-up.d
mkdir etc/network/if-post-down.d
echo "# loopback
auto lo
iface lo inet loopback
# Ethernet // this is default and can be changed for per system
auto eth0
iface eth0 inet dhcp
" > etc/network/interfaces
echo "
# /etc/nsswitch.conf: GNU Name Service Switch config.
#
passwd: files
group: files
shadow: files
hosts: files dns
networks: files
" > etc/nsswitch.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 ./usr/share/terminfo ../../files/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/ash" >> etc/shells
echo "Freon Linux $endtag \r \l" > etc/issue
echo "" >> etc/issue
echo "Welcome to
_________
___ ____/________________________
__ /_ __ ___/ _ \\ __ \\_ __ \\
_ __/ _ / / __/ /_/ / / / /
/_/ /_/ \\___/\\____//_/ /_/
Compiled $endtag using $hostbuild" > 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
chmod 600 etc/busybox.conf
echo "::sysinit:/etc/init.d/rc.init
::respawn:-/bin/sh
tty2::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
::ctrlaltdel:/sbin/reboot" > etc/inittab
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 /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
cp -a $workdir/files/etc/* etc
cd share
mkdir kmap
cp -a $workdir/files/share/* .
status_silent
chmod +x udhcpc/default.script
status_silent
cd ../usr/share
ln -s /share/udhcpc udhcpc
cd ../..
# mkdir x86_64-linux-gnu
# cd x86_64-linux-gnu
# ln -s ../libm-2.22.so libm.so.6
# ln -s ../libc-2.22.so libc.so.6
status
cd $workdir
}
# generate initramfs for live boot.
gen_rootfs()
{
echo -e "[$YELLOW Working $NORMAL] Generating filesystem..."
cd $workdir/src/rootfs
cp -a $freondir .
cd bin
for f in /freon/bin/*; do
ln -s $f .
done
cd ../sbin
for f in /freon/sbin/*; do
ln -s $f .
done
cd ../lib
for l in /freon/lib/*.so; do
ln -nsf $l .
done
for l in /freon/lib/*.so*; do
ln -nsf $l .
done
for l in /freon/lib/*.o; do
ln -nsf $l .
done
cd ..
echo -n "Stripping build..."
strip -s freon/lib/*.so > /dev/null 2>&1
strip -s freon/lib/*.so* > /dev/null 2>&1
strip -s freon/bin/busybox > /dev/null 2>&1
strip -s freon/sbin/chttpd > /dev/null 2>&1
rm freon/lib/*.a
rm lib/*.a # In base-dev package
rm usr/lib/*.a
echo "#!/bin/sh
exec /freon/bin/sh \$*" > bin/bash
chmod +x bin/bash
echo -n "Compressing filesystem..."
find . -print | cpio -o -H newc | gzip -9 > ../rootfs.gz 2>&1
status
cd $workdir
}
regen_rootfs_bare()
{
echo -e "[$YELLOW Working $NORMAL] Generating filesystem..."
cd $workdir/src/rootfs
cp -a $freondir .
echo -n "Compressing filesystem..."
find . -print | cpio -o -H newc | gzip -9 > ../rootfs.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 $syslinuxdir ]; then
echo -n "Unpacking $syslinuxdir..."
tar -xzf $syslinux > /dev/null 2>&1
status
fi
if [ ! -d cdroot ]; then
mkdir cdroot
mkdir cdroot/boot
fi
cd $syslinuxdir
echo -n "Copying isolinux files to iso..."
cp bios/core/isolinux.bin ../cdroot
cp bios/com32/elflink/ldlinux/ldlinux.c32 ../cdroot
status
echo -n "Generating isolinux config..."
echo "Freon Linux $endtag
Press <enter> to boot" > ../cdroot/display.txt
echo "display display.txt
default Freon
label Freon
kernel /boot/bzImage
append initrd=/boot/rootfs.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 rootfs.gz cdroot/boot
cp $kerneldir/arch/x86/boot/bzImage cdroot/boot/bzImage
genisoimage -R -o ../freon-$endtag.iso -b isolinux.bin \
-c boot.cat -no-emul-boot -boot-load-size 4 \
-V "Freon Linux" -input-charset iso8859-1 -boot-info-table cdroot > /dev/null 2>&1
status
}
do_refer()
{
echo -e "[$YELLOW Working $NORMAL] Reconfiguring root filesystem"
cd $workdir/src/rootfs
rm etc/init.d/*
rm etc/conf.d/*
cp -av ../../files/etc/* etc/ # Copy files/etc to filesystem (init scripts)
cp -av ../../files/bin/* bin/ # Copy installer and package manager
cp -av ../../files/share/* share/ # Stuffs
cd $workdir
}
do_dropbear()
{
cd $workdir/src
# Downloading dropbear source
if [ ! -f "$dropbear" ]; then
echo "Downloading Dropbear sources..."
wget $dropbearmirror/$dropbear
tar -xf $dropbear
fi
# Configure dropbear
cd $dropbearsrcdir
cp -v options.h options.h.backup
sed -e "s@/dev/random@/dev/urandom@" options.h.backup > options.h
./configure --prefix=$workdir/src/rootfs
# Compile
make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" MULTI=1
make MULTI=1 PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" install
mkdir -pv $workdir/src/rootfs/etc/dropbear
rm $workdir/src/rootfs/sbin/dropbear
rm $workdir/src/rootfs/bin/{dropbearconvert,dropbearkey,scp,dbclient}
cd $workdir/src/rootfs/bin
ln -svf dropbearmulti dropbear
ln -svf dropbearmulti dbclient
ln -svf dropbearmulti dropbearkey
ln -svf dropbearmulti dropbearconvert
ln -svf dropbearmulti scp
cd $workdir
}
do_zlib()
{
cd $workdir/src
# Downloading zlib source
if [ ! -f "$zlib" ]; then
echo "Downloading zlib sources..."
wget $zlibmirror/$zlib
tar -xf $zlib
fi
# Confingure
cd $zlibsrcdir
./configure --prefix=$freondir
# Compile
make -j$corecount
make install
# mv -v ../../src/rootfs/usr/lib/libz.so.* ../../src/rootfs/lib
# ln -sfv ../../src/rootfs/lib/libz.so ../../src/rootfs/usr/lib/libz.so
cd $workdir
}
case $1 in
rootfs) get_files; do_libc; do_base; do_grub; do_zlib; do_dropbear; do_kernel; configure_system; do_utilities;;
refer) do_refer; regen_rootfs_bare; do_isolinux; gen_iso;;
full) get_files; do_libc; do_base; do_grub; do_zlib; do_dropbear; do_kernel; configure_system; do_utilities; gen_rootfs; do_isolinux; gen_iso;;
*) echo "Unknown argument: ./build-freon [full|refer|rootfs]";;
esac