The Suckless From Scratch Project

Table of Contents

sfs_logo.png

1. About

1.1. About the Project

Suckless from Scratch, is a project of mine where i'm trying to finally build what i consider to be a true suckless, linux based system, from scratch. I was inspired by the ideas and concept behind the 'Linux From Scratch' project. but this, is not any sort of modified version, "fork", or "respin" of said book- since this is meant to be an original project of mine. in addition it ended up also being some sort of manifestation of the posix 'rule of diversity' showing that there's more than only one true way of doing your computing- or in this case, a 'Linux From Scratch' building. i must highlight also that i never completely read that book so i figured this out by myself (quite an achievement) ;)

'Suckless From Scratch', -or 'SFS' for short- aims to be the first, fully suckless compliant, linux system ever made. the resulting system by following this document would be a linux based distribution built completely from scratch using only, suckless software and minimalistic alternatives for each whenever it's possible. the ideal of the project is to get a most minimal system working, with the least amount of software and configurations necessary for it to work, while also following Suckless's Philosophy and using their recommended set of software.

the system is in it's totality statically built, as recommended by suckless -there's no dynamic libraries- and uses the TinyCC compiler for the most part with a few exceptions; TinyCC, or TCC, which according to Bellard, compiled and linked about nine times faster than GCC did! the guide on itself also aims to be delightfully simple- the system can be built in under 30 minutes if you have a kernel ready.

of course, this is a personal guide where i've got to choose the software and the way i want to build and install it; you can change whatever you want to make it fit your needs. that's the magic behind building a linux from stratch system, you can make it exactly the way you want it to be. so take this as a guide if you want, flip your fedora hat and get used to compiling stuff because there's lots of fun approaching the boat captain!!

1.2. What Do I Want for this?

  • a suckless compliant operating system all built from scratch.
  • build only the necessary to have the most simple system
  • use ninit. (SFS's official init, you can use whatever you want though)
  • a completly TTY oriented user environment, only Framebuffer/DRM Graphics. (more in: 'Post-SFS')
  • Sbase and Ubase as the system core
  • almost completely built with the TinyCC (TCC) compiler.
  • everything built statically. (no dynamic libraries)
  • use a minimal, kernel configuration.
  • don't use udev, eudev, dbus, or anything similar, whatsoever.
  • BearSSL instead of OpenSSL
  • EIWD instead of WpaSupplicant.
  • use a suckless alternative for each package whenever it's possible
  • don't install nor configure anything unless it's really necessary.
  • a clean Directory Hierarchy, without a spaghetti of directory symlinks pointing everywhere, only one /bin folder and no /usr directory.
  • E3 as the system main editor

1.3. Before Everything

You could use any live distribution or even your own Main System for installing it on a second partition. you'll need some packages for getting this done:

  • git
  • curl
  • tar [maybe also gzip and xz (xz-utils on antix)]
  • unzip
  • base-devel on voidlinux | build-essential on antix and probably also debian
  • bash (yes, i know… we need it just for some script used by a package, the final system won't have bash installed)

You will probably know how to find the correct package names for your distribution or may as well already have them installed.

warning: you need to at least have a basic knowledge of what you are doing. you don't need to be a wizard but you should be able to recognize and fix some basic compiling errors, pay attention and replace information when needed, customize. (don't copy paste everything) and also, you need to know how to compile stuff on your own too. this document doesn't specify, nor covers the most obvious stuff, like changing directories when compiling different sources, creating the filesystem, mounting, etc.

whenever you find a file redirection like in:


cat << . > /path example .


type it manually, some terminals end up redirecting the '.' inside of the file you are filling.

1.4. Todo List

  • when i wrote this document, my english was way worse than it is now- and let me tell you… i have a lot to review and rewrite.
  • strip off all trace of GCC and GNU building dependencies from this sacred document!
  • using git when we have the option to use ftp or a http/s server is quite dumb, i'll fix it later. (i hope)
  • build the kernel with TCC (it was done before)
  • fix the tcc, musl patch- it stopped working

2. Installation

2.1. Getting Ready…

you'll need to get your disk ready and format your partitions in order to begin with the installation. in this document i'll be using ext2 and i'll disable some of its features to make it as simple of a modern file system as possible. this is for the project's sake, i'll try to keep everything as simple as possible, but of course if you are concerned of the safety of your files you can use ext4, ffs or whatever other file system of choice; you could even get this thing working on zfs with enough effort. note that this project is only about building a suckless compliant, linux based system from scratch, it only contains the basic software that you need to get a very simple system working. it really isn't about hardening or making a secure system, obviously you can, but if there's some special option for making some program less vulnerable or more secure against some sort of attack i won't explain it here- in fact, i will more likely disable those options and build only, and just only what's necessary to get the bare system working -nothing else really- which is way, way less than what linux from scratch requires for its core system to be functional. in any case, always remember that this is just a guide, and you are the only one up to decide what you do and don't want in your system, the resulting system will be yours and you can do whatever you want with it. your rules!!

you'll need the following script for downloading the sources:

Sources Script

2.2. Stage 1

2.3. Files

2.3.1. Directories


mkdir -p                  \
             /mnt/proc           \
             /mnt/dev            \
             /mnt/sys            \
             /mnt/etc/ssl/certs  \
             /mnt/tmp            \
             /mnt/var/run        \
             /mnt/root           \
             /mnt/lib            \
             /mnt/include        \
             /mnt/bin            \
             /mnt/src            \
             /mnt/src/packages   \
             /mnt/src/sources

2.3.2. Mknod


mknod -m=0600 /mnt/dev/console c 5 1
mknod -m=0666 /mnt/dev/null c 1 3
mknod -m=0666 /mnt/dev/random c 1 8
mknod -m=0666 /mnt/dev/urandom c 1 9

2.3.3. Fstab :: file:///mnt/etc/fstab

i've disabled those features here, change it as needed. replace it with your partition/s, options, mountpoint/s and file system/s.


/dev/mmcblk0p4 / ext2 rw,noatime,nodiratime,nobarrier,noload 0 0


2.3.4. Passwd :: file:///mnt/etc/passwd


root:x:0:0:root:/root:/bin/csh

bin:x:1:1:bin:/dev/null:/bin/false


2.3.5. Groups :: file:///mnt/etc/groups


root:x:0

bin:x:1


2.3.6. Shadow :: file:///mnt/etc/shadow

of course replace \yoursalt\ with your salt, and \yourpassword\ with your password, if it makes sense at all


printf "root:`openssl passwd -1 -salt \yoursalt\ \yourpassword\`::0:99999:1:::\n" > /mnt/etc/shadow

2.3.7. UTMP :: file:///mnt/var/run/utmp


touch /mnt/var/run/utmp

2.3.8. DNS :: file:///mnt/etc/resolv.conf

these are some dns i took from 'opennic.org' they claim not to keep logs.

they might be outdated by the time you're reading this.


nameserver 134.195.4.2

nameserver 168.235.111.72


2.3.9. Ca-Certificates :: file:///mnt/etc/ssl/certs/ca-certificates.crt


curl -f https://curl.se/ca/cacert.pem -o /mnt/etc/ssl/certs/ca-certificates.crt

2.3.10. Profile :: file:///mnt/etc/profile


#!/bin/csh
#PATH

setenv PATH "/bin"

#FLAGS
#only gcc will be able to use CFLAGS, tcc will only ignore them.
setenv FLAGS "-Os -march=native -pipe -g0 -static -s"
setenv CFLAGS "$FLAGS"
setenv CXXFLAGS "$FLAGS"
setenv CPPFLAGS "$FLAGS"

setenv LDFLAGS "-s -static -g0"
setenv AR "tcc -ar"
setenv RANLIB "echo"

setenv CC "tcc"

#PROMPT

set prompt=" < %/ > -: "

#TERM

setenv TERM "linux"

2.3.11. Toolchain

here we'll be downloading a musl gcc toolchain because we'll need it for some packages that won't compile with tcc this section might later disappear, check the TODO list of the project.


curl -s musl.cc | grep x86_64-linux-musl-native | xargs curl -# -fo /mnt/src/packages/x86_64-linux-musl-native.tgz \
&& mkdir -p /mnt/src/gcc-toolchain/ \
&& tar -xzf /mnt/src/packages/x86_64-linux-musl-native.tgz -C/mnt/src/gcc-toolchain/ --strip-components=1

2.3.12. Downloading Sources :: file:///mnt/src/sources.sh

Just execute the script in the /mnt/src directory. make sure to check for any error as some links might expire over time :)


./sources.sh

2.4. Musl

2.4.1. Building


env CFLAGS="-Os -pipe -march=native" \
          CC="/mnt/src/gcc-toolchain/bin/gcc" \
          LDFLAGS="-s -static -g0" \
          AR="/mnt/src/gcc-toolchain/bin/ar"  \
          RANLIB="/mnt/src/gcc-toolchain/bin/ranlib" \
./configure --prefix="/" --target=x86_64 \
                  --syslibdir="/lib" --bindir="/bin" \
                  --includedir="/include" \
                  --disable-shared --enable-static

make -j2
make DESTDIR="/mnt/" install
make distclean

2.5. TinyCC

2.5.1. Building :: GCC


env CFLAGS="-Os -pipe -march=native" \
          CC="/mnt/src/gcc-toolchain/bin/gcc" \
          LDFLAGS="-s -static -g0 -L/mnt/lib -I/mnt/include -w" \
          AR="/mnt/src/gcc-toolchain/bin/ar"  \
          RANLIB="/mnt/src/gcc-toolchain/bin/ranlib" \
./configure --config-musl --disable-rpath --enable-static \
--prefix=/ --sysincludepaths="/mnt/lib/tcc/include:/mnt/include:/lib/tcc/include:/include" \
--libpaths="/mnt/lib:/mnt/lib/tcc:/lib:/lib/tcc" --crtprefix="/mnt/lib:/lib" \
--cross-prefix="/mnt" --cc="/src/gcc-toolchain/bin/gcc -L/mnt/lib -I/mnt/include -w -s -static -g0" \
--ar="/src/gcc-toolchain/bin/ar"

make -j2
make DESTDIR="/mnt" install
make distclean

2.5.2. Rebuilding :: TinyCC

we just built tinycc with the GCC Musl toolchain. now, we are about to build tcc again, but this time, using the tcc we just built with gcc. so now it would be a tcc built with a tcc built with gcc using the toolchain's musl. our goal now is to use our own musl and have a tcc built, tcc- so we will recompile it now using our tcc and musl ;3

what? you didn't understand? there's no need for questions, just build this thing up


env CC="/mnt/bin/tcc -s -static -g0 -L/mnt/lib/ -I/mnt/include" \
          LDFLAGS="-s -static -g0" \
          AR="/mnt/bin/tcc -ar"  \
          RANLIB="echo" \
./configure --config-musl --disable-rpath --enable-static \
--prefix=/ --sysincludepaths="/mnt/lib/tcc/include:/mnt/include:/lib/tcc/include:/include" \
--libpaths="/mnt/lib:/mnt/lib/tcc:/lib:/lib/tcc" --crtprefix="/mnt/lib:/lib" \
--cross-prefix="/mnt" --cc="/bin/tcc -s -static -g0" \
--ar="/bin/tcc -ar"

make -j2
make DESTDIR="/mnt" install
make distclean

ok, so now we've got a tcc built with a tcc built with gcc from the toolchain. the difference, is that this tcc has our musl in its binary now. but, it was built with a tcc which wasn't compiled with our musl. so what now? you guessed it, time to repeat the process one more time. don't question my orders, just do it… yeah, i promise, it's necessary ;b


env CC="/mnt/bin/tcc -s -static -g0 -L/mnt/lib/ -I/mnt/include" \
          LDFLAGS="-s -static -g0" \
          AR="/mnt/bin/tcc -ar"  \
          RANLIB="echo" \
./configure --config-musl --disable-rpath --enable-static \
--prefix=/ --sysincludepaths="/mnt/lib/tcc/include:/mnt/include:/lib/tcc/include:/include" \
--libpaths="/mnt/lib:/mnt/lib/tcc:/lib:/lib/tcc" --crtprefix="/mnt/lib:/lib" \
--cross-prefix="/mnt" --cc="/bin/tcc -s -static -g0" \
--ar="/bin/tcc -ar"

make -j2
make DESTDIR="/mnt" install
make distclean

the legend says that you can crash the spyware embedded in the compilers by getting it to compile itself 50 times in a row a full moon saturday night… who knows, give it a try and you tell me.

2.6. Sbase


env CC="/mnt/bin/tcc -s -static -g0" \
          LDFLAGS="-s -static -g0" \
          AR="/mnt/bin/tcc -ar" \
          RANLIB="echo" make -e -j2
make -e PREFIX="/" DESTDIR="/mnt/" install
ln -sf xinstall /mnt/bin/install
make clean

2.7. Ubase


env CPPFLAGS="-D_FILE_OFFSET_BITS=64 -D_XOPEN_SOURCE=700 -D_GNU_SOURCE" \
          CC="/mnt/bin/tcc -s -static -g0" \
          LDFLAGS="-s -static -g0" \
          AR="/mnt/bin/tcc -ar" \
          RANLIB="echo" make -e -j2
make -e PREFIX="/" DESTDIR="/mnt/" install
make clean

2.8. Dash


env CC="/mnt/bin/tcc -s -static -g0" \
          LDFLAGS="-s -static -g0" \
          AR="/mnt/bin/tcc -ar" \
          RANLIB="echo" ./configure --prefix="/" --disable-fnmatch \
          --disable-lineno --disable-glob

make -j2
make DESTDIR="/mnt/" install
mv /mnt/bin/dash /mnt/bin/sh
make distclean

2.9. Nasm


env CC="/mnt/bin/tcc -s -static -g0"   \
          LDFLAGS="-s -static -g0" \
          AR="/mnt/bin/tcc -ar" \
          RANLIB="echo" ./configure --prefix=/

make -j2
make DESTDIR="/mnt/" install
make distclean

2.10. E3


sed 's/nasm\ -O2/\/mnt\/bin\/nasm\ -O2/' Makefile > _
mv -f _ Makefile
make 64 -j2
make -e PREFIX="/mnt/" MANDIR="/mnt/share/man/man1/" install

for i in /mnt/bin/e3*[em,ne,pi,vi,ws]; do ln -sf e3 $i; done

make clean

2.11. Netbsd-Curses


sed '514,517d' libcurses/color.c > _
mv -f _ libcurses/color.c

env CC="/mnt/bin/tcc -s -static -g0 -w" \
    AR="/mnt/src/gcc-toolchain/bin/ar" \
    LDFLAGS="-s -static -g0" make -j2 all-static

make -e PREFIX="/" DESTDIR="/mnt/" LDFLAGS="-s -static -w -g0" install-static
make clean      

2.12. Tcsh


env CC="/mnt/bin/tcc -s -static -g0" \
          LDFLAGS="-s -static -g0" \
          AR="/mnt/bin/tcc -ar" \
          RANLIB="echo" LIBS="-lcurses -lterminfo" ./configure --disable-rpath \
          --disable-nls --disable-nls-catalogs --prefix="/" --without-gnu-ld

make -j2
make DESTDIR="/mnt/" install
ln -sf tcsh /mnt/bin/csh
make clean

#load /etc/profile script
cat << . > /mnt/root/.cshrc
source /etc/profile
.


2.13. Make


env CC="/mnt/bin/tcc -s -static -g0" \
          LDFLAGS="-s -static -g0" \
          AR="/mnt/bin/tcc -ar" \
          RANLIB="echo" LD="echo" ./configure --prefix="/" --disable-nls --disable-rpath \
          --bindir=/bin --sbindir=/bin --libexecdir=/bin --without-gnu-ld

make -j2
make DESTDIR="/mnt/" install
make distclean

2.14. Byacc


env CC="/mnt/bin/tcc -s -static -g0" \
          LDFLAGS="-s -static -g0" \
          AR="/mnt/bin/tcc -ar" \
          RANLIB="echo" ./configure --prefix=/
make -j2
make DESTDIR="/mnt/" install
make distclean

2.15. Awk


env HOSTCC="/mnt/bin/tcc -s -static -g0" \
          AR="/mnt/bin/tcc -ar" RANLIB="echo" YACC="/mnt/bin/yacc -d -b awkgram" \
make -e -j2

mv ./a.out /mnt/bin/awk
make distclean

2.16. Gsed

(building dependency uhh :/)


env CC="/mnt/bin/tcc -s -static -g0" \
          LDFLAGS="-s -static -g0" \
          AR="/mnt/bin/tcc -ar" \
          RANLIB="echo" ./configure --prefix=/ --disable-nls --disable-rpath \
          --without-selinux

make -j2
make DESTDIR="./GSED/" install
mv GSED/bin/sed /mnt/bin/gsed
mv GSED/share/man/man1/sed.1 /mnt/share/man/man1/gsed.1

rm -r ./GSED
make distclean


2.17. Ggrep

(another building dependency :/)


env CC="/mnt/bin/tcc -s -static -g0" \
          LDFLAGS="-s -static -g0" \
          AR="/mnt/bin/tcc -ar" \
          RANLIB="echo" ./configure --prefix=/ --disable-nls \
          --disable-rpath --enable-threads=posix --without-gnu-ld

make -j2
make DESTDIR="../GGREP/" install

mv GGREP/bin/grep /mnt/bin/ggrep
mv GGREP/share/man/man1/grep.1 /mnt/share/man/man1/ggrep.1
rm -r ./GGREP/

make distclean

2.18. Linux-Headers


ln -sf /mnt/bin/gsed ./sed

make PATH="./:$PATH" ARCH="x86" HOSTCC="/mnt/src/gcc-toolchain/bin/gcc -Os -pipe -march=native -g0 -s -static -w" headers -j2

find usr/include/ -name \*.h -type f | while read -r file;
do f="${file%/*}"
         f="${f#usr}"
         mkdir -p -v /mnt$f/
         cp -f -v $file /mnt$f/
done

make CC="/mnt/src/gcc-toolchain/bin/gcc -s -static -g0" HOSTCC="/mnt/src/gcc-toolchain/bin/gcc -s -static -g0" ARCH="x86" distclean -j2
rm ./sed


2.19. Stage 2

2.20. Entering Chroot


chroot /mnt /bin/csh
source /etc/profile

2.21. Libz


./configure --prefix=/ --disable-shared --enable-static
make -j2
make install
make distclean

2.22. Pigz


make -e -j2
mv ./pigz /bin/pigz
ln -s pigz /bin/gzip

2.23. Xz


env LD="echo" ./configure --prefix=/ --disable-doc --disable-microlzma \
              --disable-lzip-decoder --enable-small --enable-threads=posix \
              --disable-lzmadec --disable-lzmainfo --disable-lzma-links \
              --disable-scripts --enable-sandbox=no --enable-static \
              --disable-nls --disable-rpath --without-gnu-ld --disable-shared \
              --without-pic

make LDFLAGS="-s -static -g0 -all-static" -j2
make install
make distclean

2.24. E2fsprogs


env CONFIG_SHELL="sh" LD="echo" RANLIB="echo" \
  ./configure --prefix=/ --sbindir=/bin \
  --sysconfdir=/etc --enable-libuuid --enable-libblkid \
  --disable-symlink-install --disable-nls --disable-fsck \
  --disable-elf-shlibs --enable-largefile --disable-rpath

sed -e '101,104d;179,181d' ./lib/ext2fs/rbtree.h > _
mv -f _ ./lib/ext2fs/rbtree.h

sed '1 s/ sh/\/bin\/sh/' config.status > _
mv -f _ ./config.status
chmod +x ./config.status

make -j2
make install -j2

make distclean

2.25. Less

replace 'e3em' with your editor of choice.


env LIBS="-lcurses" LD="echo" CC="tcc -s -static -g0" \
          ./configure --prefix=/ --with-no-float --with-editor=e3em \
          --with-regex=posix

make -j2
make install
make distclean

2.26. Mandoc


 sed -e 's/=ar/=\"tcc -ar\"/' -e 's/=cc/=\"tcc -s -static -g0\"/'  \
         -e 's/LOCALE=/LOCALE=us/' -e 's/LDFLAGS=/LDFLAGS=\"\$LDFLAGS\"/' \
         -e 's/\/usr\/local//' -e 's/more/less/' -e 's/\/usr//' \
     -e 's/\/sbin/\/bin/' configure > _

 mv -f _ configure
 chmod +x configure

./configure

make -j2
make MANDIR=/share/man/ install
make distclean

2.27. BearSSL


sed 's/cc/tcc/' conf/Unix.mk > _
mv -f _ conf/Unix.mk

make -e -j2

cp ./inc/* /include/
cp ./build/libbearssl.a /lib/
cp ./build/brssl /bin/
cp ./build/obj/* /lib/

make clean

2.28. LibTLS-BearSSL


 cut -f1 -d ",--version" Makefile > _
 mv -f _ Makefile
 make -j2

env PREFIX=/ make -e install-static
make clean

2.29. NetTools

for building this we shall quit the chroot environment for a moment to configure and then go back to build the package since you'll need bash for running some necessary scripts for configuring it huh. so… here we go.


exit # you leave the chroot enviroment
cd /mnt/src/sources/net-tools/

env CC="/mnt/src/gcc-toolchain/bin/gcc -L/mnt/lib -I/mnt/include -w" \
          LDFLAGS="-s -static -g0" CFLAGS="-Os -pipe -march=native" \
          AR="/mnt/src/gcc-toolchain/bin/ar" RANLIB="/mnt/src/gcc-toolchain/bin/ranlib" \
          make -j2 #configure what you need

env CC="/mnt/src/gcc-toolchain/bin/gcc -L/mnt/lib -I/mnt/include -w" \
          LDFLAGS="-s -static -g0" CFLAGS="-Os -pipe -march=native" \
          AR="/mnt/src/gcc-toolchain/bin/ar" RANLIB="/mnt/src/gcc-toolchain/bin/ranlib" \
          make -j2

cd /mnt/src;
chroot /mnt /bin/csh #comming back to the action!!
source /etc/profile
cd /src/sources/net-tools

make -e -j2

make -e install DESTDIR="./NETTOOLS"
mv ./NETTOOLS/bin/* /bin/
mv ./NETTOOLS/sbin/* /bin/

rm -r ./NETTOOLS/
make clean

2.30. Tiny-Curl

i disabled many features i didn't use here, remember that you can issue the "–help" flag to ./configure to see a list of options and things to enable or disable, choose what fit your needs.


env CC="/src/gcc-toolchain/bin/gcc -Os -pipe -march=native -w -s -static -g0" \
          AR="/src/gcc-toolchain/bin/ar" RANLIB="/src/gcc-toolchain/bin/ranlib" \
          LDFLAGS="-s -static -g0 -L/lib -I/include" LD="echo" LIBS="-lbearssl -L/lib -I/include" \
          ./configure --prefix=/ --bindir=/bin --sbindir=/bin \
          --enable-unix-sockets --enable-symbol-hiding --disable-ipv6 \
          --disable-ldap --disable-ares --with-bearssl=/ \
          --without-pic --without-librtmp \
          --without-icu --without-libpsl --without-libidn \
          --without-libidn2 --without-brotli --without-zstd \
          --enable-static --without-shared --without-zsh-functions-dir \
          --without-fish-functions-dir --without-gnu-ld --disable-manual \
          --enable-pthreads --disable-ntlm --disable-mqtt --disable-libgcc \
          --disable-sspi --disable-ntlm-wb --disable-doh --disable-mime \
          --disable-netrc --disable-progress-meter --disable-dnsshuffle \
          --disable-alt-svc --without-nss --without-mesalink --without-hyper \
          --without-ldap --without-gssapi --without-libgsasl \
          --without-libssh2 --without-libssh --without-winidn \
          --without-quiche --disable-ech \
          --disable-curldebug --disable-debug --disable-ldaps --disable-rtsp \
          --disable-telnet --disable-tftp --disable-smb \
          --disable-cookies --without-schannel \
          --without-secure-transport

make LDFLAGS="-s -static -all-static -g0" -j2
make LDFLAGS="-s -static -all-static -g0" -j2 -i #if an error related with the docs appears you can just ignore it with -i
make install -j2
make clean -j2
make distclean -j2

2.31. EIWD

you don't really need eiwd unless you are planning to use a wifi connection.


env LD="echo" CC="/src/gcc-toolchain/bin/gcc -Os -pipe -march=native -s -static -g0" \
          ./configure --prefix=/ --libexecdir=/bin --bindir=/bin --sbindir=/bin \
          --disable-systemd-service --disable-dbus-policy --disable-dbus --localstatedir=/var \
          --disable-manual-pages --disable-pie --disable-shared --enable-static

sed 's/$(LDFLAGS) -o/-all-static $(LDFLAGS) -o/' Makefile > _
mv -f _ Makefile
make -j2
make install
make distclean

creating the configuration file: i will edit the files using the classic redirections but you can use any of the default text editors, ed or e3. remember to replace "YourSSID" and "YourPassphrase" with your data.


mkdir -p /etc/iwd /var/lib/iwd/
touch /etc/iwd/main.conf

cat << . > /etc/iwd/main.conf
[General]
EnableNetworkConfiguration=true
NameResolvingService=none
UseDefaultInterface=true

[Network]
RoutePriorityOffset=200

[Scan]
DisablePeriodicScan=true
.
cat << . > /var/lib/iwd/YourSSID.psk
[Security]
Passphrase=YourPassphrase
.

2.32. Kernel

user's job ;D

yep, now you are all alone for this part. mostly because there's so much to explain and so many options to configure. also, everything will be different for each different hardware- unless you build a generic kernel of course, but it isn't the ideal of the project. i'll give you some advice though:

for the config you can look for some guides or just keep tweaking options until it works (how does that sound? very professional of course!), thing is, after messing for a while with it things will start to make more sense. that worked for me, now it's easier. also read the info of each option you change, so you can get an idea of what you are doing, you'll learn something, and well, generally it'll just help.

i have some personal config files uploaded on my git so you can check it out if you want. they are insecure and very unlikely to work on your hardware though, since i made them specifically for my computer and my needs. btw, i use these patches: uncompressed.diff / O3-for-all-architectures, they are very neat.

this is a very important part, here you should debloat the kernel as much as possible. the kernel is the core of your system. suckless from scratch, being all the core userland software, will just interact with and give instructions to the kernel, if the kernel is bloated then this whole thing is kinda pointless.

ok but, how would you make it "suck less"? first of all i encourage you to use a module-less configuration. build everything statically in the kernel. suckless from scratch doesn't use an initramfs so it is a must, unless you really need one of course. (you probably don't) after you take a good look to the config and options in general you can use the ncurses menu to choose and see info about each option. another and very important way to make your kernel suck less, (and way more less) is by enabling and giving support only to what you need- why would you need support for a ps2 keyboard if you don't even have the port for it, nor even the keyboard to begin?. that happens with more of a thousand other types of devices, motherboard related features and support, efi and bios, file systems, and many many other options you'll find around. just keep what you need and only what you need, keep polishing until you are comfortable with the result and be prepared to see some kernel panics before getting it in the right spot- just don't panic yourself, those are very normal around here.

there's also so many security options… it depends on what you need. this project isn't about making a hardened system and i am not into hardening my kernel either so, it depends on what you want and what your specific needs are. note that security features usually get the kernel very, very bloated– just saying, but lots of the bloat and memory usage comes from there.

also note that sfs doesn't have a hostname file as many distributions do, that's because it will use the kernel's default hostname value instead- so change it to whatever you want. as you will see later in the 'ninit' section, you might also want to change the init path to '/bin/init' instead of sbin. if you are planning not to use an external bootloader you can use your kernel as one. this is only possible if you have efi, in case you do, don't forget to enable such option in your kernel "CONFIGEFISTUB" i'll explain more in the Bootloader Section.

2.33. Ninit

sfs only uses one /bin folder for all the binaries of the system, so the init will be installed in there. you must specify that in the kernel config, replacing /sbin/init with /bin/init.


cd src

make -e -j2
make NINITBIN=/bin install
make clean

ln -sf /bin/nhalt /bin/halt
ln -sf /bin/nhalt /bin/reboot
ln -sf /bin/ninit /bin/init

cd ../

you may want to write your own boot and halt init scripts, your service/daemon scripts you want running at booting time, and so on. you'll have an example of a working set of scripts that i wrote at: "/ninit/initscripts/sfs" or "/ninit/initscripts/voidlinux" (for voidlinux) you can take them as an example for writing yours or just use mine if you'd like.

i will proceed to install my own:


cp ./initscripts/sfs/boot /etc/ninit/boot
cp ./initscripts/sfs/halt /etc/ninit/halt

mkdir -p /etc/ninit/scripts
mkdir -p /etc/ninit/services

cp ./initscripts/sfs/scripts/* /etc/ninit/scripts/
cp ./initscripts/sfs/services/* /etc/ninit/services/avail/

#activate services
#you can activate them by hand. list the servies
#in /etc/ninit/services/avail and activate each with
#sv -a service_name; or just iterate with csh
#on all of them, you can write a script for this
#if you think you will need to do this frequently.
#(aka: you're lazy)

#write by hand:
foreach s (/etc/ninit/services/avail/*)
   sv -a `basename $s`
end

#let's make sure the folder and its files have the right permissions.
chmod -R 700 /etc/ninit

2.34. Bootloader

if you have an EFI or UEFI system you don't need to have a third party bootloader since the kernel can act as one, learn about EFISTUB.

if this is your case you can have multiple kernels that can be read as bootloaders, then you can choose which system to boot by manually typing it in your efi shell. to "install" your kernel in the efi partition just format one fat32/vfat partition and move your kernel "vmlinuz" to the EFI directory inside of said partition. preferably adding the .efi extension. as an example, i have my efi partition mounted in /boot/efi so, i will move my "vmlinuz" file to /boot/efi/EFI/sfs.efi sfs standing for Suckless From Scratch.

2.34.1. EFISTUB

\EFI\sfs.efi in /boot/efi efishell: sfs.efi root=/dev/mmcblk0p4

once inside of the efi shell, change to the specific efi partition. enter in the EFI directory, and load the kernel with: ./sfs.efi root=/dev/mmcblk0p4 that's where my root partition is. you must specify yours.

on the other side, if you really need a bootloader you can use a simple one like LILO, or ELILO for efi. it is up to you to do your own research on the subject.

sfs_meme.jpg


this project is free under public domain - do whatever you want with it

have fun! :)

Author: L. Baus (Nyght)

Created: 2025-05-10 Sat 05:07

Validate