Tested with Debian 12 Bookworm:
- CPU 4 cores (Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz), RAM 4GB, swap 3GB.
- CPU 3 cores (Intel(R) Core(TM) i5-5575R CPU @ 2.80GHz), RAM 4GB, swap 3GB.
Target: x86_64 architecture with UEFI
This project is based on the Official LFS 12.2 Book
https://www.linuxfromscratch.org/lfs/view/12.2/
Add the following packages
sudo apt install gcc g++ make patch bison gawk git htop texinfo file dosfstools gettext
Set these Environment Variables
export LFS=/mnt/lfs
export ALFS=/mnt/lfs/alfs
export NONROOT_USER=user- Create a new empty GPT partition table (option g)
- Create a new vfat parition /dev/sdb1 (option n, 150MB) for EFI
- Create a new ext4 parition /dev/sdb2 (option n, 1GB) for boot
- Create a new ext4 parition /dev/sdb3 (option n) for root
- Create a new swap parition /dev/sdb4 (option n, 4GB) for swap
sudo fdisk /dev/sdb
sudo mkfs.vfat -v /dev/sdb1
sudo mkfs -v -t ext4 /dev/sdb2
sudo mkfs -v -t ext4 /dev/sdb3
sudo mkswap /dev/sdb4Mount new partitions
sudo mkdir $LFS
sudo mount -vt ext4 /dev/sdb3 $LFS
sudo mkdir $LFS/boot
sudo mount -vt ext4 /dev/sdb2 $LFS/boot
sudo mkdir $LFS/boot/efi
sudo mount -vt vfat /dev/sdb1 -o codepage=437,iocharset=iso8859-1 $LFS/boot/efiGrab the alfs project files
sudo git clone https://github.com/vuonglequoc/alfs.git $ALFSChange directory to alfs
cd $ALFSVerify required programs
# Chapter 2
sudo $ALFS/scripts/version_check.shDownload toolchain source code from wget-list
# Chapter 3
sudo -E $ALFS/scripts/host_get_packages.shSetup the LFS user environment
# Chapter 4
sudo -E $ALFS/scripts/host_setup_lfs_env.shThese scripts are required to run as the new LFS user
sudo su lfs
# Chapter 5
# build 30 minutes
$ALFS/scripts/host_compile_cross-toolchain.sh
# Chapter 6
# build 35 minutes
$ALFS/scripts/host_cross-compile_temp-tools.sh
exitRun as root with environment variables set earlier
# Chapter 7
# build 11 minutes
sudo -E $ALFS/scripts/chroot_build_addtemp-toolchain.sh
# backup 32 minutes
sudo -E $ALFS/scripts/host_backup_temp-toolchain.sh
# Chapter 8
# build 6 hours 8 minutes
# gcc 3 hours
sudo -E $ALFS/scripts/chroot_build_basic_system_software.sh
# Chapter 9
# build <1 minutes
sudo -E $ALFS/scripts/chroot_system_configuration.sh
# Chapter 10
# build 15 minutes
sudo -E $ALFS/scripts/chroot_make_system_bootable.shBelow is how I installed GRUB with UEFI support while inside the chrooted LFS system
https://www.linuxfromscratch.org/blfs/view/12.2/postlfs/grub-efi.html
Consider reading the LFS book for backing up your bootloader.
https://www.linuxfromscratch.org/lfs/view/12.2/chapter10/grub.html
sudo -E $ALFS/extras/chroot.sh /dev/sdb3
mountpoint /sys/firmware/efi/efivars || mount -v -t efivarfs efivarfs /sys/firmware/efi/efivarsPrepare background
mkdir -pv /boot/grub/images/
cp /alfs/defaults/boot/grub/images/splash.png /boot/grub/images/splash.pngUpdating grub defaults for boot menu with background
cp /alfs/defaults/etc/default/grub /etc/default/grubAdd menu entry for Windows and helpful Reboot, Shutdown
cp /alfs/defaults/etc/grub.d/40_custom /etc/grub.d/40_customMake grub.cfg with grub-mkconfig instead of typing manually.
grub-install --target x86_64-efi --bootloader-id=LFS --recheck
efibootmgr | cut -f 1
grub-mkconfig -o /boot/grub/grub.cfgExit chroot environment
umount efivarfs
exitBackup final OS
# backup 35 minutes
sudo -E $ALFS/scripts/host_backup_lfs_os.shUn-mount LFS partitions
cd /home
sudo umount $LFS/boot/efi
sudo umount $LFS/boot
sudo umount $LFSAt this step, we have a basic LFS system that can boot and play around with bash shell.
Prepare remote environment with OpenSSH to use LFS system efficiently to install other packages instead of chroot environment.
Mount LFS partitions
sudo mount -vt ext4 /dev/sdb3 $LFS
sudo mount -vt ext4 /dev/sdb2 $LFS/boot
sudo mount -vt vfat /dev/sdb1 -o codepage=437,iocharset=iso8859-1 $LFS/boot/efiEnter chroot environment and build software for remote environment
sudo -E $ALFS/scripts/chroot_build_remote_software.shFrom now on, we can use LFS system remotely for other installation with $NONROOT_USER user and pass $NONROOT_USER.
Reboot to LFS Machine
sudo rebootRemote to LFS Machine from Dev Machine for the rest building
ssh $NONROOT_USER@LFS_MACHINE_IPSet these Environment Variables
export NONROOT_USER=usersudo -E /alfs/scripts/build_post_lfs.shReboot to LFS Machine again to take effect
sudo reboot
ssh $NONROOT_USER@LFS_MACHINE_IP
export NONROOT_USER=usersudo /alfs/scripts/build_general_utilities.shsudo /alfs/scripts/build_networking.shReboot to LFS Machine again to take effect
sudo reboot
ssh $NONROOT_USER@LFS_MACHINE_IP
export NONROOT_USER=usersudo -E /alfs/scripts/build_multimedia.shReboot to LFS Machine again to take effect
sudo reboot
ssh $NONROOT_USER@LFS_MACHINE_IP
export NONROOT_USER=userUsing sample:
# Play audio
ffplay music.mp3
nvlc music.mp3
mpv music.mp3# Play video without sound
sudo -E ffmpeg -re -i ${VIDEO} -filter:v scale=1024:-1 -c:v rawvideo -pix_fmt bgra -f fbdev /dev/fb0# Play video with sound
sudo -E ffmpeg -re -i ${VIDEO} -filter:v scale=1024:-1 -c:v rawvideo -pix_fmt bgra -f fbdev /dev/fb0 > ${VIDEO}_video.log 2>&1 < /dev/null &
ffplay ${VIDEO} -autoexit > ${VIDEO}_sound.log 2>&1 < /dev/null &
# Stop
sudo pkill -9 ffmpeg
sudo pkill -9 ffplay# Play Youtube video + sound with yt-dlp
# Need to install yt-dlp
./yt-dlp ${VIDEO_URL} -o - 2>/dev/null | tee >(sudo ffmpeg -re -i - -filter:v scale=1024:-1 -c:v rawvideo -pix_fmt bgra -loglevel quiet -f fbdev /dev/fb0) >(ffplay -autoexit -loglevel quiet -) >/dev/null# Adjust audio Volume
sudo alsamixerI decided to use modern Wayland instead of traditional X system.
# build 3 hours 40 minutes
# librsvg 10 minutes
# SPIRV-Tools 15 minutes
# libclc 20 minutes
# GTK+ 10 minutes
# gtkmm 10 minutes
# Waybar 10 minutes
# mesa 46 minutes
sudo -E /alfs/scripts/build_graphic.shFix /tmp folder permission for XDG RUNTIME DIR
sudo chmod -R 777 /tmpLet's change to Run level 5 and re-login to see the Desktop:
sudo telinit 5
exitSome key bindings for beginner:
- MOD key (Windows/Command)
- MOD + Return: Start terminal (foot)
- MOD + Space: Start launcher (Wofi)
- MOD + Shift + Q: Kill focused window
- MOD + Shift + T: Switch the current focus window between tiling and floating mode
- MOD + Shift + Return: Lock the screen (type password and press Return for Unlock)
- MOD + Shift + C: Reload Sway configuration file
- MOD + Shift + E: Exit Sway (logout of Wayland session)
sudo /alfs/scripts/build_graphic_software.shTODO: Office
Confirm that LFS and ALFS environment variables are both set and LFS partition is mounted.
Re-enter chroot and pass partition
sudo -E $ALFS/extras/chroot.sh /dev/sdb3Emulate the LFS system with QEMU (pass drive)
sudo -E $ALFS/extras/qemu.sh /dev/sdbEmulate the LFS system with QEMU + graphics (pass drive)
sudo -E $ALFS/extras/xqemu.sh /dev/sdb vmwareThe root password in the LFS chrooted system is root.
The lfs user on the host system can be deleted with sudo deluser lfs the lfs user /home/lfs folder can also be removed. It is only required to build the first toolchain.
Before building the package, increase the stack size
ulimit -s 32768- Tested with CPU 4 cores, RAM
4GB, swap3GB-> OK
This can happen if you are trying to boot from qemu and the entry for root=/dev/??? is not sda
Simply edit vi /boot/grub/grub.cfg and change root references to sda1
root=/dev/sda1When I am booting from my physical server I had to set it back to sdb3, because sda is my primary Debian installation.
root=/dev/sdb3Linux From Scratch 12 Book: https://www.linuxfromscratch.org/lfs/view/12.2/
Beyond Linux From Scrach 12 Book: https://www.linuxfromscratch.org/blfs/view/12.2/
Windy's ALFS: https://github.com/mattwind/alfs
Armstrong's Sway : https://www.dwarmstrong.org/sway
Sway Add ons: https://github.com/swaywm/sway/wiki/Useful-add-ons-for-sway
Waybar config: https://man.archlinux.org/man/extra/waybar/waybar-clock.5.en
GNU toolchain: https://en.wikipedia.org/wiki/GNU_toolchain
How a toolchain is constructed: https://crosstool-ng.github.io/docs/toolchain-construction/
Linux Booting Process:
- https://en.wikipedia.org/wiki/Booting_process_of_Linux
- https://www.freecodecamp.org/news/the-linux-booting-process-6-steps-described-in-detail/
- https://learn.adafruit.com/running-programs-automatically-on-your-tiny-computer/sysv-init-runlevels
- System startup (BIOS): search, load, execute boot loader program
- default: EFI/BOOT/BOOTX64.EFI
- GRUB: EFI/grub/grubx64.efi
- custom: EFI/LFS/grubx64.efi (same as GRUB)
- Bootloader stage (GRUB): load kernel image /boot/vmlinuz-*
- Kernel: execute /sbin/init with configuration in /etc/inittab
- Init (SysV): execute init scripts in /etc/rc.d/rcS.d/ then /etc/rc.d/rc[run level].d/ (symlink -> /etc/rc.d/init.d/*).
-
Run level 0: /etc/rc.d/rc0.d/ : Power off
-
Run level 1: /etc/rc.d/rc1.d/ : Rescue (single-user)
-
Run level 3: /etc/rc.d/rc3.d/ : Multi-user with networking (default)
-
Run level 5: /etc/rc.d/rc5.d/ : level 3 + Graphical
-
Run level 6: /etc/rc.d/rc6.d/ : Reboot
For Run level from 1 to 6, final step is execute /sbin/agetty to opens a tty port, prompts for a login name and invokes the /bin/login command.
After a successful login, an interactive login shell is started.
Interactive login shell was defined in /etc/passwd. (root:x:0:0:root:/root:/bin/bash)
The /etc/shadow file stores user passwords in Linux.
From now on, we can interact with linux system by interactive login shell.
Wayland: https://wayland.freedesktop.org/docs/html/ch03.html



