LFS之后的配置
LFS(Linux from scratch) 提供了一个基础系统,不过实际使用时,需要在完成LFS安装部署后,继续做一些补充配置
Firmware
Linux系统要能够在真实硬件上良好运行,需要安装不同厂商提供的硬件firmware:
CPU微码(microcode): 用于修复CPU漏洞
GPU firmware: 典型的是三家GPU厂商 - AMD, Intel, Nvidia
有线网卡firmware: 通常能够修复问题提升性能
其他设备firmware: 例如无线网卡需要特定firmware驱动才能工作
CPU microcode
检查CPU信息:
head -n7 /proc/cpuinfo
检查当前微码(还没有更新之前):
[ 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
中有说明可检查
Processor |
Stepping |
F-M-S/PI |
Old Ver |
New Ver |
Products |
---|---|---|---|---|---|
HSX-E/EP |
Cx/M1 |
|
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
配置 ,直接执行 initramfs 中 mkinitramfs
会自动添加cpu microcode。
在
/boot/grub/grub.cfg
中添加initrd
配置:
# 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
可以看到最高版本)
[ 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
,但实际上 getty
是 agetty
的一个软链接,而 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
修订
/boot/grub/grub.cfg
添加内核参数console=tty0 console=ttyS0,115200n8
(这里的案例在 在QEMU中运行GPU passthrough的Debian 基础上完成,所以内核参数还有一部分是 IOMMU 配置 ):
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, 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中配置如下:
/etc/default/grub
配置GRUB串口GRUB_TERMINAL="serial console"
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200"
但是非常奇怪没有效果,待后续再排查