System Bootstrap

Congratulations on completing the lengthy toolchain creation phase! Your reward is a mammoth, 18+ hour compilation of the standard Shedbuilt system, at the end of which you won't have so much as a graphical desktop. What I hope you will have, in addition to a system ready for any task you select for it, is an appreciation for the contributions of people all over the world who have, over the course of decades, worked together to produce the stable, performant, open-source software that undergirds the Internet, our phones and tablets, and so many other things we take for granted. I'll get off my soapbox now. Let's build this sucker.

The Easy Way

As with the toolchain build, we have a couple of handy scripts that can automate tedious bootstrapping process. If you're installing to a partition mounted somewhere other than /mnt/shedstrap you'll need to modify the first line below before pasting everything into the terminal:

cd /mnt/shedstrap/tools
cat > bootstrap_shedbuilt.sh << "EOF"
#!/tools/bin/bash

# Install all packages
shedmake install-list /var/shedmake/repos/remote/system/bootstrap_${SHED_DEVICE}.sml --verbose

# Remove static libraries
rm -f /usr/lib/lib{bfd,opcodes}.a
rm -f /usr/lib/libbz2.a
rm -f /usr/lib/lib{com_err,e2p,ext2fs,ss}.a
rm -f /usr/lib/libltdl.a
rm -f /usr/lib/libfl.a
rm -f /usr/lib/libfl_pic.a
rm -f /usr/lib/libz.a
EOF
chmod +x bootstrap_shedbuilt.sh
cd ~/
cat > perform_bootstrap.sh << "EOF"
#!/bin/bash
# perform_bootstrap
# Description: Sets up virtual file systems and Shedbuilt system repository on
# on the bootstrap partition, in preparation for system compilation in chroot.
# Example: ./perform_bootstrap.sh https://github.com/shedbuilt/shedbuilt-system.git amano orangepi-one /mnt/shedstrap

if [ $# -lt 4 ]; then
   echo "Too few arguments to perform_bootstrap"
   echo "Expected: perform_bootstrap <system-repo-url> <release> <device> <install-root>"
   exit 1
fi

INSTALLROOT="${4%/}"
BOOTSTRAPDEV="$3"
SYSRELEASE="$2"
SYSREPOURL="$1"

# Mount kernel virtual file systems at destination
if ! mount | grep -q "${INSTALLROOT}/sys"; then
    mkdir -pv "${INSTALLROOT}"/{dev,proc,sys,run}
    mknod -m 600 "${INSTALLROOT}/dev/console" c 5 1
    mknod -m 666 "${INSTALLROOT}/dev/null" c 1 3
    mount -v --bind /dev "${INSTALLROOT}/dev"
    mount -vt devpts devpts "${INSTALLROOT}/dev/pts" -o gid=5,mode=620
    mount -vt proc proc "${INSTALLROOT}/proc"
    mount -vt sysfs sysfs "${INSTALLROOT}/sys"
    mount -vt tmpfs tmpfs "${INSTALLROOT}/run"
    if [ -h "${INSTALLROOT}/dev/shm" ]; then
        mkdir -pv "${INSTALLROOT}"/$(readlink "${INSTALLROOT}/dev/shm")
    fi
fi

# Create Shedbuilt system repository at destination
TMPDIR="${INSTALLROOT}/var/tmp"
REPODIR="${INSTALLROOT}/var/shedmake/repos"
REMOTEREPODIR="${REPODIR}/remote"
LOCALREPODIR="${REPODIR}/local"
SYSREPONAME="system"
LOCALREPONAME="default"
mkdir -pv "$TMPDIR"
mkdir -pv "$REMOTEREPODIR"
mkdir -v "$LOCALREPODIR"
cd "$LOCALREPODIR"
mkdir "$LOCALREPONAME"
cd "$LOCALREPONAME"
git init
cd "$REMOTEREPODIR"
if [ ! -d "$SYSREPONAME" ]; then
    git clone "$SYSREPOURL" "$SYSREPONAME" && \
    cd "$SYSREPONAME" && \
    git checkout "$SYSRELEASE" && \
    git submodule init || exit 1
else
    cd "$SYSREPONAME" && \
    git pull || exit 1
fi
git submodule update || exit 1

# Cache all required source files
shedmake fetch-source-list bootstrap_${BOOTSTRAPDEV}.sml || exit 1

# Enter chroot and execute the bootstrap install script
chroot "$INSTALLROOT" /tools/bin/env -i \
            HOME=/root                  \
            TERM="$TERM"                \
            PS1='(bootstrap) \u:\w\$ '  \
            PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin \
            SHED_DEVICE="$BOOTSTRAPDEV" \
            /tools/bin/bash +h /tools/bootstrap_shedbuilt.sh

# Set up the swap file
dd if=/dev/zero of="${INSTALLROOT}/var/swap" bs=1M count=512
chmod 600 "${INSTALLROOT}/var/swap"
mkswap "${INSTALLROOT}/var/swap"
EOF
chmod +x perform_bootstrap.sh

Having entered the above you're ready to begin compiling all of the standard Shedbuilt system packages using your newly constructed toolchain. Again, it would be wise to start up screen if you're building over ssh to prevent a dropped connection from derailing the build. When you're ready, run the perform_bootstrap.sh script as root with appropriate options like so:

sudo ./perform_bootstrap.sh https://github.com/shedbuilt/shedbuilt-system.git amano orangepi-one /mnt/shedstrap

If you want to install a version of Shedbuilt other than the current System 1 'Amano' release or your bootstrap partition is mounted to a folder other than /mnt/shedstrap then you'll need to modify the above command.

When you execute the script, compiler commands will once again whizz by as the 90 or so packages in the standard Shedbuilt system are built and lovingly installed in the places specified by the Filesystem Hierarch Standard. The end result will be a system very nearly ready to boot up. We'll go through the finishing touches in the next section.

The Hard Way

And again, for those who find automation to be too convenient or need more control over the build, there's always the hard way. To do so you'll need to manually perform all the steps in the above script as root, stopping at the comment # Enter chroot and execute the bootstrap install script. Then, manually enter chroot by entering:

sudo chroot /mnt/shedstrap /tools/bin/env -i \
                 HOME=/root                  \
                 TERM="$TERM"                \
                 PS1='(bootstrap) \u:\w\$ '  \
PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin \
/tools/bin/bash --login +h

Once in the chroot environment, you can perform an automated bootstrap by passing the appropriate bootstrap_DEVICE.sml file to shedmake's install-list command:

shedmake install-list /var/shedmake/repos/system/bootstrap_orangepi-one.sml

Alternatively, you can build and install packages one-by-one by appending the lines that appear in /var/shedmake/repos/system/bootstrap.sml to shedmake install. For instance, the first package can be manually installed like so:

shedmake install shedbuilt-base-layout --mode bootstrap