Uefi_PXE
PXE Config & Grub2 debug
背景
起因 :
客户在厂PXE安装系统时,批量到500台时,会出现一半卡在grub启动到启动linux内核之间
客户环境 :
CentOs5.6 + DHCP + TFTP + NFS
简单诊断:
安装停留为grub2选择页面和下载内核进度条之间,由此可以判定grub2.cfg已经请求完毕,在grub2解析配置文件和下一步下载linux内核之间,怀疑是tftp请求不到文件;
但是客户反馈旧主板500台没有任何问题,提供的log也不全面,无法作出任何判断.
使用旧主板NetworkStack 测试, 客户反馈Fail.
221222 : 客户复现log 显示 server
准备 grub2 源代码编译
wget http://archive.ubuntu.com/ubuntu/pool/main/g/grub2-unsigned/grub2-unsigned_2.06.orig.tar.xz
源代码如上链接,开始的时候按照INSTALL
里的指导编译,一堆问题.
直到我意识到了它是利用autoconf/automake
这个系统来自动编译的.
具体的编译步骤
autoreconf -if
./configure --target=x86_64 --with-platform=efi
make
./grub-mkimage -p . -d ./grub-core/ -O x86_64-efi -o grub.efi normal
注意:这里是编译一个x86_64 的 efi 文件.而且重新编译时一定要清理之前产生的所有文件,从头开始,不然会在第4步时遇到Invalid ELF Header
生产不了对应平台的efi文件.
如果make
如有Warning As Error 的情况生,则可以在第2步的参数里加上--disable-werror
. 其它参数可以输入./configure -h
查看帮助信息.
调试PXE启动时看到请求了很多其它文件,仔细查看分为两部分grub.cfg-XXX
和**.lst
部分. 在它的changlist里写了可以通过在内嵌配置文件中加入set feature_net_search_cfg=n
来取消对grub.cfg-XXX
的请求; **.lst
则在misc.h
中找到了一个控制的宏 grub_no_modules
, 将其置为 1
,重新make
即可.
客户在测试平台上client在请求文件grub.cfg
时, 请求的路径为./grub.cfg
并不是grub.efi
启动的位置.
仔细查看grub-mkimage
的用法, 原来-p
命令就是用来设置前缀的,即设置变量prefix
,grub.efi
启动的位置为变量cmdpath
, 所以第四步中加入参数--prefix=$cmdpath
替换-p .
就行.
同样也可以在内嵌文件中加入set prefix=$cmdpath
达到同样的效果.
最终我的第四步命令如下.
将所有模块加入efi文件, 这里我拿掉了ahci
和uhci
模块
grub-mkimage --prefix=$cmdpath -c precfg.cfg -d ./grub-core/ -O x86_64-efi -o grubnetx64.efi acpi adler32 affs afs afsplitter all_video aout appleldr archelp ata at_keyboard backtrace bfs bitmap bitmap_scale blocklist boot bsd bswap_test btrfs bufio cat cbfs cbls cbmemc cbtable cbtime chain cmdline_cat_test cmp cmp_test configfile cpio_be cpio cpuid crc64 cryptodisk crypto cs5536 ctz_test datehook date datetime diskfilter disk div div_test dm_nv echo efifwsetup efi_gop efinet efi_uga ehci elf eval exfat exfctest ext2 extcmd f2fs fat file fixvideo font fshelp functional_test gcry_arcfour gcry_blowfish gcry_camellia gcry_cast5 gcry_crc gcry_des gcry_dsa gcry_idea gcry_md4 gcry_md5 gcry_rfc2268 gcry_rijndael gcry_rmd160 gcry_rsa gcry_seed gcry_serpent gcry_sha1 gcry_sha256 gcry_sha512 gcry_tiger gcry_twofish gcry_whirlpool geli gettext gfxmenu gfxterm_background gfxterm_menu gfxterm gptsync gzio halt hashsum hdparm hello help hexdump hfs hfspluscomp hfsplus http iorw iso9660 jfs jpeg json keylayouts keystatus ldm legacycfg legacy_password_test linux16 linux loadbios loadenv loopback lsacpi lsefimmap lsefi lsefisystab lsmmap ls lspci lssal luks2 luks lvm lzopio macbless macho mdraid09_be mdraid09 mdraid1x memdisk memrw minicmd minix2_be minix2 minix3_be minix3 minix_be minix mmap morse mpi msdospart mul_test multiboot2 multiboot nativedisk net newc nilfs2 normal ntfscomp ntfs odc offsetio ohci part_acorn part_amiga part_apple part_bsd part_dfly part_dvh part_gpt part_msdos part_plan part_sun part_sunpc parttool password password_pbkdf2 pata pbkdf2 pbkdf2_test pcidump pgp play png priority_queue probe procfs progress raid5rec raid6rec random rdmsr read reboot regexp reiserfs relocator romfs scsi search_fs_file search_fs_uuid search_label search serial setjmp setjmp_test setpci sfs shift_test signature_test sleep sleep_test smbios spkmodem squash4 strtoull_test syslinuxcfg tar terminal terminfo test_blockarg testload test testspeed tftp tga time tpm trig tr true udf ufs1_be ufs1 ufs2 usb_keyboard usb usbms usbserial_common usbserial_ftdi usbserial_pl2303 usbserial_usbdebug usbtest video_bochs video_cirrus video_colors video_fb videoinfo video videotest_checksum videotest wrmsr xfs xnu xnu_uuid xnu_uuid_test xzio zfscrypt zfsinfo zfs zstd
其中的precfg.cfg
文件内容如下
set feature_net_search_cfg=n
grub2 DEBUG 方法
grub.cfg
文件中加入debug=all
即可打开所有模块的debug消息,把all
换成disk
,efinet
即可打开disk
和efinet
模块的debug消息.打开debug消息的嵌入文件添加内容如下:
set debug=net,efinet
grub2 PXE 启动文件准备
grub.cfg
文件内容如下, 这里设置默认启动项为0, grub输出为串口0,打印disk和net模块的debug消息,内核加载后从http启动安装,内核消息从串口0输出.
set default=0
set timeout=10
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal_input serial;terminal_output serial
debug=disk,net
echo -e "\nWelcome FT live boot KYLIN!\n\n"
menuentry 'PXE install for KYLIN SP1 M70Z' {
linux uefi/vmlinuz ip=dhcp console=ttyS0,115200 url=http://192.168.0.103/Kylin-Desktop-V10-SP1-2203-X86_64_KM70zG1tsB02Y1.iso
initrd uefi/initrd.img
}
Ubuntu2204-PXE启动
DHCP
这里采用isc-dhcp-server
,搭DHCP服务器,
- 网关为自己的小路由器地址192.168.0.1,关闭路由器的DHCP功能,设置自己的工作机(SSH)和Server为静态IP
同时设置dhcp使用的网卡,我的网卡名称为enp1s0
,配置文件/etc/default/isc-dhcp-server
中设置:lsINTERFACESv4="enp1s0"
- 配置文件
/etc/dhcp/dhcpd.conf
,这里只考虑UEFI的情况,且使用ubuntu PXE netboot efi文件grubnetx64.efi
文件加入以下内容:subnet 192.168.0.0 netmask 255.255.255.0 { range 192.168.0.150 192.168.0.250; option routers 192.168.0.1; option subnet-mask 255.255.255.0; option broadcast-address 192.168.0.255; option domain-name-servers 192.168.0.1; next-server 192.168.0.103; filename "grubnetx64.efi"; }
- 启动DHCP服务器并检查
systemctl start isc-dhcp-server
systemctl status isc-dhcp-server
TFTP
- 使用
tftp-hpa
搭建tftp服务器,配置文件/etc/default/tftpd-hpa
,内容如下:TFTP_USERNAME="tftp" TFTP_DIRECTORY="/home/www/tftp" TFTP_ADDRESS="0.0.0.0:69" TFTP_OPTIONS="-l -c -s -vvv"
- 启动TFTP
systemctl start tftpd-hpa
systemctl status tftpd-hpa
- TFTP 根目录加入PXE 启动需要文件,grub配置文件,内核文件
grub.cfg, vmlinuz, initrd.img
NFS
使用nfs-server + rpcbind
软件搭建NFS 服务器;
- 配置文件
/etc/exports
内容中添加
/home/www/nfs 192.168.0.0/24(ro) #193.168.0.XXX 子网访问, 只读模式挂载
- 启动NFS
systemctl start rpcbind
systemctl start nfs-server
- 这样配置出来的NFS 还是无法
mount
, 报错Invaild Input/Output error
.
暂时还没有解决.
PXE 启动流程分析
Server Log 如下:
可以看到,
- 先是DHCP请求;
- 之后直接去next-server请求grubnetx64.efi;
- 然后再根据grubnetx64.efi的来源地请求grub.cfg;
- 解析grub.cfg,去tftp对应路径请求linux内核配置文件;
Dec 22 07:23:57 serverbl dhcpd[833]: DHCPDISCOVER from 9c:2d:cd:52:3b:8b via enp1s0
Dec 22 07:23:58 serverbl dhcpd[833]: DHCPOFFER on 192.168.0.160 to 9c:2d:cd:52:3b:8b via enp1s0
Dec 22 07:24:00 serverbl dhcpd[833]: DHCPREQUEST for 192.168.0.160 (192.168.0.103) from 9c:2d:cd:52:3b:8b via enp1s0
Dec 22 07:24:01 serverbl dhcpd[833]: Wrote 9 leases to leases file.
Dec 22 07:24:01 serverbl dhcpd[833]: DHCPACK on 192.168.0.160 to 9c:2d:cd:52:3b:8b via enp1s0
Dec 22 07:24:01 serverbl in.tftpd[33191]: RRQ from 192.168.0.160 filename grubnetx64.efi
Dec 22 07:24:01 serverbl in.tftpd[33191]: tftp: client does not accept options
Dec 22 07:24:07 serverbl in.tftpd[33228]: RRQ from 192.168.0.160 filename grubnetx64.efi
Dec 22 07:24:46 serverbl in.tftpd[33333]: RRQ from 192.168.0.160 filename /grub.cfg
Dec 22 07:24:57 serverbl in.tftpd[33366]: RRQ from 192.168.0.160 filename uefi/vmlinuz
Dec 22 07:28:45 serverbl in.tftpd[33876]: RRQ from 192.168.0.160 filename uefi/initrd.img
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现