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.cfghas correctroot=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:
- LFS: https://www.linuxfromscratch.org/
- BLFS: https://www.linuxfromscratch.org/blfs/
- Documentation: https://www.linuxfromscratch.org/lfs/view/stable/
🎉 Happy Linux Building! 🐧