文章目录

  • 前言
  • 宿主机环境
  • 搭建宿主机
  • 前期准备
  • 宿主系统要求
  • 创建分区
  • 分区
  • 格式化
  • 挂载分区
  • 准备软件包
  • 最后的准备工作
  • 构建临时系统
  • Binutils-2.32 - 第 1 遍
  • GCC-8.2.0 - 第 1 遍
  • Linux-4.20.12 API 头文件
  • Glibc-2.29
  • GCC-8.2.0 中的 Libstdc++
  • Binutils-2.32 - 第 2 遍
  • GCC-8.2.0 - 第 2 遍
  • 构建LFS系统
  • 准备虚拟内核文件系统
  • 进入 Chroot 环境
  • 创建目录、文件、软链接
  • Linux-4.20.12 API 头文件
  • Man-pages-4.16
  • Glibc-2.29
  • 调整工具链
  • Zlib-1.2.11
  • 省略的
  • 清理
  • 重新进入chroot环境
  • 系统配置
  • 网络配置
  • 设备管理
  • ......
  • 让LFS系统可引导
  • 创建 /etc/fstab 文件
  • Linux-4.20.12
  • 使用 GRUB 设置启动过程
  • 尾声


前言

内容基本摘抄LFS BOOK,意义不大
稍微有点内容的工作,请跳转至Linux内核编译

宿主机环境

VMware Workstation 16 Pro
OpenEuler 20.03 LTS SP1

搭建宿主机

新建虚拟机

自定义(高级)

硬件兼容性默认

稍后安装操作系统

Linux(其他Linux4.x内核64位——对应openEuler 20.03 LTS SP1)

选择位置

处理器数量——建议与PC相同

内存大小——建议设为PC内存的一半

后面均选默认设置(新磁盘,将虚拟磁盘存储为单个文件,只用做LFS宿主机就10G左右)

openeuler相对于centos几_openeuler相对于centos几

前期准备

宿主系统要求

用书中脚本检查相关软件版本即可,对于openEuler 20.03 LTS SP1,请用yum -y install命令安装缺失的软件包;

对于缺少的yacc:

openeuler相对于centos几_lfs_02


根据书中提示,yacc是bison的符号链接,可用命令创建:

ln -s /usr/bin/bison /usr/bin/yacc

创建分区

对于虚拟机,建议新增硬盘作为LFS分区:
打开虚拟机设置-选择硬盘-添加-选择硬盘下一步-SCSI-创建新虚拟磁盘-选择大小(建议25G)-将虚拟磁盘存储为单个文件-选择保存位置-完成
这样,就相当于在物理机上新插上了一块硬盘,下面进入宿主机系统,分区,格式化:

分区

使用fdisk工具进行磁盘分区(亦可使用带UI的cfdisk)

fdisk /dev/sdb

Note: Linux下,/dev/sda代表第一块硬盘,sdb代表第二块硬盘,依次类推;
/dev/sdb1则代表第一块硬盘下的第一个分区

然后敲命令“n”(表示新分区)回车 - 直接回车或敲命令“p”(主分区)- 直接回车或输入分区号“1” - 回车 - 回车(全部大小)

“p”命令可以查看要执行的操作(在敲“w”命令前,操作都不会生效)

确定无误后敲入“w”命令:

openeuler相对于centos几_linux_03

格式化

格式化为ext4文件系统,只需一句命令:

mkfs -t ext4 /dev/sdb1

lsblk命令可以查看所有分区:

lsblk

挂载分区

export LFS=/mnt/lfs
mkdir -pv $LFS
mount -v -t ext4 /dev/sdb1 $LFS

openeuler相对于centos几_lfs_04


有警告,暂时不管;

查看已有的swap分区,已有swap分区可以不另行创建。

swapon -s

openeuler相对于centos几_bash_05

准备软件包

软件包从某位B站大佬处获得:视频地址 创建sources目录,可用scp将软件包拷入

mkdir -v $LFS/sources
chmod -v a+wt $LFS/sources

openeuler相对于centos几_bash_06


校验文件完整性:

pushd $LFS/sources
md5sum -c md5sums
popd

最后的准备工作

在 $LFS 中新建一个用于安装临时工具的目录,增加一个非特权用户用于降低风险,并为该用户创建合适的构建环境。
下一步是在宿主系统中创建 /tools 的符号链接,将其指向 LFS 分区中新建的目录:

mkdir -v $LFS/tools
ln -sv $LFS/tools /

添加新用户:

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

更改权限:

chown -v lfs $LFS/tools
chown -v lfs $LFS/sources

切换为用户lfs登录:

su - lfs

设置环境

cat > ~/.bash_profile << "EOF"
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
EOF
cat > ~/.bashrc << "EOF"
set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
LFS_TGT=$(uname -m)-lfs-linux-gnu
PATH=/tools/bin:/bin:/usr/bin
export LFS LC_ALL LFS_TGT PATH
EOF
source ~/.bash_profile

set +h 命令关闭了 bash 的哈希功能(?)

openeuler相对于centos几_openeuler相对于centos几_07

构建临时系统

构建一个最小的Linux系统作为“桥梁”。第一步,是构建一个与宿主系统无关的新工具链(编译器、汇编器、链接器、库和一些有用的工具)。第二步则是使用该工具链,去构建其它的基础工具。

Note: 查看平台名称和动态连接器

cd $LFS/sources
tar -xvf binutils-2.32.tar.xz 
./binutils-2.32/config.guess
readelf -l /bin/ls | grep interpreter
cd ~

openeuler相对于centos几_bc_08

得到:
 x86_64-pc-linux-gnu
 /lib64/ld-linux-x86-64.so.2

Binutils-2.32 - 第 1 遍

cd $LFS/sources/binutils-2.32
mkdir -v build
cd build
../configure --prefix=/tools \
--with-sysroot=$LFS \
--with-lib-path=/tools/lib \
--target=$LFS_TGT \
--disable-nls \
--disable-werror
make -j4
case $(uname -m) in
x86_64) mkdir -v /tools/lib && ln -sv lib /tools/lib64 ;;
esac
make install

GCC-8.2.0 - 第 1 遍

11 SBU,很慢…

cd $LFS/sources/
tar -xvf gcc-8.2.0.tar.xz 
cd gcc-8.2.0

tar -xf ../mpfr-4.0.2.tar.xz
mv -v mpfr-4.0.2 mpfr
tar -xf ../gmp-6.1.2.tar.xz
mv -v gmp-6.1.2 gmp
tar -xf ../mpc-1.1.0.tar.gz
mv -v mpc-1.1.0 mpc
# 修改 GCC 默认的动态链接器的位置,安装到 /tools 目录
for file in gcc/config/{linux,i386/linux{,64}}.h
do
cp -uv $file{,.orig}
sed -e 's@/lib\(64\)\?\(32\)\?/ld@/tools&@g' \
-e 's@/usr@/tools@g' $file.orig > $file
echo '
#undef STANDARD_STARTFILE_PREFIX_1
#undef STANDARD_STARTFILE_PREFIX_2
#define STANDARD_STARTFILE_PREFIX_1 "/tools/lib/"
#define STANDARD_STARTFILE_PREFIX_2 ""' >> $file
touch $file.orig
done

case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' \
-i.orig gcc/config/i386/t-linux64
;;
esac
mkdir -v build
cd build
../configure \
--target=$LFS_TGT \
--prefix=/tools \
--with-glibc-version=2.11 \
--with-sysroot=$LFS \
--with-newlib \
--without-headers \
--with-local-prefix=/tools \
--with-native-system-header-dir=/tools/include \
--disable-nls \
--disable-shared \
--disable-multilib \
--disable-decimal-float \
--disable-threads \
--disable-libatomic \
--disable-libgomp \
--disable-libmpx \
--disable-libquadmath \
--disable-libssp \
--disable-libvtv \
--disable-libstdcxx \
--enable-languages=c,c++
make -j4
make install

Linux-4.20.12 API 头文件

同理tar解压再cd,后面不再赘述

make mrproper
make INSTALL_HDR_PATH=dest headers_install
cp -rv dest/include/* /tools/include

Glibc-2.29

mkdir -v build
cd build
../configure \
--prefix=/tools \
--host=$LFS_TGT \
--build=$(../scripts/config.guess) \
--enable-kernel=3.2 \
--with-headers=/tools/include
make -j4# 有报告说多线程可能失败
make install

Caution
到这里需要检查新工具链是否正常,

echo 'int main(){}' > dummy.c
$LFS_TGT-gcc dummy.c
readelf -l a.out | grep ': /tools'

应该输出:

openeuler相对于centos几_openeuler相对于centos几_09


清理掉:

rm -v dummy.c a.out

再继续。

GCC-8.2.0 中的 Libstdc++

Libstdc++ 是 GCC 源文件的一部分,在gcc文件夹里重新创建build。

mkdir -v build
cd build
../libstdc++-v3/configure \
--host=$LFS_TGT \
--prefix=/tools \
--disable-multilib \
--disable-nls \
--disable-libstdcxx-threads \
--disable-libstdcxx-pch \
--with-gxx-include-dir=/tools/$LFS_TGT/include/c++/8.2.0
make -j4
make install

Binutils-2.32 - 第 2 遍

第2遍是指用我们刚才交叉编译好的不完整gcc来编译binutils

mkdir -v build
cd build
CC=$LFS_TGT-gcc \
AR=$LFS_TGT-ar \
RANLIB=$LFS_TGT-ranlib \
../configure \
--prefix=/tools \
--disable-nls \
--disable-werror \
--with-lib-path=/tools/lib \
--with-sysroot
make -j4
make install

为下一章的「Re-adjusting」阶段准备链接器:

make -C ld clean
make -C ld LIB_PATH=/usr/lib:/lib
cp -v ld/ld-new /tools/bin

GCC-8.2.0 - 第 2 遍

用我们刚才交叉编译好的不完整gcc来编译一个完整的gcc
耗时14 SBU,过程省略

后面的步骤也省略了,请参考Linux From Scratch BOOK

构建LFS系统

准备虚拟内核文件系统

mkdir -pv $LFS/{dev,proc,sys,run}
mknod -m 600 $LFS/dev/console c 5 1
mknod -m 666 $LFS/dev/null c 1 3
mount -v --bind /dev $LFS/dev
mount -vt devpts devpts $LFS/dev/pts -o gid=5,mode=620
mount -vt proc proc $LFS/proc
mount -vt sysfs sysfs $LFS/sys
mount -vt tmpfs tmpfs $LFS/run
if [ -h $LFS/dev/shm ]; then
mkdir -pv $LFS/$(readlink $LFS/dev/shm)
fi

进入 Chroot 环境

chroot "$LFS" /tools/bin/env -i \
HOME=/root \
TERM="$TERM" \
PS1='(lfs chroot) \u:\w\$ ' \
PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin \
/tools/bin/bash --login +h

创建目录、文件、软链接

mkdir -pv /{bin,boot,etc/{opt,sysconfig},home,lib/firmware,mnt,opt}
mkdir -pv /{media/{floppy,cdrom},sbin,srv,var}
install -dv -m 0750 /root
install -dv -m 1777 /tmp /var/tmp
mkdir -pv /usr/{,local/}{bin,include,lib,sbin,src}
mkdir -pv /usr/{,local/}share/{color,dict,doc,info,locale,man}
mkdir -v /usr/{,local/}share/{misc,terminfo,zoneinfo}
mkdir -v /usr/libexec
mkdir -pv /usr/{,local/}share/man/man{1..8}
case $(uname -m) in
x86_64) mkdir -v /lib64 ;;
esac
mkdir -v /var/{log,mail,spool}
ln -sv /run /var/run
ln -sv /run/lock /var/lock
mkdir -pv /var/{opt,cache,lib/{color,misc,locate},local}
ln -sv /tools/bin/{bash,cat,chmod,dd,echo,ln,mkdir,pwd,rm,stty,touch} /bin
ln -sv /tools/bin/{env,install,perl,printf} /usr/bin
ln -sv /tools/lib/libgcc_s.so{,.1} /usr/lib
ln -sv /tools/lib/libstdc++.{a,so{,.6}} /usr/lib
install -vdm755 /usr/lib/pkgconfig
ln -sv bash /bin/sh
ln -sv /proc/self/mounts /etc/mtab

创建用户:

cat > /etc/passwd << "EOF"
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/dev/null:/bin/false
daemon:x:6:6:Daemon User:/dev/null:/bin/false
messagebus:x:18:18:D-Bus Message Daemon User:/var/run/dbus:/bin/false
systemd-bus-proxy:x:72:72:systemd Bus Proxy:/:/bin/false
systemd-journal-gateway:x:73:73:systemd Journal Gateway:/:/bin/false
systemd-journal-remote:x:74:74:systemd Journal Remote:/:/bin/false
systemd-journal-upload:x:75:75:systemd Journal Upload:/:/bin/false
systemd-network:x:76:76:systemd Network Management:/:/bin/false
systemd-resolve:x:77:77:systemd Resolver:/:/bin/false
systemd-timesync:x:78:78:systemd Time Synchronization:/:/bin/false
systemd-coredump:x:79:79:systemd Core Dumper:/:/bin/false
nobody:x:99:99:Unprivileged User:/dev/null:/bin/false
EOF

创建用户组:

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:
usb:x:14:
cdrom:x:15:
adm:x:16:
messagebus:x:18:
systemd-journal:x:23:
input:x:24:
mail:x:34:
kvm:x:61:
systemd-bus-proxy:x:72:
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:
wheel:x:97:
nogroup:x:99:
users:x:999:
EOF

可以解析用户名和组名了

exec /tools/bin/bash --login +h

初始化日志文件:

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

Linux-4.20.12 API 头文件

清理:

make mrproper

提取头文件

make INSTALL_HDR_PATH=dest headers_install
find dest/include \( -name .install -o -name ..install.cmd \) -delete
cp -rv dest/include/* /usr/include

Man-pages-4.16

make install

Glibc-2.29

打补丁

patch -Np1 -i ../glibc-2.29-fhs-1.patch

链接

ln -sfv /tools/lib/gcc /usr/lib
case $(uname -m) in
i?86) GCC_INCDIR=/usr/lib/gcc/$(uname -m)-pc-linux-gnu/8.2.0/include
ln -sfv ld-linux.so.2 /lib/ld-lsb.so.3
;;
x86_64) GCC_INCDIR=/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include
ln -sfv ../lib/ld-linux-x86-64.so.2 /lib64
ln -sfv ../lib/ld-linux-x86-64.so.2 /lib64/ld-lsb-x86-64.so.3
;;
esac
rm -f /usr/include/limits.h
mkdir -v build
cd build
CC="gcc -isystem $GCC_INCDIR -isystem /usr/include" \
../configure --prefix=/usr \
--disable-werror \
--enable-kernel=3.2 \
--enable-stack-protector=strong \
libc_cv_slibdir=/lib
unset GCC_INCDIR
make

链接以支持测试:

case $(uname -m) in
i?86) ln -sfnv $PWD/elf/ld-linux.so.2 /lib ;;
x86_64) ln -sfnv $PWD/elf/ld-linux-x86-64.so.2 /lib ;;
esac
make check

一些修复

touch /etc/ld.so.conf
sed '/test-installation/s@$(PERL)@echo not running@' -i ../Makefile

安装:

make install
cp -v ../nscd/nscd.conf /etc/nscd.conf
mkdir -pv /var/cache/nscd
install -v -Dm644 ../nscd/nscd.tmpfiles /usr/lib/tmpfiles.d/nscd.conf
install -v -Dm644 ../nscd/nscd.service /lib/systemd/system/nscd.service

安装语言地域:

mkdir -pv /usr/lib/locale
localedef -i POSIX -f UTF-8 C.UTF-8 2> /dev/null || true
localedef -i cs_CZ -f UTF-8 cs_CZ.UTF-8
localedef -i de_DE -f ISO-8859-1 de_DE
localedef -i de_DE@euro -f ISO-8859-15 de_DE@euro
localedef -i de_DE -f UTF-8 de_DE.UTF-8
localedef -i el_GR -f ISO-8859-7 el_GR
localedef -i en_GB -f UTF-8 en_GB.UTF-8
localedef -i en_HK -f ISO-8859-1 en_HK
localedef -i en_PH -f ISO-8859-1 en_PH
localedef -i en_US -f ISO-8859-1 en_US
localedef -i en_US -f UTF-8 en_US.UTF-8
localedef -i es_MX -f ISO-8859-1 es_MX
localedef -i fa_IR -f UTF-8 fa_IR
localedef -i fr_FR -f ISO-8859-1 fr_FR
localedef -i fr_FR@euro -f ISO-8859-15 fr_FR@euro
localedef -i fr_FR -f UTF-8 fr_FR.UTF-8
localedef -i it_IT -f ISO-8859-1 it_IT
localedef -i it_IT -f UTF-8 it_IT.UTF-8
localedef -i ja_JP -f EUC-JP ja_JP
localedef -i ja_JP -f SHIFT_JIS ja_JP.SIJS 2> /dev/null || true
localedef -i ja_JP -f UTF-8 ja_JP.UTF-8
localedef -i ru_RU -f KOI8-R ru_RU.KOI8-R
localedef -i ru_RU -f UTF-8 ru_RU.UTF-8
localedef -i tr_TR -f UTF-8 tr_TR.UTF-8
localedef -i zh_CN -f GB18030 zh_CN.GB18030
localedef -i zh_HK -f BIG5-HKSCS zh_HK.BIG5-HKSCS

包含中文,不用再执行make localedata/install-locales了
时区:

ln -sfv /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

动态库:

cat > /etc/ld.so.conf << "EOF"
# Begin /etc/ld.so.conf
/usr/local/lib
/opt/lib
EOF

调整工具链

让新编译的程序链接到这些新的库上
BOOK上的命令均能通过

Zlib-1.2.11

./configure --prefix=/usr
make
make check
make install
mv -v /usr/lib/libz.so.* /lib
ln -sfv ../../lib/$(readlink /usr/lib/libz.so) /usr/lib/libz.so

省略的

File-5.36——判断给定的某个或某些文件文件类型的工具

Readline-8.0——提供命令行编辑和历史功能的库的集合

M4-1.4.18——宏处理器

Bc-1.07.1——任意精度数值处理的语言

Binutils-2.32——一个链接器、一个汇编器、以及其它处理目标文件的工具

GMP-6.1.2——数学库。这里有对任意精度数值计算很有用的函数

MPFR-4.0.2——多精度数学函数

MPC-1.1.0——能以任意高精度进行复数数值计算和对结果进行正确四舍五入的库

Shadow-4.6——以安全方式处理密码的程序

GCC-8.2.0(92 SBU???)——GNU 编译器集,其中有 C 和 C++ 的编译器

check结果:(与标准比对,无异常)

openeuler相对于centos几_bc_10


完整性检查必须保证通过!!!

(我第一遍因为gcc的完整性检查没过,导致后面编译软件make出错,智能重新来了一遍,结果gcc check会有make error,但完整性检查又都能过了,暂时先放着吧)

Bzip2-1.0.6——压缩和解压缩的程序,用 bzip2 压缩文本文件能获得比传统的 gzip 更好的压缩比
Pkg-config-0.29.2——在配置和 make 文件运行时把 include 路径和库路径传递给编译工具的工具
Ncurses-6.1——用于不依赖于特定终端的字符屏幕处理的库
Attr-2.4.48——管理文件系统对象的扩展属性的工具
test中:1 PASS,1 FAIL
Acl-2.2.53——管理访问控制列表的工具,访问控制列表用于定义文件和目录更细粒度的自定义访问权限
Libcap-2.26——可用在 Linux 内核上的对 POSIX 1003.1e 功能的用户空间接口,这些功能将所有强大root 权限划分为不同的权限组合
Sed-4.7——流编辑器
Psmisc-23.2——用于显示运行中进程信息的程序
Iana-Etc-2.30——为网络服务和协议提供数据
Bison-3.3.2——语法生成器
Flex-2.6.4——用于生成识别文本模式的程序的工具
Grep-3.3——用于在文件中搜索的程序
Bash-5.0——Bourne-Again Shell
Libtool-2.4.6——GNU 通用库支持脚本,它用一致的、可移植的接口封装复杂的共享库
GDBM-1.18.1——GNU 数据库管理器
Gperf-3.1——为键集合生成完美的哈希函数
Expat-2.2.6——用于解析 XML 的面向流的 C 库
Inetutils-1.9.4——包含基本的网络程序
Perl-5.28.1——包含实用信息抽取与报告语言
XML::Parser-2.44——到 James Clark 的 XML 解析器的 Perl Expat 接口
Intltool-0.51.0——从源文件中抽取可翻译字符串的国际化工具
Autoconf-2.69——用于生成自动配置源代码的 shell 脚本的程序
Automake-1.16.1——生成可与 Autoconf 一同使用的 Makefile 的程序
Xz-5.2.4——用于压缩和解压文件的程序
Kmod-26——用于加载内核模块的库和工具
Gettext-0.19.8.1——用于国际化和本土化的工具
Libelf 源自 Elfutils-0.176——处理 ELF(可执行与可链接格式)文件的库
Libffi-3.2.1——为各种调用规范提供了一个可移植的,高级编程接口
OpenSSL-1.1.1a——管理工具和加密相关的库
Python-3.7.2——Python 的开发环境
Ninja-1.9.0——专注于速度的小型构件系统
Meson-0.49.2——开源代码构建系统
Coreutils-8.30——用于显示和设置基本系统特性的工具
Check-0.12.0——C 语言的单元测试框架
Diffutils-3.7——显示文件和目录差异的程序
Gawk-4.2.1——操作文本文件的程序
Findutils-4.6.0——查找文件的程序
Groff-1.22.4——用于处理和格式化文本的程序
GRUB-2.02——多重启动管理器(GRand Unified Bootloader)
Less-530——文本文件查看器
Gzip-1.10——压缩和解压文件的程序
IPRoute2-4.20.0——基于 IPV4 网络的基本和高级程序
Kbd-2.0.4——键表文件、控制台字体和键盘工具
Libpipeline-1.5.1——以灵活方便方式管理管道和子进程的库
Make-4.2.1——用于编译软件的程序
Patch-2.7.6——通过打「补丁」创建或修改文件的程序,补丁文件通常由 diff 程序生成
Man-DB-2.8.5——用于查找和查看 man 页面的程序
Tar-1.31——归档程序
Texinfo-6.5——用于读、写以及转换信息页的程序
Vim-8.1——强大的文本编辑器
systemd-240——用于控制启动、运行和关闭系统的程序
D-Bus-1.12.12——消息总线系统,应用之间相互通信的简单方式
Procps-ng-3.3.15——监视进程的程序
Util-linux-2.33.1——其它实用程序,包括处理文件系统、控制台、分区以及消息等工具
E2fsprogs-1.44.5——用于处理 ext2 文件系统的工具,它也支持 ext3 和 ext4 日志文件系统

清理

可不做

重新进入chroot环境

后面如果退出了,均用这个命令重新进入chroot

logout
chroot "$LFS" /usr/bin/env -i \
HOME=/root TERM="$TERM" \
PS1='(lfs chroot) \u:\w\$ ' \
PATH=/bin:/usr/bin:/sbin:/usr/sbin \
/bin/bash --login

系统配置

请用上方命令进入chroot环境,再进行系统配置

网络配置

参照BOOK,建议先配个DHCP试试,别配静态IP

设备管理

看一看,不用动

均按照BOOK走即可

让LFS系统可引导

创建 /etc/fstab 文件

cat > /etc/fstab << "EOF"
# Begin /etc/fstab
# file system mount-point type options dump fsck
# order
/dev/sda1 / ext4 defaults 1 1
# End /etc/fstab
EOF

这里设为sda1的原因是:最后我会新建一个空的虚拟机来挂载有LFS系统的这块硬盘,于是就变成了sda1

Linux-4.20.12

重头戏,编译Linux内核,我的LFS系统之前一直不启动就出错在这里!!!
也是先解压,再cd Linux-4.20.12,然后保证内核树的绝对干净

make mrproper

内核配置是一个比较庞大的工程,先使用make defconfig会参考你的机器架构生成一份基本能用的基础配置,于是

make defconfig

然后使用图形化配置内核

make menuconfig

那么,如何选择?
事实上,要考虑的因素太多太多了,现在回想,我最初的问题应该是出在VMWare虚拟机上,内核配置需要针对虚拟机这类虚拟硬件进行选择,最终我在linuxquestions.org找到的解决方案:

make -j4
make modules_install
cp -iv arch/x86/boot/bzImage /boot/vmlinuz-4.20.12-lfs-8.4-systemd
cp -iv System.map /boot/System.map-4.20.12
cp -iv .config /boot/config-4.20.12
install -d /usr/share/doc/linux-4.20.12
cp -r Documentation/* /usr/share/doc/linux-4.20.12

使用 GRUB 设置启动过程

在有LFS的硬盘上安装grub

grub-install /dev/sdb

这里是对于宿主机来说,装了LFS的硬盘是第二块sdb

创建 GRUB 配置文件

cat > /boot/grub/grub.cfg << "EOF"
# Begin /boot/grub/grub.cfg
set default=0
set timeout=5
insmod ext2
set root=(hd0,1)
menuentry "GNU/Linux, Linux 4.20.12-lfs-8.4-systemd" {
linux /boot/vmlinuz-4.20.12-lfs-8.4-systemd root=/dev/sda1 ro
}
EOF

这里是对于即将要新建的虚拟机而言,只有一块硬盘sda,然后在grub中hd0对应sda

尾声

参照book执行命令~关机后:

在VMWare中,新建一个空的虚拟机,不要新建磁盘,而是添加现有的LFS磁盘即可。

然后打开这个虚拟机:

openeuler相对于centos几_lfs_11


openeuler相对于centos几_bash_12