+------------------------------------------------------------------------------+ | Tin Can Linux installation guide (the hard way) | +------------------------------------------------------------------------------+ This is a guide to building Tin Can Linux from the ground up by bootstrapping the system yourself. This is a somewhat advanced process, so make sure you know what you're doing! Unless you want to tinker with the process or need to build for a different architecture, the easy method is recommended. === Contents ============ [010] Bootstrapping the system [011] Obtain sources [012] Initial bootstrap [013] Obtain the repositories [014] Enter chroot environment [015] Rebuild the system [020] Finish repository setup [021] Obtain the repositories [022] Set $ARC_PATH [030] Rebuild the system (again) [031] Set compiler flags [032] Rebuild all packages [040] Set up Linux kernel [041] Download kernel sources [042] Download firmware blobs [043] Install required packages [044] Configure the kernel [045] Build and install the kernel [050] Install more packages [051] Init scripts [052] Bootloader [053] Filesystem utilities [054] Networking utilities [055] Other optional tools [060] Make the system bootable [061] Setup disks [062] Create /etc/fstab [063] Install Tin Can to disk [064] Install bootloader [070] Post installation [071] Set root password [072] Create a normal user [073] Graphical environment [074] Get counted === Bootstrapping the system [010] ================================== This step involves building a preliminary rootfs which you can enter via a chroot environment. === Obtain sources [011] Clone the main git repo, $/tincan-linux/tincan, with the following command: -------------------------------------------------------------------------------- $ git clone --recurse-submodules https://github.com/tincan-linux/tincan -------------------------------------------------------------------------------- This will obtain the bootstrap scripts along with the required submodules (the bootstrap process uses $/firasuke/mussel to build an initial cross compiler toolchain) Then cd into this directory. === Initial bootstrap [012] To perform the initial bootstrap, simply run: -------------------------------------------------------------------------------- $ ./bootstrap -------------------------------------------------------------------------------- This (should) generate an initial root filesystem from which the distribution will be built. === Obtain the repositories [013] For this initial rootfs, only $/tincan-linux/repo-core is required. Clone it into the rootfs with: -------------------------------------------------------------------------------- $ mkdir -pv sysroot/var/repo $ git clone https://github.com/tincan-linux/repo-core sysroot/var/repo/core -------------------------------------------------------------------------------- === Enter chroot environment [014] The next step is to enter a chroot environment with sysroot/ as the new root. For convenience, a modified version of kiss-chroot is provided; to enter the chroot, execute the following (with root privileges): -------------------------------------------------------------------------------- # ./arc-chroot sysroot -------------------------------------------------------------------------------- If all goes well, you should be presented with some lines of text that indicate filesystems being mounted, followed by a shell prompt. === Rebuild the system [015] Once inside the chroot environment, you must rebuild all the packages, since mussel does not use the latest versions, and also to start tracking packages with arc, the package manager (see @/wiki/arc for more information on it). First, you will need to make sure that the compiler is able to find all needed header files for compiling packages. Right now, it is likely using an incorrect include path that is based on the direcory where ./bootstrap was run. First, find out what this path is by executing the following: -------------------------------------------------------------------------------- # gcc -v -x c -E /dev/null -------------------------------------------------------------------------------- This will produce a bunch of diagnostic output about GCC. In this output, look for the lines that are similar to the following (they should be somewhere in the middle): -------------------------------------------------------------------------------- gcc version 13.2.0 (GCC) COLLECT_GCC_OPTIONS='-v' '-E' '-mtune=generic' '-march=x86-64' /lib/gcc/x86_64-linux-musl/13.2.0/cc1 -E -quiet -v /dev/null -mtune=generic -ma rch=x86-64 -dumpbase null ignoring nonexistent directory "/home/xxxxx/tincan/sysroot/usr/local/include" ignoring nonexistent directory "/lib/gcc/x86_64-linux-musl/13.2.0/../../../../x8 6_64-linux-musl/include" ignoring nonexistent directory "/home/xxxxx/tincan/sysroot/usr/include" #include "..." search starts here: #include <...> search starts here: /lib/gcc/x86_64-linux-musl/13.2.0/include End of search list. -------------------------------------------------------------------------------- The last nonexistent directory, /home/xxxxx/tincan/sysroot/usr/include, is what we need. Create this directory and point it to /include (replace this with the approrpiate path, based on the previous output): -------------------------------------------------------------------------------- # mkdir -pv /home/xxxxx/tincan/sysroot/usr/ # ln -sv /include /home/xxxxx/tincan/sysroot/usr/include -------------------------------------------------------------------------------- Now, if you re-run the gcc command from above, there should be an additional directory under '#include<...>': -------------------------------------------------------------------------------- #include <...> search starts here: /home/xxxxx/tincan/sysroot/usr/include /lib/gcc/x86_64-linux-musl/13.2.0/include End of search list. -------------------------------------------------------------------------------- Now, we are ready to build the packages. The packages must be built in a specific order for everything to work as expected. Perform the following (in this exact order): -------------------------------------------------------------------------------- # arc b linux-headers # arc b musl # arc b m4 # arc b binutils # arc b gcc # arc b make # arc b busybox # arc b rustup # rustup default stable # arc b arc Or in a single command, so you can walk away and come back later: # arc yb linux-headers && arc yb musl && arc yb m4 && arc yb binutils \ && arc yb gcc && arc yb make && arc yb busybox && arc yb rustup \ && rustup default stable && arc yb arc Remove the compatibility symlink to /include: # rm -rf /home/xxxxx -------------------------------------------------------------------------------- Hopefully, everything will go well. If not, exit the chroot, remove the sysroot/ directory, and start back at [012]. From this point on, the guide is very similar to the easy method. As the maintainer of Tin Can Linux, this is where I would clean up some stuff and create a tarball of the rootfs. === Finish repository setup [020] ================================= In this step, we will finish proper setup of the official repositories. === Obtain the repositories [021] Temporarily exit the chroot environment, as we haven't yet installed git inside the rootfs: -------------------------------------------------------------------------------- # exit -------------------------------------------------------------------------------- This will unmount the filesystems that were previously mounted and drop you back into the host machine's shell. From there, we can clone the remaining repos: -------------------------------------------------------------------------------- $ git clone https://github.com/tincan-linux/repo-extra sysroot/var/repo/extra $ git clone https://github.com/tincan-linux/repo-xorg sysroot/var/repo/xorg -------------------------------------------------------------------------------- Now re-enter the chroot: -------------------------------------------------------------------------------- # ./arc-chroot -------------------------------------------------------------------------------- === Set $ARC_PATH [022] The environment variable $ARC_PATH is used by arc to determine where to find the repositories. This allows you to install repositories to any location on the system. To let arc know where to find the official repositories, add this line to /etc/profile: -------------------------------------------------------------------------------- export ARC_PATH=/var/repo/core:/var/repo/extra:/var/repo/xorg -------------------------------------------------------------------------------- Then, source /etc/profile to apply the changes to your current shell: -------------------------------------------------------------------------------- # source /etc/profile -------------------------------------------------------------------------------- From now on, arc will look for packages in /var/repo/core, /var/repo/extra, and /var/repo/xorg. See @/wiki/arc to learn more about how $ARC_PATH works. === Rebuild the system (again) [030] ==================================== In order to ensure that all packages have been built with the latest versions of dependencies, and to install some packages that were not included the first time, we will rebuild all the packages in the system. === Set compiler flags [031] It may be helpful to set the following compiler flags: - CFLAGS: Setting one of '-O2', '-Os', or '-O3' can be used to optimize the binaries that are produced. - CFLAGS: Setting '-pipe' can speed up compilation at the cost of higher memory usage. - CFLAGS: Setting '-march=native' makes the compiler use processor-specific optimizations. Omit this if you are planning to create a portable install (e.g. on a thumb drive) - MAKEFLAGS: Setting '-j$(nproc)' will enable builds to use all available CPU cores. However, this can make it harder to track down compile errors. With this in mind, add the following lines to /etc/profile: -------------------------------------------------------------------------------- export CFLAGS="-O3 -pipe -march=native" export CPPFLAGS="$CFLAGS" export CXXFLAGS="$CFLAGS" export MAKEFLAGS="-j$(nproc)" -------------------------------------------------------------------------------- And source it to apply the changes to your current shell: -------------------------------------------------------------------------------- # source /etc/profile -------------------------------------------------------------------------------- === Rebuild all packages [032] Run the following to rebuild all packages (and install some new ones): -------------------------------------------------------------------------------- # arc b arc binutils bison busybox certs flex gcc git gmp \ linux-headers m4 make mpc mpfr musl rustup zlib -------------------------------------------------------------------------------- === Set up Linux kernel [040] ============================= This step will detail how to configure, build, and install the Linux kernel. === Download kernel sources [041] First, you will need to select a kernel. There are a few common variants: - Vanilla kernel. Nothing special. - Hardened kernel. A fork of the kernel focused on security. - Long term kernel. Designed for long-term support and server usage. - Zen kernel. An effort by kernel hackers to improve the vanilla kernel. There are also some other less common kernels; see this Arch Wiki article for more information. The kernel sources can then be obtained from one of these URLs, depending on which variant you want to use: - Vanilla: https://www.kernel.org/ - Hardened: https://github.com/anthraxx/linux-hardened - Long term: https://www.kernel.org/ - Zen: https://github.com/zen-kernel/zen-kernel Then download and extract it with the following: -------------------------------------------------------------------------------- # curl -fLO [KERNEL_SOURCE] # tar xf [KERNEL_SOURCE] # cd [KERNEL_SOURCE] -------------------------------------------------------------------------------- === Download firmware blobs [042] It is likely that your hardware may need some additional firmware that isn't provided in the kernel. Some of this firmware can be found at this mirror: https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git Other firmware, such as Intel Microcode, may need to be obtained from other sources. See @/wiki/kernel for more detailed info on selecting and obtaining the correct firmware for your hardware. After obtaining the necessary firmware, extract the tarballs and copy required files to /usr/lib/firmware: -------------------------------------------------------------------------------- # tar xf [FIRMWARE] # mkdir -pv /usr/lib/firmware # cp -R ./path/to/blob /usr/lib/firmware/ -------------------------------------------------------------------------------- === Install required packages [043] Some additional packages are required beyond the ones installed so far in order to compile the kernel. Install them now: -------------------------------------------------------------------------------- # arc b libelf pkgconf For menuconfig support (highly recommended): # arc b ncurses -------------------------------------------------------------------------------- === Configure the kernel [044] This is one of the most critical (and also tricky) steps of the process. Doing something wrong here can prevent your system from booting. While there are many ways to go about configuring the kernel, I will be presenting one method here which has worked for me. Start with a default config, which should include some sane default settings, then open the configuration menu: -------------------------------------------------------------------------------- # make defconfig # make menuconfig -------------------------------------------------------------------------------- This will open a blue TUI where you can configure the kernel options. While there isn't a one-size-fits-all procedure for this part of the process, here are some bits that I found are important to note: - YOU NEED GRAPHICS DRIVERS!!! One of the most common pitfalls with kernel configuration is leaving out a graphics driver, usually for the framebuffer. Your system probably will not boot without these options: - CONFIG_FB - CONFIG_FB_CORE - CONFIG_FB_DEVICE - CONFIG_FB_NOTIFY - CONFIG_FRAMEBUFFER_CONSOLE - CONFIG_SYSFB - CONFIG_SYSFB_SIMPLEFB Additionally, some combination of these may be needed: - CONFIG_FB_EFI - CONFIG_FB_VESA - CONFIG_FB_VGA16 - CONFIG_DRM_FBDEV_EMULATION There may be some other ones beyond these that I haven't covered. A good check is to do 'grep "FB" .config && grep "FRAMEBUFFER" .config' to see what other framebuffer-related graphics drivers are available. In additon to these, graphics drivers for specific graphics cards are also probably needed, such as: - CONFIG_DRM_I915 for Intel graphics cards - CONFIG_DRM_AMDGPU for AMD graphics cards - CONFIG_DRM_SIMPLEDRM + additional firmware for NVIDIA graphics cards; see https://wiki.archlinux.org/title/NVIDIA - Specific hardware, such as WiFi cards, touchpads, etc. may also require additional kernel options to be enabled. A good way to see what's needed is to run 'lspci' and 'lsmod' from the live environment: - 'lspci' gives information on installed hardware devices, so that you can look up what drivers are needed for your specific model. - 'lsmod' tells you what kernel modules are currently loaded. This can point out some options that need to be enabled in the kernel (just google the module name to find its equivalent in the kernel menuconfig) - The Gentoo Wiki is a great source of information about kernel configuration. Try looking up your model or laptop brand to see if it has a dedicated wiki page with kernel configuration info. For example, I found this one for the Framework Laptop that saved me a lot of trouble. - If you're stuck, Reddit is your friend! There's probably someone out there who had the same problem you do, and if not, there are plenty of communities where you could ask a question and see if someone can help you get to the answer. - Also check out @/wiki/kernel which serves as a place for all things related to kernel configuration. Tips, tricks, etc. Although it's looking kinda empty right now :( Once that's done, change all modules to baked-in (since modules are yucky): -------------------------------------------------------------------------------- # sed -i 's/=m/=y/g' .config -------------------------------------------------------------------------------- === Build and install the kernel [045] Execute the following commands to build and install the kernel: -------------------------------------------------------------------------------- # make # make install # mv /boot/vmlinuz /boot/vmlinuz-[VERSION] # mv /boot/System.map /boot/System.map-[VERSION] -------------------------------------------------------------------------------- The 'make install' step may throw a LILO error. This is normal and doesn't indicate any problems in the build or install process. === Install more packages [050] =============================== In this section, we will install some more pacakges -- the final ones needed before we can make the system bootable. === Init scripts [051] The package 'tincan-base' provides a tiny init script, $/tincan-linux/init along with some files unique to Tin Can Linux. Install it with the following: -------------------------------------------------------------------------------- # arc b tincan-base -------------------------------------------------------------------------------- === Bootloader [052] Tin Can Linux uses $/limine-bootloader/limine instead of GRUB (why?) -- install it with this command: -------------------------------------------------------------------------------- # arc b limine -------------------------------------------------------------------------------- === Filesystem utilities [053] While not strictly required, filesystem utilities may be needed for checking disks with 'fsck': -------------------------------------------------------------------------------- # arc b e2fsprogs dosfstools -------------------------------------------------------------------------------- === Networking utilities [054] Again, these are not strictly required, but I assume most people want WiFi: -------------------------------------------------------------------------------- # arc b dhcpcd openresolv libudev-zero eiwd -------------------------------------------------------------------------------- === Other optional tools [055] These are some other utilities that you may find useful: -------------------------------------------------------------------------------- # arc b ssu -------------------------------------------------------------------------------- === Make the system bootable [060] ================================== Finally, it's time to boot your new, shiny Linux system! Go ahead and exit the chroot: -------------------------------------------------------------------------------- # exit -------------------------------------------------------------------------------- === Setup disks [061] The first step is to partition the disk that you will be installing Tin Can Linux to. You will need at least two partitions (one for boot, one for root) but this guide will use three (boot, root, and swap). First, identify your disk (I use /dev/sda in these examples). Then, for a UEFI install, run these commands as root to partition the disks: -------------------------------------------------------------------------------- # parted /dev/sda -- mklabel gpt # parted /dev/sda -- mkpart root ext4 512MB -8GB # parted /dev/sda -- mkpart swap linux-swap -8GB 100% # parted /dev/sda -- mkpart ESP fat32 1MB 512MB # parted /dev/sda -- set 3 esp on -------------------------------------------------------------------------------- And for a BIOS install: -------------------------------------------------------------------------------- # parted /dev/sda -- mklabel msdos # parted /dev/sda -- mkpart primary 512MB -8GB # parted /dev/sda -- mkpart primary linux-swap -8GB 100% # parted /dev/sda -- mkpart primary fat32 1MB 512MB # parted /dev/sda -- set 3 boot on -------------------------------------------------------------------------------- Feel free to change these partition sizes as you see fit, or add other partitions (for example, some users like to have a separate home partition). Next, format these partitions appropriately: -------------------------------------------------------------------------------- # mkfs.ext4 -L tincan /dev/sda1 # mkswap -L swap /dev/sda2 # mkfs.fat -F 32 -n boot /dev/sda3 -------------------------------------------------------------------------------- Finally, mount the root and boot partitions: -------------------------------------------------------------------------------- # mount /dev/sda1 /mnt # mkdir -pv /mnt/boot # mount /dev/sda3 /mnt/boot -------------------------------------------------------------------------------- === Create /etc/fstab [062] Now that the disks are set up, you will need to create the /etc/fstab file. As the root user, create sysroot/etc/fstab (we're not in the chroot anymore) with these contents, assuming the partitioning scheme above: -------------------------------------------------------------------------------- # Begin /etc/fstab # file system mount-point type options dump fsck LABEL=boot /boot vfat defaults 0 0 LABEL=tincan / ext4 defaults 0 1 LABEL=swap swap swap pri=1 0 0 proc /proc proc nosuid,noexec,nodev 0 0 sysfs /sys sysfs nosuid,noexec,nodev 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 tmpfs /run tmpfs defaults 0 0 devtmpfs /dev devtmpfs mode=0755,nosuid 0 0 tmpfs /dev/shm tmpfs nosuid,nodev 0 0 cgroup2 /sys/fs/cgroup cgroup2 nosuid,noexec,nodev 0 0 # End /etc/fstab -------------------------------------------------------------------------------- === Install Tin Can to disk [063] To install your shiny new distro, simply copy the contents of sysroot/ to /mnt: -------------------------------------------------------------------------------- # cp -R sysroot/* /mnt/ -------------------------------------------------------------------------------- === Install bootloader [064] The final step is to install the bootloader. First, re-enter the chroot with: -------------------------------------------------------------------------------- # ./arc-chroot /mnt -------------------------------------------------------------------------------- Then, for a BIOS install (run from the chroot): -------------------------------------------------------------------------------- # cp /usr/share/limine/limine-bios.sys /boot/ # limine bios-install /dev/sda -------------------------------------------------------------------------------- Or for a UEFI install: -------------------------------------------------------------------------------- # mkdir -pv /boot/EFI/BOOT # cp /usr/share/limine/BOOTX64.EFI /boot/EFI/BOOT/ -------------------------------------------------------------------------------- Next, create /boot/limine.conf with this content: -------------------------------------------------------------------------------- timeout: 5 /Tin Can Linux protocol: linux kernel_path: boot():/vmlinuz-[VERSION] kernel_cmdline: root=UUID=xxxx-xx--xxx ro loglevel=3 rootwait quiet -------------------------------------------------------------------------------- To get the UUID of your root partition, simply run 'blkid'. You can also replace the 'UUID=xxxx' part with '/dev/sda1' but this may be less reliable than using the disk's UUID. If there's a kernel panic when booting that somewhat resembles 'VFS not syncing' then try replacing the UUID with /dev/sda1. And that's it! Tin Can Linux should now be installed. Exit the chroot, then reboot to enter your shiny new system: -------------------------------------------------------------------------------- # exit # reboot now -------------------------------------------------------------------------------- Oh, what's that? It didn't work? Here are some reasons why: - It doesn't even reach the bootloader: - You may have secure boot enabled. - It gets to the bootloader, but hangs at a black screen: - Congratulations, your kernel configuration didn't work! Go back to [044] and play around with some stuff. If it did work, and you reach a login prompt, then congratulations! Enjoy your very own scrappy distro! === Post installation [070] =========================== Now that you've booted into Tin Can Linux, here's some stuff you can do: === Set a root password [071] PLEASE DO THIS. IT'S A SECURITY RISK IF YOU DON'T. -------------------------------------------------------------------------------- # passwd root -------------------------------------------------------------------------------- === Create a normal user [072] Avoid accidentally wrecking your system: -------------------------------------------------------------------------------- # adduser [USER] # passwd [USER] -------------------------------------------------------------------------------- === Graphical environment [073] Install the xorg server and some other bits to make it work: -------------------------------------------------------------------------------- # arc b xorg-server sx xf86-input-libinput -------------------------------------------------------------------------------- Window managers, terminals, etc are not provided. You will have to obtain and build these yourself. I recommend trying out sowm for a window manager, st for a terminal, and dmenu to launch programs. And to install a minimal web browser: -------------------------------------------------------------------------------- # arc b netsurf -------------------------------------------------------------------------------- === Get counted [074] Now that you're a user of Tin Can Linux, head on over to @/register to get counted and immortalize yourself in the Tin Can Linux user list! You can also see who else is using Tin Can Linux. === Resources ============= These are some resources used throughout the making of this guide, in no particular order: - https://www.linuxfromscratch.org - https://github.com/firasuke/mussel - https://kisslinux.github.io - https://nixos.org/manual/nixos/stable - https://wiki.archlinux.org/title/Limine - https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Kernel - https://wiki.gentoo.org/wiki/Framework_Laptop_13 - https://wiki.archlinux.org/title/Kernel - https://wiki.archlinux.org/title/NVIDIA ________________________________________________________________________________ AVS Origami (C) 2024