There are two methods for PXE boot, one is via BIOS, another one is vis EFI. Please be aware of the differents first.

Configuring PXE Boot for BIOS

  1. yum install tftp-server dhcpd
  2. edit /etc/xinet.d/tftp and change disabled from yes to no
  3. change flags to IPv6 if you want to set pxe for IPv6
  4. cp pxelinux.0 /var/lib/tftpboot/pxelinux/
  5. edit /etc/dhcp/dhcpd.conf if you want setup pxe for IPv4
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
option space pxelinux;
option pxelinux.magic code 208 = string;
option pxelinux.configfile code 209 = text;
option pxelinux.pathprefix code 210 = text;
option pxelinux.reboottime code 211 = unsigned integer 32;

subnet 192.168.0.0 netmask 255.255.255.0 {
        option routers 192.168.0.254;
        range 192.168.0.2 192.168.0.253;

        class "pxeclients" {
                match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
                next-server 192.168.0.1;

                filename "pxelinux/pxelinux.0";
        }
}
  1. edit /etc/dhcp/dhcpd6.conf if you want setup pxe for IPv6
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# cat /etc/dhcp/dhcpd6.conf
default-lease-time 2592000;
preferred-lifetime 604800;
option dhcp-renewal-time 3600;
option dhcp-rebinding-time 7200;
option dhcp6.name-servers 2012::1;
option dhcp6.domain-search "test.example.com","example.com";
option dhcp6.info-refresh-time 21600;
option dhcp6.bootfile-url code 59 = string;

subnet6 2012::/64 {
        range6 2012::10 2012::100;
        range6 2012:: temporary;
        prefix6 2012:: 2012:: /64;
        option dhcp6.bootfile-url "tftp://[2012::1]/pxelinux/pxelinux.0";
}

  1. mkdir /var/lib/tftpboot/pxelinux/pxelinux.cfg
  2. edit /var/lib/tftpboot/pxelinux/pxelinux.cfg/default
1
2
3
4
5
UI vesamenu.c32
LABEL rhel6_desktop
        MENU LABEL ^1) Install Desktop
        KERNEL rhel6/vmlinuz
        APPEND initrd=rhel6/initrd.img
  1. cp /boot/grub/splash.xpm.gz /var/lib/tftpboot/pxelinux/splash.xpm.gz

  2. cp /path/to/x86_64/os/images/pxeboot/{vmlinuz,initrd.img} /var/lib/tftpboot/pxelinux/rhel6/.

    Note the dir here is rhel6, it may changed with different release.

After these steps, the directory would like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
/var/lib/tftpboot/pxelinux/
 |
 | -- pxelinux.0
 | -- splash.xpm.gz
 | -- pxelinux.cfg/
 |    |
 |    |-- default
 |
 | -- rhel6/
        |
        | -- initrd.img
        | -- vmlinuz


Configuring PXE Boot for EFI

Config bios

  1. Enable EFI and disable CSM

Config Server

  1. yum install tftp-server
  2. edit /etc/xinet.d/tftp and change disabled from yes to no
  3. change flags to IPv6 if you want to set pxe for IPv6
  4. Create a directory path within tftpboot for the EFI boot images, and then copy them from your boot directory
  5. tftpboot topo
 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
# pwd
/var/lib/tftpboot
# tree
.
`-- pxelinux
    `-- bootx64.efi
        |-- BOOTX64.efi	(This must be executable file, or it will fail with access denied)
        |-- efidefault
        |-- grubx64.efi
        |-- rhel6
        |   |-- initrd.img
        |   `-- vmlinuz
        `-- rhel7
            |-- initrd.img
            `-- vmlinuz

# cat efidefault
default=0
timeout=5
hiddenmenu
title RHEL6
        root (nd)
        kernel /rhel6/vmlinuz method=http://[2012::1]/rhel6/ lang=en_US keymap=us
        initrd /rhel6/initrd.img
title RHEL7
        root (nd)
        kernel /rhel7/vmlinuz
        initrd /rhel7/initrd.img
  1. edit /etc/dhcp/dhcpd.conf for IPv4
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
option space pxelinux;
option pxelinux.magic code 208 = string;
option pxelinux.configfile code 209 = text;
option pxelinux.pathprefix code 210 = text;
option pxelinux.reboottime code 211 = unsigned integer 32;

subnet 192.168.0.0 netmask 255.255.255.0 {
        option routers 192.168.0.254;
        range 192.168.0.2 192.168.0.253;

        class "pxeclients" {
                match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
                next-server 192.168.0.1;

                filename "pxelinux/bootx64.efi/BOOTX64.efi";
        }
}
  1. edit /etc/dhcp/dhcpd6.conf for IPv6
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# cat /etc/dhcp/dhcpd6.conf
default-lease-time 2592000;
preferred-lifetime 604800;
option dhcp-renewal-time 3600;
option dhcp-rebinding-time 7200;
option dhcp6.name-servers 2012::1;
option dhcp6.domain-search "test.example.com","example.com";
option dhcp6.info-refresh-time 21600;
dhcpv6-lease-file-name "/usr/local/var/db/dhcpd6.leases";
option dhcp6.bootfile-url code 59 = string;

subnet6 2012::/64 {
        range6 2012::10 2012::100;
        range6 2012:: temporary;
        prefix6 2012:: 2012:: /64;
        option dhcp6.bootfile-url "tftp://[2012::1]/pxelinux/bootx64.efi/BOOTX64.efi";
}

  1. mount RHEL ISO in /var/www/html and start httpd
  2. start radvd for IPv6 autoconfig, because when init install program, it will start NetworkManager and auto config IPv6, If you choose DHCP type IPv6, then no need for radvd.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# cat /etc/radvd.conf
interface eth0
{
        AdvSendAdvert on;
        MinRtrAdvInterval 30;
        MaxRtrAdvInterval 100;
        prefix 2012::/64
        {
                AdvOnLink on;
                AdvAutonomous on;
                AdvRouterAddr off;
        };

};
# echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
# echo 1 > /proc/sys/net/ipv6/conf/eth0/forwarding
  1. restart services
1
2
3
service xinetd restart
service httpd restart
service radvd restart

Start each services

1
2
3
4
5
6
chkconfig xinetd on
chkconfig ftfp on
ip addr add 192.168.0.1/24 dev eth0
ip addr add 2012::1/64 dev eth0
service dhcpd start
service dhcpd6 start

Test steps after install

  1. disable security boot and enable EFI
  2. check ip address are configed after reboot
  3. iptables -F; ip6tables -F
  4. add yum repo and install some packages
1
2
3
4
5
6
# cat rhel6.repo
[rhel6]
name=Red Hat Enterprise Linux $releasever - $basearch - Source
baseurl=http://2000::ffff/rhel6
enabled=1
gpgcheck=0

An anaconda-ks.cfg for all the configurations

NOTE: As this is a very old blog, I have forgot if this works. Please just take it as a reference.

  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
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
install
url --url=http://download.englab.brq.redhat.com/pub/rhel/released/RHEL-6/6.4/Workstation/x86_64/os/
lang en_US.UTF-8
keyboard us
cmdline
rootpw redhat
timezone --utc Europe/Prague

# partitioning: autopart
bootloader --location=mbr
zerombr
clearpart --all --initlabel
autopart

network --device=eth0 --bootproto=dhcp --onboot=no --activate

#services --enabled=dhcpd,xinetd,httpd
services --enabled=xinetd,httpd
firewall --enable --trust eth0

reboot


%packages
@base
@client-mgmt-tools
@core
@debugging
@basic-desktop
@desktop-debugging
@desktop-platform
@directory-client
@fonts
@input-methods
@internet-browser
@java-platform
@legacy-x
@network-file-system-client
@print-client
@remote-desktop-clients
@server-platform
@workstation-policy
@x11
mtools
pax
python-dmidecode
oddjob
sgpio
device-mapper-persistent-data
abrt-gui
samba-winbind
certmonger
pam_krb5
krb5-workstation
libXmu

wireshark-gnome
dhcp
tftp-server
httpd
syslinux
emacs
tftp
%end

# NB.PY
%post
wget http://file.brq.redhat.com/~mbanas/nb.py -O /root/nb.py

cat > /etc/yum.repos.d/nb.repo << EOF
[nb_repo]
name=nb_repo
baseurl=http://download.eng.brq.redhat.com/pub/rhel/released/RHEL-6/6.4/Workstation/x86_64/os/
gpgcheck=0

EOF
%end

# SCRIPTS
%post
cat > /usr/local/sbin/pxe-setup <<EOF
#!/bin/bash
if [ -z "\$1" ]; then
    exit 1
fi
wget --progress=bar -r \$1 -nH --cut-dirs 8 -P /var/www/html/os/
cp -r /var/www/html/os/images /var/lib/tftpboot
# TODO: rozbalit grub.efi a vytvorit grub.conf v $TFTPBOOT
mkdir /mnt/efiboot
mount -o loop /var/lib/tftpboot/images/efiboot.img /mnt/efiboot
cp /mnt/efiboot/EFI/BOOT/BOOTX64.efi /var/lib/tftpboot/grub.efi
umount /mnt/efiboot
rmdir /mnt/efiboot
EOF
chmod +x /usr/local/sbin/pxe-setup

cat > /usr/local/sbin/pxe-start <<EOF
#!/bin/bash
echo "Be sure to have cable unplugged from internal network!!!"
read -p "press enter to continue"
nmcli con down id 'System eth0'
nmcli con up id static
service dhcpd start
service dhcpd6 start
EOF
chmod +x /usr/local/sbin/pxe-start

cat > /usr/local/sbin/pxe-stop <<EOF
#!/bin/bash
service dhcpd stop
service dhcpd6 stop
nmcli con down id static
nmcli con up id 'System eth0'
EOF
chmod +x /usr/local/sbin/pxe-stop
%end

# CONFIGURATION
%post --log=/dev/console
# INIT 5
sed -i -re 's/^id:[0-9]:initdefault:$/id:5:initdefault:/'  /etc/inittab
# AUTOLOGIN
sed -ri '/^\[daemon\]$/ a AutomaticLogin = root' /etc/gdm/custom.conf
sed -ri '/^\[daemon\]$/ a AutomaticLoginEnable = true' /etc/gdm/custom.conf

cat > /etc/dhcp/dhcpd.conf <<EOF
option domain-name "local";
option domain-name-servers 192.168.100.1;

# UEFI
#  option space PXE;
#  option PXE.mtftp-ip    code 1 = ip-address;
#  option PXE.mtftp-cport code 2 = unsigned integer 16;
#  option PXE.mtftp-sport code 3 = unsigned integer 16;
#  option PXE.mtftp-tmout code 4 = unsigned integer 8;
#  option PXE.mtftp-delay code 5 = unsigned integer 8;
option arch code 93 = unsigned integer 16; # MOZNA POVOLIT PRO UEFI

class "pxeboot" {
	match if substring(option vendor-class-identifier, 0, 9)="PXEClient";
	next-server 192.168.100.1;
	if option arch = 00:07 {
            filename "grub.efi";
        } else {
	    filename "pxelinux.0";
        }
}


subnet 192.168.100.0 netmask 255.255.255.0 {
        range 192.168.100.10 192.168.100.100;
        option routers 192.168.100.1;
}
EOF

cat > /etc/dhcp/dhcpd6.conf <<EOF
default-lease-time 2592000;
preferred-lifetime 604800;
option dhcp-renewal-time 3600;
option dhcp-rebinding-time 7200;
allow leasequery;
option dhcp6.name-servers 2001:db8:1:0::1;
option dhcp6.domain-search "test.example.com","example.com";
option dhcp6.info-refresh-time 21600;
option dhcp6.bootfile-url code 59 = string;
subnet6 2001:db8:1:0::/64 {
        range6 2001:db8:1:0::100 2001:db8:1:0::200;
        range6 2001:db8:1:0:: temporary;
        prefix6 2001:db8:1:0:: 2001:db8:1:11:: /64;
	option dhcp6.bootfile-url "tftp://[2001:db8:1:0::1]/grub.efi";
}
EOF

TFTPBOOT=/var/lib/tftpboot
mkdir $TFTPBOOT/pxelinux.cfg
cat >$TFTPBOOT/pxelinux.cfg/default <<EOF
DISPLAY boot.txt
TIMEOUT 100
ONTIMEOUT l
LABEL i
	kernel images/pxeboot/vmlinuz
	append initrd=images/pxeboot/initrd.img repo=http://192.168.100.1/os/
	ipappend 2
LABEL l
        LOCALBOOT 0
EOF

cat >$TFTPBOOT/boot.txt <<EOF
Boot Menu
---------
i - install
l - local boot
EOF

cp /usr/share/syslinux/pxelinux.0 $TFTPBOOT
cp /usr/lib/syslinux/pxelinux.0 $TFTPBOOT

cat >$TFTPBOOT/efidefault <<EOF
splashimage=/foo
timeout 5
title install
	root (nd)
	kernel /images/pxeboot/vmlinuz ip=dhcp repo=http://192.168.100.1/os/
	initrd /images/pxeboot/initrd.img
title simple.ks
	root (nd)
	kernel /images/pxeboot/vmlinuz ip=dhcp ks=http://192.168.100.1/simple.ks
	initrd /images/pxeboot/initrd.img
EOF

cat >/var/www/html/simple.ks <<EOF
install
url --url=http://192.168.100.1/os/
lang en_US.UTF-8
keyboard us
network --device eth0 --bootproto dhcp
rootpw rootoor
authconfig --useshadow
timezone --utc Europe/Prague
bootloader --location=mbr
clearpart --all --initlabel
autopart
reboot
%%packages
%%end

%%post
if [ -x '/usr/sbin/efibootmgr' ]; then
    BOOT=\$(/usr/sbin/efibootmgr -v | grep BootOrder | awk '{print $2}')
    PXE_SLOT=\$(/usr/sbin/efibootmgr -v | grep -Ei '(netboot|pxe|IPv4)' |head -n 1 |cut -c5-8)
    # If There is no Netboot Entry we can't continue
    # You have to manually setup a Netboot entry first
    # from EFI maint menu.
    if [ ! -z $PXE_SLOT ]; then
       NEWBOOT=\$(echo $BOOT| sed -e "s/\s$PXE_SLOT,//")
       NEWBOOT=\$(echo $NEWBOOT| sed -e "s/,$PXE_SLOT//")
       /usr/sbin/efibootmgr -o $PXE_SLOT,$NEWBOOT
       /usr/sbin/efibootmgr -n \$(echo $BOOT | cut -d, -f 1)
    fi
fi

%%end
EOF

chkconfig tftp on
sed -ri 's/(.*flags.*)/#\1/' /etc/xinetd.d/tftp

/usr/local/sbin/pxe-setup ftp://download.englab.brq.redhat.com/pub/rhel/released/RHEL-6/6.4/ComputeNode/x86_64/os/

# TODO: pridat staticky nastaveni NM
cat >/etc/sysconfig/network-scripts/ifcfg-pxe_server <<EOF
TYPE=Ethernet
BOOTPROTO=none
IPADDR=192.168.100.1
PREFIX=24
DEFROUTE=yes
IPV4_FAILURE_FATAL=yes
IPV6INIT=yes
IPV6FORWARDING=yes
IPV6ADDR=2001:db8:1:0::1
NAME=pxe-server
UUID=e913932d-a73c-4736-9c58-a05cdc055dcc
ONBOOT=no
EOF

%end

Reference

  1. Fedora netboot pxe config
  2. RHEL6 AP install server