Skip to content
Henryk Paluch edited this page Apr 19, 2024 · 5 revisions

Linux From Scratch

Cross-building and then building Linux from Scratsh (LFS). You need Host OS to start (I tested Debian 12).

Homepage:

Normally you also need at least part of BLFS (Beyond LFS) - because there are important tools including Dhcp client, SSH Server, curl, git, wget, ...

Generating PDF manuals:

It is quite easy on Fedora 39 - see top of my page Fedora. Otherwise it is lot of effort on (B)LFS because you need working Java (FOP that generates PDF is written in Java)

Automated LFS: It uses clever idea to extract scripts from Handbooks (which are written in XML Docbook) and run them from generated Makefiles. It is also used by LFS team to verify that instructions in LFS book are correct.

I thing that using ALFS is currently only sane way to start, because otherwise you have to correctly copy & paste around 90 build and install commands. It is to easy to miss something or sometimes too smart terminal will change commands without knowing that something is wrong.

ALFS Homepage: https://www.linuxfromscratch.org/alfs/

Here is my incubating project - with my configs:

Quick Setup:

  • host: Debian 12
sudo apt-get update
sudo apt-get dist-upgrade
sudo reboot
# packages for me:
sudo apt-get install tmux mc rsync
# package for LFS:
sudo apt-get install build-essential texinfo m4 gawk bison flex \
                libncurses5-dev wget subversion libxml2-utils xsltproc
# Debian 12 does not allow to release /bin/sh -> dash so we must use force!
sudo ln -sf /bin/bash /bin/sh
/bin/sh -c 'echo $SHELL'
# above must show: /bin/bash

Now we have to paste latest check script from https://www.linuxfromscratch.org/lfs/view/stable/chapter02/hostreqs.html and run it. In my case (Apr 14, 2024):

$ ./version-check.sh 

OK:    Coreutils 9.1    >= 8.1
OK:    Bash      5.2.15 >= 3.2
OK:    Binutils  2.40   >= 2.13.1
OK:    Bison     3.8.2  >= 2.7
OK:    Diffutils 3.8    >= 2.8.1
OK:    Findutils 4.9.0  >= 4.2.31
OK:    Gawk      5.2.1  >= 4.0.1
OK:    GCC       12.2.0 >= 5.2
OK:    GCC (C++) 12.2.0 >= 5.2
OK:    Grep      3.8    >= 2.5.1a
OK:    Gzip      1.12   >= 1.3.12
OK:    M4        1.4.19 >= 1.4.10
OK:    Make      4.3    >= 4.0
OK:    Patch     2.7.6  >= 2.5.4
OK:    Perl      5.36.0 >= 5.8.8
OK:    Python    3.11.2 >= 3.4
OK:    Sed       4.9    >= 4.1.5
OK:    Tar       1.34   >= 1.22
OK:    Texinfo   6.8    >= 5.0
OK:    Xz        5.4.1  >= 5.0.0
OK:    Linux Kernel 6.1.0 >= 4.19
OK:    Linux Kernel supports UNIX 98 PTY
Aliases:
OK:    awk  is GNU
OK:    yacc is Bison
OK:    sh   is Bash
Compiler check:
OK:    g++ works
OK: nproc reports 4 logical cores are available

Setup chroot:

  • in my case I cross-build in chroot - I will later create .tar and unpack it on real target
  • I use Azure VM of type Standard_E4bds_v5 which has local temporary storage mounted under /mnt
  • here is my script recreate_mnt.sh that u(n)mounts /mnt and mounts it as /mnt/build_dir (required by LFS):
#!/bin/bash
set -euo pipefail

# Found backing device
DEV=`awk '$2=="/mnt" {print $1}' /proc/mounts`

[ -n "$DEV" -a -b "$DEV" ] || {
	echo "ERROR: Unable to find backing device for /mnt" >&2
	exit 1
}
set -x
sudo umount /mnt
sudo mkdir -p /mnt/build_dir
sudo mount $DEV /mnt/build_dir
sudo chown $USER /mnt/build_dir
exit 0

Now we have to install additional requirements for ALFS:

sudo apt-get install docbook-xml docbook-xsl git-core

Clone sources:

mkdir -p ~/projects
cd ~/projects/
git clone https://git.linuxfromscratch.org/jhalfs.git
cd jhalfs
git branch -v
#   * trunk d3df258 Adapt packInstall.sh.porg to xdg-utils location
make menuconfig

WARNING! If you plan to run LFS on different CPU models (my case) you have to disable GMP optimizations:

diff -u /mnt/build_dir/jhalfs/lfs-commands/chapter08/819-gmp{.orig,}
--- /mnt/build_dir/jhalfs/lfs-commands/chapter08/819-gmp.orig	2024-04-14 08:18:15.843374261 +0000
+++ /mnt/build_dir/jhalfs/lfs-commands/chapter08/819-gmp	2024-04-14 08:20:30.882635238 +0000
@@ -37,6 +37,7 @@
 ./configure --prefix=/usr    \
             --enable-cxx     \
             --disable-static \
+	    --host=none-linux-gnu \
             --docdir=/usr/share/doc/gmp-6.3.0
 make
 make html

Only then start build under /mnt/build_dir/jhalfs

TODO

TIP: If you have earlier backup of /mnt/build_dir/sources you should unpack it to avoid downloading lot of files...

Strongly Recommended:

  • build also BLFS - it will build many essential things (curl, git,wget)

WARNING!

  • GMP crashes if you build binary for another kind CPU than that on Host system
  • when you configure DNS and also build BLFS it must work from your Host!
  • the 014-z-make-ca from BLFS otherwise will crash, because it will be unable to fetch current CA list...

WARNING!

  • do not build with pacman package manager I got this error in /mnt/build_dir/jhalfs/logs/711-11-pkgconfig
    tar: option requires an argument -- 'f'
    Try 'tar --help' or 'tar --usage' for more information.
    
  • so my advice is to start Without package manager...

Simple to solve problem is fakeroot not found:

  • main page: https://snapshot.debian.org/package/fakeroot/1.29-1/
  • download:
    cd /mnt/build_dir/sources
    curl -fLO https://snapshot.debian.org/archive/debian-debug/20220522T204931Z/pool/main/f/fakeroot/fakeroot_1.29.orig.tar.gz
  • WARNING! I was unable to download it from CURL, but using Firefox was OK...

Enter chroot after build phase (paragraph 8):

Do just this:

cd /mnt/build_dir/jhalfs/
make chroot

You will enter root shell in chroot.

One exit it will be released (including bind-nmounts).

Setup password for root

passwd root

Setup user for building:

  • WARNING! Id's 1000:1000 matches my Debian 12 host
/usr/sbin/groupadd -g 1000 lfs
/usr/sbin/useradd -g 1000 -u 1000 -m -s /bin/bash -c 'LFS User' lfs
passwd lfs

NOTE: I don't build grub - it is already done when you enable BLFS build.

In chroot create /usr/sbin/mkiniramfs

But we must first build CPIO:

  • on Host:
    cd /mnt/build_dir/home/lfs/sources
    curl -fLO https://ftp.gnu.org/gnu/cpio/cpio-2.15.tar.bz2
    md5sum -b cpio-2.15.tar.bz2 
    
    3394d444ca1905ea56c94b628b706a0b *cpio-2.15.tar.bz2
  • in chroot as "lfs" user:
    cd ~/sources/
    tar xf cpio-2.15.tar.bz2 
    cd cpio-2.15
    ./configure --prefix=/usr  
    make
  • as root in chroot:
    cd /home/lfs/sources/cpio-2.15
    make install

Building custom kernel in chroot:

  • I will misuses my Gentoo config:

Outside chroot you have to download my kernel-config from gentoo:

# on Host system:
sudo bash
cd /mnt/build_dir/usr/src/
curl -fLO https://raw.githubusercontent.com/hpaluch/gentoo-files/master/kernels/libvirt_defconfig
exit 
# ENTER LFS chroot
cd /mnt/build_dir/jhalfs/
make chroot
# now as root in chroot
tar xpvf /sources/linux-6.8.2.tar.xz -C /usr/src
cd /usr/src
ln -s linux-6.8.2 linux
cd linux
cp ../libvirt_defconfig arch/x86/configs
make libvirt_defconfig
make menuconfig
make -j`nproc`
make install # Cannot find LILO (TODO)
# workaround: cp arch/x86_64/boot/bzImage /boot/vmlinuz-6.8.2-libvirt
make modules_install

Is you properly prepared initramfs you can just run:

mkinitramfs 6.8.2-libvirt
mv initrd.img-6.8.2-libvirt /boot/

Here is my example /boot/grub/grub.cfg

xxxx

Initrd NOTE:

  • I have to manually load disk driver in /usr/share/mkinitramfs/init.in
    • for AHCI I added there modprobe ahci
    • for VirtIO SCSI Q35 I added there modprobe virtio_pci
  • also you may need to append rootdelay=5 to kernel boot parameters in /boot/grub/grub.cfg
Clone this wiki locally