替换CentOS官方ISO内核 ,生成自己的iso镜像文件

替换CentOS ISO内核

原文地址:https://starguard.cn/blog/post/admin/%E6%9B%BF%E6%8D%A2CentOS-ISO%E5%86%85%E6%A0%B8

各临时路径说明

将内核解包在/root/kernel/linux-4.14.141
原生ISO文件内容复制到/ISO/
将initrd解包在/root/initrd/
将内核模块安装在/root/modinstall
将squashfs解包在/root/,rootfs.img会在/root/squash-root/LiveOS/rootfs.img

过程中遇到的错误与解决方法

  1. vmlinuz没有增加执行权限。
  2. initrd.img无法被加载,改用gzip进行压缩,修改isolinux/isolinux.cfg中的initrd.img为initrd.gz。
  3. initrd.img体积庞大,有两种解决办法,一是在编译内核时用make modules_install
    INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=/root/modinstall,build
    ko的时候会加上–strip-debug,这样会让build出的ko大小大幅缩小;二是编译完成后,在lib/modules/中执行find
    . -name *.ko -exec eu-strip –remove-comment {} ;
  4. 在VMware测试并不需要修改grub.conf或grub.cfg,因为VMware用的是ISOLINUX引导方式,只需要修改isolinux/isolinux.cfg文件。
  5. 制作kernel的rpm有两种办法,一种是使用rpmrebuild修改旧版rpm,替换里面的vmlinuz、initrd.img,修改SPEC文件,但这种方式需要修改的内容较多,容易找不到文件,故采取另一种方式;另一种方法是直接使用make
    rpm-pkg -j64。
  6. genisoimage命令的选项-b使用错误(-b后面应该跟引导镜像isolinux.bin)导致isolinux.cfg变成了二进制文件,所以无法引导系统。
  7. squashfs.img和initrd.gz中的lib/modules/4.14.141必须一致,否则进入anaconda安装界面会报错。
  8. 如果修改了Packages里的包,一定要执行createrepo命令,根据comps.xml重新生成repodata,否则最终安装kernel的rpm时会报错error
    populating transaction。
  9. 系统安装进入dracut的可能原因是没有找到光盘介质,在grub.cfg中的inst.stage2=hd:LABEL=后面的名称一定要和genisoimage的-V参数后面的名称相同。

其他可能失败的解决方法

  1. 可以通过修改.vmx配置文件或启动虚拟机时选择打开电源时进入固件来进入BIOS设置,选择光盘为第一启动项,不过一般不会是这个原因。
  2. 如果内核rpm缺少依赖抛出kernel panic,rpm -qpR
    kernel-xxx.rpm查看依赖,修改/root/kernel/linux-4.14.141/scripts/package下的mkspec脚本,make
    rpm-pkg时,会调用到该脚本来生成内核RPM的SPEC文件,PreReq表示依赖类型为install前,这样就能先于内核rpm安装依赖。

替换内核全过程

编译内核

$ cd /root/kernel/
$ tar -xvJf linux-4.14.141.tar.xz # 或分两步,xz -d linux-4.14.141.tar.xz,tar -xvf linux-4.14.141.tar
$ cd linux-4.14.141
$ make mrproper
$ cp /boot/config-xxx ./.config # 使用系统中的config文件
$ yum install -y ncurses-devel bc flex ...
$ make menuconfig # 要选择XFS相关功能
$ make bzImage -j8 && make modules -j8 && make modules_install INSTALL_MOD_PATH=/root/modinstall/ INSTALL_MOD_STRIP=1 -j8

挂载系统ISO并复制ISO内容到磁盘

$ mkdir /mnt/cdrom /ISO
$ mount -o loop /root/CentOS-xxx.iso /mnt/cdrom
$ rsync -a /mnt/cdrom/ /ISO/ --exclude=repodata/ # 后续通过createrepo命令生成repodata
$ find /ISO/ -name TRANS.TBL -exec rm -f {} \; -print # 或者在上一步加上--exclude=TRANS.TBL参数

制作initrd.gz(或xz压缩方式的initrd.img)

$ cp /ISO/isolinux/initrd.img /root/
$ xz -d /root/initrd.img
$ mkdir /root/initrd
$ cd /root/initrd
$ cpio -ivmd < ../initrd.img
$ cp -r /root/modinstall/lib/modules/4.14.141/ /root/initrd/lib/modules/
$ rm -rf /root/initrd/lib/modules/3.10.x # 删除ISO中原来版本的内核模块目录
$ find ./ | cpio --quiet -H newc -o | gzip -9 -c >../initrd.gz # 如果使用xz -z打包,文件名就为initrd.img,系统安装时会自动判断为xz打包方式
制作kernel-xxx.rpm并替换
$ make rpm-pkg -j8 # 或者按下面的操作使用rpmrebuild修改旧版rpm
$ cp /root/rpmbuild/RPSS/x86/kernel-4.14.141.rpm /ISO/Packages

还有两个方法:
通过源码包和spec文件构建rpm:

rpmbuild kernel.spec

通过源码包重修改:
参考我的SRPM重修改方法笔记:
http://blog.leanote.com/post/scott_liu/Linux_RPM

复制bzImage和initrd.gz到isolinux/

$ cp /root/kernel/linux-4.14.141/arch/x86/boot/bzImage /ISO/isolinux/vmlinuz
$ chmod +x /ISO/isolinux/vmlinuz # 内核文件的权限必须至少是755
$ cp /root/initrd.gz /ISO/isolinux/initrd.gz

修改isolinux.cfg

$ vi isolinux.cfg
label linux
  menu label ^Install CentOS 7
  menu default
  kernel vmlinuz
  append initrd=initrd.gz inst.stage2=hd:LABEL=CentOS7

menu default表示默认指向Install CentOS 7
然后定义内核文件、initrd的名字以及ISO的label,该label和后面genisoimage命令的-V选项保持一致。

修改并替换squashfs.img

$ cp squashfs.img /root
$ cd /root
$ unsquashfs squashfs.img
$ mkdir /rootfs
$ mount squashfs-root/LiveOS/rootfs.img /rootfs
$ cp -r /root/modinstall/lib/modules/4.14.141/ /rootfs/modules/
$ rm -rf /rootfs/modules/3.10.x
$ umount /rootfs
$ unsquashfs -stat squashfs.img # 查看压缩方式和block大小
$ mksquashfs squashfs-root/ newsquashfs.img -comp xz -b 131072 -Xbcj x86 -Xdict-size 131072 # 根据原来的squashfs.img设置参数
$ cp newsquashfs.img /ISO/LiveOS/squashfs.img
制作comps.xml,生成repodata
$ cp /mnt/cdrom/repodata <随机值>-comps.xml /ISO/comps.xml # 如果新增了包,要修改该文件,替换内核rpm包不需要修改该文件
$ cd /ISO
$ createrepo -g comps.xml . # 否则Packages会校验失败,报error populating transaction错误

制作ISO镜像

$ genisoimage -joliet-long -V CentOS7 -o centos7.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -R -J -v -cache-inodes -T -eltorito-alt-boot -b images/efiboot.img -no-emul-boot /ISO # -eltorito-alt-boot -e images/efiboot.img -no-emul-boot用于EFI引导模式

如果没有ISOLINUX引导,只使用EFI引导:

$ genisoimage -joliet-long -V CentOS7 -o centos7.iso -b EFI/BOOT/grubaa64.efi -c boot.catalog -no-emul-boot -boot-load-size 4 -boot-info-table -R -J -v -cache-inodes -T -eltorito-alt-boot  -e images/efiboot.img -no-emul-boot /ISO

执行该命令使ISO能写入U盘被BIOS引导,否则只能通过DVD等引导:

$ isohybrid centos7.iso

安装系统

anaconda安装日志

https://blog.csdn.net/zhoudaxia/article/details/7172020
一般性的anaconda消息anaconda.log,由anaconda运行的所有外部程序信息anaconda.program.log,可扩展的存储模块信息anaconda.storage.log,网络接口配置相关信息anaconda.ifcfg.log,yum安装软件包的信息anaconda.yum.log,硬件相关的系统信息anaconda.syslog。注意如果系统安装失败,则这些文件的信息会一起放在一个anaconda-tb-identifier文件中,这里identifier是一个随机字符串。