前言

这不是一份简短的Gentoo Linux安装手册,我想在这篇文章中向你展示更多Gentoo Linux的魅力。

为什么选择Gentoo?

Gentoo 是一个基于源码的滚动发行版。 Gentoo的基础包和软件都是由源码来构建的并且有Portage的USE标记来开启或者是关闭软件的特性。Gentoo提供了一个类似于ports的系统(Portage)所以Gentoo更适合于系统的定制化。

如果你有使用其他的Linux经验也可能会问为什么不用Archlinux,也是滚动发行版包管理器也比portage快。

你是对的,Portage的包管理工具比Arch或者是其他发行版的包管理更加复杂和强大,但是这是由于设计哲学上的问题:

Gentoo的目标是努力创建近乎理想的工具,可以满足许多不同目标用户的工具。

Arch的哲学就是: Keep It Simple, Stupid. 在简单的安装了一台虚拟机之后也确实感觉到了这一点。

但是我还是更喜欢Gentoo的设计一点,有一种整个系统尽在掌握的感觉。

less is more, but more is also less.

缘起

我是一个非常贫苦刚刚步入社会的学生。

今年毕业之后因为疫情的影响好不容易进了一家公司,但是日常的开销不足以让我更换掉现在的机器(只有单个核心的年迈机器。)。

前些日子在和一位帅气的学长 温柔的学姐在茶会上聊起了工作的一些事情可能是听到了我的抱怨了吧哈哈哈,当时说要送我一台笔记本,当时还在想不会吧?这两天收到了发现是一台Macbook Pro 2015年的15寸版本,还有一个yubico。

配置大概是这样子的

型号CPU内存硬盘
Macbook Pro 2015 15inchI7 4770HQ16G2TB

在此之前一直都有想要试试看Gentoo的想法,但是奈何手上的笔记本只有可怜的单核2G内存,因为日常还需要使用的缘故结果自然也是不了了之。

这次就有机会尝试一下了,并且将其作为主力系统进行使用。

这次安装Gentoo打算使用这样的组合:

类别包或包组说明
基础系统@system基础系统
X WindowsXorg Server使用Xorg作为X Windows的后端服务
桌面kde本次安装将会使用KDE桌面
输入法fcitx-rime使用fcitx作为输入法框架,使用rime输入法作为日常使用
浏览器chromium + firefox多来几个浏览器方便debug
邮箱客户端thunderbird雷鸟邮件客户端
密码管理器keepassxc + pass一个为gui的一个为命令行的密码管理器
截图软件flameshot很棒的截图软件

环境准备

先来说明一下安装Gentoo的环境准备。

我这里是准备了以下:

  1. Macbook Pro * 1 (安装机器)
  2. Dell 老机器 * 1 (我将会在这个节点进行操作)
  3. U盘 * 1 (安装介质)
  4. USB千兆网卡 (因为发现在Gentoo下面无线有问题,信道支持有限,在Ubuntu Livecd下工作正常,正在尝试解决这个问题。) 拓扑图如下:

Network_Arch

制作安装介质

之前一直有听说Gentoo安装比较麻烦,看了一些关于Gentoo安装的文档,我认为难点在于内核的配置上,其他应该问题不大(😂)。

为了能够最大程度少去配置内核我这里选择了Ubuntu Desktop Livecd,将会以这个内核配置为基础进行自己的内核配置

下载ISO文件

1
wget -c https://mirrors.aliyun.com/ubuntu-releases/20.10/ubuntu-20.10-desktop-amd64.iso

制作USB启动盘

将U盘插入这台老的Dell机器然后使用dd刻录安装介质

1
sudo dd if=ubuntu-20.10-desktop-amd64.iso of=/dev/sdb bs=20M status=progress

耐心等待程序执行完成。

等到执行完成之后你就有了一个Ubuntu 20.10 Desktop的安装介质

启动安装介质

将制作好的启动介质插到Macbook Pro上然后按住Option键再按开机,会出现一个EFI的选项,这个EFI选项就是我们的Ubuntu安装介质选择这个然后回车启动!

接下来会出现一个Grub菜单,选择 safe graphical 这个选项回车。

Grub Menu

接下来会检测磁盘分区如果不喜欢可以选择 Ctrl+c 结束掉。 Check Disk

最后来到Ubuntu的欢迎界面,这里选择 Try Ubuntu Welcome Come Ubuntu

配置SSH

首先右键桌面打开终端:

Open Terminal

输入 sudo -i 提升为root用户

sudo

配置密码

为了能够正常连接到这个livdcd环境还需要给这个livecd配置一个密码

1
passwd ubuntu # 输入密码没有回显,不是你没有输入

Change Password

配置openssh-server

除此之外还需要配置openssh-server来让我的另外一台电脑可以通过ssh进行链接

1
apt-get update && apt-get install openssh-server -y && systemctl start sshd && systemctl status sshd

Setup Openssh Server 如上图所示可以看到openssh-server已经运行了,接下来我们需要验证一下是否可以正常链接。

使用ip命令查看当前主机分配到的ip

1
ip addr show

Show IP

这里的enp1s0就是物理网卡192.168.122.230就是我们livecd获取到的地址我们可以通过这个ip来进行链接。

连接到livecd

使用ssh命令来连接到livecd

1
ssh ubuntu@192.168.122.230

ubuntu用户就是我们设置过密码的管理员账户

192.168.122.230就是livecd通过DHCP获取到的地址

Connect to livecd

安装Gentoo

在能够正常连接到livecd之后我们就可以开始安装Gentoo了

分区

使用fdisk 查看当前分区

1
fdisk -l

Check Partition

这里的/dev/nvme0n1就是Mac的硬盘,我的Gentoo系统也会安装到这里。

这次分区我打算使用LUKS做一个全盘加密,分区就比较简单:

文件系统类型挂载点大小
/dev/nvme0n1p1fat32/boot64M
/dev/nvme0n1p2luksnilall
/dev/mapper/rootext4/all

使用fdisk来进行分区

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
fdisk /dev/nvme0n1
Welcome to fdisk (util-linux 2.36).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): n # 创建新的分区
Partition number (1-128, default 1):
First sector (34-4000797326, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-4000797326, default 4000797326): +64M # 大小为64M的分区

Created a new partition 1 of type 'Linux filesystem' and of size 64 MiB.
Partition #1 contains a vfat signature.

Do you want to remove the signature? [Y]es/[N]o: Y

The signature will be removed by a write command.
Command (m for help): n # 创建另外一个分区
Partition number (2-128, default 2):
First sector (133120-4000797326, default 133120):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (133120-4000797326, default 4000797326): # 不输入默认所有
Created a new partition 2 of type 'Linux filesystem' and of size 1.9 TiB.

Command (m for help):w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

查看分区表

1
fdisk -l

List Partition

这里分区就创建完成了。

初始化文件系统

在分区创建完成之后需要格式化成特定的文件系统挂载才能够正常使用,根据我们之前的分区规划我们来对当前的2个分区来进行初始化。

初始化 /dev/nvme0n1p1

1
mkfs.fat -F32 /dev/nvme0n1p1

初始化 /dev/nvme0n1p2

这里我选择的是在LUKS上创建文件系统,所以先要初始化LUKS

1
cryptsetup luksFormat /dev/nvme0n1p2

Format Luks

这里会提示你的输入大写的YES

然后输入你的密码,这里同样是没有回显的放心输入好了。

这里LUKS就初始化完成了,但是我们的初始化分区工作还没有完成还需要解开LUKS来对分区初始化

打开LUKS 分区

1
cryptsetup luksOpen /dev/nvme0n1p2 system

这里会提示输入密码(这个密码就是在之前初始化时候的密码)

Open Luks

可以看到在密码正确输入之后分区被打开了,设备位置位于/dev/mapper/system

初始化/dev/mapper/system

1
mkfs.ext4  -i 8192 /dev/mapper/system

到这里分区的初始化就完成了

挂载分区

在完成了分区的初始化之后,就要开始挂载分区了。

首先我们创建一个挂载点

1
mkdir -pv /mnt/gentoo

挂载分区

1
mount /dev/mapper/system /mnt/gentoo

创建 /boot挂载点

1
mkdir -pv /mnt/gentoo/boot

挂载/boot分区

1
mount /dev/nvme0n1p1 /mnt/gentoo/boot

挂载目录结构如下图所示

show mount

到这里我们就完成挂载分区了

安装Gentoo安装文件

设置日期和时间

在安装Gentoo之前,我们要确保livecd里面的时间设置正确。错误的时间配置可能会导致安装包的时候抛出异常和一堆错误。

设置时区

1
timedatectl set-timezone "Asia/Shanghai"

选择安装文件

选择对一个基础的压缩包将会为稍后的安装节省大量的时间:

  • multilib (包含32和64位程序的兼容性)
  • no-multilib (只支持64位的程序)

考虑到我是刚开始折腾Gentoo我这里就选择的是multilib

下载stage压缩包

首先进入到/mnt/gentoo目录

1
cd /mnt/gentoo

我这里使用的是阿里云的源你也可以选择其他的源

目录基本在gentoo/releases/amd64/autobuilds/current-stage3-amd64/下面

这个下载链接可能会因为时间的关系失效,如果失效可以进入到这个目录下面选择最新的压缩包进行下载。

1
2
3
4
wget -c http://mirrors.aliyun.com/gentoo/releases/amd64/autobuilds/current-stage3-amd64/stage3-amd64-20210117T214503Z.tar.xz
wget -c http://mirrors.aliyun.com/gentoo/releases/amd64/autobuilds/current-stage3-amd64/stage3-amd64-20210117T214503Z.tar.xz.DIGESTS
wget -c http://mirrors.aliyun.com/gentoo/releases/amd64/autobuilds/current-stage3-amd64/stage3-amd64-20210117T214503Z.tar.xz.CONTENTS.gz
wget -c http://mirrors.aliyun.com/gentoo/releases/amd64/autobuilds/current-stage3-amd64/stage3-amd64-20210117T214503Z.tar.xz.DIGESTS.asc

查验压缩包的SHA512校验值

1
awk '/SHA512 HASH/{getline;print}' stage3-amd64-*.tar.xz.DIGESTS.asc | sha512sum --check

确保值一致

接下来解压压缩包

1
tar xpvf stage3-*.tar.xz --xattrs-include='*.*' --numeric-owner

请确保使用的是这个解压命令(保持权限还是压缩之前的状态)

Portage 文件说明

在开始配置Portage之前我们先对Portage有哪些文件先做一下说明

/etc/portage下的文件文件说明
repos.conf指定特定站点的仓库配置,包括仓库的同步机制和URL
make.conf这个文件包含了Portage的各种重要的变量定义。这些变量还告诉系统:
  1. 默认接受的许可(比如说所有软件,或者是FSF便好的免费软件 )
  2. 系统架构(比如说amd64 架构实际上是对64位处理器的通用引用无论是AMD还是Intel
  3. 关于系统显卡和输入设备的信息
  4. 设置系统是处于稳定版本还是测试版本
  5. 系统默认的全局USE
  6. 设置Portage distfile tarball的URL 从而加速下载
  7. 构建期间的日志记录
除此之外还有很多的配置
package.maskpackage.mask中指定的软件将会不被安装(可以将其看成黑名单),当新版本的软件出现一些问题的时候(或者是不兼容)可以在这个文件中添加对应的记录。
package.unmask这个文件的作用将会覆盖package.mask的效果(安装白名单)。
package.usepackage.use包含单个软件包的USE标志的列表。 当指定仅具有局部含义的标志或者是在特殊情况下希望将其打开(比如说测试特性),它会派上用场
package.license这个文件允许你基于每个软件包来设置许可证(比如说我想要整个系统都是free的但是某个软件例外)
package.accept_keywords这个文件主要的作用是允许你使用测试而非稳定分支的包。最好少用以避免依赖污染。有的时候是必要的比如说:portage 树中没有可用的稳定软件时
env这里是定义特殊的配置文件比如说只允许单核心编译MAKEOPTS="-j1" 这里的配置文件是给package.env作为引用
package.envpackage.env 允许将上面定义的环境设置引用到特定的软件包

Atoms, Packages, Categories, Versions, Sets and SLOTs

这里来对Portage包管理的一些术语做一些简单的介绍

  • 软件包指的是同类软件块,每个都提供一个可以安装的ebuild,不管是额外的包还是gentoo的包。
  • 包作为树的叶子,被分组为类别,这些类别就相当于是通过功能来划分,比如说openvpn属于net-vpn这个类别
  • 程序的原子指的是由完整类别组成的名称,没有版本和其他的限定符号比如说 net-vpn/openvpn 什么时候会用到原子呢?比如说你要引用一个基于SQLite的数据库 dev-python/axiom 但是这个是和sci-mathematics/axiom 是一个软件包名字这个时候原子就派上用场了。
  • 通常可以通过 packages::reponame 附加到原子上从而指定特定仓库中的ebuild来安装软件包
  • Portage支持一个软件的多个版本,这里是需要portage tree中存在这个软件的多个版本ebuild。
  • 在有些时候需要打开软件包的某个特性的时候就需要修改 /etc/portage/package.use下面的内容,如果指定的是基本原子那就是意味着对这个程序的所有版本都应用这个USE,当然也可以指定特定版本的。可以使用这些前缀来指定特定版本的原子:(">", ">=", "=", "<=", "<") 这些将会限制原子在特定版本下的USE比如说 >=net-vpn/openvpn-2.4.3 inotify将这个添加到/etc/portage/package.use文件中这就意味着告诉Portage在openvpn大于等于2.4.3的时候启用inotify这个USE。 关于更多的原子的细节可以参考 man 5 ebuild
  • 可以将多个原子分为一组,从而可以针对整个组来进行操作(比如说重建某个组)。对于这个组有个名字:集合,集合以@作为前缀,其中一些是在Portage里由预先定义的比如说 @system集合包括主要的系统软件包。像是我们安装一个软件包(原子)这个就会记录在 /var/lib/portage/world中。(@world集合包含了@system集合,如果有需要还可以自己定义集合。)。
  • 关于Gentoo的系统版本,你可能会发现Gentoo和其他发行版不太一样不像是Ubuntu有那种Xenial Xerus之类的版本,如果你有用过Archlinux之类的滚动发行版你可能会知道Gentoo也是滚动发行版。Gentoo本身就没有版本,当你更新系统的时候都会更新到最新的版本(取决于你是在稳定分支还是测试分支)。这样的好处就是当新的软件的ebuild到了portage tree的时候可以修改portage配置文件来尝试使用。但是同样的也带来一个新的问题相较于Ubuntu这样的二进制发行版,有的时候编译会不通过。

是时候回到安装了!

配置Portage

我们的第一个Portage的配置是确保 下载/拆包/准备/配置/编译/安装/合并 这个周期能够尽可能的高效,这意味着要利用系统可以提供的任何并行性。

我们需要从两个方面入手

  1. 最大运行Portage的作业数量
  2. 以及每个ebuild自身调用make进程并行线程的最大数量。

按照Gentoo Wiki的建议我们将会吧并发的作业数量和make线程数设置为等于系统CPU的线程数+1,当系统平均负载到达或者是超过CPU数量的时候,我们需要阻止新的作业加入或者是新的编译开始。

我们要设置的两个变量是EMERGE_DEFAULT_OPTS(Portage作业数控制)和MAKEOPTS(make的线程数),这些通常是在make.conf里面定义。 因为Portage不支持命令替换之类的高级Bash功能,所以我们将会在 root 的.bashrc中设置。

Tips: 一般来说,emerge是以root用户启动的,当编译的时候,emerge通常会降低特权以“portage”这个用户运行。

用你喜欢的编辑器打开/mnt/gentoo/root/.bashrc文件(本教程用nano作为主要的编辑器)

Tips: -w 选项是告诉nano编辑器不要自动换行,因为自动换行有的时候会搞乱配置文件。 nano是一个很简单的编辑器:用方向键可以上下左右移动,像是任何文本处理工具一样进行编辑,完成编辑之后使用Ctrl+x退出(按住Ctrl的同时再按x):如果你修改了文件系统会提示你是否要保存,这个时候输入y再按enter退出,保存更改。输入n退出即是不保存更改退出。

1
nano -w /mnt/gentoo/root/.bashrc

内容如下

1
2
3
4
export NUMCPUS=$(nproc)
export NUMCPUSPLUSONE=$(( NUMCPUS + 1 ))
export MAKEOPTS="-j${NUMCPUSPLUSONE} -l${NUMCPUS}"
export EMERGE_DEFAULT_OPTS="--jobs=${NUMCPUSPLUSONE} --load-average=${NUMCPUS}"

保存并退出nano

Tips: 如果在编译的时候遇到并行的问题希望回到更加保守的配置,可以设置上面的MAKEOPTS="-j1"来进行全局设定。

接下来我们要确保.bashrc这个文件是root登陆的shell读取的,因此还需要复制一份默认的.bash_profile配置文件

1
cp -v /mnt/gentoo/etc/skel/.bash_profile /mnt/gentoo/root/

接下来进入make.conf配置文件本身。我们安装的stage3文件已经包含了基本的配置。我们将用nano编辑器打开这个文件,删除现有行,然后替换我们的配置。(nano中,Ctrl+k 可以用来快速剪切当前行)

1
nano -w /mnt/gentoo/etc/portage/make.conf

内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# Build setup as of <add current date>

# C, C++ and FORTRAN options for GCC.
COMMON_FLAGS="-march=native -O2 -pipe"
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${COMMON_FLAGS}"
FCFLAGS="${COMMON_FLAGS}"
FFLAGS="${COMMON_FLAGS}"

# Note: MAKEOPTS and EMERGE_DEFAULT_OPTS are set in .bashrc

# The following licence is required.
ACCEPT_LICENSE="*"

# WARNING: Changing your CHOST is not something that should be done lightly.
# Please consult http://www.gentoo.org/doc/en/change-chost.xml before changing.
CHOST="x86_64-pc-linux-gnu"

# Use the 'stable' branch - 'testing' no longer required for Gnome 3.
# NB, amd64 is correct for both Intel and AMD 64-bit CPUs
ACCEPT_KEYWORDS="amd64"

# Additional USE flags supplementary to those specified by the current profile.
USE=""
CPU_FLAGS_X86="mmx mmxext sse sse2"

# Important Portage directories.
PORTDIR="/var/db/repos/gentoo"
DISTDIR="/var/cache/distfiles"
PKGDIR="/var/cache/binpkgs"

# Distfile Mirrors
GENTOO_MIRRORS="https://mirrors.aliyun.com/gentoo"

# GRUB Platforms
GRUB_PLATFORMS="efi-64"

# ABI Version
ABI_X86="64"
# This sets the language of build output to English.
# Please keep this setting intact when reporting bugs.
LC_MESSAGES=C

# Turn on logging - see http://gentoo-en.vfose.ru/wiki/Gentoo_maintenance.
PORTAGE_ELOG_CLASSES="info warn error log qa"
# Echo messages after emerge, also save to /var/log/portage/elog
PORTAGE_ELOG_SYSTEM="echo save"

# Ensure elogs saved in category subdirectories.
# Build binary packages as a byproduct of each emerge, a useful backup.
FEATURES="split-elog buildpkg"

# Settings for X11
VIDEO_CARDS="intel i965"
INPUT_DEVICES="libinput wacom synaptics"

Tips: 在/etc/portage/make.conf中给你的系统设置特定的VIDEO_CARDSINPUT_DEVICES。参见下边的这张表

保存并退出nano

这里是刚开始的stage3文件中包含的make.conf配置简要,以及我们所添加的。

变量类型默认值我们设置的值描述
COMMON_FLAGSStandard-O2 -pipe-march=native -O2 -pipe这个变量仅定义一些通用的标志,这些标志会传给GNU编译器,在编译源码的时候使用,缺省值为 -O2,这是它推荐设置的级别(以较小的编译时间为代价,生成更小,更快的代码),以及-pipe,它指示编译器在可能的情况下更多的使用管道而不是临时文件从而加快编译速度。我们保留这些添加了-march=native。这个会自动检查CPU的类型,并且会利用CPU其特性生成代码。需要注意的是在这个设置了情况下编译的软件在其他的计算机是很可能无法使用的!
CFLAGSStandard${COMMON_FLAGS}${COMMON_FLAGS}这个变量设置在编译C代码时的编译器标志
CXXFLAGSStandard${COMMON_FLAGS}${COMMON_FLAGS}这个变量设置在编译C++ 代码时候的编译器标志
FCFLAGSStandard${COMMON_FLAGS}${COMMON_FLAGS}将CPU标志传给FORTRAN编译器
FFLAGSStandard${COMMON_FLAGS}${COMMON_FLAGS}将CPU标志传给 FORTRAN77编译器
ACCEPT_LICENSEIncremental-* @FREE*接受所有许可的软件
CHOSTStandardx86_64-pc-linux-gnux86_64-pc-linux-gnuCHOST变量非常重要。 它是Architecture-vendor-operating_system-C_library的元组,用于控制构建过程。这里我们不会进行更改。
ACCEPT_KEYWORDSIncrementalamd64amd64这个变量就是控制你的系统是稳定版本还是非稳定版本 amd64就是处于稳定分支的系统只接受上游测试通过的软件包 ~amd64就是测试版本接受最新的ebuild 即使可能不稳定。
USEIncrementalvarious flags set by profileempty默认的stage3是有一个bindist的USE的这里留空,使用profile的默认USE
CPU_FLAGS_X86USE_EXPANDmmx mmxext sse sse2mmx mmxext sse sse2这个变量告诉Portage 使用哪个处理器的特定标志(比如说启动MMX的支持),我们这里保留默认的配置在章节中我们会使用app-portage/cpuinfo2cpuflags这个包自动为我们生成适合优化的配置。
PORTDIRStandard/var/db/repos/gentoo/var/db/repos/gentoo这个变量定义了Portage树的位置,这里我们保持原样。
DISTDIRStandard/var/cache/distfiles/var/cache/distfiles这个变量定义了存储源码包的tarball位置,这里我们保持原样。
PKGDIRStandard/var/cache/binpkgs/var/cache/binpkgs这个变量定义了存储二进制包的位置,这里我们保持原样。
LC_MESSAGESStandardCC这个变量用于设置编译时候输出的语言。我们这里设置为C(表示英文输出),这是提交编译报错时必须的,但是你也可以根据自己的需要来更改方便你的使用
PORTAGE_ELOG_CLASSESStandardabsentinfo warn error log qa这个变量告诉Portage要记录哪些ebuild信息,我们这里的设置为打开所有信息。
PORTAGE_ELOG_SYSTEMStandardabsentecho save这个变量指示Portage处理日志消息,在这个设置下日志将会输出回显,并保存。
FEATURESIncrementalvarious features set by profilesplit-elog buildpkg顾名思义,这个变量用于打开或者是关闭Portage的功能。我们打开了split-elog,确保日志会存在 /var/log/portage/elog的子目录中,同时我们也打开了 buildpkg的功能,这个是在构建成功软件包的时候保存一份二进制版本到之前设置的PKGDIR中。
VIDEO_CARDSUSE_EXPANDcomprehensive list of video cards set by profileintel i965这个变量就是告诉各种程序在你的系统里面是什么显卡。我在这里制定了 intel i965这么几个驱动(这个也是在Mac上测试通过可以正常启动X的情况)
INPUT_DEVICESUSE_EXPANDvarious input devices set by profilelibinput wacom synaptics这个变量是告诉X Windows我们需要支持哪些输入设备。

Chroot

Chroot的最终准备

我们需要创建并配置一个文件,这个文件/mnt/gentoo/etc/portage/repos.conf/gentoo.conf将会告诉Portage从哪里获取最新的Portage树。

首先我们需要创建文件夹

1
2
3
mkdir -p -v /mnt/gentoo/etc/portage/repos.conf
cp -v /mnt/gentoo/usr/share/portage/config/repos.conf /mnt/gentoo/etc/portage/repos.conf/gentoo.conf
nano -w /mnt/gentoo/etc/portage/repos.conf/gentoo.conf

修改内容如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
[DEFAULT]
main-repo = gentoo

[gentoo]
location = /var/db/repos/gentoo
sync-type = webrsync
#sync-type = rsync
sync-uri = rsync://rsync.mirrors.aliyun.com/gentoo-portage/gentoo-portage/
sync-webrsync-verify-signature = true
auto-sync = yes

sync-rsync-verify-jobs = 1
sync-rsync-verify-metamanifest = yes
sync-rsync-verify-max-age = 24
sync-openpgp-keyserver = hkps://keys.gentoo.org
sync-openpgp-key-path = /usr/share/openpgp-keys/gentoo-release.asc
sync-openpgp-key-refresh-retry-count = 40
sync-openpgp-key-refresh-retry-overall-timeout = 1200
sync-openpgp-key-refresh-retry-delay-exp-base = 2
sync-openpgp-key-refresh-retry-delay-max = 60
sync-openpgp-key-refresh-retry-delay-mult = 4

保存并退出

上面这个配置文件说明了以下内容:

设置主要的仓库为gentoo 存储位置是在 /var/db/repos/gentoo 同步方式为websync(之后会改为增量的 rsync)

接下来我们要确保chroot之后还可以使用这个Mac的网络,也就是我们需要复制一下 /etc/resolv.conf配置文件

1
cp -v -L /etc/resolv.conf /mnt/gentoo/etc/

-L选项可确保我们不会错误地复制符号链接,因为一旦chroot,主机文件系统将变得不可访问。

然后,我们还需要确保 chroot 之后还可以使用 /proc, /sys, /dev/,这些特殊的文件系统

1
2
3
4
5
mount -v -t proc none /mnt/gentoo/proc
mount -v --rbind /sys /mnt/gentoo/sys
mount -v --rbind /dev /mnt/gentoo/dev
mount -v --make-rslave /mnt/gentoo/sys
mount -v --make-rslave /mnt/gentoo/dev

Tips: 在非Gentoo官方的Livecd中 /dev/shm可能被连接到了/run/shm还需要运行以下命令

1
2
3
test -L /dev/shm && rm /dev/shm && mkdir /dev/shm
mount --types tmpfs --options nosuid,nodev,noexec shm /dev/shm
chmod 1777 /dev/shm

进入chroot

这里进入chroot的准备工作就完成了,我们现在就可以进入chroot了

1
chroot /mnt/gentoo /bin/bash

进入chroot之后可能遇到命令无法执行的情况我们需要执行以下操作

1
2
source /etc/profile
export PS1="(chroot) $PS1"

我们设置了一个PS1这个方便区分我们当前是在什么环境

安装和更新Portage Tree

在这里我们要安装Portage树的快照,通知Portage可以安装哪些文件,可用的配置文件等等。

为了安全起见,我们需要更新必要的公共密钥,然后下载并验证最新的快照,运行以下命令即可:

1
emaint sync --auto

现在我们有了基本的portage树,我们可以切换到rsync协议,使其保持更新的状态:

1
nano -w /etc/portage/repos.conf/gentoo.conf

sync-type改为rsync注销掉原来的那行 webrsync

1
2
3
#sync-type = webrsync
sync-type = rsync
sync-uri = rsync://mirrors.aliyun.com/gentoo-portage/gentoo-portage/

再次同步

1
emaint sync --auto

有的时候会遇到源不可用的情况,这里再补充一种利用git同步Portage tree的配置。

在完成了第一次webrsync同步之后安装git包

1
emerge --ask  dev-vcs/git

再去修改配置文件

1
nano -w /etc/portage/repos.conf/gentoo.conf

内容更改如下

1
2
3
4
5
6
7
8
[DEFAULT]
main-repo = gentoo

[gentoo]
location = /var/db/repos/gentoo
sync-type = git
sync-uri = https://github.com/gentoo-mirror/gentoo.git
auto-sync = yes

保存退出后我们需要将原来的目录删除

1
rm -rf /var/db/repos/gentoo

再次进行同步

1
emaint sync --auto

设置基本的配置文件

像是之前所说到的Gentoo使用配置文件来设置特定的架构和使用场景。配置文件还限制了可以安装的可以安装软件包的版本,默认的USE之类的,这个基本的profile是由Gentoo开发者来维护的。

这里我们检查一下是否在17.1 amd64配置文件即可,

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
eselect profile list
Available profile symlink targets:
  [1]   default/linux/amd64/17.1 (stable) *
  [2]   default/linux/amd64/17.1/selinux (stable)
  [3]   default/linux/amd64/17.1/hardened (stable)
  [4]   default/linux/amd64/17.1/hardened/selinux (stable)
  [5]   default/linux/amd64/17.1/desktop (stable)
  [6]   default/linux/amd64/17.1/desktop/gnome (stable)
  [7]   default/linux/amd64/17.1/desktop/gnome/systemd (stable)
  [8]   default/linux/amd64/17.1/desktop/plasma (stable)
  [9]   default/linux/amd64/17.1/desktop/plasma/systemd (stable)
  [10]  default/linux/amd64/17.1/desktop/systemd (dev)
  [11]  default/linux/amd64/17.1/developer (stable)
  [12]  default/linux/amd64/17.1/no-multilib (stable)
  [13]  default/linux/amd64/17.1/no-multilib/hardened (stable)
  [14]  default/linux/amd64/17.1/no-multilib/hardened/selinux (stable)
  [15]  default/linux/amd64/17.1/systemd (stable)
  [16]  default/linux/amd64/17.0 (dev)
  [17]  default/linux/amd64/17.0/selinux (dev)
  [18]  default/linux/amd64/17.0/hardened (dev)
  [19]  default/linux/amd64/17.0/hardened/selinux (dev)
  [20]  default/linux/amd64/17.0/desktop (dev)
  [21]  default/linux/amd64/17.0/desktop/gnome (dev)
  [22]  default/linux/amd64/17.0/desktop/gnome/systemd (dev)
  [23]  default/linux/amd64/17.0/desktop/plasma (dev)
  [24]  default/linux/amd64/17.0/desktop/plasma/systemd (dev)
  [25]  default/linux/amd64/17.0/developer (dev)
  [26]  default/linux/amd64/17.0/no-multilib (dev)
  [27]  default/linux/amd64/17.0/no-multilib/hardened (dev)
  [28]  default/linux/amd64/17.0/no-multilib/hardened/selinux (dev)
  [29]  default/linux/amd64/17.0/systemd (dev)
  [30]  default/linux/amd64/17.0/x32 (dev)
  [31]  default/linux/amd64/17.0/musl (exp)
  [32]  default/linux/amd64/17.0/musl/hardened (exp)
  [33]  default/linux/amd64/17.0/musl/hardened/selinux (exp)
  [34]  default/linux/amd64/17.0/uclibc (exp)
  [35]  default/linux/amd64/17.0/uclibc/hardened (exp)

在这里我们的默认配置文件已经在这个profile文件,如果你想要手动选一下可以使用eselect工具来设置配置文件

1
eselect profile set "default/linux/amd64/17.1"

你可以通过这条命令来查看配置文件make.conf环境,这个在提交bug的时候最好也附加上去

1
emerge --info

如果你对USE标志的含义不是很理解可以通过下面这条命令去查找其含义(比如说useflag

1
grep -i useflag /var/db/repos/gentoo/profiles/use.desc

或者是在线查询

确保更新了Portage

在完成了更新portage tree的时候portage提示Portage有可用的更新了,可以通过这条命令来更新Portage

1
emerge --ask --verbose --oneshot portage

--oneshot选项是通知Portage不要把自己记录在world文件 --ask-verbose选项是emerge在对系统进行任何更改之前通知你,并产生详细的输出(可以简写为 -av)。 按回车进行更新

更新Portage树的同时也会带来一些新闻条目,这些发布的新闻条目最好是阅读一下,这些是很重要的,这些通常是Gentoo开发者对用户发布的简单公告,如果想要查看当前的新闻条目可以运行:

1
eselect news list

你会注意到有新闻的编号,假如你想要阅读新闻N,可以输入:

1
eselect news read N

如果你已经看完了所有的新闻,你可以运行这条命令来清除已经阅读过的新闻

1
eselect news purge

设置时区和语言环境

我们还没有设置时区和语言环境,我们现在来设置这些。

首先是时区设置。你可以在/usr/share/zoneinfo/下面找到你所在位置的对应时区(这里比如说亚洲上海时区)

1
echo "Asia/Shanghai" > /etc/timezone

现在我们需要重新配置sys-libs/timezone-data包,重建这个包将会从/etc/timezone中取值,并在/etc/localtime中反应正确的值。

1
emerge -v --config sys-libs/timezone-data

其次我们必须设置合适的语言环境,我们必须要在/etc/locale.gen中指定要使用的语言环境。编辑这个文件,并添加以下内容

1
nano -w /etc/locale.gen

这里我们以英文和中文为例子:

1
2
en_US.UTF-8 UTF-8
zh_CN.UTF-8 UTF-8

保存并退出文件。

接下来我们必须要基于/etc/locale.gen文件中的配置,运行locale.gen来创建语言环境:

1
locale-gen

在运行成功之后,我们还需要指定以后默认使用的语言环境,使用下面这条命令来查找当前的系统有的语言环境

1
2
3
4
5
6
7
8
9
eselect locale list
Available targets for the LANG variable:
  [1]   C
  [2]   C.utf8
  [3]   POSIX
  [4]   en_US.utf8
  [5]   zh_CN.utf8
  [6]   C.UTF8 *
  [ ]   (free form)

我们现在先保持为C环境,后面再修改成实际的语言环境

1
eselect locale set "C"

现在重新载入环境

1
env-update && source /etc/profile && export PS1="(chroot) $PS1"

通知Portage使用特定的CPU功能

在之前配置/etc/portage/make.conf中我们把CPU_FLAGS_X86设置成默认的值mmx mmxext sse sse2,在这里我们将会用到 app-portage/cpuid2cpuflags这个工具来设置对应的变量

1
emerge --verbose --oneshot app-portage/cpuid2cpuflags

安装完成之后,运行这个工具并且记录下输出(你运行的输出可能和我的不太一样,这个输出取自我这台Mac)

1
2
cpuid2cpuflags
CPU_FLAGS_X86: aes avx avx2 f16c fma3 mmx mmxext pclmul popcnt rdrand sse sse2 sse3 sse4_1 sse4_2 ssse3

然后修改/etc/portage/make.conf文件

1
nano -w /etc/portage/make.conf

内容如下

1
CPU_FLAGS_X86="aes avx avx2 f16c fma3 mmx mmxext pclmul popcnt rdrand sse sse2 sse3 sse4_1 sse4_2 ssse3"

保存并退出。

Gentoo Bootstrap: 从Stage1到Stage2

首先我们要构建自己的工具链! Gentoo Portage Tree里面提供了一个bootstrap.sh脚本。 现在我们切换到脚本存在的目录:

1
cd /var/db/repos/gentoo/scripts

然后运行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
./bootstrap.sh --pretend
Gentoo Linux; http://www.gentoo.org/
Copyright 1999-2020 Gentoo Authors; Distributed under the GPLv2
-------------------------------------------------------------------------------
  [[ (0/3) Locating packages ]]
 * Using baselayout : >=sys-apps/baselayout-2
 * Using portage    : sys-apps/portage
 * Using os-headers : >=sys-kernel/linux-headers-5.4-r1
 * Using binutils   : sys-devel/binutils
 * Using gcc        : sys-devel/gcc
 * Using gettext    : sys-devel/gettext
 * Using libc       : sys-libs/glibc:2.2
 * Using texinfo    : sys-apps/texinfo
 * Using zlib       : sys-libs/zlib
 * Using ncurses    : sys-libs/ncurses
-------------------------------------------------------------------------------
  [[ (1/3) Configuring environment ]]
-------------------------------------------------------------------------------
  [[ (2/3) Updating portage ]]
!!! CONFIG_PROTECT is empty

注意这里输出的版本可能和你的不一样

Gentoo FAQ建议是先查看这个并编辑,接下来我们也会这么做,这里面也存在几个问题:

  1. 对于现代的GCC,我们需要添加一个openmp的USE。
  2. CONFIG_PROTECT为空表示在这个bootstrap过程中配置文件将会被覆盖。
  1. 修复GCC的USE问题

使用nano打开/var/db/repos/gentoo/scripts/bootstrap.sh文件

1
nano -w /var/db/repos/gentoo/scripts/bootstrap.sh

按Ctrl+w输入export USE="-按Enter进行搜索

修改这行内容如下

1
export USE="-* bootstrap ${ALLOWED_USE} ${BOOTSTRAP_USE} openmp"

保存并退出

  1. 做配置文件备份

我们可以使用qfile来查询我们已经修改过的文件属于那个程序,以及这次重构是否会影响到,如果影响到我们就需要进行备份。

1
2
qfile /etc/locale.gen
sys-libs/glibc: /etc/locale.gen

这里我们的重构会影响到这个glibc,所以我们要对更改的文件做一个备份。

1
cp -v /etc/locale.gen{,.bak}

现在一切就绪,让我们开始真正的bootstrap程序吧

1
./bootstrap.sh

bootstrap.sh完成之后,我们还需要检查一下GCC的配置,因为在之前的重新构建编译器过程中,可能Portage Tree中有新的可用版本构建的就是新的GCC。

1
2
gcc-config --list-profiles
 [1] x86_64-pc-linux-gnu-9.3.0 *

这里看起来只有一个配置,如果你选择的是测试分支(~amd64)可能会有多个可用的GCC版本 你可以运行这条命令来切换到最新的GCC

1
gcc-config 1 # 这个1 就是最新版本的GCC 前面的那个1

还需要更新环境

1
env-update && source /etc/profile && export PS1="(chroot) $PS1"

如果你的输出是只有一个GCC那么这些是不用再去操作的。

如果你更新了GCC你还需要做这些

再备份一次glibc的配置文件

1
cp -v /etc/locale.gen{,.bak}

现在我们需要再运行一次bootstrap.sh脚本,以确保使用新的编译器重新构建了工具链中的所有内容,

1
./bootstrap.sh

完成bootstrap.sh之后,我们需要还原备份的配置文件,然后重新生成语言环境

1
2
mv -v /etc/locale.gen{.bak,}
locale-gen

现在再来检查语言环境是否是C

1
eselect locale show

最后返回 / 目录

1
cd /

Gentoo Bootstrap 从Stage2到Stage3

现在我们需要使用我们在上面构建出来的全新工具链来构建@world集合里面的所有包。

在开始之前我们还需要创建一个空的timestamp文件,这个文件可以用于在构建完成之后检查可执行文件和库被重建,并且对这些进行标记。

1
touch /tmp/prebuild_checkpoint

现在我们已经准备好重新构建@world集合中的所有内容,运行这条命令开始构建:

1
emerge --ask --verbose --emptytree --with-bdeps=y @world

别忘了回车开始构建。 这里是关于我们上述这条命令的解释

参数简写描述
--ask-a在开始之前,会显示会发生什么(比如说升级降级卸载slot等),然后询问你是否继续还是终止,这个选项建议每次使用都保留
--verbose-v提供emerge操作的更多信息。(比如说--ask提供的信息中每个包的USE标记)
--emptytree-e编译并安装所有的包(在这里安装的是@world这个集合里面所包含的所有包以及其相应的依赖关系)。这里是让在计算依赖关系的时候假设系统没有任何的包
--with-bdeps=yN/A将编译时依赖关系也考虑进来,从而让依赖关系树更加完整。
@worldN/A这里指定是@world集合 @标记后面加上集合的名称就表示引用的是一个集合的软件包而非单个包(原子)

Tips: 这个操作将会持续相当长的时间,建议使用会话管理的工具来去保存构建工作 推荐使用screen或者是tmux

Screen安装和使用

这里只介绍非常基本的使用,想要了解更多的screen用法可以查阅man手册

1
emerge --ask --verbose --oneshot app-misc/screen

安装完成之后,我们要创建一个会话来保存我们的构建工作

1
screen -S rebuild

这里就会进入一个名为rebuild的会话中,运行重新构建@world集合。

1
emerge --ask --verbose --emptytree --with-bdeps=y @world

现在我们可以使用Ctrl+a 再按D 保存这个会话并且回到原来的会话。

如果你想要回到这个rebuild会话可以输入

1
screen -R rebuild

这样就回到rebuild也就是正在构建@world这个会话查看进度如何。

Tmux 安装和使用

Tmux也是一个会话管理,我日常使用比较多的也是tmux这里也简单介绍一下tmux的简单使用

安装tmux

1
emerge --ask --verbose --oneshot app-misc/tmux

创建一个名为rebuild会话

1
tmux new -A -s rebuild

运行重新构建@world

1
emerge --ask --verbose --emptytree --with-bdeps=y @world

运行Ctrl-b +d 脱离会话,回到当前的shell中,如果想要重新连接到这个会话可以运行

1
tmux attach -t rebuild

经过长时间的构建我们终于从Stage2构建到了Stage3,这里可能有一些包已经经过升级了,如果你想要卸载掉旧的包可以执行:

1
emerge --depclean

或者想要再来一次可以执行

1
emerge --depclean && emerge --ask --verbose --emptytree --with-bdeps=y @world

验证bootstrap

首先恭喜你完成了bootstrap,当前chroot环境里面的所有二进制文件,库都被重新构建了。这里为了确保没有遗漏的包的发生,我们要对之前创建的时间戳文件进行检查。

运行这条命令(可能需要耗费一些时间):

1
find / -type d -path /boot -prune -o -path /proc -prune -o -type f -executable -not -newer /tmp/prebuild_checkpoint -print0 2>/dev/null | xargs -0 file --no-pad --separator="@@@" | grep -iv '@@@.* text'

这个命令会查找所有可执行的文件。它不会产生输出(如果我们的bootstrap重建完成会重新创建所有这类文件)。

对于可执行的二进制文件来说太多了(动态库,静态库),我们已经检查了大多数的共享库,因为它们的执行位已经设置过了,但是相对于那些静态库和对象文件我们还没有设置位还需要运行另外一个测试

1
find / -type d -path /boot -prune -o -path /proc -prune -o -type f -not -executable -not -newer /tmp/prebuild_checkpoint -print0 2>/dev/null | xargs -0 file --no-pad --separator="@@@" | grep '@@@.*\( ELF\| ar archive\)'

这个测试同样会耗费一些时间请耐心等待。

切换配置文件

在完成bootstrap之后我们要再去选择一个自己喜欢的配置文件。 这里我不打算上DE(Desktop environment),打算上WM(节省更多的内存可以用于做实验或者是其他)。 所以我这里选择的profile是desktop的profile,用这条命令设置:

1
eselect profile set "default/linux/amd64/17.1/desktop"

在更新profile文件之后最好是更新一下环境,载入新的环境变量

1
env-update && source /etc/profile && export PS1="(chroot) $PS1"

更新系统

1
emerge --ask --verbose --deep --with-bdeps=y --newuse --update @world

这次切换profile文件之后再去更新出现了报错我们借助这个机会来看看如何根据Portage提供的信息来排错

这里Portage告诉我们当前的USE标记不能够让让Portage继续为我们更新系统,我们需要对这两个包的USE进行调整。 还记得Portage在哪里调整单个包的USE吗?没错就是在/etc/portage/package.use下面,这个位置可以是单个文件也可以是一个目录。 我个人比较推荐使用目录的方式去管理USE,在目录下创建单个包(原子)的文件来管理单个包的USE。

1
mkdir -pv /etc/portage/package.use

Python 我们按照之前说过的如何对单个包的USE进行配置,来配置python的USE

1
echo "dev-lang/python -sqlite" > /etc/portage/package.use/python

Sqlite

Sqlite同样处理一下

1
echo "dev-db/sqlite -icu" > /etc/portage/package.use/sqlite

现在重新尝试更新一下系统

1
emerge --ask --verbose --deep --with-bdeps=y --newuse --update @world

但是这次Portage还是不给我们过并且又抛出一个错误

同样的我们按照这个提示进行修改

Python

1
echo "dev-lang/python -sqlite -bluetooth" > /etc/portage/package.use/python

bluez

1
echo "net-wireless/bluez -oboex" > /etc/portage/package.use/bluez

现在重新尝试更新一下系统

1
emerge --ask --verbose --deep --with-bdeps=y --newuse --update @world

现在可以正常更新了,这个更新会根据profile里面的USE设定重新构建大量的包。(可以继续工作了,让它慢慢更新好了。)

安装和配置内核

接下来就是安装和配置内核,也是最为繁琐的一个步骤。

Gentoo有很多种内核可以选择

名称描述
GenkernelGenkernl是一个用于构建内核和initramfs的构建工具,它提供了一个默认的内核配置文件。通常建议不熟悉手动编译内核的用户使用
gentoo-sources对于大多数用户,建议使用的是这个内核,Gentoo会对这个内核进行维护(打一些轻量的补丁以修复安全问题,内核错误和兼容性问题)
gentoo-kernel这个内核提供了默认的配置以适用于大多数不同的系统,适用于不想从头配置自己内核的用户。
ck-sources这个内核是Con Kolivas的内核补丁集,这个内核主要用于提高系统响应的能力和交互性,并针对于各种工作负载进行配置。
git-sources这个内核是跟踪上游开发内核的每日快照,如果你对内核的最新特性感兴趣或者是想要参与内核的开发和测试那么这个内核就是为你而生的。

在这里我会分别介绍三种配置内核的方式

  1. Genkernel 方式配置内核
  2. Gentoo-kernel-bin 方式配置内核
  3. 利用已有的内核配置文件配置内核

在配置内核之前

在配置内核之前我们需要查看当前的硬件配置:

1
lspci

如果没有lspci命令可以安装这个包

1
emerge -av sys-apps/pciutils

当然还有一种方法不让这个pciutils在这个@world集合里面我们可以自己创造一个集合 创建/etc/portage/sets文件夹

1
mkdir -pv /etc/portage/sets

创建并编辑/etc/portage/set/yafa文件

1
nano -w /etc/portage/sets/yafa

内容如下

1
2
# mandatory!
sys-apps/pciutils

告诉Portage安装@yafa这个集合中的包并且自动安装其依赖

1
emerge --ask --noreplace @yafa

查看当前的硬件和使用的内核模块

1
lspci -nnk

lspci 再这个图中就是我现在的这个Mac的硬件情况以及使用的内核驱动

Genkernel 方式配置内核

Genkernel 是一个自动化构建内核和initramfs的工具,Genkernel可以做这些事情:

  1. 配置内核
  2. 构建内核(bzImage)并复制到/boot
  3. 创建initramfs并复制到/boot
  4. 创建 symlinks 到 /boot
  5. 添加自定义的功能到initramfs
  6. 压缩initramfs

安装

1
emerge -av sys-kernel/genkernel

Genkernel用一般用法为

1
genkernel --选项 动作

选项

Genkernel选项有很多大部分可以在/etc/genkernel.conf 这个文件中找到,在使用genkernel的时候命令行给定的参数优先级别是比/etc/genkernel.conf文件中的参数优先级高

用户交互选项

选项描述
–config=/path/to/genkernel.conf指定配置文件。如果不实用这个选项默认使用的是/etc/genkernel.conf配置文件
–[no-]menuconfig在开始构建内核之前,激活或者是停用(make menuconfig)命令 这个命令会启动交互式配置菜单
–gconfig这个提供了依赖于GTK+库的内核配置程序。这个好处是用这个工具配置更加容易和清楚,不好的地方就是需要X Windows的支持没办法运行在命令行下面
–xconfig--gconfig选项类似,不过这个是基于QT的
–[no-]save-config是否将内核配置保存到/etc/kernels目录下,建议开启方便以后备份和使用。
–kernname=NickName允许修改/boot目录中的内核和initramfs的名称,生成的类似这种格式kernel-nickname-versioninitramfs-nickname-version

系统选项

此处列出的配置选项定义哪些功能会或不会在生成内核和 initramfs 中启用。

选项描述
–[no-]splash是否在initramfs中激活Fbsplash缓冲帧的支持。要覆盖fbsplash使用的默认主题,请使用--splash=PreferredTheme(其中PreferredTheme/etc/splash目录中目录之一的标题,你可以选择其他的)。
–splash-res=PreferredResolution这个选项允许系统在启动的时候准备挂载/阶段的分辨率。为了缩小initramfs的大小尽量选择系统支持的分辨率其他的分辨率就关掉(如果你是打算给livecd编译内核最好是省略这个选项)
–do-keymap-auto在启动过程中强制选择键盘映射
–lvm如果你有使用LVM逻辑卷管理请启用这个选项。(在启用之前确保系统已经安装了sys-fs/lvm2的包)
–dmraid这个选项包含了对DMRAID的支持,如果你在使用DMRAID作为/文件系统请确保开启了这个选项
–luks这个选项包含了对LUKS的支持,这个选项是我现在所需要的因为开启了LUKS加密,这个选项让initramfs加入了对LUKS的工具支持。
–disklabel把对磁盘标签和对UUID的支持加入到initramfs
–iscsi添加iscsi的支持到initramfs
–multipath添加multipath的支持到initramfs
–linuxrc=/path/to/the/linuxrc_file这个选项可以指定一个用户创建的linuxrc文件(这个文件在内核启动阶段,实际引导过程之前的初始化脚本)。这个脚本可以在/usr/share/genkernel/下找到默认的脚本
–cachedir=/path/to/alt/dir重新编译内核时候使用的默认缓存位置
–tempdir=/path/to/new/tempdir指定编译内核的时候genkernel使用的临时目录位置
–unionfs在 initramfs镜像中包含统一文件系统的支持。
–mountboot是否要将/boot挂载到单独的分区上。这个会检查/etc/fstab里面的内容来获取挂载引导分区的说明(如果你需要的话)。
–microcode为Xen和Linux早期微码支持创建一个Intel/Amd处理器微码的早期cpio

构建选项

Genkernel 支持下面这些选项,并且在构建内核的时候将其传给相关的应用程序。

选项说明
–kernel-cc=someCompiler指定内核在编译时候使用的编译器
–kernel-ld=someLinker指定内核编译过程中使用的链接器
–kernel-as=someAssembler指定内核编译过程中使用的汇编程序
–kernel-make=someMake指定内核编译过程中使用的Make程序的替代方法
–utils-cc=someCompiler指定在编译实用工具过程中使用的编译器
–utils-ld=someLinker指定在编译实用工具过程中使用的链接器
–utils-as=someAssembler指定在编译实用工具过程中使用的汇编程序
–utils-make=someMake指定在编译实用工具过程中使用的Make程序的替代方法
–makeopts=-jX指定编译内核和实用工具时候的并发线程数。(通常是线程数+1)

在编译过程中起作用的选项

下面这些选项通常在编译过程中生效:

选项说明
–kerneldir=/path/to/sources/指定内核源码的位置,可以不是默认的/usr/src/linux目录
–kernel-config=/path/to/config-file指定内核使用的配置文件。默认情况下会在 --kerneldir中找到的内核版本,并在/etc/kernel/下面找到对应的内核版本。如果没有找到genkernel将会在/usr/share/genkernel/$arch/下面找通用的内核配置。
–module-prefix=/path/to/prefix-directory/指定要安装内核模块的目录。(默认是/lib/modules)
–[no-]clean在编译内核之前执行或者是不执行make clean命令。
–[no-]mrproper在内核编译之前启用或停用make mrproper命令。像是之前的make clean命令类似的这个命令会删除所有目标文件和依赖项但是除了这些还会删除旧的配置文件。如果你不想要删除你的旧内核配置文件请保持这个选项关闭
–oldconfig发出make oldconfig命令,这个命令将会尝试从/usr/share/genkernel/中的通用脚本收集系统的信息。这是一个非交互的过程:没有用户输出。(如果和--clean结合使用后面的--clean将会失效)
–[no-]module-rebuild在构建内核和内核模块之后,运行或者是不运行emerge @module-rebuild来构建额外的模块(比如说virtualbox的模块)。默认的情况下启用这个选项
–callback=“echo hello”在构建内核和内核模块之后,但是在构建initramfs之前,调用指定的参数在这个例子里面为 hello
–[no-]install激活或者是取消make install命令,这个命令将会把内核文件和initrafms文件copy到引导分区。
–no-ramdisk-modules避免将任何模块复制到genkernel创建的initramfs中。
–all-ramdisk-modules将所有可用的模块全部复制到genkernel创建的initramfs中。
–genzimage在创建内核之前先创建initramfs(这个只适用于PPC)

debug 参数

在内核编译过程中可以通过调整debug参数来控制输出的信息和显示方式。

选项说明
--loglevel=<0|1|2|3|4|5>控制genkernel打印信息的详细程度。变量loglevel是0-5之间的整数。0代表无输出5代表在内核编译和制作initramfs过程中尽可能提供更多的信息
–logfile=/path/to/output_fileGenkernel默认的输出的日志文件。默认的输出在/var/log/genkernel.log
–[no-]color激活或者是取消带颜色输出
–[no-]cleanup激活或取消运行后的清理,从而达到调试的目的

动作

Genkernel 支持以下操作:

动作描述
all构建所有的东西,包括initramfskernelmodules
bzImage只构建内核的镜像
kernel只构建内核镜像和模块
initramfs只构建initramfs

配置

Genkernel 给用户提供了一个最简单的方法那就是genkernel all但是会生成大量不必要的模块,这里有一个适用于大多数系统的通用配置:

1
genkernel --luks --no-install --no-clean --menuconfig all

上面这条命令就是创建了一个可以支持LUKS的initramfs,但是内核和initramfs都不会被安装到引导分区后面的--menuconfig将会打开交互式配置工具,从而进行交互式配置。 在交互界面如果你是老手你可以开始配置你的内核,如果你是新手这次我们先选择退出按esc会提示是否保存配置文件,我们选择保存,就会开始构建新的内核以及initramfs

等到构建完成之后可以看/var/tmp/genkernel/下面这里面就是我们构建的内核以initramfs文件了。

1
2
ls /var/tmp/genkernel/
System.map-x86_64-5.4.80-gentoo-r1-x86_64  initramfs-x86_64-5.4.80-gentoo-r1-x86_64  kernel-x86_64-5.4.80-gentoo-r1-x86_64

除了这种交互式的配置还可以通过修改配置文件来减少刚开始配置内核的工作量,还记得genkernel的默认配置文件位置吗?我们将会复制一份在此基础上进行修改来生成我们的第一份内核配置文件。

首先创建我们的工作目录

1
2
mkdir -pv /tmp/workdir
cd /tmp/workdir

复制一份默认的配置文件

1
cp -v /etc/genkernel.conf .

修改配置文件

1
nano -w genkernel.conf

内容如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
INSTALL="no"
OLDCONFIG="yes"
MENUCONFIG="yes"
MRPROPER="no"
CLEAN="yes"
SAVE_CONFIG="yes"
NOCOLOR="false"
LUKS="yes"
MICROCODE="intel"
MICROCODE_INITRAMFS="yes"
BUSYBOX="yes"
E2FSPROGS="yes"
GK_SHARE="${GK_SHARE:-/usr/share/genkernel}"
CACHE_DIR="/var/cache/genkernel"
DISTDIR="${GK_SHARE}/distfiles"
LOGFILE="/var/log/genkernel.log"
LOGLEVEL=1
DEFAULT_KERNEL_SOURCE="/usr/src/linux"

再次生成内核文件和initramfs文件:

1
genkernel --config=genkernel.conf all

到这里你就有了一份基本的内核配置并且已经可以启动了(大概率),但是网卡之类的可能还是不能正常工作。这个时候就需要针对于自己的硬件去查找对于的配置了。 这里我推荐你查看金步国配置内核选项介绍这篇文档,来去配置你的内核,当然内核配置和我们现在安装的选项有很大的不同了,还需要再去搜索内核文档这些选项的意义。 如果你有充足的时间我建议你可以尝试使用make config然后使用Google搜索。

使用gentoo-kernel-bin配置内核

gentoo-kernel-bin就是上游打好的内核如果想要快速进入系统,后面再去慢慢配置内核这个内核也是一个不错的选项。

安装

1
emerge -av sys-kernel/gentoo-kernel-bin

安装完成之后内核以及initramfs已经在/boot下面了。

使用已有的配置文件配置内核

我这里有一份配置好的内核配置,功能上已经调好了,内核使用的是gentoo-sources内核

在安装内核之前我们要先设置一下gentoo-sources的USE

1
echo "sys-kernel/gentoo-sources experimental symlink" > /etc/portage/package.use/gentoo-sources

symlink可以当更新内核的时候自动将最新的内核软连接到/usr/src/linux目录。 experimental 这个可以针对CPU来进行优化,和一些实验性特性,详细可以参考这里 现在我们可以安装内核了

1
emerge --ask --verbose gentoo-sources

首先进入内核文件夹

1
cd /usr/src/linux

下载我的内核配置文件

1
wget -O .config  https://raw.githubusercontent.com/yafa-xena/dotfiles/main/etc/kernels/config-5.4.80-gentoo-r1-x86_64

使用make oldconfig去生成一份新的配置文件

1
make oldconfig

也许你需要在我这个内核基础上再去做一些修改

1
make menuconfig

修改工作完成之后可以运行以下命令生成新的内核和模块并将其安装到/boot目录下

1
2
3
make -j9
make modules_install
make install

生成initramfs

initramfs其实是initrd的替代品,它是一个临时的文件系统,它在启动阶段被linux内核调用。initrd主要当作/文件系统被挂载之前做准备工作。 如果你将必要的驱动都build in内核是可以不要initramfs的,这里我使用的LUKS全盘加密,需要initramfs阶段来解开LUKS分区。

生成initramfs的方式也有很多,这里我会介绍以下2种方式生成initramfs:

  1. genkernel
  2. Dracut

genkernel

在之前genkernel安装的内核的时候已经介绍的非常详细了如果你想要单独生成一个initramfs可以使用这条命令

1
genkernel --luks initramfs

--luks这个参数是因为我这次安装是用到了luks所以要在initramfs中加入LUKS的工具支持。

除此之外还要安装sys-fs/cryptsetup这个包,不然重启之后由于缺少这个工具还是没办法正常使用

1
emerge -av sys-fs/cryptsetup

Dracut

安装

1
emerge -av  sys-kernel/dracut

构建initramfs 首先确保你的/boot分区已经挂载了

1
dracut

这样不加任何参数将会创建一个通用的initrmafs 如果你想要只为这个机器创建initrmafs可以加--hostonly

1
dracut --hostonly

dracut还有很多额外的模块,像是这次安装我们就需要用到crypt模块,还有很多模块如下表:

模块名称描述Enable?额外包
dash包含了/bin/dash/bin/shalways
i18n包含了键盘布局,console的字体等等always
rpmversioninitramfs中包含dracut的版本信息/etc/redhat-release 存在的时候这个模块会被打开
convertfs在下一次启动中将 / 合并到 /usrnever
kernel-modules包含用于/文件系统和其他设备启动时设备的内核模块always
fstab-sys安排在rootfs之前挂载任意分区/etc/fstab.sys存在的时候,或者是命令行包含--fstab 或者是--add_fstab时。
resume允许initramfs 从低功耗模式状态恢复。当存在swap分区的时候
rootfs-block安排包含要挂载rootfs的块设备。always
terminfo包含terminfo文件always
udev-rules包含一些非常基本的udev规则always
securityfs安排尽早挂载securityfsnever
usrmount安排挂载 /usralways
base包含大部分基本的工具always
fs-lib包含了文件系统工具(包括mount命令)always
img-lib包含了用于解压图像的工具never
shutdown设置用于关机的hookalways
biosdevname开启BIOS网络设备的重命名always需要安装sys-apps/pciutilssys-apps/biosdevname
btrfsbtrfs文件系统的支持host-only: rootfssys-fs/btrfs-progs
caps支持在初始化之前删除功能systemd init 不使用sys-libs/libcap
crypt支持全盘加密rootfshost-only: rootfssys-fs/cryptsetup这里我们使用了LUKS加密所以还要安装这个包
crypt-gpg将GPG用于crypt支持(需要crypt模块)neverapp-crypt/gnupg
dmraid支持rootfs在FakeRAID上host-only: rootfssys-fs/multipath-tools, sys-fs/dmraid
dmsquash-live支持LiveCD的rootfsnever (host-only: refused)
gensplash包含一个静态启动画面nevermedia-gfx/splashutils在官网的portage树已经找不到了
iscsirootfs在iscsi设备上的支持host-only: rootfssys-block/open-iscsi
livenet通过HTTP检索rootfs需要dmsquash-live模块never
lvm支持rootfs在LVM逻辑卷管理上host-only: rootfssys-fs/lvm2
mdraid支持rootfs在软RAID上host-only: rootfssys-fs/mdadm
multipath支持rootfs在多路径上host-only: rootfssys-fs/multipath-tools
nbd支持rootfs在网络块设备上host-only: rootfssys-block/nbd
nfs支持NFS挂载rootfshost-only: rootfsnet-fs/nfs-utilsnet-nds/rpcbind
plymouth包含启动动画alwayssys-boot/plymouth
ssh-client包含ssh和scp客户端neverdev-libs/openssl
syslog包含远程登陆日志neverapp-admin/syslog-ng或者是rsyslog
debug包含常用的故障排除工具never安装Dracut时候开启 USE=debug
dm包含 device-mapperneversys-fs/device-mapper 或者是 sys-fs/lvm2
ifcfg在运行时候生成网络配置never
network为网络启动启用网络alwaysnet-misc/dhcpsys-apps/iproute2
selinux安排要加载的Selinux策略当安装开启 USE=selinux的时候
url-lib包含curl命令和SSL证书nevernet-misc/curl

设定配置文件 主配置文件默认在/etc/dracut.conf

我这里创建一个全新的文件来做dracut的配置

1
nano -w /etc/dracut.conf.d/yafa.conf

内容如下

1
2
3
4
hostonly="yes"
compress="xz"
add_drivers+=" i915 "
omit_dracutmodules+=" resume crypt base dash "

保存并退出

生成initramfs文件

1
dracut --kver 5.4.80-gentoo-r1-x86_64 /boot/initramfs.img

安装bootload

这里使用的bootload是GRUB

安装

1
emerge --ask --verbose sys-boot/grub

安装grub到引导分区

1
grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=Gentoo

因为我们使用LUKS还需要对grub进行配置

1
nano -w /etc/default/grub

按Ctrl+w 进入查找模式输入 GRUB_CMDLINE_LINUX回车,去掉掉这行的注释(删除#号) 修改内容如下

1
GRUB_CMDLINE_LINUX="crypt_root=UUID=dbdff0d5-0c06-44b8-9879-a56400c80135  root=/dev/mapper/root root_trim=yes rhgb  alpha_support=1 loglevel=7"

分别来说一下添加这些内容的含义

crypt_root=UUID=dbdff0d5-0c06-44b8-9879-a56400c80135 这个是LUKS分区的UUID可以用过lsblk查看:例如

1
2
3
4
5
6
7
/dev/nvme0n1p1: UUID="46CB-9AA9" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="72c3ee7b-0dd2-0a40-905b-aac98ac8595c"
/dev/nvme0n1p2: UUID="dbdff0d5-0c06-44b8-9879-a56400c80135" TYPE="crypto_LUKS" PTTYPE="atari" PARTUUID="5204fbd0-506e-9544-9c6f-a97c6eb3db9b"
/dev/sdb1: BLOCK_SIZE="2048" UUID="2020-10-22-14-30-30-00" LABEL="Ubuntu 20.10 amd64" TYPE="iso9660" PARTLABEL="ISO9660" PARTUUID="7ee1ffac-4072-46b8-885f-a7ea3f9c70cf"
/dev/sdb2: SEC_TYPE="msdos" LABEL_FATBOOT="ESP" LABEL="ESP" UUID="F366-AE33" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="Appended2" PARTUUID="7ee1ffac-4072-46b8-885c-a7ea3f9c70cf"
/dev/sdb4: LABEL="writable" UUID="7de65921-149d-4ed6-bb21-aa48ed19953a" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="c34a7c6d-268d-5b40-91f1-e4e268a26a40"
/dev/mapper/system: UUID="7e664075-eedd-4d1a-9218-ac4c6471b033" BLOCK_SIZE="4096" TYPE="ext4"
/dev/sdb3: PARTLABEL="Gap1" PARTUUID="7ee1ffac-4072-46b8-885d-a7ea3f9c70cf"

这里的话/dev/nvme0n1p2就是LUKS分区所在的UUID不要复制错了

root=/dev/mapper/root 这个是解开LUKS分区后的默认位置 root_trim=yes 开启ssd的trim功能 rhgb 详细模式像是硬件检测之类的信息都会打印出来如果你不想要这些你可以设置为quite alpha_support=1 测试的支持 loglevel=7 内核debug模式 如果你不想要详细的输出可以尝试调成其他的数值0-7

保存退出

生成grub.cfg文件

1
grub-mkconfig -o /boot/grub/grub.cfg

配置fstab

配置fstab可以选择手写的方式也可以选择使用Archlinux的genfstab来生成fstab文件,个人比较推荐用Archlinx的genfstab来去做,减少人工输入的错误。

手写的方式配置fstab

基本语法 /etc/fstab这个文件中每行都包含一个分区,驱动器或者是网络共享必须要设置。每行有6列,由空格和制表符分割。列内容如下:

  1. 设备文件,UUID或者是标签或者是其他找到分区或数据源的方法
  2. 将分区或者是数据源挂载到的目录
  3. 文件系统类型
  4. 选项,包括是否在引导阶段挂载系统
  5. 调整分区的存档计划(app-arch/dump使用)。0为禁用,1为启用该功能。
  6. 控制fsck在引导时检查设备/分区是否有错误,根分区应该是1。 其他的分区应该是2 (用于在root之后检查)用0就是完全不检查。 e.g.
1
<file system> <mount point>   <type>  <options>       <dump>  <pass>

让我们一起写一个很简单的挂载/分区的例子,首先查看一下当前分区的UUID

1
2
3
4
5
6
7
8
blkid
/dev/nvme0n1p1: UUID="46CB-9AA9" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="72c3ee7b-0dd2-0a40-905b-aac98ac8595c"
/dev/nvme0n1p2: UUID="dbdff0d5-0c06-44b8-9879-a56400c80135" TYPE="crypto_LUKS" PTTYPE="atari" PARTUUID="5204fbd0-506e-9544-9c6f-a97c6eb3db9b"
/dev/sdb1: BLOCK_SIZE="2048" UUID="2020-10-22-14-30-30-00" LABEL="Ubuntu 20.10 amd64" TYPE="iso9660" PARTLABEL="ISO9660" PARTUUID="7ee1ffac-4072-46b8-885f-a7ea3f9c70cf"
/dev/sdb2: SEC_TYPE="msdos" LABEL_FATBOOT="ESP" LABEL="ESP" UUID="F366-AE33" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="Appended2" PARTUUID="7ee1ffac-4072-46b8-885c-a7ea3f9c70cf"
/dev/sdb4: LABEL="writable" UUID="7de65921-149d-4ed6-bb21-aa48ed19953a" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="c34a7c6d-268d-5b40-91f1-e4e268a26a40"
/dev/mapper/system: UUID="7e664075-eedd-4d1a-9218-ac4c6471b033" BLOCK_SIZE="4096" TYPE="ext4"
/dev/sdb3: PARTLABEL="Gap1" PARTUUID="7ee1ffac-4072-46b8-885d-a7ea3f9c70cf"

以及挂载点

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sdb           8:16   1  57.8G  0 disk
|-sdb1        8:17   1   2.8G  0 part
|-sdb2        8:18   1   4.9M  0 part
|-sdb3        8:19   1   300K  0 part
`-sdb4        8:20   1  55.1G  0 part
nvme0n1     259:0    0   1.9T  0 disk
|-nvme0n1p1 259:1    0    64M  0 part  /boot
`-nvme0n1p2 259:2    0   1.9T  0 part
  `-system  253:0    0   1.9T  0 crypt /

我们可以看到这个/dev/mapper/system这个分区是挂载在/下面的其分区UUID为7e664075-eedd-4d1a-9218-ac4c6471b033那么我们可以这样写fstab

1
/dev/mapper/system      /               ext4            defaults    0 1

也许你注意到了这里有个 defaults参数这个是干嘛的?这个是给使用的文件系统传输挂载的选项,许多都是通用的但是有些选项是特定文件系统才有的,这个说起来有点复杂请看下面这个表格:

选项说明
defaults使用默认挂载选项 rw,suid,dev,exec,auto,nouser,async
auto在启动的时候自动挂载文件系统
noauto不在启动的时候自动挂载文件系统(这个通常为了安全可以这样设置,比如说boot下面存LUKS的KEY)
ro以只读的方式挂载文件系统
rw读写的方式挂载文件系统
sw挂载swap文件系统
atime每次读取的时候更新inode的访问时间
relatime仅在写入时更新inode的访问时间以提高性能
noatime从不更新inode的访问时间来获得最高性能
sync在每次写入之后同步到设备。这个可能会缩短SSD的寿命
async异步同步驱动器
discard等于开启了trim的支持
exec允许执行二进制文件
noexec不允许执行二进制文件
suid跟随SUIDSGID位。
nosuid不跟随SUIDSGID
user允许用户挂载文件系统
users允许每个用户挂载文件系统
nouser只允许root用户挂载文件系统

这些选项可以根据你的需要来灵活调整。

genfstab方式配置fstab

可以从我的dotfiles里面找到这个genfstab脚本

1
2
wget -c O /usr/bin/genfstab https://raw.githubusercontent.com/yafa-xena/dotfiles/main/usr/bin/genfstab
chmod +x /usr/bin/genfstab

生成fstab格式的输出

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
genfstab -U / 
# /dev/mapper/system
/dev/mapper/system      /               ext4            rw,relatime     0 1

# /dev/nvme0n1p1
/dev/nvme0n1p1          /boot           vfat            rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2

# cgroup2
cgroup2                 /sys/fs/cgroup/unified  cgroup2         rw,nosuid,nodev,noexec,relatime,nsdelegate      0 0

# efivarfs
efivarfs                /sys/firmware/efi/efivars       efivarfs        rw,nosuid,nodev,noexec,relatime 0 0

# none
none                    /sys/fs/bpf     bpf             rw,nosuid,nodev,noexec,relatime,mode=700        0 0

# tracefs
tracefs                 /sys/kernel/debug/tracing       tracefs         rw,nosuid,nodev,noexec,relatime 0 0

# tracefs
tracefs                 /sys/kernel/tracing     tracefs         rw,nosuid,nodev,noexec,relatime 0 0

将输出追加到/etc/fstab文件中

1
genfstab -U / >> /etc/fstab

这里有很多不需要的可以删除掉类似tracefscgroup2none等等,精简后的fstab文件如下

1
2
3
4
5
# /dev/mapper/system
/dev/mapper/system      /               ext4            rw,relatime     0 1

# /dev/nvme0n1p1
/dev/nvme0n1p1          /boot           vfat            rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2

到这里fstab的配置就算是完成了。

安装网络组件

为了重启之后机器还能够正常上网和排障,所以这里还需要安装一个网络组建,我这里更倾向于NetwrokManager这个网络组建,当然你也可以选择其他的网络组件

安装

1
emerge -av networkmanager

启动

1
rc-update add NetworkManager default

设置主机名

编辑/etc/conf.d/hostname 修改内容如下

1
2
# Set to the hostname of this machine
hostname="yafa"

你可以将yafa设置成你喜欢的名字

添加和设置管理员账户

现在我们可以给root用户设置密码了

1
passwd root

注意输入密码是没有回显的

但是日常用root操作还是太过于危险了,我们需要创建一个管理员用户作为我们日常的使用:

1
useradd -m -G users,wheel,portage,usb,video,tty xena 

xena 是我的用户名你可以换成你的

设置密码

1
passwd xena

注意输入密码是没有回显的

为了实现临时的超级管理员权限我们还需要安装一个包

1
emerge -av app-admin/sudo

配置sudo

1
sed -i 's/\# \%wheel ALL=(ALL) ALL/\%wheel ALL=(ALL) ALL/g' /etc/sudoers

这样在wheel组的用户在使用sudo的时候输入密码的时候就可以使用root的权限运行了。

安装网络组件

可以选择使用dhcp或者是NetworkManager服务去管理服务

dhcp

1
emerge -av dhcpcd 

开机启动

1
rc-update add dhcpcd default

networkmanager

安装:

1
emerge -av networkmanager

开机启动:

1
rc-update add NetworkManager default

安装系统推荐组件

安装记录日志的程序

1
emerge -av app-admin/sysklogd

加入到开机启动

1
rc-update add sysklogd default

定时任务

cron可以做定时任务,比如说每天,每周,每个月执行什么操作非常方便,建议安装。

安装定时任务

1
emerge --ask sys-process/cronie

加入到开机启动

1
rc-update add cronie default

文件索引

1
emerge --ask sys-apps/mlocate

远程访问(可选)

开机启动openssh-server

1
rc-update add sshd default

备份和清理工作

清理

删除之前下载的stage3文件

1
rm -rf /stage3-amd64-*

配置文件备份

可以暂时在/root下创建一个备份的文件夹用于备份

1
mdkir -pv /root/dotfiles

复制我们所修改的文件到这个文件夹

1
2
3
4
5
cp -v /etc/conf.d/hostname /root/dotfiles
cp -v /etc/dracut.conf /root/dotfiles
cp -v /etc/locale.gen /root/dotfiles
cp -v /usr/src/linux/.config /root/kernel-config
cp -v /tmp/workdir/genkernel.conf /root/dotfiles

重启

现在可以准备重启了,我们先要退出chroot环境

1
exit

然后卸载文件系统

1
umount -R /mnt/gentoo

最后重启

1
reboot

在重启过grub的时候会提示让输入LUKS卷的密码输入之后就应该可以正常引导系统了! 但是现在只是基础的系统,距离我们想要用的桌面还还差一点。

故障排除

有的时候会遇到一些错误,这里记录一下可能遇到的错误以及如何处理。

安装和配置桌面

这里安装的桌面为KDE桌面,为了方便安装我们首先要切换一下系统的配置文件:

1
eselect  profile  set "default/linux/amd64/17.1/desktop/plasma"

更新系统

1
emerge --ask --verbose --deep --with-bdeps=y --newuse --update @world

在更新完成之后我们来安装桌面和必要的包

安装KDE桌面及应用

KDE 这里安装的是整个KDE+完整的应用:

1
emerge --ask kde-plasma/plasma-meta kde-apps/kde-apps-meta

配置KDE启动

这次启动我不打算用DM去管理改用startx的方式。

创建并编辑~/.xinitrc文件:

1
nano -w ~/.xinitrc

内容如下

1
2
3
4
5
#!/bin/bash

eval "$(dbus-launch --sh-syntax --exit-with-session)"
[ -f "$HOME/.xprofile" ] && . ~/.xprofile
exec dbus-launch --exit-with-session startplasma-x11

接下来我们还要创建一个~/.xprofile文件:

1
nano -w ~/.xprofile

内容如下:

1
2
3
4
5
6
7
#!/bin/sh
# Fcitx
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
export GTK_IM_MODULE DEFAULT=xim
export QT_IM_MODULE  DEFAULT=xim

保存退出。 现在输入startx之后就可以启动桌面了。

现在我们已经算是安装完成了ww。

最后的话

这次历时4天的安装体验让我学到了很多,像是Linux的启动流程,Initramfs,内核配置,桌面配置等等。 感受了Gentoo Linux的魅力,虽然这篇文章到这里就结束了,但是这也是我使用Gentoo Linux的开始。 感谢学姐送的Mac,同时也感谢Telegram Gentoo-zh群组热心大神的支持! 是时候回到工作了!

参考文档