Bash script to build LFS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Cyril CONSTANTIN 86d9c53cb7 add one error in vim tests 1 day ago
build add one error in vim tests 1 day ago
COPYING initial successfull build 4 weeks ago
LICENSE initial successfull build 4 weeks ago
Makefile initial successfull build 4 weeks ago
README.md Update README 3 weeks ago
build.sh Trap error of util-linux and update grub config 3 weeks ago
linux-config-i686.txt initial successfull build 4 weeks ago
linux-config-x86_64.txt Fix anos and add linux config for 64 bits 3 weeks ago
md5sums initial successfull build 4 weeks ago
wget-list-systemd.txt initial successfull build 4 weeks ago

README.md

cclfs

It's a compliant bash script that builds Linux From Scratch.

If you don't know what this is, or haven't built Linux From Scratch on your own before, you should go through the LFS book before using this script.

This is a script based on https://github.com/krglaws/MyLFS.git. It was developped on debian (bookworm i686, trixie x86_64).

Requirements

The requirements are those of the book : https://www.linuxfromscratch.org/lfs/view/stable-systemd/

The /mnt/lfs partition is not created by the script. You have to create it by yourself. Some commands are provided by the script.

The lfs user is mandatory :

groupadd lfs
useradd -s /bin/bash -g lfs -m -k /dev/null lfs
passwd lfs

Some additionnal requirements :

  • the lfs user is mandatory
    • The script should by executed by lfs user
  • sudo command is necessary
    • a sudoers file is provided for lfs user to restrict rights to stricts requirements.
    • this sudoers file allow to protect the host and restrict command only to /mnt/lfs directory
    • it allow the following commands on /mnt/lfs : chown mount install chroot
  • build directory is hardcoded : /mnt/lfs
  • mount |grep -q "/mnt/lfs type ext4" should return ok
  • /etc/bash.bashrc should not be used on host
    • sudo mv -v /etc/bash.bashrc /etc/bash.bashrc.NOUSE
  • cross compilation for glibc seems to need some specific packages
    • sudo apt install flex libzstd-dev pkgconf
  • you can't execute in parallel the script on the same namespace.

How It Works

Copy the repository under any location <build_directory>.

The script do some writings only under :

  • <build_directory>
  • LFS_PACKAGE_DIR if it does not contains all required packages
  • ~lfs/
  • /tmp/lfs*
  • /mnt/lfs/
  • /mnt/lfs/sources/

The script builds LFS by completing the following steps:

  1. Download package source code and save to the packages directory.
  2. Build initial cross compilation tools. This corresponds to chapter 5 in the LFS book, and "phase 1" of the script.
  3. Begin to build tools required for minimal chroot environment. (chapter 6/phase 2)
  4. Enter chroot environment, and build remaining tools needed to build the entire LFS system. (chapter 7/phase 3)
  5. Build the entire LFS system from within chroot envirnment, including the kernel, GRUB, and others. (chapter 8+/phase 4)

The script ask for validation for each step. You can disable validation until desired step with a number as argument. The number is the chapter (of the books) on 5 digits until you validate. If you want to start validation at 5. Compiling a Cross-Toolchain, it's 50000.

To configure it, execute a first time the make command. A file ~lfs/.lfsbuild_config will be created. You can customize it by setting the BREAKPOINT var.

Or create and customize the file before :

cat /home/lfs/.lfsbuild_config << EOSF
# location of local package sources
LFS_PACKAGE_DIR=/home/lfs/packages
# Number of processors to use
LFS_NPROC=$(nproc)
# Bypass step by step validation until a breakpoint
LFS_BREAKPOINT=1
# strip binaries or not
LFS_STRIP_BINARIES=true
# bypass network config validation by taking network config from host
LFS_NETWORKSAMEASHOST=false
# bypass network configuration for full offline build
LFS_NETWORKOFFLINE=false
# bypass linux config validation by taking linux config from host
LFS_LINUXCONFIGPROVIDED=false
EOSF

Examples

Execute as lfs user.

make

Grub config

Grub is initiated with the following menu :

$ cat /mnt/lfs/boot/grub/grub.cfg 
# Begin /boot/grub/grub.cfg
set default=0
set timeout=5
insmod part_gpt
insmod ext2
search --set=root --fs-uuid=8c137b8d-3612-4715-94c2-8203e273318f
set gfxpayload=1024x768x32
menuentry "GNU/Linux, Linux 6.18.10-lfs-13.0-systemd with blockdevice" {
        linux   /boot/vmlinuz-6.18.10-lfs-13.0-systemd root=/dev/vdb1 ro
}
menuentry "GNU/Linux, Linux 6.18.10-lfs-13.0-systemd with partuuid" {
        linux   /boot/vmlinuz-6.18.10-lfs-13.0-systemd root=PARTUUID=001cdfe1-01 ro
}

The partuuid section is not required, but can be helpful if you add another disk or change boot order in bios. partuuid is more immutable than vdx.

Devices are extracted from the following command :

$ lsblk -o UUID,PARTUUID,PATH,MOUNTPOINT
UUID                                 PARTUUID                             PATH      MOUNTPOINT
                                                                          /dev/sr0  
                                                                          /dev/vda  
e46c1c50-d494-44f2-a826-41afc1b76eae 9ffe027f-01                          /dev/vda1 /
                                     9ffe027f-02                          /dev/vda2 
cae0487a-2eca-44c7-aa5f-060ea258f30c 9ffe027f-05                          /dev/vda5 [SWAP]
                                                                          /dev/vdb  
8c137b8d-3612-4715-94c2-8203e273318f 001cdfe1-01                          /dev/vdb1 /mnt/lfs

In this configuration extracted from a libvirt host ( /dev/vdxn ) with a second disk dedicated to LFS, /mnt/lfs device entry is filtered. The grub config is made with it.

cclfs doesn't install the bootloader. It use the bootloader of the host. You can install it if you want before or after the first boot. See instruction in LFS book and BLFS book. There is only one bootloader by default at boot nonetheless.

Debian configuration

On Debian Trixie (13) (at least), OS_PROBER is disabled. Just uncomment the line in /etc/default/grub or customize a config file in /etc/grub.d/ . And reinstall the bootloader.

$ sudo vim /etc/default/grub
$ grep PROBER /etc/default/grub
GRUB_DISABLE_OS_PROBER=false
$ sudo update-grub

In default configuration, libvirt/kvm doesn't activate a second disk, so it won't boot. You have to activate the second disk in the boot options.

You can find devices seen by bios with the grub console : type c at grub general menu

ls
(hd0,msdos1) (hd0,msdos5) (hd1,msdos1)

If you don't see your LFS partition, it won't boot.

Automated LFS is not LFS

The goal of LFS is to learn how to build a GNU/Linux OS.

Read the book is a very convenient way to learn. That's why the script follow at most the book.

Copy and paste command is not learning, it learn to copy/paste, maybe. Manual commands with modification may generate errors you don't see. You don't know where you made the mistake, you restart, you fail, you don't understand, and you give up.

Or you write a small bash script to avoid copy/paste errors. And you write this.

Writing a script like this is a lot of learning. And automation may help to encourage in LFS development.

Forking the repo and personnal appropriation seems IMHO a good choice.

Why not use alfs , jhlfs and reinvent the wheel ?

The following section of the README is not convenient for my personnal usage.

5. RUNNING::

   IMPORTANT::
         You must be logged as a normal user with sudo privileges to run
      the Makefile. Furthermore, you are supposed to have enough privilege
      to become any user. If you are not bothered about security issues,
      the entry for the user running the tool in /etc/sudoers could be
      <user> ALL=(ALL) NOPASSWD:ALL

On a dedicated VM for tests, ok. On a real computer with other roles, give all root rights is NOT acceptable.

cclfs works with a dedicated lfs user with only required rights only on /mnt/lfs. There is absolutely no possibility to break anything else on the host than /mnt/lfs.