6.23. Making the Temporary System Bootable

6.23.1. Introduction

In a normal LFS building procedure, we will chroot into the temporary system and continue to build additional temporary tools. But, obviously we can't execute LoongArch binaries on our host system (a Linux distro running on x86), so the chroot approach is not suitable here. Instead, we need to make the temporary system bootable and boot it on the target system.

6.23.2. Setting Up the Configuration

EFI firmware loads the bootloader from an EFI executable file at a path in a vfat filesystem, the filesystem is located in a partition called EFI partition. The path may be hardcoded in the firmware or configurable. LoongArch firmware has a hardcoded path /EFI/BOOT/BOOTLOONGARCH.EFI, for example. GRUB works on LoongArch by install itself as an EFI executable there. Then it loads GRUB modules in the boot partition. The default location of modules is set with --prefix option, see below.

Install the GRUB EFI executable:

mkdir -pv $LFS/boot/efi/EFI/BOOT
$LFS_TGT-grub-mkimage \
    --prefix '(,gpt2)/grub'                           \
    --output $LFS/boot/efi/EFI/BOOT/BOOTLOONGARCH.EFI \
    --format loongarch64-efi                          \
    ext2 part_gpt

The meaning of the command options:

--prefix '(,gpt2)/grub'

Tells GRUB to load modules and grub.cfg from grub directory in the second partition (we'll use it as the boot partition), on the same disk where the EFI partition is.

ext2 and part_gpt

Buile ext2 and part_gpt module into the EFI executable, so it can parse the GPT partition table and ext2 filesystem to load other modules.

Install GRUB modules into the boot partition:

mkdir -pv $LFS/boot/grub
cp -av $LFS/tools/lib/grub/loongarch64-efi \
       $LFS/boot/grub/loongarch64-efi

6.23.3. Creating the GRUB Configuration File

Generate $LFS/boot/grub/grub.cfg:

cat > $LFS/boot/grub/grub.cfg << "EOF"
# Begin /boot/grub/grub.cfg
set default=0
set timeout=5

menuentry "LFS Temporary System" {
        linux   /vmlinux root=/dev/sda3 rw init=/bin/bash
        initrd  /acpi-initrd
        boot
}
EOF

The meaning of the linux command options:

root=/dev/sda3

We will use the third parition as the partition for the root filesystem of the LFS system.

rw

Tell the kernel to mount the root filesystem read-write. In normal distros there is ro instead, so the kernel will mount the root filesystem read-only. Then the init process can check the filesystem integrity and remount it read-write. For the temporary system it's not needed.

init=/bin/bash

By default the kernel runs /sbin/init as the first process. It's provided by SysVinit or Systemd package, which is not installed yet. We explicitly tell the kernel to run /bin/bash instead to start a shell, so we can run further commands interactively.

(optional) console=ttyS0,115200

Use the serial port at /dev/ttyS0 as the output console device. It's very useful if the virtual console is not avaliable (for example, the target system may lack graphic output, or the framebuffer console may be too slow). And, by connecting the host system and the target system with a NULL modem or USB serial converter, it will be able to copy the commands from the book and paste it into a terminal emulator (for example, GNU Screen) on the host, to execute them on the target system. 115200 specifies the baudrate, the default (9600) is too slow for large amount of console output building LFS.

[Note]

Note

From GRUB's perspective, the kernel files are relative to the partition used. We will use a a separate /boot partition, so /boot is not needed in the above linux line.

6.23.4. Copy the Temporary System to the Target Machine

[Note]

Note

The commands in the subsection must be performed on the host system while logged in as user root and no longer as user lfs. Also, double check that $LFS is set in root's environment.

Now it's the time to copy the $LFS hierarchy over to your target machine. You'll need a moveable device for this. Using a normal USB sticks is likely a bad choice: the USB sticks are generally not optimized for reading or writing many small files (which will happen building packages from source). Especially, if a ext filesystem is used, the performance can be very bad. You may use a USB to SATA adapter and a HDD or SSD (then you can directly connect it onto the SATA port of the target system, or continuing to use the USB to SATA adapter), or a USB stick with an I/O controller for SSD (such a USB stick is significantly more expansive than a normal one).

Create a GUID partition table on the device, and then create three partitions on it. The first will be used as the EFI partition, 100 MB is enough to fit the GRUB EFI executable. The second will be used as the boot partition, 500 MB is sufficient enough. The third will be the root partition, it should be at least 20 GB.

Create filesystems for the partitions:

mkfs.vfat /dev/sdx1
mkfs.ext2 /dev/sdx2
mkfs.ext4 /dev/sdx3

In Section 7.14, “Cleaning up and Saving the Temporary System” it's optional to make a backup for the temporary system. If you'd like to do so, prepare another parition (1 GB should be enough) and make a ext4 filesystem to hold the backup:

mkfs.ext4 /dev/sdx4

sdx should be replaced with the name of the device node corresponding to your moveable device. Then mount the filesystems:

mkdir -pv /mnt/lfs-target
mount -v -t ext4 /dev/sdx3 /mnt/lfs-target
mkdir -pv /mnt/lfs-target/boot
mount -v -t ext2 /dev/sdx2 /mnt/lfs-target/boot
mkdir -pv /mnt/lfs-target/boot/efi
mount -v -t vfat /dev/sdx1 /mnt/lfs-target/boot/efi

Copy the temporary system onto the device, and change the ownership of the copy to user root:

cp -av $LFS/* /mnt/lfs-target
chown -R root:root /mnt/lfs-target
[Note]

Note

The cp command above will complain that it can not preserve the owner of the contents in $LFS/boot/efi. It's normal because vfat does not support UNIX file owner and group mechanism, anything in the EFI parition can only be owned by root now. The next chown will change the owner of the entire system to root in the next steps anyway.

Create the mountpoint for devtmpfs, so the kernel will mount it automatically:

install -v -dm755 /mnt/lfs-target/dev

Now, unmount the device:

umount -Rv /mnt/lfs-target

You can now unplug the device and connect it onto the target system.