LFS之后的配置

LFS(Linux from scratch) 提供了一个基础系统,不过实际使用时,需要在完成LFS安装部署后,继续做一些补充配置

Firmware

Linux系统要能够在真实硬件上良好运行,需要安装不同厂商提供的硬件firmware:

  • CPU微码(microcode): 用于修复CPU漏洞

  • GPU firmware: 典型的是三家GPU厂商 - AMD, Intel, Nvidia

  • 有线网卡firmware: 通常能够修复问题提升性能

  • 其他设备firmware: 例如无线网卡需要特定firmware驱动才能工作

CPU microcode

  • 检查CPU信息:

检查CPU信息
head -n7 /proc/cpuinfo
  • 检查当前微码(还没有更新之前):

更新前的CPU微码
[    3.590214] microcode: Current revision: 0x00000049

备注

在执行 构建 microcode.img 前,先完成 cpio 安装

  • 构建 microcode.img :

构建 microcode.img
cd /sources

microcode_VERSION=20241112

tar xf Intel-Linux-Processor-Microcode-Data-Files-microcode-${microcode_VERSION}.tar.gz
cd Intel-Linux-Processor-Microcode-Data-Files-microcode-${microcode_VERSION}

mkdir -p initrd/kernel/x86/microcode
cd initrd

# 注意: 需要按照CPU型号转换十六进制,并找到对应 intel-ucode 目录下微码目录进行复制
# cpu family	: 6
# model		: 63
# stepping	: 2
# 转换为十六进制: 06-3f-02
cp -v ../intel-ucode/06-3f-02 kernel/x86/microcode/GenuineIntel.bin

# 准备initrd: 
find . | cpio -o -H newc > /boot/microcode.img
  • Intel发布的微码 releasenote.md 中有说明可检查

Intel微码 releasenote.md 更新 Xeon E5 v3

Processor

Stepping

F-M-S/PI

Old Ver

New Ver

Products

HSX-E/EP

Cx/M1

06-3f-02 /6f

00000046

00000049

Core Gen4 X series; Xeon E5 v3

备注

在执行 /boot/grub/grub.cfg 中添加 initrd 配置 前,先查看一下 initramfs 是否有必要一起完成。

目前我还没有使用 initramfs ,仅加载 CPU microcode : 后续有需要在补充添加 initramfs (可以补充在cpu microcode 的 initrd 后面加载

另外,如果 intel-ucode 微码目录完整复制到 /lib/firmware 目录下,那么 也可以 不用执行下面一步 在 /boot/grub/grub.cfg 中添加 initrd 配置 ,直接执行 initramfsmkinitramfs 会自动添加cpu microcode。

  • /boot/grub/grub.cfg 中添加 initrd 配置:

配置 grub.cfg
# GRUB serial, but not effect. Why?
serial --unit=0 --speed=115200
terminal_input serial console
terminal_output serial console

menuentry "GNU/Linux, Linux 6.10.5-lfs-12.2" {
  search --set=root --fs-uuid 81368941-bd96-4539-bf8e-7215d532a872
  linux   /boot/vmlinuz-6.10.5-lfs-12.2 root=PARTUUID=cf8d6f20-92bf-4f81-982e-50bea63e6ca3 ro iommu=pt intel_iommu=on pcie_acs_override=downstream,multifunction console=tty0 console=ttyS0,115200n8
  initrd  /boot/microcode.img
}
  • 重启系统,然后检查:

检查启动系统输出
dmesg | grep -e 'microcode' -e 'Linux version' -e 'Command line'

由于我的系统CPU在之前 Ubuntu Linux 安装运行时已经自动更新过CPU microcode,所以这里没有更新信息,还是 0x00000049 (也是之前检查 releasenote.md 可以看到最高版本)

检查启动系统输出显示CPU微码更新情况
[    0.000000] Linux version 6.10.5 (root@zcloud.staging.huatai.me) (gcc (GCC) 14.2.0, GNU ld (GNU Binutils) 2.43.1) #2 SMP PREEMPT_DYNAMIC Tue Jan 21 15:59:56 CST 2025
[    0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-6.10.5-lfs-12.2 root=PARTUUID=cf8d6f20-92bf-4f81-982e-50bea63e6ca3 ro
[    3.592464] microcode: Current revision: 0x00000049

网卡firmware

待补充...

Bash Shell启动文件

有关bash的一些环境设置:

  • 交互式登录 shell 在成功登录后通过读取 /etc/passwd 文件使用 /bin/login 启动

  • shell通常读取 /etc/profile 和用户私有等效 ~/.bash_profile~/.profile

  • 在 私有等效 ~/.bash_profile~/.profile 调用读取 ~/.bashrc

  • 通常自己 定制内容 应该存放在 ~/.bashrc

  • ~/.bash_logout 在用户推出交互式登陆 shell 时被读取和执行(类似退出清理动作可以在这里设置)

  • 很多发行版使用 /etc/bashrc 进行非登陆shell的系统范围初始化,该文件通常还会从用户的 ~/.bashrc 文件中调用而不是直接内置在bash本身中

  • 创建 /etc/profile

/etc/profile
cat > /etc/profile << "EOF"
# Begin /etc/profile
# Written for Beyond Linux From Scratch
# by James Robertson <[email protected]>
# modifications by Dagmar d'Surreal <[email protected]>

# System wide environment variables and startup programs.

# System wide aliases and functions should go in /etc/bashrc.  Personal
# environment variables and startup programs should go into
# ~/.bash_profile.  Personal aliases and functions should go into
# ~/.bashrc.

# Functions to help us manage paths.  Second argument is the name of the
# path variable to be modified (default: PATH)
pathremove () {
        local IFS=':'
        local NEWPATH
        local DIR
        local PATHVARIABLE=${2:-PATH}
        for DIR in ${!PATHVARIABLE} ; do
                if [ "$DIR" != "$1" ] ; then
                  NEWPATH=${NEWPATH:+$NEWPATH:}$DIR
                fi
        done
        export $PATHVARIABLE="$NEWPATH"
}

pathprepend () {
        pathremove $1 $2
        local PATHVARIABLE=${2:-PATH}
        export $PATHVARIABLE="$1${!PATHVARIABLE:+:${!PATHVARIABLE}}"
}

pathappend () {
        pathremove $1 $2
        local PATHVARIABLE=${2:-PATH}
        export $PATHVARIABLE="${!PATHVARIABLE:+${!PATHVARIABLE}:}$1"
}

export -f pathremove pathprepend pathappend

# Set the initial path
export PATH=/usr/bin

# Attempt to provide backward compatibility with LFS earlier than 11
if [ ! -L /bin ]; then
        pathappend /bin
fi

if [ $EUID -eq 0 ] ; then
        pathappend /usr/sbin
        if [ ! -L /sbin ]; then
                pathappend /sbin
        fi
        unset HISTFILE
fi

# Set up some environment variables.
export HISTSIZE=1000
export HISTIGNORE="&:[bf]g:exit"

# Set some defaults for graphical systems
export XDG_DATA_DIRS=${XDG_DATA_DIRS:-/usr/share}
export XDG_CONFIG_DIRS=${XDG_CONFIG_DIRS:-/etc/xdg}
export XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-/tmp/xdg-$USER}

# Set up a red prompt for root and a green one for users.
NORMAL="\[\e[0m\]"
RED="\[\e[1;31m\]"
GREEN="\[\e[1;32m\]"
if [[ $EUID == 0 ]] ; then
  PS1="$RED\u [ $NORMAL\w$RED ]# $NORMAL"
else
  PS1="$GREEN\u [ $NORMAL\w$GREEN ]\$ $NORMAL"
fi

for script in /etc/profile.d/*.sh ; do
        if [ -r $script ] ; then
                . $script
        fi
done

unset script RED GREEN NORMAL

# End /etc/profile
EOF
  • 创建 /etc/profile.d 目录

/etc/profile.d 目录
install --directory --mode=0755 --owner=root --group=root /etc/profile.d
  • /etc/profile.d/bash_completion.sh

备注

以下bash补全脚本会在bash环境中添加许多行(通常超过1000行),并且很难用 set 命令检查简单的环境变量。省略词脚本不会映像bash使用tab键进行文件名补全的能力。

我没有添加这个脚本

bash_completion.sh
cat > /etc/profile.d/bash_completion.sh << "EOF"
# Begin /etc/profile.d/bash_completion.sh
# Import bash completion scripts

# If the bash-completion package is installed, use its configuration instead
if [ -f /usr/share/bash-completion/bash_completion ]; then

  # Check for interactive bash and that we haven't already been sourced.
  if [ -n "${BASH_VERSION-}" -a -n "${PS1-}" -a -z "${BASH_COMPLETION_VERSINFO-}" ]; then

    # Check for recent enough version of bash.
    if [ ${BASH_VERSINFO[0]} -gt 4 ] || \
       [ ${BASH_VERSINFO[0]} -eq 4 -a ${BASH_VERSINFO[1]} -ge 1 ]; then
       [ -r "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion" ] && \
            . "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion"
       if shopt -q progcomp && [ -r /usr/share/bash-completion/bash_completion ]; then
          # Source completion code.
          . /usr/share/bash-completion/bash_completion
       fi
    fi
  fi

else

  # bash-completions are not installed, use only bash completion directory
  if shopt -q progcomp; then
    for script in /etc/bash_completion.d/* ; do
      if [ -r $script ] ; then
        . $script
      fi
    done
  fi
fi

# End /etc/profile.d/bash_completion.sh
EOF

确保目录存在:

确保 /etc/bash_completion.d 目录存在
install --directory --mode=0755 --owner=root --group=root /etc/bash_completion.d
  • /etc/profile.d/dircolors.sh

这个脚本使用 ~/.dircolors/etc/dircolors 文件夹来控制目录列表中文件的颜色。可以控制 ls --color 等命令的色彩输出

/etc/profile.d/dircolors.sh
cat > /etc/profile.d/dircolors.sh << "EOF"
# Setup for /bin/ls and /bin/grep to support color, the alias is in /etc/bashrc.
if [ -f "/etc/dircolors" ] ; then
        eval $(dircolors -b /etc/dircolors)
fi

if [ -f "$HOME/.dircolors" ] ; then
        eval $(dircolors -b $HOME/.dircolors)
fi

alias ls='ls --color=auto'
alias grep='grep --color=auto'
EOF
  • /etc/profile.d/extrapaths.sh

这个脚本向 PATH 添加了一些用用的路径,并可用于定制所有用户可能需要的其他 PATH 相关环境变量(例如 LD_LIBRARY_PATH 等)

/etc/profile.d/extrapaths.sh
cat > /etc/profile.d/extrapaths.sh << "EOF"
if [ -d /usr/local/lib/pkgconfig ] ; then
        pathappend /usr/local/lib/pkgconfig PKG_CONFIG_PATH
fi
if [ -d /usr/local/bin ]; then
        pathprepend /usr/local/bin
fi
if [ -d /usr/local/sbin -a $EUID -eq 0 ]; then
        pathprepend /usr/local/sbin
fi

if [ -d /usr/local/share ]; then
        pathprepend /usr/local/share XDG_DATA_DIRS
fi

# Set some defaults before other applications add to these paths.
pathappend /usr/share/info INFOPATH
EOF
  • /etc/profile.d/readline.sh

这个脚本设置默认的 inputrc 配置文件

/etc/profile.d/readline.sh
cat > /etc/profile.d/readline.sh << "EOF"
# Set up the INPUTRC environment variable.
if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ] ; then
        INPUTRC=/etc/inputrc
fi
export INPUTRC
EOF
  • /etc/profile.d/umask.sh

设置 umask 值对于安全非常重要,这里对系统用户及当前用户名和组名不同时,默认组写权限关闭。

/etc/profile.d/umask.sh
cat > /etc/profile.d/umask.sh << "EOF"
# By default, the umask should be set.
if [ "$(id -gn)" = "$(id -un)" -a $EUID -gt 99 ] ; then
  umask 002
else
  umask 022
fi
EOF
  • /etc/profile.d/i18n.sh

这个脚本设置本地语言支持所需的环境变量

/etc/profile.d/i18n.sh
cat > /etc/profile.d/i18n.sh << "EOF"
# Set up i18n variables
for i in $(locale); do
  unset ${i%=*}
done

# 这里我修改为直接设置 en_US.UTF-8
export LANG=en_US.UTF-8
EOF
  • /etc/bashrc

基础 /etc/bashrc ,请阅读文件中的注释

/etc/bashrc
cat > /etc/bashrc << "EOF"
# Begin /etc/bashrc
# Written for Beyond Linux From Scratch
# by James Robertson <[email protected]>
# updated by Bruce Dubbs <[email protected]>

# System wide aliases and functions.

# System wide environment variables and startup programs should go into
# /etc/profile.  Personal environment variables and startup programs
# should go into ~/.bash_profile.  Personal aliases and functions should
# go into ~/.bashrc

# Provides colored /bin/ls and /bin/grep commands.  Used in conjunction
# with code in /etc/profile.

alias ls='ls --color=auto'
alias grep='grep --color=auto'

# Provides prompt for non-login shells, specifically shells started
# in the X environment. [Review the LFS archive thread titled
# PS1 Environment Variable for a great case study behind this script
# addendum.]

NORMAL="\[\e[0m\]"
RED="\[\e[1;31m\]"
GREEN="\[\e[1;32m\]"
if [[ $EUID == 0 ]] ; then
  PS1="$RED\u [ $NORMAL\w$RED ]# $NORMAL"
else
  PS1="$GREEN\u [ $NORMAL\w$GREEN ]\$ $NORMAL"
fi

unset RED GREEN NORMAL

# End /etc/bashrc
EOF
  • ~/.bash_profile

以下时一个基础的 ~/.bash_profile ,如果希望每个新用户自动拥有这个文件,只需要将命令输出更为为 /etc/skel/.bash_profile ,并在运行命令后检查权限。然后可以将 /etc/.skel/.bash_profile 复制到现有用户(包括root)的祝目录,并是饿到甚至所有者和组

~/.bash_profile
cat > ~/.bash_profile << "EOF"
# Begin ~/.bash_profile
# Written for Beyond Linux From Scratch
# by James Robertson <[email protected]>
# updated by Bruce Dubbs <[email protected]>

# Personal environment variables and startup programs.

# Personal aliases and functions should go in ~/.bashrc.  System wide
# environment variables and startup programs are in /etc/profile.
# System wide aliases and functions are in /etc/bashrc.

if [ -f "$HOME/.bashrc" ] ; then
  source $HOME/.bashrc
fi

if [ -d "$HOME/bin" ] ; then
  pathprepend $HOME/bin
fi

# Having . in the PATH is dangerous
#if [ $EUID -gt 99 ]; then
#  pathappend .
#fi

# End ~/.bash_profile
EOF
  • ~/.bsashrc

~/.bashrc
cat > ~/.bashrc << "EOF"
# Begin ~/.bashrc
# Written for Beyond Linux From Scratch
# by James Robertson <[email protected]>

# Personal aliases and functions.

# Personal environment variables and startup programs should go in
# ~/.bash_profile.  System wide environment variables and startup
# programs are in /etc/profile.  System wide aliases and functions are
# in /etc/bashrc.

if [ -f "/etc/bashrc" ] ; then
  source /etc/bashrc
fi

# Set up user specific i18n variables
#export LANG=<ll>_<CC>.<charmap><@modifiers>

# End ~/.bashrc
EOF
  • ~/.bash_logout

这里是空白的 ~/.bash_logout 模版。注意基本的 ~/.bash_logout 并不包含 clear 命令,这是因为 clear 是由 /etc/issue 文件处理的

~/.bash_logout
cat > ~/.bash_logout << "EOF"
# Begin ~/.bash_logout
# Written for Beyond Linux From Scratch
# by James Robertson <[email protected]>

# Personal items to perform on logout.

# End ~/.bash_logout
EOF
  • /etc/dircolors

如果要使用 dircolors 能力,则执行以下命令

也可以在 /etc/skel 目录下添加同样的 .colors ,这样新用户就会自动拥有 ~/.dircolors 文件以便用户自己定制目录颜色

/etc/dircolors
dircolors -p > /etc/dircolors

/etc/vimrc~/.vimrc 文件

  • 基本的 /etc/vimrc~/.vimrc 文件

基本的 /etc/vimrc~/.vimrc
" 我的基本设置
" Syntax highlight
syntax enable

" Tabs are spaces
set expandtab
" Number of spaces per tab
set tabstop=4

" Search as soon as characters are entered
set incsearch
" Highlight search results
set hlsearch

set columns=80
set wrapmargin=8
set ruler

随机数生成

通过 blfs-bootscripts-20240416 软件包安装 /etc/rc.d/init.d/random 初始化脚本

安装 /etc/rc.d/init.d/random 初始化脚本
cd /sources

bootscripts_VERSION=20240416
tar xf blfs-bootscripts-${bootscripts_VERSION}.tar.xz
cd blfs-bootscripts-${bootscripts_VERSION}

make install-random

串口控制台

备注

这部分似乎在BLFS中没有涉及,但是我主要在服务器 HPE ProLiant DL380 Gen9服务器 上使用LFS,需要有一个串口控制台方便通过 IPMI工具ipmitool 管理

这部分设置主要参考 Debian ,也就是在 Debian虚拟机精简系统初始化 中设置的方法。在 debian 中,虽然配置采用了 /usr/sbin/getty ,但实际上 gettyagetty 的一个软链接,而 agetty 已经在 LFS(Linux from scratch) 部署中安装了,所以只需要配置即可

  • agetty 创建一个软链接 getty ( Debian 系统就是如此 ):

agetty 创建一个软链接 getty ,后续配置就可以继续使用 getty
cd /usr/sbin
ln -s agetty getty
  • 创建一个 /etc/init/ttyS0.conf :

/etc/init/ttyS0.conf 配置getty
# ttyS0 - getty
#
# This service maintains a getty on ttyS0 from the point the system is
# started until it is shut down again.

start on stopped rc RUNLEVEL=[12345]
stop on runlevel [!12345]

respawn
exec /sbin/getty -L 115200 ttyS0 vt102
内核参数添加 console=tty0 console=ttyS0,115200n8
# GRUB serial, but not effect. Why?
serial --unit=0 --speed=115200
terminal_input serial console
terminal_output serial console

menuentry "GNU/Linux, Linux 6.10.5-lfs-12.2" {
  search --set=root --fs-uuid 81368941-bd96-4539-bf8e-7215d532a872
  linux   /boot/vmlinuz-6.10.5-lfs-12.2 root=PARTUUID=cf8d6f20-92bf-4f81-982e-50bea63e6ca3 ro iommu=pt intel_iommu=on pcie_acs_override=downstream,multifunction console=tty0 console=ttyS0,115200n8
  initrd  /boot/microcode.img
}

警告

这里我搬运了 Ubuntu Linux 配置GRUB serail输出的配置部分(参考 archlinux: Working with the serial console ):

GRUB配置serial输入输出
# GRUB serial, but not effect. Why?
serial --unit=0 --speed=115200
terminal_input serial console
terminal_output serial console

menuentry "GNU/Linux, Linux 6.10.5-lfs-12.2" {
  search --set=root --fs-uuid 81368941-bd96-4539-bf8e-7215d532a872
  linux   /boot/vmlinuz-6.10.5-lfs-12.2 root=PARTUUID=cf8d6f20-92bf-4f81-982e-50bea63e6ca3 ro iommu=pt intel_iommu=on pcie_acs_override=downstream,multifunction console=tty0 console=ttyS0,115200n8
  initrd  /boot/microcode.img
}

上述参数是从 Ubuntu Linux/etc/default/grub 配置通过 update-grub 命令生成的, /etc/default/grub 在Ubuntu中配置如下:

Ubuntu /etc/default/grub 配置GRUB串口
GRUB_TERMINAL="serial console"
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200"

但是非常奇怪没有效果,待后续再排查

参考