Learn from Linux from Scratch (LFS) (Part 1)

Learn from Linux from Scratch (LFS)这个系列的文章是我在阅读Linux from Scratch 9.1过程中的笔记。我用的宿主系统为CentOS 8(运行于VituralBox虚拟机中,VirtualBox虚拟机的Host是Windows 10)。

本篇对应于书的Preface至第4章”Final Preparations”。

分区并格式化

使用gparted,gnome-disks为LFS准备一个专门的分区不是难事。我没有用过fdisk,这里一并学习用fdisk分区。

fdisk被设计用来进行“交互式”分区,也就是说从用户友好度上来说它和那些用GUI的软件应该差不多。虽然如此还是有值得记住的命令行参数

fdisk -l  # 列出分区

不过我个人认为fdisk -l配合lsblk更好。使用这些命令的目的是为了找到要操作哪个分区。因为真正开始操作是从这个命令开始:

fdisk /dev/sdb

几个重要的交互命令:

  • p: 显示当前分区表
  • n: 创建新分区
  • d: 删除分区
  • t和L: 选择分区类型(例如是Linux分区或是Swap分区?)
  • w: 写入更改
  • q: 退出

格式化的命令就很简单了。还是先用lsblk或者fdisk -l /dev/sdb确认一下要操作的分区(以免出错)

fdisk -l /dev/sdb
Disk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x18eb9bc6

Device Boot Start End Sectors Size Id Type
/dev/sdb1 2048 206847 204800 100M 83 Linux
/dev/sdb2 206848 21178367 20971520 10G 83 Linux
/dev/sdb3 21178368 37955583 16777216 8G 83 Linux
/dev/sdb4 37955584 41943039 3987456 1.9G 82 Linux swap / Solaris

然后mkfs.ext4, mkswap进行格式化。这两个命令带-L选项还可以设置卷标。今后想要改卷标的话就用e2lable

mkfs.ext4 -L boot /dev/sdb1
...
mkswap -L swap /dev/sdb4

LFS的构建思路

LFS先利用宿主系统的构建工具构建自己工具链,存放在/mnt/lfs/tools,然后再利用这个工具链构建系统中的其他组件。一个问题就此而来:为什么不直接利用宿主系统的构建工具构建LFS的全部组件,而是先构建工具链?

这个问题在书的第5.2节给出了解答。简单的说就是减少宿主系统的头文件、动态静态库污染工具链,特别是工具链中的Binutils和GCC。Binutils和GCC会“记住”生成它们的库和头文件的路径。

创建中间工具链的目的应该在编译“最小Linux系统”的过程中认真体会。

创建宿主系统上的专用构建账号

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

题外话,专用构建账户这种实践,在fedora包管理中也有。可以说这是一种基本的安全措施。

Login shell and a clean environment

Login shell通过su - [user]登入。与不加“-”号的su的主要区别是,这个加了“-“的版本会清除之前shell的环境变量。

但是这仍然不够,宿主系统的/etc/profile仍然会污染我们的lfs。因此需要借助exec(替换当前shell)和env -i(无视现有环境运行某个程序):

exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash

不过我不能理解的是为什么这句话写入.bash_profile才管用,直接在现有shell运行不完全起作用。

巧妙利用bash和cat创建新文件

书中多次出现了类似于

cat > ~/.bash_profile << "EOF"

的技巧。

bash的hash function

bash内置了一个hash表,它会保留上一次在PATH中找到的可执行程序的完整路径,从而避免每一次运行ls都去查一遍PATH确认ls是在/bin/ls这样的位置。但是,在构建LFS,我们希望总是能重新搜索PATH=/tools/bin:/bin:/usr/bin:有些程序在宿主机的/bin/usr/bin也存在,但是我们希望在中间工具链构建的过程中,尽可能使用位于/tools/bin的自行编译的版本。因此在构建中间工具链的环境中应该使用set +h关掉bash的这个功能。

umask

umask掩码规定了在创建新文件时,哪些权限是被删除的。例如,umask 022表示创建的新文件的实际权限为666-022=644(均为八进制),也就是rw-r–r–;创建的新目录的实际权限为777-022=755(均为八进制),也就是rwxr-xr-x。。

注意1:umask 022并不会去掉编译程序所生成文件的执行权限。

注意2:umask可能是bash内置命令,也可能是/usr/bin/umask。用command -v umask确定用的到底是哪个!

发表评论

电子邮件地址不会被公开。