The Suckless From Scratch Project

Table of Contents

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 "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 no only one true way for doing something, in this case a Linux From Scratch building. i never completly read that book so i figured this out by myself ;)

of course, this is a personal guide where i've got to choose the software and the way i wanted to build and install it, you can change whatever you want to make it fit your needs. that's the magic of building a linux system from stratch system, you can make it the way you want it. 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. (my personal init, you can use whatever you want tho)
  • a completly TTY oriented user environment, only Framebuffer/DRM Graphics. (more in: 'Post-SFS')
  • Sbase and Ubase as the system core
  • almost completly compiled with the TinyCC (TCC) compiler.
  • everything Statically built.
  • 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 spagetti of directory symlinks pointing to everywhere, only one /bin folder and no /usr directory.

1.3. Before Everything

You could use any live distribution or 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 already have those packages 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 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

  • 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

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, obviouslly 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 i need to get the system working, and nothing else really. which is way, way less than what linux from scratch requires for its core system. 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 whith it. your rules!!

you'll need this 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 might be outdated by now.


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 dind'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 gussed 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 enviroment 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 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 hardware. unless you build a generic kernel of course, but it isn't the ideal of this 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!), after messing for a while with it things will start making 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 will 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?. 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 confortable 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 on your specific needs. note that security features usually get the kernel very, very bloated. just saying but lots of the bloat and memory usage comes from there. alse note that sfs doesn't have a hostname file, that's because it will use the kernel's default hostname instead. so change it to whatever you want. as you will see later in 'ninit' 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, so the init will be installed 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 mine's


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 wich 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.

Author: LB. (Nyght)

Created: 2024-11-20 Wed 13:39

Validate