3. After LFS Configuration Issues
LFS的目的是提供一个您可以在其上构建的基本系统。许多人在完成基本安装后,都想知道关于整理系统的一些事情。我们希望在本章中讨论这些问题。
大多数从非unix背景进入Linux的人都觉得纯文本配置文件的概念有点奇怪。在Linux中,几乎所有的配置都是通过对文本文件的操作完成的。这些文件中的大多数可以在/etc层次结构中找到。通常有图形化配置程序可用于不同的子系统,但大多数只是编辑文本文件过程的漂亮前端。纯文本配置的优点是,您可以使用自己喜欢的文本编辑器编辑参数,无论是vim、emacs还是其他任何编辑器。
第一个任务是在Creating a Custom Boot Device中创建恢复启动设备,因为这是最关键的需求。接下来将讨论与固件和其他设备相关的硬件问题。然后将系统配置为方便添加新用户,因为这会影响您在后面两个主题中所做的选择—The Bash Shell Startup Files和The vimrc Files。
还有一个主题:Customizing your Logon with /etc/issue。它与本章的其他主题没有太多的互动。
3.1 Creating a Custom Boot Device
体面的救援启动设备需求
这一部分实际上是关于创建一个救援设备。顾名思义,主机系统有问题,通常是分区信息丢失或文件系统损坏,导致主机无法正常启动和/或操作。由于这个原因,您不能依赖于被“拯救”的主机的资源。假设任何给定的分区或硬盘驱动器都是可用的是一个有风险的假设。
在现代系统中,有许多设备可以用作救援设备:软盘、cdrom、usb驱动器,甚至网卡。使用哪一个取决于您的硬件和BIOS。过去,救援设备被认为是软盘。今天,许多系统甚至没有软盘驱动器。
建造一个完整的救援设备是一项具有挑战性的任务。在许多方面,它相当于构建一个完整的LFS系统。此外,这将是对现有资料的重复。由于这些原因,这里不提供救援设备映像的程序。
创建救援软盘
当今系统的软件已经变得很大。Linux 2.6不再支持直接从软盘引导。尽管如此,还是有一些使用旧版本Linux的解决方案。其中最好的一个是Tom的Root/Boot Disk,可以在http://www.toms.net/rb/上找到。这将在单个软盘上提供一个最小的Linux系统,并在必要时提供自定义磁盘内容的能力。
创建可引导光盘
有几种资源可用于救援CD-ROM。几乎任何商业发行版的安装cd-rom或dvd都可以。包括RedHat、Ubuntu和SuSE。一个非常流行的选择是Knoppix。
此外,LFS社区已经开发了自己的LiveCD,可在[https://www.linuxfromscratch.org/livecd/上获得。这个LiveCD,不再能够构建一个完整的LFS/BLFS系统,但仍然是一个很好的救援CD-ROM。如果您下载ISO映像,请使用xorriso将映像复制到CD-ROM上。
使用GRUB2制作自定义救援CD-ROM的说明也可在LFS Chapter 10中获得。
创建可启动u盘
USB Pen驱动器,有时称为拇指驱动器,被Linux识别为SCSI设备。使用这些设备中的一个作为救援设备的优点是,它通常足够大,可以容纳超过一个最小的引导映像。您可以将关键数据保存到驱动器,以及使用它来诊断和恢复损坏的系统。引导这样的驱动器需要BIOS支持,但是构建系统包括格式化驱动器、添加GRUB以及Linux内核和支持文件。
用户笔记: https://wiki.linuxfromscratch.org/blfs/wiki/CreatingaCustomBootDevice
3.2 About Console Fonts
LFS系统可以在没有图形桌面的情况下使用,除非或直到您安装了a graphical environment,否则您将不得不在控制台中工作。大多数(如果不是全部的话)pc启动时都是8x16字体——不管实际屏幕大小如何。您可以做一些事情来改变控制台上的显示。其中大多数都涉及更改字体,但第一个更改的是grub使用的命令行。
用户笔记: https://wiki.linuxfromscratch.org/blfs/wiki/aboutconsolefonts
在grub中设置较小的屏幕大小
现代屏幕通常比过去使用的屏幕有更多的像素。如果你的屏幕是1600像素宽,一个8x16的字体会给你200列的文本——除非你的显示器是巨大的,否则文本会很小。解决这个问题的一种方法是告诉grub使用较小的大小,例如1024x768或800x600甚至640x480。即使你的屏幕没有4:3的宽高比,这也应该行得通。
要尝试这样做,您可以重新启动并编辑grub的命令行,在’root=/dev/sdXn’和’ro’之间插入一个’video=’参数,例如root=/dev/sda2 video=1024x768 ro,这是基于LFS第10.4.4节:10.4. Using GRUB to Set Up the Boot Process.
如果您决定这样做,那么您可以(作为root用户)编辑/boot/grub/grub.cfg。
使用标准的psf字体
在LFS中使用kbd包。它提供的字体是PC屏幕字体,通常称为PSF,它们被安装到/usr/share/consolefonts中。如果这些包含unicode映射表,则文件后缀通常更改为.psfu,尽管诸如terminal-font(见下文)之类的包不会添加’u’。这些字体通常用gzip压缩以节省空间,但这不是必需的。
最初的PC文本屏幕有8种颜色,如果使用原始8种颜色的明亮版本,则有16种颜色。PSF字体最多可以包含256个字符(技术上是字形),同时允许16种颜色,或最多512个字符(在这种情况下,明亮的颜色将不可用)。显然,这些控制台字体不能用于显示CJK文本——这将需要数千种可用的字形。
kbd中的一些字体可以覆盖超过512个码点(‘字符’),具有不同的保真度:unicode包含几个空格codepoints都可以映射到一个空间,破折号的品种可以映射到一个负号,聪明的引号可以映射到普通的ASCII引号而不是任何用于“codepoint不在场或无效”,和那些斯拉夫字母或希腊字母看起来像拉丁字母可以映射到它们,所以“a”也可以充当斯拉夫字母和希腊α,和“P”也可以充当斯拉夫字母和希腊ρ。不幸的是,当从BDF文件创建字体时(terminus和debian的console-setup中的方法),并不总是完成将附加代码点映射到现有字形的操作,尽管terminus ter-vXXn字体可以很好地完成此操作。
在kbd中有超过120种字体和大小的组合:通常一种字体有几种字符大小,有时品种涵盖了unicode的不同子集。大多数是8像素宽,高度从8到16像素,但也有一些是9像素宽,其他一些是12x22,甚至有一个(latarcyrheb-sun32.psfu)已经缩放到16x32。使用更大的字体是使大屏幕上的文本更容易阅读的另一种方法。
测试不同字体
您可以作为普通用户测试字体。如果你有一个尚未安装的字体,你可以用:
setfont /path/to/yourfont.ext
对于已经安装的字体,您只需要名称,所以使用gr737a-9x16.psfu.gz作为示例:
setfont gr737a-9x16
要查看字体中的字形,使用:
showconsolefont
如果字体看起来可能有用,那么您可以继续进行更彻底的测试。
当你找到一个你想使用的字体时,(作为root用户)编辑/etc/vconsole.conf,如LFS第9.6节所述9.6. Configuring the Linux Console..
对于kbd包中没有提供的字体,你需要选择用gzip压缩它/它们,然后以root用户安装它/它们。
使用psf工具编辑字体
虽然有些控制台字体是从BDF文件创建的,BDF文件是一种文本格式,字符的每一行像素都有十六进制值,但是有更现代的工具可用于编辑psf字体。psftools包允许您将字体转储为文本表示,其中一个破折号表示关闭(黑色)的像素,一个散列表示打开(白色)的像素。然后,您可以编辑文本文件以添加更多字符,或重塑它们,或将额外的代码点映射到它们上,然后使用您的更改创建新的psf字体。
使用Terminus-font字体
Terminus Font包提供固定宽度的位图字体,专为长时间(每天8小时以上)使用电脑工作而设计。在该页的“字符变体”下是补丁列表(在“alt/”目录中)。如果你使用图形浏览器来查看该页面,你可以看到补丁的作用,例如:’ll2’使’l’更明显地不同于’i’和’1’。
默认情况下,terminal-fonts将尝试创建几种类型的字体,如果没有安装来自Xorg Applications的bdftopcf,它将失败。只有当您继续将所有字体(控制台和X11位图)安装到正确的目录时,配置脚本才真正有用,就像在发行版中一样。要只构建PSF字体及其依赖项,请运行:
make psf
这将创建超过240个ter-*.psf字体。后缀“b”表示明亮,“n”表示正常。然后,您可以对它们进行测试,看看它们是否符合您的要求。除非您正在创建一个发行版,否则安装它们似乎没有什么意义。
作为一个例子,要安装这些字体中的最后一个,你可以gzip它,然后作为root用户:
install -v -m644 ter-v32n.psf.gz /usr/share/consolefonts
3.3 About Firmware
在一些最新的个人电脑上,加载固件以使其发挥最佳性能是必要的,或者是可取的。有一个目录,/lib/firmware,内核或内核驱动程序在其中查找固件映像。
目前,大多数固件可以在 git 仓库中找到:https://git.kernel.org/cgit/linux/kernel/git/firmware/linux-firmware.git/tree/。为了方便,LFS项目创建了一个镜像,每天更新,这些固件文件可以通过 wget 或web浏览器在https://anduin.linuxfromscratch.org/BLFS/linux-firmware/访问。
要获得固件,可以将浏览器指向上述存储库之一,然后下载所需的项目,或者安装git-2.39.2并克隆该存储库。
对于一些其他固件,特别是对于英特尔微码和某些wifi设备,所需的固件在上述存储库中不可用。其中一些问题将在下面讨论,但有时需要在互联网上搜索所需的固件。
固件文件通常被称为blob,因为您无法确定它们将做什么。请注意,固件是在各种不同的许可证下发布的,这些许可证不允许拆卸或逆向工程。
个人电脑固件分为四类:
-
对CPU进行更新以解决勘误表问题,通常称为微码。
-
视频控制器固件。在x86机器上,这是ATI设备(Radeon和AMDGPU芯片)所必需的,对于Intel (Skylake和更高版本)和Nvidia (Kepler和更高版本)gpu可能很有用。
ATI Radeon和AMDGPU设备都需要固件能够使用KMS(内核模式设置-首选选项)以及Xorg。对于旧的radeon芯片(在R600之前),固件仍然在内核源代码中。
从Skylake开始的英特尔集成GPU可以使用GuC(图形微控制器)固件,也可以用于HuC (HEVC/H265微控制器,卸载到GPU)和DMC(显示微控制器),以提供额外的低功耗状态。GuC和HuC在内核中有一个曲折的历史,更新的固件可能在默认情况下被禁用,这取决于内核版本。更多的细节可以在01.org和Arch linux上找到。
从开普勒开始的Nvidia gpu需要签名固件,否则新驱动程序无法提供硬件加速。Nvidia现在已经发布了高达安培的固件(GeForce30系列)到linux固件。请注意,发布的固件不支持比默认时钟更快的时钟。
-
有线网络端口的固件更新。大多数情况下,即使没有更新,它们也能工作,但可能它们会更好地与更新的固件一起工作。对于一些现代笔记本电脑,在使用有线网络之前,需要有线以太网(例如rtl_nic)和蓝牙设备(例如qca)的固件。
-
其他设备(如wifi)的固件。这些设备不是PC启动所必需的,但在使用这些设备之前需要固件。
注意
虽然不需要加载固件blob,但以下工具可能有助于确定、获取或准备所需的固件,以便将其加载到系统中: cpio-2.13, git-2.39.2, pciutils-3.9.0, 和 Wget-1.21.3
用户笔记: https://wiki.linuxfromscratch.org/blfs/wiki/aboutfirmware
CPU的微码更新
一般来说,微码可以通过BIOS或UEFI加载,并且可以通过升级到较新的版本来更新。在linux上,如果您使用的是AMD系列10h或更高版本的处理器(2007年底首次推出),或者使用1998年及以后版本的英特尔处理器(Pentium4、Core等),如果更新的微码已经发布,您也可以从内核加载微码。这些更新只会持续到机器关机,因此需要在每次启动时应用它们。
当新的漏洞暴露出来时,英特尔会为Skylake和后来的处理器提供他们的微码更新,并且在过去为SandyBridge以后的处理器提供了更新,尽管这些不再支持新的修复程序。新版本的AMD固件很少,通常只适用于少数型号,尽管主板制造商获得AGESA (AMD通用封装软件架构)更新来改变BIOS值,例如支持更多的内存变体,新的漏洞修复或更新的cpu。
加载微码有两种方式,分别是“early”和“late”。早加载发生在用户空间启动之前,晚加载发生在用户空间启动之后。但是,已知延迟加载是有问题的,并且不再支持(请参阅内核提交x86/microcode: Taint and warn on late loading)。事实上,早期的加载需要在早期启用TSX的Intel Haswell处理器中解决一个特定的勘误。(参见Intel Disables TSX Instructions: Erratum Found in Haswell, Haswell-E/EP, Broadwell-Y。)如果没有这个更新,glibc在不常见的情况下可能会出错。
在本书的早期版本中,建议稍后加载微代码以查看它是否被应用,然后使用initrd强制提前加载。但是现在Intel微码tarball的内容已经被文档化了,并且AMD微码可以被Python脚本读取以确定它所覆盖的机器,因此没有真正的理由使用延迟加载。
仍然可以手动强制延迟加载微代码。但它可能会导致内核故障,您应该自己承担风险。您需要为这两种方法重新配置内核。这里的说明将向您展示如何创建用于早期加载的initrd。也可以将相同的微码bin文件构建到内核中,这允许早期加载,但需要重新编译内核以更新微码。
要确认您有什么处理器(如果有多个,它们将是相同的),请查看/proc/cpuinfo。通过运行以下命令确定cpu系列,型号和步进的十进制值(它也会报告当前微码版本):
head -n7 /proc/cpuinfo
将cpu系列、型号和步进转换为十六进制数字对,并记住“微码”字段的值。您现在可以检查是否有任何可用的微码。
如果你正在创建一个initrd来更新不同机器的固件,就像发行版一样,进入“早期加载微码”并将所有英特尔blobs转移到GenuineIntel.bin或将所有AMD blobs转移到AuthenticAMD.bin。这将创建一个更大的initrd—对于20200609更新中的所有Intel机器,initrd的大小为3.0 MB,而一台机器的大小通常为24 KB。
Intel微码的CPU
第一步是获取最新版本的英特尔微码。这必须通过导航到https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/releases/并在那里下载最新的文件来完成。在撰写本文时,最安全的微码版本是microcode-20230214。以正常方式提取该文件,微码位于intel-ucode目录中,包含各种blob,其名称形式为XX-YY-ZZ。还有各种其他文件,以及一份发布说明。
在过去,英特尔没有提供任何关于哪些blobs更改了版本的细节,但现在发布说明详细说明了这一点。您可以将/proc/cpuinfo中的微码版本与发布说明中CPU型号的版本进行比较,以了解是否有更新。
为旧处理器提供的最新固件是为了处理现在已经公开的漏洞,对于其中的一些漏洞,例如微架构数据采样(MDS),您可能希望通过禁用超线程来增加保护,或者禁用内核的默认缓解,因为它对编译时间有影响。请在https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/index.html上阅读在线文档。
对于Icelake mobile(描述为Intel(R) Core(TM) i7-1065G7 CPU),相关值为CPU系列6,型号126,步骤5,因此在这种情况下所需的标识为06-7e-05。发布说明说,它的最新微码版本是0xb8。如果/proc/cpuinfo中“microcode”字段的值大于等于0xb8,则表示微码更新已经被BIOS应用。否则,配置内核以支持加载英特尔微码,然后进入the section called “Early loading of microcode”:
General Setup --->
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support [CONFIG_BLK_DEV_INITRD]
Processor type and features --->
[*] CPU microcode loading support [CONFIG_MICROCODE]
[*] Intel microcode loading support [CONFIG_MICROCODE_INTEL]
AMD微码的CPU
首先从https://anduin.linuxfromscratch.org/BLFS/linux-firmware/amd-ucode/为您的CPU家族下载一个固件容器。族总是以十六进制指定。家族10h到14h(16到20)在microcode_amd.bin中。家族15h, 16h, 17h (Zen, Zen+, Zen2)和19h (Zen3)有自己的容器,但很少有机器可能获得更新的微码。相反,AMD向主板制造商提供更新的AGESA,主板制造商可能会使用它提供更新的BIOS。有一个Python3脚本在https://github.com/AMDESE/amd_ucode_info/blob/master/amd_ucode_info.py。下载该脚本并针对bin文件运行它,以检查哪些处理器有更新。
对于非常老的Athlon(tm) II X2,在这些示例中,值是cpu家族16,模型5,步骤3,给出family =0x10 model =0x05 step =0x03的标识。amd_ucode_info.py脚本输出中有一行描述了它的微码版本:
Family=0x10 Model=0x05 Stepping=0x03: Patch=0x010000c8 Length=960 bytes
如果/proc/cpuinfo中“microcode”字段的值大于等于0x10000c8,则说明BIOS已经应用了微码更新。否则,配置内核以支持加载AMD微码,然后进入the section called “Early loading of microcode”:
General Setup --->
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support [CONFIG_BLK_DEV_INITRD]
Processor type and features --->
[*] CPU microcode loading support [CONFIG_MICROCODE]
[*] AMD microcode loading support [CONFIG_MICROCODE_AMD]
微码的早期加载
如果您已经确定更新后的微码可用于您的系统,那么是时候为早期加载做好准备了。这需要一个额外的包cpio-2.13,并创建一个initrd,它需要添加到grub.cfg中。
在哪里准备initrd并不重要,一旦它开始工作,您就可以将相同的initrd应用到同一台机器上的后续LFS系统或更新的内核上,至少在任何更新的微代码发布之前是这样。使用以下命令:
mkdir -p initrd/kernel/x86/microcode
cd initrd
对于AMD机器,使用以下命令(替换
cp -v ../<MYCONTAINER> kernel/x86/microcode/AuthenticAMD.bin
或者对于Intel机器,使用以下命令复制适当的blob:
cp -v ../intel-ucode/<XX-YY-ZZ> kernel/x86/microcode/GenuineIntel.bin
现在准备initrd:
find . | cpio -o -H newc > /boot/microcode.img
现在需要在/boot/grub/grub.cfg中添加一个新条目,并且应该在节中的linux行之后添加一个新行。如果/boot是一个单独的挂载点:
initrd /microcode.img
如果不是这样的话:
initrd /boot/microcode.img
如果你已经用initrd启动了(参见the section called “About initramfs”一节),你应该在把适当的blob或容器放入/lib/firmware之后再次运行mkinitramfs。更准确地说,在运行mkinitramfs之前,把一个intel blob放到/lib/firmware/intel-ucode目录中,或者把一个AMD容器放到/lib/firmware/amd-ucode目录中。或者,您可以将两个initrd放在同一行,例如 initrd /microcode.img /other-initrd.img (如果/boot不是一个单独的挂载点,请按照上面的方法进行调整)。
现在你可以用添加的initrd重新启动,然后使用以下命令检查早期加载是否工作:
dmesg | grep -e 'microcode' -e 'Linux version' -e 'Command line'
如果您进行了更新以解决漏洞,您可以查看lscpu命令的输出,以查看现在报告的内容。
在AMD和Intel机器中,早期加载发生的地点和时间是非常不同的。首先,以早期加载的Intel(Icelake mobile)为例:
[ 0.000000] microcode: microcode updated early to revision 0xb8, date = 2022-08-31
[ 0.000000] Linux version 6.1.11 (xry111@stargazer) (gcc (GCC) 12.2.0, GNU ld (GNU Binutils) 2.40) #2 SMP PREEMPT_DYNAMIC Tue Feb 14 23:23:31 CST 2023
[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-6.1.11-lfs-11.3-rc1 root=PARTUUID=<CLASSIFIED> ro
[ 0.452924] microcode: sig=0x706e5, pf=0x80, revision=0xb8
[ 0.453197] microcode: Microcode Update Driver: v2.2.
AMD历史上的一个例子:
[ 0.000000] Linux version 4.15.3 (ken@testserver) (gcc version 7.3.0 (GCC))
#2 SMP Sun Feb 18 02:32:03 GMT 2018
[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-4.15.3-sda5 root=/dev/sda5 ro
[ 0.307619] microcode: microcode updated early to new patch_level=0x010000c8
[ 0.307678] microcode: CPU0: patch_level=0x010000c8
[ 0.307723] microcode: CPU1: patch_level=0x010000c8
[ 0.307795] microcode: Microcode Update Driver: v2.2.
显卡固件
ATI视频芯片固件(R600及更高版本)
这些说明不适用于R600系列之前的旧氡。对于这些,固件在内核的/lib/firmware/目录中。如果您打算避免Xorg之类的图形化设置,并且满足于使用默认的80x25显示而不是framebuffer,那么它们也不适用。
早期的radeon设备只需要一个2K的固件。最近的设备需要几个不同的斑点,其中一些要大得多。radeon固件目录的总大小超过500K—在大型现代系统上,您可能会节省空间,但是每次构建系统时安装所有未使用的文件仍然是多余的。
更好的方法是安装pciutils-3.9.0,然后使用lspci来确定安装了哪个VGA控制器。
有了这些信息,检查Xorg wiki的RadeonFeature页面Decoder ring for engineering vs marketing names以确定家族(您可能需要知道BLFS中的Xorg驱动程序-Southern Islands 和 Sea Islands使用radeonsi驱动程序)和特定模型。
现在您知道了您正在使用的控制器,请查阅Gentoo wiki的Radeon页面,其中有一个表列出了各种芯片组所需的固件blob。请注意,与早期的内核相比,Southern Islands和Sea Islands芯片在内核3.17和后续版本中使用了不同的固件。识别并下载所需的blob,然后安装它们:
mkdir -pv /lib/firmware/radeon
cp -v <YOUR_BLOBS> /lib/firmware/radeon
实际上有两种安装固件的方法。BLFS,在Xorg ATI Driver-19.1.0一节的“额外固件的内核配置”部分给出了一个将固件编译到内核中的示例——加载速度略快,但使用更多的内核内存。这里我们将使用另一种方法,使radeon驱动程序成为一个模块。在内核配置中设置以下内容:
Device Drivers --->
Graphics support --->
Direct Rendering Manager --->
[*] Direct Rendering Manager (XFree86 ... support) [CONFIG_DRM]
[M] ATI Radeon [CONFIG_DRM_RADEON]
从/lib/firmware加载几个大blobs需要花费明显的时间,在此期间屏幕将是空白的。如果您不启用企鹅framebuffer徽标,或者通过使用更大的字体更改控制台大小,那么这可能无关紧要。如果需要,您可以按照上面链接的BLFS中所介绍的为CONFIG_DRM_RADEON指定’y’的替代方法略微减少时间—如果这样做,您必须指定每个所需的radeon blob。
固件AMD/ATI amdgpu视频芯片
所有使用amdgpu内核驱动程序的视频控制器都需要固件,无论您是使用xorg amdgpu驱动程序、xserver的模式设置驱动程序,还是仅仅使用内核模式设置来获得大于80x25的控制台帧缓冲区。
安装pciutils-3.9.0并使用它来检查型号名称(查找’VGA兼容控制器:’)。如果你有一个APU(加速处理单元,即CPU和视频在同一芯片上),它可能会告诉你这个名字。如果你有一个单独的amdgpu视频卡,你需要搜索以确定它使用的名称(例如,一张卡被描述为Advanced Micro Devices, Inc. [AMD/ATI] Baffin [Radeon RX 550 640SP / RX 560/560X]需要polararis 11固件)。在Gentoo wiki的AMDGPU页面的内核部分末尾有一个“家族,芯片组名称,产品名称和固件”表。
确定固件名称后,安装所有相关文件。例如,上面提到的Baffin卡有21个不同的polaris11*文件,APU如renoir和picasso至少有12个文件,并且可能在未来的更新中获得更多(例如raven APU现在有第13个文件,raven_ta.bin)。
mkdir -pv /lib/firmware/amdgpu
cp -v <YOUR_BLOBS> /lib/firmware/amdgpu
如果磁盘空间不是问题,您可以安装所有当前的amdgpu固件文件,而不必担心安装了哪个芯片组。
建议将内核amdgpu驱动程序构建为一个模块。在内核.config中设置至少以下选项,并根据目标硬件检查其他AMDGPU选项,例如“ACP(音频协处理器)配置”:
Device Drivers --->
Graphics support --->
Direct Rendering Manager --->
[*] Direct Rendering Manager (XFree86 ... support) [CONFIG_DRM]
[M] AMD GPU [CONFIG_DRM_AMDGPU]
Display Engine Configuration --->
[*] AMD DC - Enable new display engine (NEW) [CONFIG_DRM_AMD_DC]
如上所述,在“ATI视频芯片的固件”一节的末尾,从/lib/firmware加载大blobs可能需要一段明显的时间,在此期间屏幕将是空白的。在速度较慢的机器上,您可能希望参考Xorg AMDGPU Driver-23.0.0的“额外固件的内核配置”部分,并将所有必需的模块编译到内核中以减少此时间,代价是使用更多的内核内存。
Nvidia视频芯片固件
英伟达已经为最近的图形芯片发布了基本的签名固件,但这是在芯片和它自己的二进制驱动程序首次可用之后才发布的。对于其他芯片,必须从二进制驱动程序中提取固件。
有关哪些芯片需要提取固件的详细信息,请参见 https://nouveau.freedesktop.org/wiki/VideoAcceleration/#firmware.
首先,内核Nvidia驱动必须被激活:
Device Drivers --->
Graphics support --->
Direct Rendering Manager --->
<*> Direct Rendering Manager (XFree86 ... support) [CONFIG_DRM]
<*/M> Nouveau (NVIDIA) cards [CONFIG_DRM_NOUVEAU]
如果linux-firmware的nvidia/目录中有必要的固件,将其复制到/lib/firmware/nouveau。
如果linux-firmware中没有提供固件,对于上面nouveau wiki链接中提到的旧芯片,请确保您已安装Python-2.7.18并运行以下命令:
wget https://raw.github.com/imirkin/re-vp2/master/extract_firmware.py
wget https://us.download.nvidia.com/XFree86/Linux-x86/325.15/NVIDIA-Linux-x86-325.15.run
sh NVIDIA-Linux-x86-325.15.run --extract-only
python2 extract_firmware.py
mkdir -p /lib/firmware/nouveau
cp -d nv* vuc-* /lib/firmware/nouveau/
网络接口固件
内核喜欢为某些网络驱动程序加载固件,特别是那些来自Realtek (/lib/linux-firmware/rtl_nic/)目录的固件,但它们通常看起来没有固件也能工作。因此,您可以引导内核,检查dmesg中关于这个丢失的固件的消息,如果有必要,下载固件并将其放在/lib/firmware中的指定目录中,以便在后续引导时找到它。请注意,对于当前的内核,无论驱动程序是否被编译或作为模块构建,都可以工作,不需要将该固件构建到内核中。这里是一个示例,其中R8169驱动程序已编译,但固件不可用。一旦提供了固件,就不会在以后的引导中提到它。
dmesg | grep firmware | grep r8169
[ 7.018028] r8169 0000:01:00.0: Direct firmware load for rtl_nic/rtl8168g-2.fw failed with error -2
[ 7.018036] r8169 0000:01:00.0 eth0: unable to load firmware patch rtl_nic/rtl8168g-2.fw (-2)
其他设备固件
识别正确的固件通常需要您安装pciutils-3.9.0,然后使用 lspci 来识别设备。然后,您应该在线搜索,检查它使用的是哪个模块、哪个固件,以及从哪里获得固件——并不是所有的固件都在linux-firmware中。
如果可能的话,应该在第一次引导LFS系统时使用有线连接。要使用无线连接,您需要使用网络工具,如Wireless Tools-29和wpa_supplicant-2.10。
不同的国家对无线设备的无线电频谱使用有不同的规定。您可以安装固件使无线设备遵守当地的频谱规则,这样您就不会被当地当局询问或发现您的无线网卡干扰其他设备(例如,远程控制器)的频率。监管数据库固件可以从https://kernel.org/pub/software/network/wireless-regdb/下载。要安装它,只需提取regulatory.db和regulatory.db.p7s从tarball到/lib/firmware。接入点将发送一个国家代码到你的无线网卡,wpa_supplicant-2.10将告诉内核从regulatory.db加载这个国家的法规,并执行它。
其他设备(如SCSI控制器、蓝牙适配器或电视录像机)也可能需要固件。同样的原则也适用。
3.4 About Devices
尽管在BLFS中包所需的大多数设备都是由udev使用LFS在/etc/udev/rules.d中安装的默认规则正确设置的,但在某些情况下,必须修改或增加规则。
用户笔记: https://wiki.linuxfromscratch.org/blfs/wiki/aboutdevices
多声卡
如果系统中有多个声卡,则“默认”声卡变为随机的。建立声卡顺序的方法取决于驱动程序是否是模块。如果将声卡驱动程序编译到内核中,则通过内核命令行参数/boot/grub/grub.cfg进行控制。例如,如果系统同时具有FM801卡和SoundBlaster PCI卡,则可以在命令行中添加以下内容:
snd-fm801.index=0 snd-ens1371.index=1
如果声卡驱动被构建为模块,命令可以在/etc/modprobe.conf文件中建立:
options snd-fm801 index=0
options snd-ens1371 index=1
USB设备问题
USB设备通常有两种与之相关联的设备节点。
第一种是由内核中特定于设备的驱动程序(例如,usb_storage/sd_mod或usblp)创建的。例如,USB大容量存储设备将是/dev/sdb, USB打印机将是/dev/usb/lp0。这些设备节点仅在加载特定于设备的驱动程序时存在。
即使设备没有内核驱动程序,也会创建第二种设备节点(/dev/bus/usb/BBB/DDD,其中BBB是总线号,DDD是设备号)。通过使用这些“原始”USB设备节点,应用程序可以与设备交换任意USB数据包,也就是说,绕过可能存在的内核驱动程序。
当用户空间程序充当设备驱动程序时,需要访问原始USB设备节点。但是,要使程序成功打开设备,必须正确设置权限。默认情况下,出于安全考虑,所有原始USB设备都由root用户和USB组拥有,并且具有0664权限(需要读取访问权限,例如,lsusb要工作,程序要访问USB集线器)。包含用户空间USB设备驱动程序的包(如SANE和libgphoto2)还附带了udev规则,这些规则可以更改受控制的原始USB设备的权限。也就是说,由SANE安装的规则会更改已知扫描仪的权限,但不会更改打印机的权限。如果包维护者忘记为您的设备编写规则,请向BLFS(如果包存在)和上游报告错误,您将需要编写自己的规则。
有一种情况是,这种带有预先生成的udev规则的细粒度访问控制不起作用。也就是说,像KVM、QEMU和VirtualBox这样的PC模拟器使用原始USB设备节点向客户机操作系统提供任意USB设备(注意:需要补丁才能使其在没有下面描述的过时的/proc/bus/usb挂载点的情况下工作)。显然,这些包的维护者无法知道哪些USB设备将连接到客户机操作系统。您可以自己为所有需要的USB设备编写单独的udev规则,或者使用默认的“USB”组,其中的成员可以向所有USB设备发送任意命令。
在Linux-2.6.15之前,原始USB设备访问不是使用/dev/bus/usb/BBB/DDD设备节点,而是使用/proc/bus/usb/BBB/DDD伪文件。一些应用程序(例如,VMware工作站)仍然只使用这种过时的技术,不能使用新的设备节点。要使其工作,请使用“usb”组,但请记住,成员将不受限制地访问所有usb设备。为过时的usbfs文件系统创建fstab条目:
usbfs /proc/bus/usb usbfs devgid=14,devmode=0660 0 0
注意
将用户添加到“usb”组本质上是不安全的,因为他们可以绕过通过驱动程序特定的usb设备节点施加的访问限制。例如,它们可以在不属于“磁盘”组的情况下从USB硬盘驱动器读取敏感数据。尽量避免将用户添加到此组。
Udev设备属性
通过创建额外的udev规则,可以对设备属性(如组名和权限)进行微调。厂商和产品可以通过搜索/sys/devices目录条目或在设备连接后使用udevadm info来找到。详细信息请参见当前udev目录/usr/share/doc中的文档。
SUBSYSTEM=="usb_device", SYSFS{idVendor}=="05d8", SYSFS{idProduct}=="4002", \
GROUP:="scanner", MODE:="0660"
注意
以上一行仅用于描述目的。扫描器udev规则是在安装SANE-1.0.32时设置的。
用于DVD驱动器的设备
如果初始引导过程没有正确设置/dev/dvd设备,可以使用以下修改默认udev规则来安装它。作为root用户,运行:
sed '1d;/SYMLINK.*cdrom/ a\
KERNEL=="sr0", ENV{ID_CDROM_DVD}=="1", SYMLINK+="dvd", OPTIONS+="link_priority=-100"' \
/lib/udev/rules.d/60-cdrom_id.rules > /etc/udev/rules.d/60-cdrom_id.rules
3.5 Configuring for Adding Users
/usr/sbin/useradd命令和/etc/skel目录(两者都易于设置和使用)一起提供了一种方法,以确保将新用户添加到LFS系统时具有相同的初始设置,例如PATH,键盘处理和其他环境变量。使用这两个工具可以更容易地确保添加到系统中的每个新用户的初始状态。
当/usr/sbin/useradd程序添加新用户时,/etc/skel目录保存了各种初始化文件和其他文件的副本,这些文件可能被复制到新用户的主目录中。
Useradd
useradd程序使用保存在/etc/default/useradd中的默认值集合。这个文件是由Shadow包在基本LFS安装中创建的。如果它已被删除或重命名,则useradd程序使用一些内部默认值。执行/usr/sbin/useradd -D命令可查看默认值。
要更改这些值,只需以root用户修改/etc/default/useradd文件。直接修改文件的另一种方法是作为root用户运行useradd,同时在命令行上提供所需的修改。关于如何做到这一点的信息可以在useradd手册页中找到。
/etc/skel
首先,创建一个/etc/skel目录,并确保它只能由系统管理员(通常是root)写。将目录创建为root是最好的方法。
你放入/etc/skel中的这部分文件的模式应该只有所有者可以写。另外,由于不知道用户最终会在这些文件的副本中放置什么样的敏感信息,因此应该通过“group”和“other”使它们不可读。
你也可以把其他文件放在/etc/skel中,它们可能需要不同的权限。
决定在每个(或大多数)新用户的主目录中应该提供哪些初始化文件。您所做的决定将影响您在接下来的两个部分中所做的事情,The Bash Shell Startup Files和The vimrc Files。这些文件中的一些或全部对于root、任何已经存在的用户和新用户都很有用。
您可能想要放在/etc/skel中的这些节中的文件包括 .inputrc, .bash_profile, .bashrc, .bash_logout, .dircolors, 和 .vimrc. 如果您不确定应该放在哪里,请继续阅读以下部分,阅读每个部分和提供的任何参考资料,然后做出决定。
您将运行一组稍微修改过的命令,用于放置在/etc/skel中的文件。每一节都会提醒你这一点。简而言之,这本书的命令是为没有添加到/etc/skel的文件编写的,而是将结果发送到用户的主目录。如果文件将在/etc/skel中,更改图书的命令,将输出发送到那里,然后将文件从/etc/skel复制到适当的目录,如/etc, ~或系统中任何其他用户的主目录。
添加用户时
当用useradd添加一个新用户时,使用-m参数,它告诉useradd创建用户的主目录,并从/etc/skel(可以覆盖)复制文件到新用户的主目录。例如(以root用户执行):
useradd -m <newuser>
如果您正在与另一个Linux发行版(例如,用于构建LFS的主机发行版)共享/home或/usr/src,那么您可以创建一个具有相同UID(以及相同的主组GID)的用户,以保持跨系统的文件所有权一致。首先,在另一个发行版上,获取用户的UID和用户主组的GID:
getent passwd <username> | cut -d ':' -f 3,4
该命令应该输出UID和GID,用冒号分隔。现在在BLFS系统中,创建主组和用户:
groupadd -g <GID> <username> &&
useradd -u <UID> -g <username> <username>
3.6 About System Users and Groups
在整个BLFS中,许多包安装的程序作为守护进程运行,或者以某种方式应该分配一个用户名或组名。通常,这些名称用于映射供系统使用的用户ID (uid)或组ID (gid)。通常,这些应用程序使用的特定uid或gid编号并不重要。当然,例外情况是,root的uid和gid为0(零),这确实很特殊。uid值存储在/etc/passwd中,gid值存储在/etc/group中。
Unix系统通常将用户和组分为两类:系统用户和普通用户。系统用户和组的数值较低,普通用户和组的数值大于所有系统值。这些数字的截止值可以在/etc/login.defs配置文件中的两个参数中找到。UID_MIN默认值为1000,GID_MIN默认值为1000。如果在使用useradd创建用户或使用groupadd创建组时没有指定特定的uid或gid值,则分配的值将始终高于这些截止值。
此外,Linux Standard Base建议系统uid和gid值应低于100。
下面是除了基本LFS安装中定义的uid/gid值之外,在BLFS中使用的建议uid/gid值的表。这些可以根据需要进行更改,但提供一组建议的一致值。
Table 3.1. UID/GID Suggested Values
| Name | uid | gid |
|---|---|---|
| bin | 1 | |
| lp | 9 | |
| adm | 16 | |
| atd | 17 | 17 |
| messagebus | 18 | 18 |
| lpadmin | 19 | |
| named | 20 | 20 |
| gdm | 21 | 21 |
| fcron | 22 | 22 |
| systemd-journal | 23 | 23 |
| apache | 25 | 25 |
| smmsp | 26 | 26 |
| polkitd | 27 | 27 |
| rpc | 28 | 28 |
| exim | 31 | 31 |
| postfix | 32 | 32 |
| postdrop | 33 | |
| sendmail | 34 | |
| 34 | ||
| vmailman | 35 | 35 |
| news | 36 | 36 |
| kdm | 37 | 37 |
| fetchmail | 38 | |
| mysql | 40 | 40 |
| postgres | 41 | 41 |
| dovecot | 42 | 42 |
| dovenull | 43 | 43 |
| ftp | 45 | 45 |
| proftpd | 46 | 46 |
| vsftpd | 47 | 47 |
| rsyncd | 48 | 48 |
| sshd | 50 | 50 |
| stunnel | 51 | 51 |
| dhcpcd | 52 | 52 |
| svn | 56 | 56 |
| svntest | 57 | |
| git | 58 | 58 |
| games | 60 | 60 |
| kvm | 61 | |
| wireshark | 62 | |
| lightdm | 63 | 63 |
| sddm | 64 | 64 |
| lightdm | 65 | 65 |
| scanner | 70 | |
| colord | 71 | 71 |
| systemd-journal-gateway | 73 | 73 |
| systemd-journal-remote | 74 | 74 |
| systemd-journal-upload | 75 | 75 |
| systemd-network | 76 | 76 |
| systemd-resolve | 77 | 77 |
| systemd-timesync | 78 | 78 |
| systemd-coredump | 79 | 79 |
| uuidd | 80 | 80 |
| systemd-oom | 81 | 81 |
| ldap | 83 | 83 |
| avahi | 84 | 84 |
| avahi-autoipd | 85 | 85 |
| netdev | 86 | |
| ntp | 87 | 87 |
| unbound | 88 | 88 |
| plugdev | 90 | |
| wheel | 97 | |
| anonymous | 98 | |
| nobody | 65534 | |
| nogroup | 65534 |
3.7 The Bash Shell Startup Files
shell程序/bin/bash(以下简称“shell”)使用一组启动文件来帮助创建环境。每个文件都有特定的用途,并且可能以不同的方式影响登录和交互环境。/etc目录下的文件通常提供全局设置。如果在主目录中存在等效文件,它可能会覆盖全局设置。
一个交互式登录shell在成功登录后启动,使用/bin/login,通过读取/etc/passwd文件。这个shell调用通常读取/etc/profile和它的私有等价物~/.bash_profile(或~/.profile在启动时被称为/bin/sh)。
交互式非登录shell通常在命令行使用shell程序(例如,[prompt]$/bin/bash)或通过/bin/su命令启动。交互式非登录shell也可以从图形化环境中使用终端程序(如xterm或konsole)启动。这种类型的shell调用通常会复制父环境,然后读取用户的~/.bashrc文件以获取额外的启动配置说明。
当shell脚本运行时,通常会出现一个非交互式shell。它是非交互式的,因为它正在处理脚本,而不是在命令之间等待用户输入。对于这些shell调用,只使用从父shell继承的环境。
文件~/.bash_logout不用于shell的调用。它在用户从交互式登录shell退出时被读取并执行。
许多发行版使用/etc/bashrc来初始化非登录shell的系统范围。该文件通常从用户的~/.bashrc文件中调用,而不是直接构建到bash本身。本节将遵循这一约定。
有关更多信息,请参见 info bash – Nodes: Bash Startup Files and Interactive Shells.
注意
下面的大多数指令用于创建位于/etc目录结构中的文件,这需要您以root用户执行命令。如果选择在用户的主目录中创建文件,则应该以非特权用户的身份运行这些命令。
用户笔记: https://wiki.linuxfromscratch.org/blfs/wiki/bash-shell-startup-files
/etc/profile
这是一个基本的/etc/profile。该文件首先设置一些辅助函数和一些基本参数。它指定了一些bash历史参数,出于安全考虑,禁用为root用户保留永久的历史文件。它还设置了一个默认的用户提示符。然后它调用/etc/profile.d目录下的小的、单一用途的脚本来提供大部分初始化。
有关可用于提示符(即PS1环境变量)的转义序列的更多信息,请参见 info bash – Node: Printing a Prompt.
cat > /etc/profile << "EOF"
# Begin /etc/profile
# Written for Beyond Linux From Scratch
# by James Robertson <jameswrobertson@earthlink.net>
# modifications by Dagmar d'Surreal <rivyqntzne@pbzpnfg.arg>
# 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完成脚本(由许多其他BLFS包安装),以允许TAB命令行完成。
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
确保该目录存在:
install --directory --mode=0755 --owner=root --group=root /etc/bash_completion.d
有关更完整的安装,请参见 https://wiki.linuxfromscratch.org/blfs/wiki/bash-shell-startup-files#bash-completions.
/etc/profile.d/dircolors.sh
这个脚本使用~/.dircolors和/etc/dircolors文件来控制目录列表中文件名的颜色。它们控制像ls –color之类的东西的彩色输出。关于如何初始化这些文件的说明在本节的末尾。
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等),这些变量可能是所有用户都需要的。
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/man MANPATH
pathappend /usr/share/info INFOPATH
EOF
/etc/profile.d/readline.sh
这个脚本设置默认的inputrc配置文件。如果用户没有单独的设置,则使用全局文件。
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值对于安全性很重要。在这里,当用户名和组名不相同时,系统用户的默认组写权限被关闭。
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
该脚本设置了本地语言支持所需的环境变量。关于确定这个变量的完整讨论可以在LFS Bash Shell Startup Files页面上找到。
cat > /etc/profile.d/i18n.sh << "EOF"
# Set up i18n variables
. /etc/locale.conf
export LANG
EOF
其他初始化值
其他初始化可以很容易地添加到profile通过添加额外的脚本到/etc/profile.d目录。
/etc/bashrc
这里是一个基础/etc/bashrc。文件中的注释应该解释您所需要的一切。
cat > /etc/bashrc << "EOF"
# Begin /etc/bashrc
# Written for Beyond Linux From Scratch
# by James Robertson <jameswrobertson@earthlink.net>
# updated by Bruce Dubbs <bdubbs@linuxfromscratch.org>
# 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
~/.bash_profile
这是一个基本的~/.bash_profile。如果您希望每个新用户都自动拥有此文件,只需将命令的输出更改为/etc/skel/.bash_profile,并在命令运行后检查权限。然后,您可以将/etc/skel/.bash_profile复制到现有用户的主目录中,包括root,并设置适当的所有者和组。
cat > ~/.bash_profile << "EOF"
# Begin ~/.bash_profile
# Written for Beyond Linux From Scratch
# by James Robertson <jameswrobertson@earthlink.net>
# updated by Bruce Dubbs <bdubbs@linuxfromscratch.org>
# 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
~/.profile
这是一个基本的~/.profile。上面关于为.bash_profile使用/etc/skel的注释和说明也适用于此。只有目标文件名不同。
cat > ~/.profile << "EOF"
# Begin ~/.profile
# Personal environment variables and startup programs.
if [ -d "$HOME/bin" ] ; then
pathprepend $HOME/bin
fi
# Set up user specific i18n variables
#export LANG=<ll>_<CC>.<charmap><@modifiers>
# End ~/.profile
EOF
~/.bashrc
这是一个基础 ~/.bashrc.
cat > ~/.bashrc << "EOF"
# Begin ~/.bashrc
# Written for Beyond Linux From Scratch
# by James Robertson <jameswrobertson@earthlink.net>
# 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文件中处理的。
cat > ~/.bash_logout << "EOF"
# Begin ~/.bash_logout
# Written for Beyond Linux From Scratch
# by James Robertson <jameswrobertson@earthlink.net>
# Personal items to perform on logout.
# End ~/.bash_logout
EOF
/etc/dircolors
如果您想使用dircolors功能,那么运行以下命令。上面所示的/etc/skel设置步骤也可以用于在设置新用户时提供一个~/.dircolors文件。与前面一样,只需在以下命令中更改输出文件名,并确保所创建和/或复制的文件的权限、所有者和组是正确的。
dircolors -p > /etc/dircolors
如果你想为不同的文件类型定制颜色,你可以编辑/etc/dircolors文件。设置颜色的说明嵌入在文件中。
最后,Ian Macdonald编写了一个很棒的提示和技巧集来增强shell环境。您可以在https://www.caliban.org/bash/index.shtml在线阅读。
3.8 The /etc/vimrc and ~/.vimrc Files
LFS书安装Vim作为它的文本编辑器。在这一点上,应该注意到有很多不同的编辑应用程序,包括Emacs, nano, Joe等等。任何在互联网(尤其是usenet)上呆过一段时间的人肯定会看到至少一场火焰大战,通常涉及Vim和Emacs用户!
LFS手册创建了一个基本的vimrc文件。在本节中,您将看到对该文件进行增强的尝试。在启动时,vim读取全局配置文件(/etc/vimrc)以及用户特定的文件(~/.vimrc)。可以对其中一个或两个进行定制,以适应您的特定系统的需要。
这是一个稍微扩展的.vimrc,你可以把它放在~/.vimrc中,以提供用户特定的效果。当然,如果你把它放到/etc/skel/.vimrc中,它将会被你添加到系统中的用户使用。您也可以将文件从/etc/skel/.vimrc复制到系统上已有用户的主目录,例如root。如果要直接从/etc/skel复制任何内容,请确保设置权限、所有者和组。
" Begin .vimrc
set columns=80
set wrapmargin=8
set ruler
" End .vimrc
注意,注释标签是’‘,而不是更常见的#或//。这是正确的,vimrc的语法有点不寻常。
下面你会发现这个示例文件中每个选项的含义的快速解释:
-
set columns=80: 这只是设置屏幕上使用的列数。 -
set wrapmargin=8: 这是从开始换行的右窗口边框开始的字符数。 -
set ruler: 这使得vim显示当前行和列在屏幕的右下角。
关于许多vim选项的更多信息可以通过阅读vim本身的帮助来找到。通过在vim中输入:help来获取一般帮助,或者通过输入:help usr_toc.txt来查看用户手册目录。
3.9 Customizing your Logon with /etc/issue
当您第一次启动新的LFS系统时,登录屏幕将是漂亮而简单的(就像在一个基本系统中一样)。然而,许多人希望他们的系统在登录消息中显示一些信息。这可以使用文件/etc/issue来完成。
/etc/issue文件是一个纯文本文件,它也接受某些转义序列(见下文),以便插入有关系统的信息。还有一个文件issue.net,可以在远程登录时使用。但是,ssh只会在您在配置文件中设置该选项时使用它,并且不会解释如下所示的转义序列。
人们想要做的最常见的事情之一就是在每次登录时清除屏幕。最简单的方法是在/etc/issue中放入一个“clear”转义序列一种简单的方法是发出clear > /etc/issue.这将在/etc/issue文件的开头插入相关的转义代码。注意,如果这样做,在编辑文件时,应该只在第一行留下字符(通常是’^[[H^[[2J’)。
注意
终端转义序列是终端识别的特殊代码。^[ 表示ASCII ESC字符。ESC [ H将光标置于屏幕的左上角,ESC 2 J将屏幕删除。有关终端转义序列的更多信息,请参见 http://rtfm.etla.org/xterm/ctlseq.html
以下序列由agetty(通常解析/etc/issue的程序)识别。此信息来自man agetty,您可以在其中找到有关登录过程的额外信息。
issue文件可以包含某些字符序列来显示各种信息。所有issue序列都由一个反斜杠()紧跟着下面解释的一个字母组成(因此/etc/issue中的\d将插入当前日期)。
b Insert the baudrate of the current line.
d Insert the current date.
s Insert the system name, the name of the operating system.
l Insert the name of the current tty line.
m Insert the architecture identifier of the machine, e.g., i686.
n Insert the nodename of the machine, also known as the hostname.
o Insert the domainname of the machine.
r Insert the release number of the kernel, e.g., 2.6.11.12.
t Insert the current time.
u Insert the number of current users logged in.
U Insert the string "1 user" or "<n> users" where <n> is the
number of current users logged in.
v Insert the version of the OS, e.g., the build-date etc.