linux_dist
Markdown

Complete Build Summary

Complete Linux Distribution Build Summary

Quick Reference Guide - All Steps from Scratch to Bootable System


Phase 1: Preparation (Host System)

1. Verify Host System Requirements

# Create version check script
cat > version-check.sh << "EOF"
#!/bin/bash
export LC_ALL=C
bash --version | head -n1 | cut -d" " -f2-4
MYSH=$(readlink -f /bin/sh)
echo "/bin/sh -> $MYSH"
echo $MYSH | grep -q bash || echo "ERROR: /bin/sh does not point to bash"
unset MYSH
echo -n "Binutils: "; ld --version | head -n1 | cut -d" " -f3-
bison --version | head -n1
echo -n "Coreutils: "; chown --version | head -n1 | cut -d")" -f2
diff --version | head -n1
find --version | head -n1
gawk --version | head -n1
gcc --version | head -n1
g++ --version | head -n1
grep --version | head -n1
gzip --version | head -n1
cat /proc/version
m4 --version | head -n1
make --version | head -n1
patch --version | head -n1
echo Perl `perl -V:version`
python3 --version
sed --version | head -n1
tar --version | head -n1
makeinfo --version | head -n1
xz --version | head -n1
echo 'int main(){}' > dummy.c && g++ -o dummy dummy.c
if [ -x dummy ]; then echo "g++ compilation OK"; else echo "g++ compilation failed"; fi
rm -f dummy.c dummy
EOF

bash version-check.sh

2. Create Partitions

# Using fdisk or cfdisk
cfdisk /dev/sda

# Recommended layout:
# /dev/sda1  200M   /boot  (optional)
# /dev/sda2  30G    /      (root)
# /dev/sda3  4G     swap

3. Create Filesystems

# Format root partition
mkfs -v -t ext4 /dev/sda2

# Initialize swap
mkswap /dev/sda3

4. Set Up Environment

# Set LFS variable
export LFS=/mnt/lfs
echo 'export LFS=/mnt/lfs' >> ~/.bashrc

# Set umask
umask 022

# Create mount point
sudo mkdir -pv $LFS

# Mount partition
sudo mount -v -t ext4 /dev/sda2 $LFS
sudo swapon -v /dev/sda3

5. Create Directory Structure

sudo mkdir -pv $LFS/{etc,var,usr,tools}
sudo mkdir -pv $LFS/usr/{bin,lib,sbin}
sudo mkdir -pv $LFS/lib64  # For 64-bit
sudo mkdir -pv $LFS/sources
sudo chmod -v a+wt $LFS/sources

6. Create Build User

# Create lfs user
sudo groupadd lfs
sudo useradd -s /bin/bash -g lfs -m -k /dev/null lfs
sudo passwd lfs

# Grant ownership
sudo chown -v lfs $LFS/{usr{,/*},lib,var,etc,bin,sbin,tools,sources}
sudo chown -v lfs $LFS/lib64

# Switch to lfs user
su - lfs

7. Set Up lfs User Environment

cat > ~/.bash_profile << "EOF"
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
EOF

cat > ~/.bashrc << "EOF"
set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
LFS_TGT=$(uname -m)-lfs-linux-gnu
PATH=/usr/bin
if [ ! -L /bin ]; then PATH=/bin:$PATH; fi
PATH=$LFS/tools/bin:$PATH
CONFIG_SITE=$LFS/usr/share/config.site
export LFS LC_ALL LFS_TGT PATH CONFIG_SITE
EOF

source ~/.bash_profile

Phase 2: Download Packages

8. Download All 102 Packages

cd $LFS/sources

# Create wget list
cat > wget-list << "EOF"
https://download.savannah.gnu.org/releases/acl/acl-2.3.2.tar.xz
https://download.savannah.gnu.org/releases/attr/attr-2.5.2.tar.gz
https://ftp.gnu.org/gnu/autoconf/autoconf-2.72.tar.xz
https://ftp.gnu.org/gnu/automake/automake-1.18.1.tar.xz
https://ftp.gnu.org/gnu/bash/bash-5.3.tar.gz
https://github.com/gavinhoward/bc/releases/download/7.0.3/bc-7.0.3.tar.xz
https://sourceware.org/pub/binutils/releases/binutils-2.45.tar.xz
https://ftp.gnu.org/gnu/bison/bison-3.8.2.tar.xz
https://www.sourceware.org/pub/bzip2/bzip2-1.0.8.tar.gz
https://ftp.gnu.org/gnu/coreutils/coreutils-9.7.tar.xz
[... continue with all 102 packages ...]
EOF

# Download all packages
wget --input-file=wget-list --continue --directory-prefix=$LFS/sources

# Verify checksums (create md5sums file first)
md5sum -c md5sums

Phase 3: Cross-Compilation Toolchain (Chapter 5)

9. Binutils Pass 1

cd $LFS/sources
tar -xf binutils-2.45.tar.xz
cd binutils-2.45
mkdir build && cd build

../configure --prefix=$LFS/tools \
             --with-sysroot=$LFS \
             --target=$LFS_TGT \
             --disable-nls \
             --enable-gprofng=no \
             --disable-werror \
             --enable-new-dtags \
             --enable-default-hash-style=gnu

make
make install

cd $LFS/sources && rm -rf binutils-2.45

10. GCC Pass 1

cd $LFS/sources
tar -xf gcc-15.2.0.tar.xz
cd gcc-15.2.0

tar -xf ../mpfr-4.2.2.tar.xz && mv mpfr-4.2.2 mpfr
tar -xf ../gmp-6.3.0.tar.xz && mv gmp-6.3.0 gmp
tar -xf ../mpc-1.3.1.tar.gz && mv mpc-1.3.1 mpc

case $(uname -m) in
  x86_64) sed -e '/m64=/s/lib64/lib/' -i.orig gcc/config/i386/t-linux64 ;;
esac

mkdir build && cd build

../configure \
    --target=$LFS_TGT \
    --prefix=$LFS/tools \
    --with-glibc-version=2.42 \
    --with-sysroot=$LFS \
    --with-newlib \
    --without-headers \
    --enable-default-pie \
    --enable-default-ssp \
    --disable-nls \
    --disable-shared \
    --disable-multilib \
    --disable-threads \
    --disable-libatomic \
    --disable-libgomp \
    --disable-libquadmath \
    --disable-libssp \
    --disable-libvtv \
    --disable-libstdcxx \
    --enable-languages=c,c++

make
make install

cd .. && cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
  `dirname $($LFS_TGT-gcc -print-libgcc-file-name)`/include/limits.h

cd $LFS/sources && rm -rf gcc-15.2.0

11. Linux API Headers

cd $LFS/sources
tar -xf linux-6.16.1.tar.xz
cd linux-6.16.1

make mrproper
make headers
find usr/include -type f ! -name '*.h' -delete
cp -rv usr/include $LFS/usr

cd $LFS/sources && rm -rf linux-6.16.1

12. Glibc

cd $LFS/sources
tar -xf glibc-2.42.tar.xz
cd glibc-2.42

case $(uname -m) in
    i?86)   ln -sfv ld-linux.so.2 $LFS/lib/ld-lsb.so.3 ;;
    x86_64) ln -sfv ../lib/ld-linux-x86-64.so.2 $LFS/lib64
            ln -sfv ../lib/ld-linux-x86-64.so.2 $LFS/lib64/ld-lsb-x86-64.so.3 ;;
esac

mkdir build && cd build
echo "rootsbindir=/usr/sbin" > configparms

../configure \
      --prefix=/usr \
      --host=$LFS_TGT \
      --build=$(../scripts/config.guess) \
      --enable-kernel=5.4 \
      --with-headers=$LFS/usr/include \
      --disable-nscd \
      libc_cv_slibdir=/usr/lib

make
make DESTDIR=$LFS install

sed '/RTLDLIST=/s@/usr@@g' -i $LFS/usr/bin/ldd

# Sanity check
echo 'int main(){}' | $LFS_TGT-gcc -xc -
readelf -l a.out | grep ld-linux
rm -v a.out

cd $LFS/sources && rm -rf glibc-2.42

13. Libstdc++

cd $LFS/sources
tar -xf gcc-15.2.0.tar.xz
cd gcc-15.2.0
mkdir build && cd build

../libstdc++-v3/configure \
    --host=$LFS_TGT \
    --build=$(../config.guess) \
    --prefix=/usr \
    --disable-multilib \
    --disable-nls \
    --disable-libstdcxx-pch \
    --with-gxx-include-dir=/tools/$LFS_TGT/include/c++/15.2.0

make
make DESTDIR=$LFS install
rm -v $LFS/usr/lib/lib{stdc++{,exp,fs},supc++}.la

cd $LFS/sources && rm -rf gcc-15.2.0

Phase 4: Temporary Tools (Chapter 6)

14. Build Temporary Tools (as lfs user)

Build these in order:

# M4
./configure --prefix=/usr --host=$LFS_TGT --build=$(./config.guess)
make && make DESTDIR=$LFS install

# Ncurses (special configuration)
# Bash
# Coreutils
# Diffutils
# File
# Findutils
# Gawk
# Grep
# Gzip
# Make
# Patch
# Sed
# Tar
# Xz
# Binutils Pass 2
# GCC Pass 2

Standard pattern for most:

tar -xf <package>.tar.xz
cd <package>
./configure --prefix=/usr --host=$LFS_TGT --build=$(./config.guess)
make
make DESTDIR=$LFS install
cd $LFS/sources && rm -rf <package>

Phase 5: Enter Chroot (Chapter 7)

15. Prepare for Chroot

# Exit lfs user
exit

# As root, change ownership
sudo chown -R root:root $LFS/{usr,lib,var,etc,bin,sbin,tools}
sudo chown -R root:root $LFS/lib64

# Create device nodes
sudo mkdir -pv $LFS/{dev,proc,sys,run}
sudo mknod -m 600 $LFS/dev/console c 5 1
sudo mknod -m 666 $LFS/dev/null c 1 3

# Mount virtual filesystems
sudo mount -v --bind /dev $LFS/dev
sudo mount -vt devpts devpts -o gid=5,mode=0620 $LFS/dev/pts
sudo mount -vt proc proc $LFS/proc
sudo mount -vt sysfs sysfs $LFS/sys
sudo mount -vt tmpfs tmpfs $LFS/run

if [ -h $LFS/dev/shm ]; then
  install -v -d -m 1777 $LFS$(realpath /dev/shm)
else
  sudo mount -vt tmpfs -o nosuid,nodev tmpfs $LFS/dev/shm
fi

16. Enter Chroot

sudo chroot "$LFS" /usr/bin/env -i \
    HOME=/root \
    TERM="$TERM" \
    PS1='(lfs chroot) \u:\w\$ ' \
    PATH=/usr/bin:/usr/sbin \
    MAKEFLAGS="-j$(nproc)" \
    TESTSUITEFLAGS="-j$(nproc)" \
    /bin/bash --login

17. Create Essential Directories and Files

# Inside chroot
mkdir -pv /{boot,home,mnt,opt,srv}
mkdir -pv /etc/{opt,sysconfig}
mkdir -pv /lib/firmware
mkdir -pv /media/{floppy,cdrom}
mkdir -pv /usr/{,local/}{include,src}
mkdir -pv /usr/local/{bin,lib,sbin}
mkdir -pv /usr/{,local/}share/{color,dict,doc,info,locale,man}
mkdir -pv /usr/{,local/}share/{misc,terminfo,zoneinfo}
mkdir -pv /usr/{,local/}share/man/man{1..8}
mkdir -pv /var/{cache,local,log,mail,opt,spool}
mkdir -pv /var/lib/{color,misc,locate}

ln -sfv /run /var/run
ln -sfv /run/lock /var/lock

install -dv -m 0750 /root
install -dv -m 1777 /tmp /var/tmp

# Create essential files
ln -sv /proc/self/mounts /etc/mtab

cat > /etc/hosts << "EOF"
127.0.0.1  localhost localhost.localdomain
::1        localhost ip6-localhost ip6-loopback
ff02::1    ip6-allnodes
ff02::2    ip6-allrouters
EOF

cat > /etc/passwd << "EOF"
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/dev/null:/usr/bin/false
daemon:x:6:6:Daemon User:/dev/null:/usr/bin/false
messagebus:x:18:18:D-Bus Message Daemon User:/run/dbus:/usr/bin/false
systemd-journal-gateway:x:73:73:systemd Journal Gateway:/:/usr/bin/false
systemd-journal-remote:x:74:74:systemd Journal Remote:/:/usr/bin/false
systemd-journal-upload:x:75:75:systemd Journal Upload:/:/usr/bin/false
systemd-network:x:76:76:systemd Network Management:/:/usr/bin/false
systemd-resolve:x:77:77:systemd Resolver:/:/usr/bin/false
systemd-timesync:x:78:78:systemd Time Synchronization:/:/usr/bin/false
systemd-coredump:x:79:79:systemd Core Dumper:/:/usr/bin/false
uuidd:x:80:80:UUID Generation Daemon User:/dev/null:/usr/bin/false
systemd-oom:x:81:81:systemd Out Of Memory Daemon:/:/usr/bin/false
nobody:x:65534:65534:Unprivileged User:/dev/null:/usr/bin/false
EOF

cat > /etc/group << "EOF"
root:x:0:
bin:x:1:daemon
sys:x:2:
kmem:x:3:
tape:x:4:
tty:x:5:
daemon:x:6:
floppy:x:7:
disk:x:8:
lp:x:9:
dialout:x:10:
audio:x:11:
video:x:12:
utmp:x:13:
cdrom:x:15:
adm:x:16:
messagebus:x:18:
systemd-journal:x:23:
input:x:24:
mail:x:34:
kvm:x:61:
systemd-journal-gateway:x:73:
systemd-journal-remote:x:74:
systemd-journal-upload:x:75:
systemd-network:x:76:
systemd-resolve:x:77:
systemd-timesync:x:78:
systemd-coredump:x:79:
uuidd:x:80:
systemd-oom:x:81:
wheel:x:97:
users:x:999:
nogroup:x:65534:
EOF

touch /var/log/{btmp,lastlog,faillog,wtmp}
chgrp -v utmp /var/log/lastlog
chmod -v 664  /var/log/lastlog
chmod -v 600  /var/log/btmp

18. Build Additional Temporary Tools in Chroot

# Gettext (tools only)
cd /sources
tar -xf gettext-0.26.tar.xz
cd gettext-0.26
./configure --disable-shared
make
cp -v gettext-tools/src/{msgfmt,msgmerge,xgettext} /usr/bin
cd /sources && rm -rf gettext-0.26

# Bison
# Perl
# Python
# Texinfo
# Util-linux

Phase 6: Build Full System (Chapter 8)

19. Build All 70+ System Packages

Build in this order:

# Core system (inside chroot at /sources)
1. Man-pages
2. Iana-Etc
3. Glibc (full build)
4. Zlib
5. Bzip2
6. Xz
7. Lz4
8. Zstd
9. File
10. Readline
11. M4
12. Bc
13. Flex
14. Tcl
15. Expect
16. DejaGNU
17. Pkgconf
18. Binutils (full build)
19. GMP
20. MPFR
21. MPC
22. Attr
23. Acl
24. Libcap
25. Libxcrypt
26. Shadow
27. GCC (full build - CRITICAL!)
28. Ncurses
29. Sed
30. Psmisc
31. Gettext
32. Bison
33. Grep
34. Bash
35. Libtool
36. GDBM
37. Gperf
38. Expat
39. Inetutils
40. Less
41. Perl
42. XML::Parser
43. Intltool
44. Autoconf
45. Automake
46. OpenSSL
47. Kmod
48. Libelf
49. Libffi
50. Python
51-70. [Continue with remaining packages...]

Standard build pattern:

cd /sources
tar -xf <package>.tar.xz
cd <package>
./configure --prefix=/usr <options>
make
make check  # Run tests
make install
cd /sources && rm -rf <package>

Phase 7: System Configuration (Chapter 9)

20. Configure Network

# Set hostname
echo "lfs" > /etc/hostname

# Configure interface (DHCP)
cat > /etc/sysconfig/ifconfig.eth0 << "EOF"
ONBOOT=yes
IFACE=eth0
SERVICE=ipv4-dhcp
EOF

# Or static IP
cat > /etc/sysconfig/ifconfig.eth0 << "EOF"
ONBOOT=yes
IFACE=eth0
SERVICE=ipv4-static
IP=192.168.1.2
GATEWAY=192.168.1.1
PREFIX=24
BROADCAST=192.168.1.255
EOF

# DNS
cat > /etc/resolv.conf << "EOF"
nameserver 8.8.8.8
nameserver 8.8.4.4
EOF

21. System Configuration Files

# Locale
cat > /etc/locale.conf << "EOF"
LANG=en_US.UTF-8
LC_ALL=en_US.UTF-8
EOF

# Console
cat > /etc/sysconfig/console << "EOF"
UNICODE="1"
KEYMAP="us"
FONT="lat1-16 -m 8859-1"
EOF

# Clock
cat > /etc/sysconfig/clock << "EOF"
UTC=1
EOF

# Profile
cat > /etc/profile << "EOF"
export LANG=en_US.UTF-8
export PATH=/usr/bin:/usr/sbin
PS1='[\u@\h \W]\$ '
EOF

22. Install Bootscripts

cd /sources
tar -xf lfs-bootscripts-20250827.tar.xz
cd lfs-bootscripts-20250827
make install
cd /sources && rm -rf lfs-bootscripts-20250827

23. Configure fstab

cat > /etc/fstab << "EOF"
# Begin /etc/fstab
/dev/sda2     /            ext4     defaults            1     1
/dev/sda3     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
EOF

24. Set Root Password

passwd root

Phase 8: Kernel and Bootloader (Chapter 10)

25. Build Linux Kernel

cd /sources
tar -xf linux-6.16.1.tar.xz
cd linux-6.16.1

make mrproper

# Configure kernel
make menuconfig
# or
make x86_64_defconfig  # For default config

# Compile
make -j$(nproc)

# Install modules
make modules_install

# Install kernel
cp -iv arch/x86/boot/bzImage /boot/vmlinuz-6.16.1-lfs-12.4
cp -iv System.map /boot/System.map-6.16.1
cp -iv .config /boot/config-6.16.1

cd /sources && rm -rf linux-6.16.1

26. Install GRUB Bootloader

# For BIOS systems
grub-install /dev/sda

# For UEFI systems
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=LFS

# Generate GRUB config
cat > /boot/grub/grub.cfg << "EOF"
set default=0
set timeout=5

insmod part_gpt
insmod ext2
set root=(hd0,2)

menuentry "GNU/Linux, Linux 6.16.1-lfs-12.4" {
        linux   /boot/vmlinuz-6.16.1-lfs-12.4 root=/dev/sda2 ro
}
EOF

Phase 9: Final Steps

27. Create System Information

cat > /etc/lsb-release << "EOF"
DISTRIB_ID="Linux From Scratch"
DISTRIB_RELEASE="12.4"
DISTRIB_CODENAME="LFS-12.4"
DISTRIB_DESCRIPTION="Linux From Scratch"
EOF

cat > /etc/os-release << "EOF"
NAME="Linux From Scratch"
VERSION="12.4"
ID=lfs
PRETTY_NAME="Linux From Scratch 12.4"
VERSION_CODENAME="LFS-12.4"
EOF

28. Exit Chroot and Unmount

# Exit chroot
logout

# Unmount virtual filesystems
umount -v $LFS/dev/pts
umount -v $LFS/dev
umount -v $LFS/run
umount -v $LFS/proc
umount -v $LFS/sys

# Unmount LFS partition
umount -v $LFS

29. Reboot into LFS

shutdown -r now

Phase 10: First Boot

30. Login and Verify

# Login as root
login: root
Password: [your-password]

# Verify system
uname -a
cat /etc/lsb-release
df -h
ip addr show
ping -c 4 google.com

# Create regular user
useradd -m -G users,wheel,audio,video -s /bin/bash john
passwd john

Build Time Estimates

  • Phase 1-2 (Prep + Download): 1-2 hours
  • Phase 3 (Cross-toolchain): 2-4 hours (15 SBU)
  • Phase 4 (Temp tools): 2-3 hours (10 SBU)
  • Phase 5 (Chroot setup): 1 hour
  • Phase 6 (Full system): 20-40 hours (150+ SBU)
  • Phase 7-8 (Config): 1-2 hours
  • Phase 9 (Kernel/Boot): 2-4 hours
  • Phase 10 (Testing): 1 hour

Total: 30-60 hours (depending on CPU and number of cores)


Quick Troubleshooting

Common Issues

Network not working:

ip link set eth0 up
dhclient eth0
ping 8.8.8.8

Can't login as root:

  • Boot with init=/bin/bash
  • Mount root: mount -o remount,rw /
  • Reset password: passwd root

Kernel panic:

  • Check /boot/grub/grub.cfg has correct root= partition
  • Verify kernel exists: ls /boot/vmlinuz-*

GRUB not found:

grub-install /dev/sda
grub-mkconfig -o /boot/grub/grub.cfg

Package Count Summary

  • Core packages: 102
  • Final system size: ~900 MB
  • Build directory size: ~10 GB (during build)
  • Recommended disk: 30 GB

Key Commands Reference

# Check LFS variable
echo $LFS

# Enter chroot (after mount)
chroot "$LFS" /usr/bin/env -i HOME=/root TERM="$TERM" PS1='(lfs chroot) \u:\w\$ ' PATH=/usr/bin:/usr/sbin /bin/bash --login

# Mount virtual filesystems
mount -v --bind /dev $LFS/dev
mount -vt devpts devpts -o gid=5,mode=0620 $LFS/dev/pts
mount -vt proc proc $LFS/proc
mount -vt sysfs sysfs $LFS/sys
mount -vt tmpfs tmpfs $LFS/run

# Standard package build
tar -xf <package>.tar.xz
cd <package>
./configure --prefix=/usr
make
make check
make install
cd /sources && rm -rf <package>

# Verify installation
echo 'int main(){}' | gcc -xc -
./a.out && echo "OK"

Congratulations!

You have successfully built Linux From Scratch 12.4 from 102 source packages totaling 900+ MB, learned how Linux works internally, and created a fully functional, bootable operating system!

Next Steps:

  • Install graphical environment (BLFS - Beyond Linux From Scratch)
  • Add more software packages
  • Create backups
  • Share your success!

Resources:

🎉 Happy Linux Building! 🐧