阅读更多
1 镜像站
1.1 网易开源镜像站
以CentOS-7.7.1908为例,下载地址为:http://mirrors.163.com/centos/7.7.1908/isos/x86_64/CentOS-7-x86_64-Minimal-1908.iso
1.2 阿里云镜像站
以ubuntu-18.04.6为例,下载地址为:https://mirrors.aliyun.com/ubuntu-releases/bionic/ubuntu-18.04.6-desktop-amd64.iso
1.3 centos镜像站
以CentOS-7.7.1908为例,下载地址列表为:http://isoredirect.centos.org/centos/7.7.1908/isos/x86_64/
2 CentOS装机
博主安装的是minimal版本
- 配网,修改
/etc/sysconfig/network-scripts/ifcfg-enp0s3,将ONBOOT修改为yes,然后执行systemctl restart network - 安装网络工具包
yum install -y net-tools.x86_64 - 安装vim
yum install -y vim
2.1 配置分区容量
默认情况下,CentOS会给根分区分配50G的容量,剩余容量则分配给home分区,我们可以通过一组命令简单得调整一下分区容量
仍然保留两个分区,将大部分的容量都分配给根分区
1 | # 1/11: 备份home分区文件 |
只保留根分区,/home只作为根分区的一个目录
1 | # 1/9: 备份home分区文件 |
2.2 LVM扩容
2.2.1 fdisk
1 | fdisk -l |
2.2.2 parted
fdisk最多只能添加容量小于2TB的硬盘,当需要添加大于2TB容量的硬盘时,需要使用parted
1 | fdisk -l |
2.3 LVM缩容
缩容需谨慎,一不小心就会导致系统整个无法使用
1 | # 将lvm的容量缩小 |
2.4 修复因断电导致磁盘inode损坏
步骤
- 进入
emergency模式- 在CentOS的boot菜单下按
e,并编辑grub命令,在linux16配置项最后追加systemd.unit=emergency.target,按Ctrl+x即可进入emergency模式 
- 在CentOS的boot菜单下按
- 找到
Linux LVM的根分区地址和设备 cat /etc/fstab确定根分区文件系统类型,通常为ext4或xfs- 若文件系统为
ext4,运行fsck -f,例如fsck -f /dev/mapper/centos-root - 若文件系统为
xfs,运行xfs_repair -v /dev/mapper/centos-root- 针对根分区已加载的情况下,可以执行
xfs_repair -d /dev/mapper/centos-root尝试修复 - 如果修复失败,可以添加参数
-L进行修复,但是这样会丢失一部分文件系统日志,不建议一开始就尝试,可以作为最终解决方案
- 针对根分区已加载的情况下,可以执行
- 若文件系统为
2.5 忘记root密码
方法1
- 进入
Single User && Emergency模式- 在CentOS的boot菜单下按
e,并编辑grub命令,在linux16配置项最后追加rw init=/sysroot/bin/bash,按Ctrl+x即可进入rw表示以可读写的方式挂载根分区init=/sysroot/bin/bash:系统安装所在分区里面路径为/bin/bash的文件,内核启动过程中会查找系统安装所在分区,然后把该分区挂载到/sysroot目录下

- 在CentOS的boot菜单下按
- 修改密码
chroot /sysrootpasswd:修改密码,键入两次新密码即可touch /.autorelabelexitreboot -f
touch /.autorelabel这个命令有什么作用:当我们用passwd修改密码时,/etc/shadow文件会在错误的SELinux上下文中被修改。touch /.autorelabel命令会创建一个隐藏文件,在下次启动时,SELinux子系统将检测到该文件,然后使用正确的SELinux上下文重新标记文件系统上的所有文件。在大磁盘上,此过程可能消耗大量的时间
方法2
- 进入
Single User模式- 在CentOS的boot菜单下按
e,并编辑grub命令,在linux16配置项最后追加init=/bin/bash,按Ctrl+x即可进入init=/bin/bash:内核启动过程中临时文件系统(initrd.img)里面路径为/bin/bash的文件

- 在CentOS的boot菜单下按
- 修改密码
mount -o remount,rw /:重新以rw的方式挂载根分区(因为这次,我们没有在内核参数中增加rw参数)passwd:修改密码,键入两次新密码即可touch /.autorelabel/sbin/reboot -f
方法3
- 进入
Single User && Emergency模式- 在CentOS的boot菜单下按
e,并编辑grub命令,在linux16配置项最后追加rd.break,按Ctrl+x即可进入rd.break:rd指的是init ram disk;break指的是boot程序在将控制权从initramfs转交给systemd之前进行中断

- 在CentOS的boot菜单下按
- 修改密码
mount -o remount,rw /sysroot:重新以rw的方式挂载根分区(因为这次,我们没有在内核参数中增加rw参数)chroot /sysrootpasswdtouch /.autorelabelexitreboot -f
2.6 恢复boot分区
当boot分区不小心被破坏之后(比如,用fdisk将boot分区误删了),机器是无法启动成功的,会出现如下错误页面

可以通过以下步骤进行恢复
第一步:找到系统的iso,并制作u盘启动盘。插入u盘后开机
第二步:在grub菜单页,依次选择Troubleshooting、Rescue a CentOS system
第三步:从u盘启动linux系统,并获取shell
第四步:重新安装grub以及grub配置文件
1 | # 硬盘的挂载点是/mnt/sysimage |
第五步(可选):这一步取决于boot分区是如何被破坏的,如果整个分区都删掉了,那么需要修改/etc/fstab将/boot分区的配置项注释掉,然后重启
2.7 概念理解
- 物理卷(physics volume)
- 可以用
pvdisplay查看逻辑卷
- 可以用
- 卷组(volume group)
- 可以用
vgdisplay查看逻辑卷
- 可以用
- 逻辑卷(logical volume)
- 可以用
lvdisplay查看逻辑卷 - 上面出现的
/dev/centos/root就是逻辑卷,而/dev/mapper/centos-root其实是一个逻辑磁盘(dm就是device mapper的缩写)/dev/mapper/centos-root其实是个链接文件,链接到了/dev/dm-0,在你的电脑上可能不是0dmsetup info /dev/dm-0可以查看/dev/dm-0的信息sudo lvdisplay|awk '/LV Name/{n=$3} /Block device/{d=$3; sub(".*:","dm-",d); print d,n;}'可以查看映射关系
- 可以用
2.8 参考
- CentOS 7 调整 home分区 扩大 root分区
- 手把手教你给 CentOS 7 添加硬盘及扩容(LVM)
- Linux Creating a Partition Size Larger Than 2TB
- What is this dm-0 device?(/dev/mapper/centos-root以及/dev/dm-0)
- centos7中的网卡名称相关知识
- What does /.autorelabel do when we reset the password in Red Hat?
- Reset lost root password
- How to Boot into Single User Mode in CentOS/RHEL 7
- Three Methods Boot CentOS/RHEL 7/8 Systems in Single User Mode
- CHAPTER 26. WORKING WITH GRUB 2
3 CentOS自定义发行版iso镜像制作
3.1 初次尝试制作镜像
在本小节,我们将iso镜像文件解压,然后将解压之后的文件原封不动地打成iso镜像,目的是为了熟悉镜像制作的各个命令行工具
为了减少环境因素对镜像制作造成的影响,这里使用docker容器来进行打包,DockerFile如下,非常简单,基础镜像为centos:7.6.1810,并用yum安装了镜像制作的相关工具
1 | FROM centos:7.6.1810 |
接下来制作docker镜像
1 | docker build -t create-iso-env:1.0.0 . |
我们先研究一下官方的iso文件的结构,我下载的是CentOS-7-x86_64-Minimal-1908.iso,解压之后,目录结构如下(rpm包太多了,这里省略掉)
1 | . |
运行docker。这里挂载了3个目录
/Users/hechenfeng/Desktop/source/CentOS-7-x86_64-Minimal-1908:该目录是我解压iso文件之后得到的目录,对应于容器中的/source目录/Users/hechenfeng/Desktop/workspace:该目录是镜像制作的工作目录,对应于容器中的/workspace目录/Users/hechenfeng/Desktop/iso:该目录用于放置生成的iso文件,对应于容器中的/target目录
1 | docker run \ |
以下命令均在容器中执行
第一步:将/source目录中的内容,拷贝到/workspace目录中
1 | # 删除除了. ..之外的所有文件以及目录,包括隐藏文件以及隐藏目录 |
第二步:根据comps.xml制作本地repo。这里有一个坑,官方的CentOS镜像解压后,是不存在comps.xml这个文件的,这个文件存在于repodata目录中(容器中的路径为/workspace/repodata),且名字是一个随机字符串。可以通过如下命令将该文件重命名且移动至上层目录,然后重新制作本地repo。此外,也可以从CentOS的官方文档中下载comps.xml文件
1 | # 找到该comps.xml文件 |
第四步:接下来,就可以制作镜像了,详细流程可以参考RedHat文档
1 | fileName=/target/my-centos-1.iso |
3.2 修改发行版信息
我们重新运行一个容器来制作镜像
1 | docker run \ |
以下命令均在容器中执行
第一步:将/source目录中的内容,拷贝到/workspace目录中
1 | # 删除除了. ..之外的所有文件以及目录,包括隐藏文件以及隐藏目录 |
第二步:修改标签以及标题
1 | originalLabelEscape="CentOS\\\\x207\\\\x20x86_64" |
第三步:根据comps.xml制作本地repo
1 | # 找到该comps.xml文件 |
第四步:制作镜像
1 | fileName=/target/my-centos-2.iso |
3.3 使用kickstart定制化安装流程
在正常装机完成之后,会有一个/root/anaconda.ks文件,其内容如下。我们的kickstart文件可以参考这个文件的内容来编写
1 | #version=DEVEL |
我们重新运行一个容器来制作镜像
1 | docker run \ |
以下命令均在容器中执行
第一步:将/source目录中的内容,拷贝到/workspace目录中
1 | # 删除除了. ..之外的所有文件以及目录,包括隐藏文件以及隐藏目录 |
第二步:编写kickstart文件,路径为/workspace/liuyehcf.ks,相比于上面展示的/root/anaconda.ks,改造点如下
- 禁用了root账号
- 增加了一个用户
liuyehcf,其密码为!Abcd1234,密文可以通过命令python3 -c 'import crypt; print(crypt.crypt("!Abcd1234", crypt.mksalt()))'获取 - 禁用自动分区,注释掉
autopart --type=lvm - 避免安装完成重启时,仍然从iso启动,增加
reboot --eject - 第一个post,将iso中的
EFI目录拷贝到操作系统中的/EFI目录(可以是任意文件或目录,这里用EFI来做示范)- 需要指定
--nochroot参数 /run/install/repo:iso的挂载点/mnt/sysimage:操作系统根目录的挂载点
- 需要指定
- 第二个post,执行一些定制化的步骤,这里是写了一个文件,
/root/greet
1 | cat > /workspace/liuyehcf.ks << 'EOF' |
第三步:修改配置文件,关联这个kickstart文件(/workspace/liuyehcf.ks)
1 | # ks文件的路径,工作目录/workspace,对iso来说就是根目录 |
第四步:根据comps.xml制作本地repo
1 | # 找到该comps.xml文件 |
第五步:制作镜像
1 | fileName=/target/my-centos-3.iso |
验证
- 装机的时候,只需要进行一步操作,磁盘分区,其他操作都是自动进行的
- 用
liuyehcf/!Abcd1234登录 - 检查
/EFI目录以及子文件子目录是否存在 - 检查
root/greet文件是否存在
3.4 Preboot Execution Environment, PXE
PXE安装的核心流程,下面拆分了DHCP Server、PXE Server、ISO Server,在实际情况中,这三者通常来说是同一个服务器
下面以一个简单的例子来演示一下如何搭建PXE环境,在示例中DHCP Server、PXE Server、ISO Server是同一台服务器。此外PXE有四种启动模式,分别为IPV4 legacy,IPV4 UEFI,IPV6 legacy,IPV6 UEFI,这里主要介绍IPV4 legacy启动模式需要的文件
3.4.1 预备工作
- 操作系统,我用的是
CentOS 7.6 - iso文件,我用的是
CentOS-7-x86_64-Minimal-1908.iso - 安装
dhcpdyum install -y dhcp
- 安装
tftpyum install -y tftp-server
- 安装
ftp/http、nfs中的任意一种,这里我选用ftpyum install -y vsftpd
3.4.2 配置并启动dhcp服务
1 | # 备份 |
allow booting:允许客户端在booting阶段查询host declarationallow bootp:允许对bootp query做出响应PXE相关配置PXE Server的ip是192.168.66.1- 启动引导器的文件名是
pxelinux.0
DHCP相关配置DHCP Server的ip是192.168.66.1- 广播地址是
192.168.66.255 - 可分配的IP范围是
192.168.66.2到192.168.66.254
3.4.3 配置并启动tftp服务
1 | # 清理tftp目录 |
3.4.4 配置并启动ftp服务
1 | # 清理ftp目录 |
3.4.5 编写pxelinux.cfg/default文件
1 | # 清理 |
3.4.6 编写kickstart文件
1 | cat > /var/ftp/iso/ks.cfg << 'EOF' |
- 配置从网络安装:
url --url="ftp://192.168.66.1/iso" - 镜像中的其他目录,可以在post阶段通过wget进行下载
3.4.7 关闭防火墙
关掉防火墙,避免dhcp、tftp、ftp、http等服务无法访问
1 | systemctl disable firewalld |
3.4.8 配置从网络启动
BIOS配置(仅供参考,不同机器的BIOS菜单可能差异很大)
NO Disk(PXE):改为enableCSM Configuration:Boot option filter:UEFI and LegacyNetwork:LegacyStorage:LegacyVideo:LegacyOther PCI devices:Legacy
3.5 其他
3.5.1 iso包含大文件(4G以上)
用genisoimage制作iso的时候,如果包含了超过4G的文件,那么需要加上参数-allow-limited-size。但是,这样会造成一个问题:如果iso中的某些文件在kickstart中会拷贝到目标的操作系统当中,那么这些文件的执行权限会丢失
如果包含了4G以上的文件,那就无法使用FAT32文件系统来制作U盘启动盘。但是我们可以使用split以及cat命令来拆分以及重建大文件,如此一来就又可以使用FAT32文件系统了
1 | # 拆分 |
3.5.2 下载某个软件的rpm包
针对当前环境,下载缺失的rpm包:yum install --downloadonly --downloaddir=<downloadDir> <app1> <app2> ...
yum install --downloadonly --downloaddir=/rpm gcc
下载所有的rpm包(无论当前系统是否存在):repotrack -a x86_64 -p <downloadDir> <app1> <app2> ...
repotrack -a x86_64 -p /rpm/ gcc wget
安装rpm包并解决冲突:rpm -ivh --replacepkgs --upgrade=*.rpm <directory>/*.rpm
rpm -ivh --replacepkgs --upgrade=*.rpm /rpm/*.rpm
3.5.3 安装时如何切换tty
- 从图形化界面切换到tty:
ctrl+alt+f<n>,n可以是1-5 - 从tty切换到图形化界面:
ctrl+alt+f6
3.5.4 查找官方iso中的comps.xml文件
- 在
CentOS 7.6.1810以及CentOS 7.7.1908中,该xml都存在于repodata目录中,只是名字是个随机串 - 在
CentOS 7.8.2003中,该xml以压缩包的形式存在于repodata目录中,压缩包的名字也是个随机串
3.5.5 kickstart语法
3.5.5.1 %packages
%packages用于指定安装包(rpm包),在CentOS-7-x86_64-DVD-xxx/repodata目录下,有个comps.xml文件,该文件内有包含environment、group等的定义,可以用<environment>以及<group>来搜索相关的定义
指定environment
1 | %packages |
指定group
1 | %packages |
指定独立的rpm包,支持通配符
1 | %packages |
排除指定的environment、group以及独立的rpm包
1 | %packages |
3.6 参考
- 使用isolinux制作liveUSB
- CentOS Composer
- 按部就班—半自动化系统安装
- mkisofs制作镜像文件
- Building a Custom Boot ISO for Red Hat Virtualization Hypervisor
- How to use and edit comps.xml for package groups
- 定制自己的CentOS发行版
- CentOS官方comps.xml文件
- 使用ISOLinux制作Linux系统安装盘
- CentOS Kickstart 官方文档
- Red Hat Kickstart 官方文档
- Anaconda kickstart 官方文档
- Anaconda kickstart and rootpw option
- kickstart 中文文档
- Kickstart详解(转载)
- CentOS/RHEL 7 LVM Partitioning in Kickstart?
- PXE Network Boot Server
- PXE的部署过程
- PXE自动化系统安装服务器(DHCP + TFTP + syslinux +vsftpd)
- dhcp、tftp及pxe简介
- Linux-pxe~install网络安装
- Computer says “succeed to download nbp file” but doesn’t boot into PE
- how to make the first disk /dev/sda always
- Download all dependencies with yumdownloader, even if already installed?
4 核心概念
4.1 BIOS与UEFI
BIOS(Basic Input Output System)是基本输入输出系统。它是一组固化到计算机内主板上一个ROM芯片上的程序,保存着计算机最重要的基本输入输出的程序、开机后自检程序和系统自启动程序,它可从CMOS中读写系统设置的具体信息
UEFI(Unified Extensible Firmware Interface)是统一可扩展固件界面,用来定义操作系统与系统硬件之间的软件界面,作为BIOS的替代方案。可扩展固件接口负责加电自检(POST),联系操作系统以及提供连接作业系统与硬体的介面
实际上PC的启动固件的引导流程从IBM PC机诞生第一天起,就没有本质改变过,无论传统BIOS还是UEFI,阳光之下没有什么新鲜的东西,启动本身无外乎三个步骤
Rom Stage:在这个阶段没有内存,需要在ROM上运行代码。这时因为没有内存,没有C语言运行需要的栈空间,开始往往是汇编语言,直接在ROM空间上运行。在找到个临时空间(Cache空间用作RAM,Cache As Ram, CAR)后,C语言终于可以粉墨登场了,后期用C语言初始化内存和为这个目的需要做的一切服务Ram Stage:在经过ROM阶段的困难情况后,我们终于有了可以大展拳脚的内存,很多额外需要大内存的东西可以开始运行了。在这时我们开始进行初始化芯片组、CPU、主板模块等等核心过程Find something to boot Stage:终于要进入正题了,需要启动,我们找到启动设备。就要枚举设备,发现启动设备,并把启动设备之前需要依赖的节点统统打通。然后开始移交工作,Windows或者Linux的时代开始
传统BIOS尽管开始全部用汇编语言完成,但后期也部分引入了C语言,这些步骤完全是一样的。什么MBR分区啊,UEFI分区都是枝节问题,都是技术上可以做到的,没有什么是UEFI可以做,传统BIOS不可以做到的。那既然有BIOS了,为什么还需要UEFI呢
- 传统
BIOS来自于IBM,之后就进入战国时代,激烈的商战让接口统一成为了不可能做到的事,只有在面对微软这个大用户的时候,才勉强提供了兼容的基于软中断的接口。它封闭、神秘和充满各种不清不楚的预设和祖传代码,在调试PCI的ROM时要小心各种ROM之间互相踩,各种只有老师傅才知道的神奇诀窍。要写个驱动,让它在各个BIOS厂商那里都能跑,简直成为了一件不可能完成的任务 - 由Intel推动,在一开始就将标准公开,拉上了微软这个PC界的霸主,强势统一了江湖。在近20年的深耕下,统一了固件启动阶段基础框架
Spec:PI Spec与操作系统的接口Spec:UEFI Spec,并将抽象硬件的原语性Spec: ACPI Spec也拉入这个大家庭,都变成UEFI Forum的一份子 - 现在只要符合
UEFI driver model的驱动都可以在各个BIOS上运行,打通了各个BIOS厂商之间的栅栏;与此同时,符合UEFI标准的操作系统都可以流畅的在各种主板上运行,无论是Windows,还是Linux各种发行版,甚至是Android。实际上,PC生态圈的繁荣,和UEFI的推广和被广泛接受是分不开的。值得一提的是UEFI内核的大部分代码是由Intel的中国工程师开发的。在大家一次次电脑的正常运行后面,有他们辛勤工作背影。他们也为固件的开源和国产化做出了自己的贡献。代码已经全部开源一部分时间了
CSM Configuration(Compatibility Support Module)(兼容性支持模块)是BIOS上Boot选项里的一个下拉子项目(一些老的主板上没有此选项),与Secure Boot(安全启动,仅适用于使用UEFI启动的操作系统)是并列项。CSM开启使得可以支持UEFI启动和非UEFI启动
- 若是需要启动传统
MBR设备,则需开启CSM,关闭Secure Boot - 若是需要启动
UEFI设备,则需要关闭CSM,开启Secure Boot
4.2 Grub
GRUB的作用有以下几个:
- 加载操作系统的内核
- 拥有一个可以让用户选择的的菜单,来选择到底启动哪个系统
- 可以调用其他的启动引导程序,来实现多系统引导
按照启动流程,BIOS在自检完成后,会到第一个启动设备的MBR中读取GRUB。在MBR中用来放置启动引导程序的空间只有446Byte,那么GRUB可以放到这里吗?答案是空间不够,GRUB的功能非常强大,MBR空间是不够使用的。那么Linux的解决办法是把GRUB的程序分成了三个阶段来执行
Stage 1:执行GRUB主程序:第一阶段是用来执行GRUB主程序的,这个主程序必须放在启动区中(也就是MBR或者引导扇区中)。但是MBR太小了,所以只能安装GRUB的最小的主程序,而不能安装GRUB的相关配置文件。这个主程序主要是用来启动Stage 1.5和Stage 2的。Stage 1.5:识别不同的文件系统:Stage 2比较大,只能放在文件系统中(分区),但是Stage 1不能识别不同的文件系统,所以不能直接加载Stage 2。这时需要先加载Stage 1.5,由Stage 1.5来加载不同文件系统中的Stage 2- 还有一个问题,难道
Stage 1.5不是放在文件系统中的吗?如果是,那么Stage 1同样不能找到Stage 1.5。其实,Stage 1.5还真没有放在文件系统中,而是在安装GRUB时,直接安装到紧跟MBR之后的32KB的空间中,这段硬盘空间是空白无用的,而且是没有文件系统的,所以Stage 1可以直接读取Stage 1.5。读取了Stage 1.5就能识别不同的文件系统,才能加载Stage 2
- 还有一个问题,难道
Stage 2:加载GRUB的配置文件:Stage 2阶段主要就是加载GRUB的配置文件/boot/grub/grub.conf,然后根据配置文件中的定义,加载内核和虚拟文件系统。接下来内核就可以接管启动过程,继续自检与加载硬件模块了
4.3 Grub2
系统启动流程
- 加载
BIOS的硬件信息与进行自检,并依据设置取得第一个可启动的设备(硬盘,光盘,U盘) - 读取并执行第一个启动设备内
MBR(主引导分区)的boot loader(如grub2)- 严格意义上,
MBR就是grub2中的boot.img,boot.img的唯一作用就是读取core.img的第一个扇区并跳转到它身上,将控制权交给该扇区的img。由于体积原因,boot.img是无法理解文件系统的,因此core.img的位置是以硬编码的方式记录在boot.img中的 core.img加载启动菜单、加载目标操作系统的信息等
- 严格意义上,
- 依据
grub2的设置加载Kernel,Kernel会开始检测硬件与加载驱动程序 - 在硬件驱动成功后,
Kernel会主动调用systemd进程(原来的init进程),并以default.targert流程开机
4.3.1 基础内容
4.3.1.1 grub2和grub的区别
- 配置文件的名称改变了。在
grub中,配置文件为grub.conf或menu.lst(grub.conf的一个软链接),在grub2中改名为grub.cfg grub2增添了许多语法,更接近于脚本语言了,例如支持变量、条件判断、循环grub2中,设备分区名称从1开始,而在grub中是从0开始的。grub2使用img文件,不再使用grub中的stage1、stage1.5和stage2- 支持图形界面配置grub,但要安装grub-customizer包,epel源提供该包。
- 在已进入操作系统环境下,不再提供
grub命令,也就是不能进入grub交互式界面,只有在开机时才能进入,算是一大缺憾。 - 在
grub2中没有了好用的find命令,算是另一大缺憾。
4.3.1.2 命名习惯和文件路径表示方式
(fd0):表示第一块软盘(hd0,msdos2):表示第一块硬盘的第二个mbr分区。grub2中分区从1开始编号,传统的grub是从0开始编号的(hd0,msdos5):表示第一块硬盘的第一个逻辑分区(hd0,gpt1):表示第一块硬盘的第一个gpt分区/vmlinuz:相对路径,表示根设备下的vmlinuz文件(hd0,msdos1)/vmlinuz:绝对路径,表示第一硬盘第一分区下的vmlinuz文件
4.3.1.3 grub2引导操作系统的方式
grub2支持两种方式引导操作系统:
- 直接引导:
(direct-load)直接通过默认的grub2 boot loader来引导写在默认配置文件中的操作系统 - 链式引导:
(chain-load)使用默认grub2 boot loader链式引导另一个boot loader,该boot loader将引导对应的操作系统
- 一般只使用第一种方式,只有想引导grub默认不支持的操作系统时才会使用第二种方式。比如安装了
Windows和Linux双系统时,系统的boot loader是grub2,但是grub2并不能引导启动Windows,所以需要将执行权转交给Widnwos系统分区的boot loader
4.3.1.4 文件分布
grub的配置文件放置位置为/boot/grub/,在grub2中,这些文件被分别放置到如下位置中
/boot/grub/grub.cfg:/etc/grub.d/:放置grub脚本的位置,这些脚本用于构建grub.cfg/etc/default/grub:这个文件包含grub的基础配置,这些配置在构建grub.cfg时,会被脚本读取
接下来介绍一下grub脚本,脚本名称前面的数字代表了脚本执行的先后顺序
00_header:该脚本用于读取grub的基础配置/etc/default/grub,包括超时等等10_linux:该脚本用于加载发行版的菜单项30_os-prober:该脚本用于扫描硬盘上其他操作系统并将其添加到启动菜单40_custom:是一个模板,可用于创建要添加到启动菜单的其他条目
如何构建新的grub.cfg文件
CentOS:grub2-mkconfig –o /boot/grub2/grub.cfg,不加-o参数会直接以标准输出的方式打印到屏幕上Ubuntu:update-grub
grub.cfg文件位置
CentOS:/boot/efi/EFI/centos/grub.cfg或者/boot/grub2/grub.cfgUbuntu:/boot/grub/grub.cfg
4.3.1.5 boot loader和grub的关系
当使用grub来管理启动菜单时,那么boot loader都是grub程序安装的。
传统的grub将Stage 1转换后的内容安装到MBR(VBR或EBR)中的boot loader部分,将Stage 1.5转换后的内容安装在紧跟在MBR后的扇区中,将Stage 2转换后的内容安装在/boot分区中。
grub2将boot.img转换后的内容安装到MBR(VBR或EBR)中的boot loader部分,将diskboot.img和kernel.img结合成为core.img,同时还会嵌入一些模块或加载模块的代码到core.img中,然后将core.img转换后的内容安装到磁盘的指定位置处
4.3.1.6 grub2的安装位置
严格地说是core.img的安装位置,因为boot.img的位置是固定在MBR或VBR或EBR上的
MBR
MBR格式的分区表用于PC BIOS平台,这种格式允许四个主分区和额外的逻辑分区。使用这种格式的分区表,有两种方式安装grub:
- 嵌入到
MBR和第一个分区中间的空间,这部分就是大众所称的boot track,MBR gap或embedding area,它们大致需要31kB的空间- 使用嵌入的方式安装
grub,就没有保留的空闲空间来保证安全性,例如有些专门的软件就是使用这段空间来实现许可限制的;另外分区的时候,虽然会在MBR和第一个分区中间留下空闲空间,但可能留下的空间会比这更小
- 使用嵌入的方式安装
- 将
core.img安装到某个文件系统中,然后使用分区的第一个扇区(严格地说不是第一个扇区,而是第一个block)存储启动它的代码- 方法二安装
grub到文件系统,但这样的grub是脆弱的。例如,文件系统的某些特性需要做尾部包装,甚至某些fsck检测,它们可能会移动这些block
- 方法二安装
grub开发团队建议将grub嵌入到MBR和第一个分区之间,除非有特殊需求,但仍必须要保证第一个分区至少是从第31kB(第63个扇区)之后才开始创建的- 现在的磁盘设备,一般都会有分区边界对齐的性能优化提醒,所以第一个分区可能会自动从第1MB处开始创建
gpt
- 一些新的系统使用
GUID分区表(GPT)格式,这种格式是EFI固件所指定的一部分。但如果操作系统支持的话,gpt也可以用于BIOS平台(即MBR风格结合gpt格式的磁盘),使用这种格式,需要使用独立的BIOS boot分区来保存grub,grub被嵌入到此分区,不会有任何风险 - 当在
gpt磁盘上创建一个BIOS boot分区时,需要保证两件事- 它最小是31kB大小,但一般都会为此分区划分1MB的空间用于可扩展性
- 必须要有合理的分区类型标识(flag type)
gun parted工具可以设置bios_grub标识- 如果使用
gdisk分区工具时,则分类类型设置为EF02
4.3.1.7 进入grub命令行
在传统的grub上,可以直接在bash下敲入grub命令进入命令交互模式,但grub2只能在系统启动前进入grub交互命令行
按下e见可以编辑所选菜单对应的grub菜单配置项,按下c键可以进入grub命令行交互模式
4.3.2 安装grub2
这里的安装指的不是安装grub程序,而是安装Boot loader,但一般都称之为安装grub,且后文都是这个意思
4.3.2.1 grub安装命令
安装方式非常简单,只需调用grub2-install,然后给定安装到的设备名即可
1 | grub2-install /dev/sda |
这样的安装方式,默认会将img文件放入到/boot目录下,如果想自定义放置位置,则使用--boot-directory选项指定,可用于测试练习grub的时候使用,但在真实的grub环境下不建议做任何改动
1 | grub2-install --boot-director=/mnt/boot /dev/fd0 |
如果是EFI固件平台,则必须挂载好efi系统分区,一般会挂在/boot/efi下,这是默认的,此时可直接使用grub2-install安装
1 | grub2-install |
如果不是挂载在/boot/efi下,则使用--efi-directory指定efi系统分区路径
1 | grub2-install --efi-directory=/mnt/efi |
4.3.2.2 各种img和stage文件的说明
img文件是grub2生成的,stage文件是传统grub生成的。下面是各种文件的说明
4.3.2.2.1 grub2中的img文件
grub2生成了好几个img文件,有些分布在/usr/lib/grub/i386-pc目录下,有些分布在/boot/grub2/i386-pc目录
下图描述了各个img文件之间的关系。其中core.img是动态生成的,路径为/boot/grub2/i386-pc/core.img,而其他的img则存在于/usr/lib/grub/i386-pc目录下。当然,在安装grub时,boot.img会被拷贝到/boot/grub2/i386-pc目录下

boot.img- 在
BIOS平台下,boot.img是grub启动的第一个img文件,它被写入到MBR中或分区的boot sector中,因为boot sector的大小是512字节,所以该img文件的大小也是512字节 boot.img唯一的作用是读取属于core.img的第一个扇区并跳转到它身上,将控制权交给该扇区的img。由于体积大小的限制,boot.img无法理解文件系统的结构,因此grub2-install将会把core.img的位置硬编码到boot.img中,这样就一定能找到core.img的位置
- 在
core.imgcore.img根据diskboot.img、kernel.img和一系列的模块被grub2-mkimage程序动态创建。core.img中嵌入了足够多的功能模块以保证grub能访问/boot/grub,并且可以加载相关的模块实现相关的功能,例如加载启动菜单、加载目标操作系统的信息等,由于grub2大量使用了动态功能模块,使得core.img体积变得足够小core.img中包含了多个img文件的内容,包括diskboot.img、kernel.img等core.img的安装位置随MBR磁盘和GPT磁盘而不同
diskboot.img- 如果启动设备是硬盘,即从硬盘启动时,
core.img中的第一个扇区的内容就是diskboot.img。diskboot.img的作用是读取core.img中剩余的部分到内存中,并将控制权交给kernel.img,由于此时还不识别文件系统,所以将core.img的全部位置以block列表的方式编码,使得diskboot.img能够找到剩余的内容。 - 该
img文件因为占用一个扇区,所以体积为512字节
- 如果启动设备是硬盘,即从硬盘启动时,
cdboot.img- 如果启动设备是光驱(
cd-rom),即从光驱启动时,core.img中的第一个扇区的的内容就是cdboo.img。它的作用和diskboot.img是一样的
- 如果启动设备是光驱(
pexboot.img- 如果是从网络的PXE环境启动,
core.img中的第一个扇区的内容就是pxeboot.img。
- 如果是从网络的PXE环境启动,
kernel.imgkernel.img文件包含了grub的基本运行时环境:设备框架、文件句柄、环境变量、救援模式下的命令行解析器等等。很少直接使用它,因为它们已经整个嵌入到了core.img中了。注意,kernel.img是grub的kernel,和操作系统的内核无关- 如果细心的话,会发现
kernel.img本身就占用28KB空间,但嵌入到了core.img中后,core.img文件才只有26KB大小。这是因为core.img中的kernel.img是被压缩过的
lnxboot.img- 该
img文件放在core.img的最前部位,使得grub像是linux的内核一样,这样core.img就可以被LILO的image=识别。当然,这是配合LILO来使用的,但现在谁还适用LILO呢
- 该
*.mod- 各种功能模块,部分模块已经嵌入到
core.img中,或者会被grub自动加载,但有时也需要使用insmod命令手动加载
- 各种功能模块,部分模块已经嵌入到
4.3.2.2.2 传统grub中的stage文件
grub2的设计方式和传统grub大不相同,因此和stage之间的对比关系其实没那么标准,但是将它们拿来比较也有助于理解img和stage文件的作用。
stage文件也分布在两个地方:/usr/share/grub/RELEASE目录下和/boot/grub目录下,/boot/grub目录下的stage文件是安装grub时从/usr/share/grub/RELEASE目录下拷贝过来的
stage1stage1文件在功能上等价于boot.img文件。目的是跳转到stage1_5或stage2的第一个扇区上
*_stage1_5*stage1_5文件包含了各种识别文件系统的代码,使得grub可以从文件系统中读取体积更大功能更复杂的stage2文件。从这一方面考虑,它类似于core.img中加载对应文件系统模块的代码部分,但是core.img的功能远比stage1_5多stage1_5一般安装在MBR后、第一个分区前的那段空闲空间中,也就是MBR gap空间,它的作用是跳转到stage2的第一个扇区。- 其实传统的
grub在某些环境下是可以不用stage1_5文件就能正常运行的,但是grub2则不能缺少core.img
stage2stage2的作用是加载各种环境和加载内核,在grub2中没有完全与之相对应的img文件,但是core.img中包含了stage2的所有功能- 当跳转到
stage2的第一个扇区后,该扇区的代码负责加载stage2剩余的内容 - 注意,
stage2是存放在磁盘上的,并没有像core.img一样嵌入到磁盘上
stage2_eltorito- 功能上等价于
grub2中的core.img中的cdboot.img部分。一般在制作救援模式的grub时才会使用到cd-rom相关文件
- 功能上等价于
pxegrub- 功能上等价于
grub2中的core.img中的pxeboot.img部分
- 功能上等价于
4.3.2.3 安装grub涉及的过程
安装grub2的过程大体分两步:
- 一是根据
/usr/lib/grub/i386-pc/目录下的文件生成core.img,并拷贝boot.img和core.img涉及的某些模块文件到/boot/grub2/i386-pc/目录下 - 二是根据
/boot/grub2/i386-pc目录下的文件向磁盘上写boot loader
当然,到底是先拷贝,还是先写boot loader,没必要去搞清楚,只要/boot/grub2/i386-pc下的img文件一定能通过grub2相关程序再次生成boot loader。所以,既可以认为/boot/grub2/i386-pc目录下的img文件是boot loader的特殊备份文件,也可以认为是boot loader的源文件
不过,img文件和boot loader的内容是不一致的,因为img文件还要通过grub2相关程序来转换才是真正的boot loader
对于传统的grub而言,拷贝的不是img文件,而是stage文件。
4.3.3 命令行和菜单项中的命令
4.3.3.1 grub菜单
菜单格式如下
1 | menuentry <title> [--class=<class> ...] [--users=<users>] [--unrestricted] [--hotkey=<key>] [--id=<id>] { |
这是grub.cfg中最重要的项。该命令定义了一个名为<title>的grub菜单项。执行顺序如下:
- 执行大括号中的命令列表
- 如果大括号中的命令全部执行成功,且成功加载了对应的内核,将执行
boot命令(menuentry都会在最后隐式携带一个boot命令),随后grub就将控制权交给了操作系统内核
4.3.3.2 命令
4.3.3.2.1 help命令
1 | help [pattern] |
显示能匹配到pattern的所有命令的说明信息和usage信息,如果不指定patttern,将显示所有命令的简短信息
4.3.3.2.2 boot命令
boot:用于启动已加载的操作系统
只在交互式命令行下可用。其实在menuentry命令的结尾就隐含了boot命令
4.3.3.2.3 set命令和unset命令
set:设置环境变量的值,如果不给定参数,则列出当前环境变量unset:释放环境变量的值
示例
1 | set [envvar=value] |
4.3.3.2.4 lsmod命令和insmod命令
lsmod:列出已加载的模块insmod:调用指定的模块
4.3.3.2.5 linux和linux16命令
1 | linux file [kernel_args] |
linux/linux16/linuxefi:都表示装载指定的内核文件,并传递内核启动参数。linux16表示以传统的16位启动协议启动内核,linux表示以32位启动协议启动内核,但linux命令比linux16有一些限制。但绝大多数时候,它们是可以通用的
在linux或linux16或linuxefi命令之后,必须紧跟着使用initrd或initrd16或initrdefi命令装载init ramdisk文件
内核文件一般为/boot分区下的vmlinuz-RELEASE_NUM文件
在grub环境下,boot分区被当作root device,即根设备,假如boot分区为第一块磁盘的第一个分区,则应该写成
1 | linux (hd0,msdos1)/vmlinuz-XXX |
或者相对路径
1 | set root='hd0,msdos1' |
在grub阶段可以传递内核的启动参数(内核的参数包括3类:编译内核时参数,启动时参数和运行时参数),可以传递的启动参数非常非常多,完整的启动参数列表。这里只列出几个常用的
init=:指定Linux启动的第一个进程init的替代程序root=:指定根文件系统所在分区,在grub中,该选项必须给定。另外,root启动参数有多种定义方式- 可以使用UUID的方式指定,例如
linux16 /vmlinuz-3.10.0-327.el7.x86_64 root=UUID=edb1bf15-9590-4195-aa11-6dac45c7f6f3 ro rhgb quiet LANG=en_US.UTF-8 - 也可以直接指定根文件系统所在分区,如
linux16 /vmlinuz-3.10.0-327.el7.x86_64 root=/dev/sda2 ro rhgb quiet LANG=en_US.UTF-8
- 可以使用UUID的方式指定,例如
ro,rw:启动时,根分区以只读还是可读写方式挂载。不指定时默认为roinitrd:指定init ramdisk的路径。在grub中因为使用了initrd或initrd16命令,所以不需要指定该启动参数rhgb:以图形界面方式启动系统quiet:以文本方式启动系统,且禁止输出大多数的log messagenet.ifnames=0:用于CentOS 7,禁止网络设备使用一致性命名方式biosdevname=0:用于CentOS 7,也是禁止网络设备采用一致性命名方式。
- 只有
net.ifnames和biosdevname同时设置为0时,才能完全禁止一致性命名,得到eth0-N的设备名
4.3.3.2.6 initrd和initrd16命令
1 | initrd file |
只能紧跟在linux或linux16或linuxefi命令之后使用,用于为即将启动的内核传递init ramdisk路径
同样,基于根设备,可以使用绝对路径,也可以使用相对路径。路径的表示方法和linux或linux16或linuxefi命令相同,例如
1 | linux16 /vmlinuz-0-rescue-d13bce5e247540a5b5886f2bf8aabb35 root=UUID=b2a70faf-aea4-4d8e-8be8-c7109ac9c8b8 ro crashkernel=auto quiet |
4.3.3.2.7 search命令
1 | search [--file|--label|--fs-uuid] [--set [var]] [--no-floppy] [--hint args] name |
通过文件[--file]、卷标[--label]、文件系统UUID[--fs-uuid]来搜索设备。
如果使用了--set选项,则会将第一个找到的设备设置为环境变量var的值,默认的变量var为root
搜索时可使用--no-floppy选项来禁止搜索软盘,因为软盘速度非常慢,已经被淘汰了
有时候还会指定--hint=XXX,表示优先选择满足提示条件的设备,若指定了多个hint条件,则优先匹配第一个hint,然后匹配第二个,依次类推
1 | if [ x$feature_platform_search_hint = xy ]; then |
- 上述
if语句中的第一个search中搜索uuid为367d6a77-033b-4037-bbcb-416705ead095的设备,但使用了多个hint选项,表示先匹配bios平台下/boot分区为(hd0,msdos1)的设备,之后还指定了几个hint,但因为search使用的是uuid搜索方式,所以这些hint选项是多余的,因为单磁盘上分区的uuid是唯一的
再举个例子,如果某启动设备上有两个boot分区(如多系统共存时),分别是(hd0,msdos1)和(hd0,msdos5),如果此时不使用uuid搜索,而是使用label方式搜索
1 | search --no-floppy --fs-label=boot --set=root --hint=hd0,msdos5 |
4.3.3.3 几个常设置的内置变量
4.3.3.3.1 root变量
该变量指定根设备的名称,使得后续使用从/开始的相对路径引用文件时将从该root变量指定的路径开始。一般该变量是grub启动的时候由grub根据prefix变量设置而来的
例如,如果grub安装在第一个硬盘的的第一个分区上,那么prefix就是(hd0,msdos1)/boot/grub;root就是(hd0,msdos1)
注意:在Linux中,从根/开始的路径表示绝对路径,如/etc/fstab。但grub中,从/开始的表示相对路径,其相对的基准是root变量设置的值,而使用(dev_name)/开始的路径才表示绝对路径
一般root变量都表示/boot所在的分区。但这不是绝对的,如果设置为根文件系统所在分区,如root=(hd0,gpt2),则后续可以使用/etc/fstab来引用(hd0,gpt2)/etc/fstab文件
另外,root变量还应该于linux或linux16或linuxefi命令所指定的内核启动参数root=区分开来,内核启动参数中的root=的意义是固定的,其指定的是根文件系统所在分区。例如:
1 | set root='hd0,msdos1' |
一般情况下,/boot都会单独分区,所以root变量指定的根设备和root启动参数所指定的根分区不是同一个分区,除非/boot不是单独的分区,而是在根分区下的一个目录
4.3.3.3.2 chosen变量
当开机时选中某个菜单项启动时,该菜单的title将被赋值给chosen变量。该变量一般只用于引用,而不用于修改
4.3.3.3.3 cmdpath变量
grub2加载的core.img的目录路径,是绝对路径,即包括了设备名的路径,如(hd0,gpt1)/boot/grub2/。该变量值不应该修改
4.3.3.3.4 default
指定默认的菜单项,一般其后都会跟随timeout变量
default指定默认菜单时,可使用菜单的title,也可以使用菜单的id,或者数值顺序,当使用数值顺序指定default时,从0开始计算
4.3.3.3.5 timeout变量
设置菜单等待超时时间,设置为0时将直接启动默认菜单项而不显示菜单,设置为-1时将永久等待手动选择
4.3.3.3.6 fallback变量
当默认菜单项启动失败,则使用该变量指定的菜单项启动,指定方式同default,可使用数值(从0开始计算)、title或id指定
4.3.3.3.7 grub_platform变量
指定该平台是pc还是efi,pc表示的就是传统的bios平台
该变量不应该被修改,而应该被引用,例如用于if判断语句中
4.3.3.3.8 prefix变量
在grub启动的时候,grub自动将/boot/grub2目录的绝对路径赋值给该变量,使得以后可以直接从该变量所代表的目录下加载各文件或模块。
例如,可能自动设置为set prefix = (hd0,gpt1)/boot/grub2/
所以可以使用$prefix/grubN.cfg来引用/boot/grub2/grubN.cfg文件。
该变量不应该修改,且若手动设置,则必须设置正确,否则牵一发而动全身
4.4 重要文件介绍
4.4.1 vmlinuz
vmlinuz是可引导的、压缩的内核。vm代表Virtual Memory。Linux支持虚拟内存,不像老的操作系统比如DOS有640KB内存的限制。Linux能够使用硬盘空间作为虚拟内存,因此得名vm。vmlinuz是可执行的Linux内核,路径为/boot/vmlinuz(具体来说形如/boot/vmlinuz-3.10.0-957.el7.x86_64)
4.4.2 initrd
initrd是initial ramdisk的简写。initrd是在系统引导过程中挂载的一个临时根文件系统,用来支持两阶段的引导过程。initrd文件中包含了各种可执行程序和驱动程序,它们可以用来挂载实际的根文件系统(当挂载完真实的根文件系统之后,可以将这个initrd卸载,并释放内存,在很多嵌入式Linux系统中,initrd就是最终的根文件系统)
initrd中包含了实现这个目标所需要的目录和可执行程序的最小集合,例如将内核模块加载到内核中所使用的insmod工具
initrd是什么文件系统?内核直接能识别这个文件系统吗?:initrd的文件系统是ext2,内核应该内置了ext2的相关模块
4.4.2.1 initramfs
kernel 2.6以来都是initramfs了,只是很多还沿袭传统使用initrd的名字
initramfs的工作方式更加简单直接一些,启动的时候加载内核和initramfs到内存执行,内核初始化之后,切换到用户态执行initramfs的程序/脚本,加载需要的驱动模块、必要配置等,然后加载rootfs切换到真正的rootfs上去执行后续的init过程。initrd是kernel 2.4及更早的用法(现在你能见到的initrd文件实际差不多都是initramfs了),运行过程大概是内核启动,执行一些initrd的内容,加载模块啥的,然后交回控制权给内核,最后再切到用户态去运行用户态的启动流程
可以通过命令行工具lsinitrd查看initramfs的内容
1 | lsinitrd |
4.5 参考
- UEFI 引导与 BIOS 引导在原理上有什么区别?
- How to make Windows 7 USB flash install media from Linux?
- 详解uefi、legacy以及U盘格式对系统安装的影响
- MBR与GPT
- 聊聊BIOS、UEFI、MBR、GPT、GRUB
- GRUB bootloader - Full tutorial
- GRUB 2 bootloader - Full tutorial
- GRUB 官方文档(简体中文)
- grub2详解(翻译和整理官方手册)
- GRUB2配置文件"grub.cfg"详解(GRUB2实战手册)
- GRUB legacy和GRUB 2介绍 与 命令【包含kernel 与 initrd的详解】使用
- Linux启动引导程序(GRUB)加载内核的过程
- GRUB入门教程
- What exactly is GRUB?
- 你知道计算机启动过程吗?
- 系统启动流程
- UEFI启动和Bios(Legacy)启动的区别
- Linux initial RAM disk (initrd) overview
- Initramfs/指南
- 浅谈linux启动的那些事(initrd.img)
- boot分区-百度百科
- initrd-百度百科
- grub Kernel_parameters
- grub Kernel_parameters(极详细)
- 启动流程、模块管理、BootLoader(Grub2)
- What on earth is Dracut?
- initrd和initramfs的区别是什么?
- The difference between initrd and initramfs?
- Initramfs 原理和实践
5 Ubuntu装机
博主安装的是server版本
- 设置root密码:
sudo passwd root - 网卡配置文件为
/etc/network/interfaces(无需修改) - 安装openssh:
apt-get install -y openssh-server - 修改ssh配置文件
/etc/ssh/sshd_config,将PermitRootLogin改为yes,重启sshd:service ssh restart
6 Ubuntu自定义发行版iso镜像制作
6.1 初次尝试制作镜像
在本小节,我们将iso镜像文件解压,然后将解压之后的文件原封不动地打成iso镜像,目的是为了熟悉镜像制作的各个命令行工具
为了减少环境因素对镜像制作造成的影响,这里使用docker容器来进行打包,DockerFile如下,非常简单,基础镜像为centos:7.6.1810,并用yum安装了镜像制作的相关工具
1 | FROM centos:7.6.1810 |
接下来制作docker镜像
1 | docker build -t create-iso-env:1.0.0 . |
运行docker。这里挂载了3个目录
/Users/hechenfeng/Desktop/source/ubuntu-18.04.4-live-server-amd64:该目录是我解压iso文件之后得到的目录,对应于容器中的/source目录/Users/hechenfeng/Desktop/workspace:该目录是镜像制作的工作目录,对应于容器中的/workspace目录/Users/hechenfeng/Desktop/iso:该目录用于放置生成的iso文件,对应于容器中的/target目录
1 | docker run \ |
以下命令均在容器中执行
第一步:将/source目录中的内容,拷贝到/workspace目录中
1 | # 删除除了. ..之外的所有文件以及目录,包括隐藏文件以及隐藏目录 |
第二步:接下来,就可以制作镜像了
1 | fileName=/target/my-ubuntu-1.iso |
6.2 使用kickstart定制化安装流程
我们重新运行一个容器来制作镜像,这里使用另一个iso(ubuntu-18.04.4-desktop-amd64.iso)来示范
1 | docker run \ |
以下命令均在容器中执行
第一步:将/source目录中的内容,拷贝到/workspace目录中
- 注意,拷贝时要用
cp -vrf /source/. /workspace/,而不是cp -vrf /source/* /workspace/,因为/source目录下存在一个隐藏文件夹.disk,如果该文件夹丢失的话,做出来的iso在装机阶段会出现unable to find a medium containing a live file system
1 | # 删除除了. ..之外的所有文件以及目录,包括隐藏文件以及隐藏目录 |
第二步:编写preseed.cfg文件,路径为/workspace/preseed.cfg
- 如何生成加密的密码
openssl passwd -crypt <my password>perl -e "print crypt('<my password>','sa');"ruby -e 'print "<my password>".crypt("JU"); print("\n");'php -r "print(crypt('<my password>','JU') . \"\n\");"python -c 'import crypt; print crypt.crypt("<my password>","Fx")'
1 | cat > /workspace/preseed.cfg << 'EOF' |
第三步:修改grub配置文件/workspace/isolinux/txt.cfg,关联这个kickstart文件(/workspace/preseed.cfg)
1 | mv /workspace/isolinux/txt.cfg /workspace/isolinux/txt.cfg.bak |
第四步:接下来,就可以制作镜像了
1 | fileName=/target/my-ubuntu-2.iso |
6.3 其他
6.3.1 确定目标磁盘挂载点
如何确定目标磁盘的挂载点:mount | grep <硬盘盘符>,例如mount | grep sda
6.3.2 下载某个软件的deb包1
我们可以通过apt install -d <name>来下载某个软件及其所有依赖的deb包。deb包的下载目录是:/var/cache/apt/archives
6.3.3 下载某个软件的deb包2
我们可以通过apt-get download <name>来下载软件包,但是该命令只会下载指定的软件包,而不会下载依赖以及依赖的依赖
我们如何确定一个软件包以及所有依赖?可以借助工具apt-rdepends
1 | # 安装apt-rdepends |
下载完成后,可以通过dpkg -i *.deb来进行软件安装
我们可以借助下面的脚本来完成依赖分析以及下载
1 | cat > ~/download.sh << 'EOF' |
6.3.4 允许root登录图形化界面
step1:编辑/usr/share/lightdm/lightdm.conf.d/50-ubuntu.conf文件,改成如下内容:
1 | [Seat:*] |
step2:编辑/etc/pam.d/gdm-autologin文件,注释掉如下行(大约是第三行):
1 | #auth required pam_succeed_if.so user != root quiet_success |
step3:编辑/etc/pam.d/gdm-password文件,注释掉如下行(大约是第三行):
1 | #auth required pam_succeed_if.so user != root quiet_success |
step4:编辑/root/.profile,修改成如下内容:
1 | # ~/.profile: executed by Bourne-compatible login shells. |
step5:重启生效配置
6.4 参考
- Automatic Installation
- Appendix B. Automating the installation using preseeding
- ubuntu preseed无人应答安装
- preseed 示例
- 定制ubuntu发行版
- 如何创建完全无人值守的Ubuntu Desktop 16.04.1 LTS安装?
- 如何创建完全无人值守的Ubuntu安装?
- ubuntu安装光盘iso修改方法总结
- InstallCDCustomization
- 定制ubuntu镜像
- XPS 9560 cannot install Ubuntu. ACPI Error / Empty Installation type / "unable to find a medium containing a live file system”
- debian软件包下载站
- ubuntu安装/查看已安装包的方法
7 其他常见问题
7.1 查看版本号
lsb_release -a:yum install -y redhat-lsbuname -r:内核版本号/etc/*-release,包括/etc/os-release/etc/centos-release/etc/debian_version
/proc/version
7.2 制作U盘启动盘
7.2.1 MacOS
1 | # 先列出所有设备 |
7.2.2 Linux
1 | # 先列出所有设备 |
7.3 安装图形化界面
如果你的CentOS是最小化安装的那默认都是不带X WINDOWS的,所以在安装这些桌面之前得先安装一下X WINDOWS,这个控制功能
1 | yum -y groupinstall "X Window System" |
7.3.1 安装GNOME
1 | yum -y groups install "GNOME Desktop" |



