前言
域名买了一亿年了,结果还是只有Hello World,实在看不下去了,总之写点东西吧。
既然是博客的第一篇文章,当然是开天辟地的(X),所以就来写一下LFS吧。 本文参考Linux From Scratch 简体中文版写成,在此特别感谢作者Gerard Beekmans以及Linux中国 LFS 翻译小组成员。
本文采用知识共享署名-非商业性使用-相同方式共享 2.0 通用许可协议授权。
Linux® 为 Linus Torvalds 注册商标。
LFS简介
LFS 就是 Linux From Scratch(Linux 从头开始) 从零开始的Linux生活 ,这个From Scratch 就是和Docker的 FROM scratch
是一样的。
简单说就是自己从源码开始完整的构建一个Linux。
准备
准备宿主
自己构建一个Linux,首先你需要一个Linux环境(……),这里我们选择ArchLinux的LiveCD作为我们的宿主环境。
在VMware里新建一个虚拟机,分配上足够的CPU,因为后面会有无尽的编译。
在选择引导的时候,按tab键修改启动参数,在最后加上cow_spacesize=1G
来确保在Live环境中有足够的空间来更新包与安装其他必备包。
启动到ArchLinux的LiveCD后,先启动sshd
服务,这样我们就可以通过ssh安装,而不用手动去敲后面那些冗长的命令了。再修改一下root密码,方便登陆。
1 | systemctl start sshd |
之后我们就可以通过ssh连上宿主了。
检查宿主环境
执行命令
1 | cat > version-check.sh << "EOF" |
得到输出
1 | bash, version 5.0.0(1)-release |
看来环境差的有点多,慢慢配吧。
首先更换pacman源,这里我选择了中科大源。
更新之后安装缺少的环境。
pacman -S binutils bison gcc make patch
再次执行version-check.sh
可以发现不缺环境了。
分区
由于这只是实验性的构建系统,我们就将磁盘分为一个区,具体操作参见fdisk
。
注意:新建虚拟机的时候采用了UEFI请再划分一个efi分区(或叫boot)
格式化
毫无疑问,我们采用ext4分区。
mkfs.ext4 /dev/sda1
注意:请根据实际情况将sda1替换为实际的分区。
设置$LFS变量
在整个构建LFS的过程中,我们会多次用到环境变量 LFS
,它应该被设置为你将要构建的 LFS 系统的目录名,这里我们使用 /mnt/lfs
export LFS=/mnt/lfs
小心
不论何时,当你离开又重新进入这个工作环境时都不要忘了检查 LFS 是否设置(比如当你使用 su 切换到 root 或是另一个用户时)。使用如下命令检查 LFS 变量是否正确设置:
echo $LFS
请确保输出的是你构建 LFS 的那个目录的路径,如果你是按照例子设置的,那就是
/mnt/lfs
。如果你输出的路径不正确,请使用前一部分提供的命令把$LFS
重新设置到正确的目录。
挂载分区
执行以下命令来挂载分区
1 | mkdir -pv $LFS |
准备软件包和补丁
在构建完整的Linux之前,我们需要一个基础环境。
在下载之前,为了方便和整洁,我们新建一个工作用的目录。
以root
权限执行,创建这个目录,并设置目录的写权限和粘滞模式。「粘滞模式」是指,即便多个用户对某个目录有写权限,但仅有文件的所有者,能在粘滞目录中删除该文件。
1 | mkdir -v $LFS/sources |
我们可以用wget-list输入wget来快捷的下载所需的软件包和补丁。
1 | wget https://lctt.github.io/LFS-BOOK/lfs-systemd/wget-list |
最后的准备
添加临时工作目录
现在我们还有最后一点需要做的准备,现在我们构建的工具都是临时的,我们需要将其放在临时的目录里,方便用完后删除。
以root用户执行
1 | mkdir -v $LFS/tools |
如果你对第二条命令感到疑惑,请查阅
ln(1)
.TL;NR:
第二命令是创建了
/tools
指向$LFS/tools
的符号链接
### 添加LFS用户
以root用户的身份构建系统可能会造成毁灭性的后果,所以我们添加一个非特特权用户来进行工作。
1 | groupadd lfs |
useradd
的-k
选项防止了复制一些奇怪的东西到用户目录
设置环境
我们现在需要为新用户配置合适的环境来确保构建的顺利。
以lfs
用户身份运行一下命令创建.bash_profile
文件:
1 | cat > ~/.bash_profile << "EOF" |
这一串命令确保了登陆lfs
用户时环境变量的纯净,防止被外部环境变量污染导致错误。
以lfs
用户身份运行一下命令创建.bashrc
文件:
1 | cat > ~/.bashrc << "EOF" |
这里关闭了bash
的哈希功能,确保每次执行的命令都会从PATH
里依次寻找,保证能使用最新编译的工具。
设置掩码(umask)为022,以确保新建的文件和目录只有其所有者可写,但任何人都可读可执行。
LFS
变量应设置成选定的挂载点。
LC_ALL
变量控制某些程序的本地化,使它们的消息遵循特定国家的惯例。设置 LC_ALL
为「POSIX」或「C」(两者是等价的),确保在 chroot 环境中一切能如期望的那样进行。
LFS_TGT
变量设置了一个虽非默认,但在构建交叉编译器、连接器和交叉编译临时工作链时,用得上到的兼容的机器说明。参考Section 5.2, “工具链技术说明”获得更多信息。
最后,执行以下命令来完成我们的准备工作吧。
source ~/.bash_profile
构建临时系统
说明
在开始构建之前请务必再进行以下检查来确保环境正确: 0. 执行echo $LFS
确保环境变量正确 1. 使用的shell是bash
2. sh
是到bash
的符号链接 3. /usr/bin/awk
是到 gawk
的符号链接。 4. /usr/bin/yacc
是到 bison
的符号链接,或者是一个执行bison
的小脚本。
构建过程
- 把所有源文件和补丁放到 chroot 环境可访问的目录,例如
/mnt/lfs/sources/
。但是千万不能把源文件放在/mnt/lfs/tools/
中。 - 进入到源文件目录。
- 对于每个软件包:
- 用
tar
程序解压要编译的软件包。构建临时系统时,确保解压软件包时你使用的是lfs
用户。 - 进入到解压后创建的目录中。
- 根据指南说明编译软件包。
- 回退到源文件目录。
- 除非特别说明,删除解压出来的目录。
- 用
构建
由于需要构建的包过于多,详细信息请从这里开始阅读,并按照说明执行,若有重要信息我会在本文里说明。
Binutils-2.31.1 - 第 1 遍
构建Binutils
的时间将会作为编译用时参考,称为SBU
在build
文件夹下的测试命令应为
time { ../configure --prefix=/tools --with-sysroot=$LFS --with-lib-path=/tools/lib --target=$LFS_TGT --disable-nls --disable-werror&&make -j12 &&make install;}
其中j12
的多核编译参数请根据自己的cpu调整
也可添加环境变量来自动设置
export MAKEFLAGS='-j12'
Tar-1.31
如果硬盘空间不够,请不要执行这个测试,血的教训啊
尾声
现在我们已经把临时系统构建好了,可以开始摸鱼了休息一下,过上若干天后,再继续或者不继续这个漫长的LFS之旅