【lfs11.1 从零开始】01-宿主机准备和创建临时系统

222 阅读9分钟

对linux体系的东西知之甚少,想要借助LFS稍微入点门,督促自己学点linux的东西,所以才有了这个系列。

整个学习的过程,除了参考官网11.1版本的手册,也在B站看了点前辈们的操作视频,遇到新的知识点翻一翻鸟哥Linux私房菜,遇到报错最好是去google一下,毕竟是套广为流传的教程,基本上我遇到的问题别人也都遇到过。

准备工作首先是要有一台宿主机,本来我自己的机器弄个虚拟机什么也可以操作,但是思来想去还是去华为云上弄了个便宜的机器,挂载了两块50G的硬盘来弄。

LFS官网:www.linuxfromscratch.org/

分区

拿到机器和硬盘,第一件事情是要分区,云上机器默认的系统盘/dev/vda好像不允许我动,所以我又额外挂载了一个50G的硬盘。分区的目标是将新的数据盘/dev/vdb 挂在到/mnt/lfs目录下

查看当前分区信息

fdisk -l
[root@ecs-341537 ~]# fdisk -l

磁盘 /dev/vda:42.9 GB, 42949672960 字节,83886080 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0x000a0e76

   设备 Boot      Start         End      Blocks   Id  System
/dev/vda1   *        2048    83886079    41942016   83  Linux

磁盘 /dev/vdb:42.9 GB, 42949672960 字节,83886080 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节

进入分区工具

fdisk /dev/vdb
[root@ecs-341537 ~]# fdisk /dev/vdb
欢迎使用 fdisk (util-linux 2.23.2)。

更改将停留在内存中,直到您决定将更改写入磁盘。
使用写入命令前请三思。

Device does not contain a recognized partition table
使用磁盘标识符 0xce13e1c3 创建新的 DOS 磁盘标签。

命令(输入 m 获取帮助):p

磁盘 /dev/vdb:42.9 GB, 42949672960 字节,83886080 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0xce13e1c3

   设备 Boot      Start         End      Blocks   Id  System

命令(输入 m 获取帮助):n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
分区号 (1-4,默认 1):
起始 扇区 (2048-83886079,默认为 2048):
将使用默认值 2048
Last 扇区, +扇区 or +size{K,M,G} (2048-83886079,默认为 83886079):
将使用默认值 83886079
分区 1 已设置为 Linux 类型,大小设为 40 GiB

分区完成,输入"p"查看信息

命令(输入 m 获取帮助):p

磁盘 /dev/vdb:42.9 GB, 42949672960 字节,83886080 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0xce13e1c3

   设备 Boot      Start         End      Blocks   Id  System
/dev/vdb1            2048    83886079    41942016   83  Linux

输入"w",按"Enter",将分区结果写入分区表中

命令(输入 m 获取帮助):w
The partition table has been altered!

Calling ioctl() to re-read partition table.
正在同步磁盘。

执行partprobe命令,将新的分区表变更同步至操作系统。

[root@ecs-341537 ~]# partprobe
[root@ecs-341537 ~]# fdisk -l

磁盘 /dev/vda:42.9 GB, 42949672960 字节,83886080 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0x000a0e76

   设备 Boot      Start         End      Blocks   Id  System
/dev/vda1   *        2048    83886079    41942016   83  Linux

磁盘 /dev/vdb:42.9 GB, 42949672960 字节,83886080 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0xce13e1c3

   设备 Boot      Start         End      Blocks   Id  System
/dev/vdb1            2048    83886079    41942016   83  Linux

格式化

ext4 格式化

[root@ecs-341537 ~]# lsblk
NAME   MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda    253:0    0  40G  0 disk
└─vda1 253:1    0  40G  0 part /
vdb    253:16   0  40G  0 disk
└─vdb1 253:17   0  40G  0 part
[root@ecs-341537 ~]# mkfs -t ext4 /dev/vdb1
mke2fs 1.42.9 (28-Dec-2013)
文件系统标签=
OS type: Linux
块大小=4096 (log=2)
分块大小=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
2621440 inodes, 10485504 blocks
524275 blocks (5.00%) reserved for the super user
第一个数据块=0
Maximum filesystem blocks=2157969408
320 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
	4096000, 7962624

Allocating group tables: 完成
正在写入inode表: 完成
Creating journal (32768 blocks): 完成
Writing superblocks and filesystem accounting information: 完成

挂载

[root@ecs-341537 ~]# mkdir /mnt/lfs
[root@ecs-341537 ~]# mount /dev/vdb1 /mnt/lfs/
[root@ecs-341537 ~]# df -TH
文件系统       类型      容量  已用  可用 已用% 挂载点
devtmpfs       devtmpfs  953M     0  953M    0% /dev
tmpfs          tmpfs     964M     0  964M    0% /dev/shm
tmpfs          tmpfs     964M  9.0M  955M    1% /run
tmpfs          tmpfs     964M     0  964M    0% /sys/fs/cgroup
/dev/vda1      ext4       43G  2.7G   38G    7% /
tmpfs          tmpfs     193M     0  193M    0% /run/user/0
/dev/vdb1      ext4       43G   51M   40G    1% /mnt/lfs

云服务器重启后,挂载会失效,需要设置开机自动挂载

查询uuid

[root@ecs-341537 ~]# blkid /dev/vdb1
/dev/vdb1: UUID="39980c95-692b-4214-8954-f823bc88f5fc" TYPE="ext4"

vi /etc/fstab 编辑

#
# /etc/fstab
# Created by anaconda on Mon Feb 14 02:14:30 2022
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=16ecf522-4607-452f-8e42-ea6b728c6d45 /                       ext4    defaults        1 1
UUID=39980c95-692b-4214-8954-f823bc88f5fc /mnt/lfs                ext4    defaults        0 2

宿主机环境配置

分区弄好以后,先把宿主机环境要求的软件和版本都准备好,然后去把lfs11.1的源码下载下来。

宿主机软件要求

检查脚本

cat > version-check.sh << "EOF"
#!/bin/bash
# Simple script to list version numbers of critical development tools
export LC_ALL=C
bash --version | head -n1 | cut -d" " -f2-4
MYSH=$(readlink -f /bin/sh)
echo "/bin/sh -> $MYSH"
echo $MYSH | grep -q bash || echo "ERROR: /bin/sh does not point to bash"
unset MYSH

echo -n "Binutils: "; ld --version | head -n1 | cut -d" " -f3-
bison --version | head -n1

if [ -h /usr/bin/yacc ]; then
  echo "/usr/bin/yacc -> `readlink -f /usr/bin/yacc`";
elif [ -x /usr/bin/yacc ]; then
  echo yacc is `/usr/bin/yacc --version | head -n1`
else
  echo "yacc not found"
fi

echo -n "Coreutils: "; chown --version | head -n1 | cut -d")" -f2
diff --version | head -n1
find --version | head -n1
gawk --version | head -n1

if [ -h /usr/bin/awk ]; then
  echo "/usr/bin/awk -> `readlink -f /usr/bin/awk`";
elif [ -x /usr/bin/awk ]; then
  echo awk is `/usr/bin/awk --version | head -n1`
else
  echo "awk not found"
fi

gcc --version | head -n1
g++ --version | head -n1
grep --version | head -n1
gzip --version | head -n1
cat /proc/version
m4 --version | head -n1
make --version | head -n1
patch --version | head -n1
echo Perl `perl -V:version`
python3 --version
sed --version | head -n1
tar --version | head -n1
makeinfo --version | head -n1  # texinfo version
xz --version | head -n1

echo 'int main(){}' > dummy.c && g++ -o dummy dummy.c
if [ -x dummy ]
  then echo "g++ compilation OK";
  else echo "g++ compilation failed"; fi
rm -f dummy.c dummy
EOF

bash version-check.sh

安装通过yum -y install 安装就好了 yacc 需要通过链接的方式

[root@ecs-341537 ~]# ln -sv /usr/bin/bison /usr/bin/yacc
"/usr/bin/yacc" -> "/usr/bin/bison"

另外,make 要求4.0, 我们这里版本是3.82

[root@ecs-341537 ~]# cd /tmp
[root@ecs-341537 tmp]# wget http://mirrors.ustc.edu.cn/gnu/make/make-4.0.tar.gz
[root@ecs-341537 tmp]# tar -xf make-4.0.tar.gz
[root@ecs-341537 tmp]# cd make-4.0
[root@ecs-341537 make-4.0]# ./configure
[root@ecs-341537 make-4.0]# make && make install

安装完了还没完,检查下版本发现还是3.82


[root@ecs-341537 make-4.0]# make -v
GNU Make 3.82
Built for x86_64-redhat-linux-gnu
Copyright (C) 2010  Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.


[root@ecs-341537 make-4.0]# whereis make
make: /usr/bin/make /usr/local/bin/make /usr/share/man/man1/make.1.gz
[root@ecs-341537 make-4.0]# cd /usr/bin/
[root@ecs-341537 bin]# mv make make.bak
[root@ecs-341537 bin]# ln -sv /usr/local/bin/make /usr/bin/make
"/usr/bin/make" -> "/usr/local/bin/make"
[root@ecs-341537 bin]# make -v
GNU Make 4.0
Built for x86_64-unknown-linux-gnu
Copyright (C) 1988-2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

设置环境变量

www.linuxfromscratch.org/lfs/view/11…

[root@ecs-341537 ~]# export LFS=/mnt/lfs
[root@ecs-341537 ~]# echo $LFS
/mnt/lfs

创建放源码的目录

www.linuxfromscratch.org/lfs/view/11…

[root@ecs-341537 ~]# mkdir -v $LFS/sources
mkdir: 已创建目录 "/mnt/lfs/sources"
[root@ecs-341537 ~]# chmod -v a+wt $LFS/sources
mode of "/mnt/lfs/sources" changed from 0755 (rwxr-xr-x) to 1777 (rwxrwxrwt)
[root@ecs-341537 ~]# cd /mnt/lfs/sources/

下载和解压11.1 tar包

下载地址 mirrors.ustc.edu.cn/

[root@ecs-341537 sources]# wget https://mirrors.ustc.edu.cn/lfs/lfs-packages/lfs-packages-11.1.tar

--2022-07-23 02:03:23--  https://mirrors.ustc.edu.cn/lfs/lfs-packages/lfs-packages-11.1.tar
正在解析主机 mirrors.ustc.edu.cn (mirrors.ustc.edu.cn)... 202.141.176.110, 202.141.160.110, 2001:da8:d800:95::110
正在连接 mirrors.ustc.edu.cn (mirrors.ustc.edu.cn)|202.141.176.110|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:482498560 (460M) [application/octet-stream]
正在保存至: “lfs-packages-11.1.tar”

10% [======>                                                                     ] 50,601,690  1.29MB/s 剩余 66s

解压

[root@ecs-341537 sources]# tar -xf lfs-packages-11.1.tar
[root@ecs-341537 sources]# ll
总用量 471196
drwxrwxr-x 2 1000 1000      4096 3   1 11:37 11.1
-rw-r--r-- 1 root root 482498560 3   1 11:42 lfs-packages-11.1.tar

将11.1 文件夹下的文件移动到sources文件夹下

[root@ecs-341537 sources]# mv 11.1/* .
[root@ecs-341537 sources]# rm -rf 11.1 lfs-packages-11.1.tar

到这里,记得创建一个镜像。

www.linuxfromscratch.org/lfs/view/11…

创建临时系统

建目录

在$LFS环境中创建一系列目录

[root@ecs-341537 sources]# mkdir -pv $LFS/{etc,var} $LFS/usr/{bin,lib,sbin}
mkdir: 已创建目录 "/mnt/lfs/etc"
mkdir: 已创建目录 "/mnt/lfs/var"
mkdir: 已创建目录 "/mnt/lfs/usr"
mkdir: 已创建目录 "/mnt/lfs/usr/bin"
mkdir: 已创建目录 "/mnt/lfs/usr/lib"
mkdir: 已创建目录 "/mnt/lfs/usr/sbin"

[root@ecs-341537 sources]# for i in bin lib sbin; do
>   ln -sv usr/$i $LFS/$i
> done
"/mnt/lfs/bin" -> "usr/bin"
"/mnt/lfs/lib" -> "usr/lib"
"/mnt/lfs/sbin" -> "usr/sbin"

[root@ecs-341537 sources]# case $(uname -m) in
>   x86_64) mkdir -pv $LFS/lib64 ;;
> esac
mkdir: 已创建目录 "/mnt/lfs/lib64"
mkdir -pv $LFS/{etc,var} $LFS/usr/{bin,lib,sbin}

for i in bin lib sbin; do
  ln -sv usr/$i $LFS/$i
done

case $(uname -m) in
  x86_64) mkdir -pv $LFS/lib64 ;;
esac

查看目录结构

[root@ecs-341537 lfs]# mkdir -pv $LFS/tools
mkdir: 已创建目录 "/mnt/lfs/tools"


[root@ecs-341537 lfs]# ll
总用量 40
lrwxrwxrwx 1 root root     7 7  23 02:17 bin -> usr/bin
drwxr-xr-x 2 root root  4096 7  23 02:17 etc
lrwxrwxrwx 1 root root     7 7  23 02:17 lib -> usr/lib
drwxr-xr-x 2 root root  4096 7  23 02:17 lib64
drwx------ 2 root root 16384 7  23 01:29 lost+found
lrwxrwxrwx 1 root root     8 7  23 02:17 sbin -> usr/sbin
drwxrwxrwt 2 root root  4096 7  23 02:18 sources
drwxr-xr-x 2 root root  4096 7  23 02:20 tools
drwxr-xr-x 5 root root  4096 7  23 02:17 usr
drwxr-xr-x 2 root root  4096 7  23 02:17 var

建无特权的账号

[root@ecs-341537 lfs]# groupadd lfs
[root@ecs-341537 lfs]# useradd -s /bin/bash -g lfs -m -k /dev/null lfs

-s /bin/bash   指定用户登入后所使用的shell。 -g lfs 指定用户所属的群组。 -m 自动建立用户的登入home目录 -k /dev/null lfs 用户名

设置lfs用户的密码

[root@ecs-341537 lfs]# passwd lfs

设置权限

[root@ecs-341537 lfs]# chown -v lfs $LFS/{usr{,/*},lib,var,etc,bin,sbin,tools}
changed ownership of "/mnt/lfs/usr" from root to lfs
changed ownership of "/mnt/lfs/usr/bin" from root to lfs
changed ownership of "/mnt/lfs/usr/lib" from root to lfs
changed ownership of "/mnt/lfs/usr/sbin" from root to lfs
"/mnt/lfs/lib" 的所有者已保留为lfs
changed ownership of "/mnt/lfs/var" from root to lfs
changed ownership of "/mnt/lfs/etc" from root to lfs
"/mnt/lfs/bin" 的所有者已保留为lfs
"/mnt/lfs/sbin" 的所有者已保留为lfs
changed ownership of "/mnt/lfs/tools" from root to lfs
[root@ecs-341537 lfs]# case $(uname -m) in
>   x86_64) chown -v lfs $LFS/lib64 ;;
> esac
changed ownership of "/mnt/lfs/lib64" from root to lfs

[root@ecs-341537 lfs]# chown -v lfs $LFS/sources
changed ownership of "/mnt/lfs/sources" from root to lfs

接下来以lfs的身份登录

[root@ecs-341537 lfs]# su - lfs
-bash-4.2$

-bash-4.2$ whoami
lfs

设置环境

-bash-4.2$ cat > ~/.bash_profile << "EOF"
> exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
> EOF

-bash-4.2$ echo $HOME
/home/lfs
-bash-4.2$ echo $TERM
xterm-256color
-bash-4.2$ echo PS1
PS1
-bash-4.2$ cat > ~/.bashrc << "EOF"
> set +h
> umask 022
> LFS=/mnt/lfs
> LC_ALL=POSIX
> LFS_TGT=$(uname -m)-lfs-linux-gnu
> PATH=/usr/bin
> if [ ! -L /bin ]; then PATH=/bin:$PATH; fi
> PATH=$LFS/tools/bin:$PATH
> CONFIG_SITE=$LFS/usr/share/config.site
> export LFS LC_ALL LFS_TGT PATH CONFIG_SITE
> EOF

切换到root用户

-bash-4.2$ exit
logout
[root@ecs-341537 lfs]# whoami
root

[root@ecs-341537 lfs]# [ ! -e /etc/bash.bashrc ] || mv -v /etc/bash.bashrc /etc/bash.bashrc.NOUSE

切换回lfs用户

[root@ecs-341537 etc]# su - lfs
lfs:~$ source ~/.bash_profile
lfs:~$ echo $LFS
/mnt/lfs
lfs:~$ echo $PATH
/mnt/lfs/tools/bin:/usr/bin

查看当前.bashrc

lfs:~$ ls -a
.  ..  .bash_history  .bash_profile  .bashrc

lfs:~$ cat .bashrc
set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
LFS_TGT=$(uname -m)-lfs-linux-gnu
PATH=/usr/bin
if [ ! -L /bin ]; then PATH=/bin:$PATH; fi
PATH=$LFS/tools/bin:$PATH
CONFIG_SITE=$LFS/usr/share/config.site
export LFS LC_ALL LFS_TGT PATH CONFIG_SITE

设置多线程处理make 其实这里设置以后多半有坑,我的机器cpu和内存有限,在后面编译gcc的时候就反复遇到瓶颈。 直接用-j1可能还少点麻烦

set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
LFS_TGT=$(uname -m)-lfs-linux-gnu
PATH=/usr/bin
if [ ! -L /bin ]; then PATH=/bin:$PATH; fi
PATH=$LFS/tools/bin:$PATH
CONFIG_SITE=$LFS/usr/share/config.site
MAKEFLAGS='-j4'
export LFS LC_ALL LFS_TGT PATH CONFIG_SITE MAKEFLAGS

使设置生效

lfs:~$ source .bashrc
lfs:~$ set | grep MAKEFLAGS
MAKEFLAGS=-j4