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 这个系统来自动编译的.

具体的编译步骤

  1. autoreconf -if
  2. ./configure --target=x86_64 --with-platform=efi
  3. make
  4. ./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文件, 这里我拿掉了ahciuhci模块

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换成diskefinet 即可打开diskefinet模块的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 如下:
可以看到,

  1. 先是DHCP请求;
  2. 之后直接去next-server请求grubnetx64.efi;
  3. 然后再根据grubnetx64.efi的来源地请求grub.cfg;
  4. 解析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
posted @   BIGBIGWORF  阅读(481)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示