Initial commit of LFS notes and scripts.

This commit is contained in:
Shaun Setlock
2025-01-20 15:44:57 -05:00
commit 386dc3cec7
78 changed files with 2628 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
# Chapter 5
## Section 2 Install Binutils (1st Pass)
A couple things to check before proceeding:
1. `echo $LFS` to ensure that environment variable is pointing in the correct location.
1. `whoami` to ensure we are running as the lfs user.
>[!Recall We are about create the cross-compiler and associated tools.]
We start by extracting the tar.
`tar -xvf binutils-2.43.1.tar.xz`
Then, move into the unpacked tape archive.
`cd binutils-2.43.1`
Create a subdirectory where we will build the files, and move into it.
```
mkdir -v build
cd build
```
Prepare for compilation.
```
../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
```
We now have a Makefile, so we can run `make` to compile `binutils`.
`make`
And finally, we can install the compiled package into an area of our lfs environment, again using make.
`make install`
## Section 3 Install of GCC (1st Pass)
Similar to binutils, the steps are,
1. Upack the tar of GCC.
1. EXTRA STEP, GCC requires additional packages, so unpack those within the extracted GCC folder.
1. EXTRA STEP, set a variable so that 64-bit OS's know to use lib64.
1. Create build directory.
1. configure, make, make install ...
1. EXTRA STEP, one file is incomplete the follow command is needed to complete it temporarily.
```
cd ..
cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
`dirname $($LFS_TGT-gcc -print-libgcc-file-name)`/include/limits.h
```
## Section 4 Install Linux API Headers
This one is a little different,
1. Remove stale files with make,
`make mrproper`
1. Generate headers with make,
```
make headers
find usr/include -type f ! -name '*.h' -delete
cp -rv usr/include $LFS/usr
```
## Section 5 Install Glibc
Start by unpacking the tarball.
`tar -xvf glibc-2.40.tar.xz`
Create symbolic links for LSB compliance of 64-bit systems.
```
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
```
glibc has a patch in this release, so we need to apply it.
`patch -Np1 -i ../glibc-2.40-fhs-1.patch`
Create a build directory, as usual.
`mkdir -v build && cd build`
Create a file called configparams that ensure `ldconfig` and `sln` are available.
`echo "rootsbindir=/usr/sbin" > configparms`
Then, configure to prepare for compilation.
```
../configure \
--prefix=/usr \
--host=$LFS_TGT \
--build=$(../scripts/config.guess) \
--enable-kernel=4.19 \
--with-headers=$LFS/usr/include \
--disable-nscd \
libc_cv_slibdir=/usr/lib
```
Then compile and install,
```
make
make DESTDIR=$LFS install
```
Fix a hardcoded path using sed,
`sed '/RTLDLIST=/s@/usr@@g' -i $LFS/usr/bin/ldd`
Finally, run some tests.
```
bash-5.1$ echo 'int main(){}' | $LFS_TGT-gcc -xc -
readelf -l a.out | grep ld-linux
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
bash-5.1$ rm -v a.out
removed 'a.out'
bash-5.1$
```
## Section 6 Install libstdc++
libstdc++ is part of GCC, but had to skip it during the first install of GCC because we didnt have glibc yet.
Unpack (or change back into) gcc and create a build directory.
`mkdir -v build && cd build`
Configure the make tool.
```
../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++/14.2.0
```
Compile and install.
```
make
make DESTDIR=$LFS install
```
Finally, remove libtool archive files because they're "harmful" for cross-compilation.
`rm -v $LFS/usr/lib/lib{stdc++{,exp,fs},supc++}.la`

View File

@@ -0,0 +1,26 @@
# Chapter 6
This chapter is all about creating tools to enable building even more tools.
In this case, these tools are cross compiled. (i.e. Built with host and targeted at lfs root.)
The tools that are created are runnable in the new, target environment. They'll be create tools natively, after chroot.
Here's the list:
1. M4
1. Ncurses
1. Bash
1. Coreutils
1. Diffutils
1. File
1. Findutils
1. Gawk
1. Grep
1. Gzip
1. Make
1. Patch
1. Sed
1. Tar
1. xz
1. Binutils (2nd Pass)
1. GCC (2nd Pass)

View File

@@ -0,0 +1,190 @@
# Chapter 7 - Chroot and Build More Tools
## Sections 7.1 - 7.3
First, the small starter filesystem we built at $LFS needs to be owned by root.
Otherwise, when we chroot, these files will be owned by a user ID for a user that doesn't exist.
```
chown --from lfs -R root:root $LFS/{usr,lib,var,etc,bin,sbin,tools}
case $(uname -m) in
x86_64) chown --from lfs -R root:root $LFS/lib64 ;;
esac
```
We can now build the "virtual filesystems" which are not on disk, hence the name.
These are used by the kernel so other systems can interact with it.
`mkdir -pv $LFS/{dev,proc,sys,run}`
Here's a snapshot of the environment we've built, so far ...
```
[root@lfs ~]# tree $LFS -L 1
/mnt/lfs
├── bin -> usr/bin
├── dev
├── etc
├── home
├── lib -> usr/lib
├── lib64
├── lost+found
├── proc
├── run
├── sbin -> usr/sbin
├── sources
├── sys
├── tools
├── usr
└── var
```
Typically, at boot, the kernel populates /dev with *devtmpfs* but since we will be chroot'ing into this
filesystem, we can bind mount our host's /dev directory.
`mount -v --bind /dev $LFS/dev`
We can now create the remaining virtual filesystems and mount them at their mountpoints.
```
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
```
And finally, deal with `shm`, as needed.
```
if [ -h $LFS/dev/shm ]; then
install -v -d -m 1777 $LFS$(realpath /dev/shm)
else
mount -vt tmpfs -o nosuid,nodev tmpfs $LFS/dev/shm
fi
```
## Section 7.4 (Chroot!!!)
Now that all the packages which are required to build the rest of the needed tools are on the system, it is time to enter
the chroot environment and finish installing the temporary tools.
This environment will also be used to install the final system. As user root, run the following command to enter the environment that is, at the moment, populated with nothing but temporary tools.
```
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
```
## Section 7.5 - Directories
From within this chroot, we can start building out the directory structure.
```
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/lib/locale
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
```
*NOTE* This includes a sticky bit on certain directories will allow users to write, but not delete another user's files.
# Section 7.6 Essential Files and Symlinks
We link the modern /proc location of kernel mountpoint.
`ln -sv /proc/self/mounts /etc/mtab`
Create an `/etc/hosts/` file.
```
cat > /etc/hosts << EOF
127.0.0.1 localhost $(hostname)
::1 localhost
EOF
```
We need root to be able to login, so `/etc/passwd` and `/etc/groups` files are needed.
```
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
```
and
```
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
```
We should also define the locale for packages which require it.
`localedef -i C -f UTF-8 C.UTF-8`
Add an ordinary user for some packages that need a regular user for testing.
```
echo "tester:x:101:101::/home/tester:/bin/bash" >> /etc/passwd
echo "tester:x:101:" >> /etc/group
install -o tester -d /home/tester
```
We are about to have our first user login, so let's make a couple log locations.
```
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
```
Finally, we can now be able to login as `root`. (Or `tester`, theoretically.)
`exec /usr/bin/bash --login`
*NOTE:*The "i have no name" should change.
# Section 7.7-7.12
Just follow the book for these package installations.
- Gettext
- Bison
- Perl
- Python
- Texinfo
- Util-linux
# Section 7.13 Clean Up
Some clean up steps can be done before performing the final package installs.
```
rm -rf /usr/share/{info,man,doc}/*
find /usr/{lib,libexec} -name \*.la -delete
rm -rf /tools
```
*NOTE:*The final step is to make a backup, but I'll just snapshot the VM.

View File

@@ -0,0 +1,5 @@
# Introduction to Part III
There are really three steps.
1. Build a limited cross compiler and its required libraries.
1. Use this cross toolchain to build utilities that are isolated from the host.
1. `chroot` into the new environment and complete the build of tools needed to construct the final system.