PXE 启动 archlinux

本文最后更新于 2024年3月30日 晚上

本文没有编写完成,以后也许不会更新。

最近想整个 PXE 启动的 archlinux 环境,启动之后像 archiso 一样,跑在内存里面。

实现思路

PXE 启动 grub, 然后走 http 下载 kernel 和 initramfs, 在 initramfs 启动过程中下载 rootfs,最后 switch_root 到 rootfs。

搭建一个 tftp、dhcp、http server

根据 archwiki 的指导,我们用 dnsmasq 作为 tftp 与 dhcp server. 下面是我的 dnsmasq 配置(与软件包内置版本的 diff)

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
diff --git a/dnsmasq.conf b/dnsmasq.conf
index 936e468..07aa658 100644
--- a/dnsmasq.conf
+++ b/dnsmasq.conf
@@ -7,7 +7,7 @@
# Listen on this specific port instead of the standard DNS port
# (53). Setting this to zero completely disables DNS function,
# leaving only DHCP and/or TFTP.
-#port=5353
+port=0

# The following two options make you a better netizen, since they
# tell dnsmasq to filter out queries which the public DNS cannot
@@ -113,7 +113,9 @@
# specified interfaces (and the loopback) give the name of the
# interface (eg eth0) here.
# Repeat the line for more than one interface.
-#interface=
+interface=wlp3s0
+interface=virbr0
+interface=br0
# Or you can specify which interface _not_ to listen on
#except-interface=
# Or which to listen on by address (remember to include 127.0.0.1 if
@@ -164,8 +166,9 @@
# a lease time. If you have more than one network, you will need to
# repeat this for each network on which you want to supply DHCP
# service.
-#dhcp-range=192.168.0.50,192.168.0.150,12h
-
+dhcp-range=192.168.122.50,192.168.122.150,12h
+dhcp-range=192.168.2.1,proxy
+dhcp-range=10.42.0.50,10.42.0.240,12h
# This is an example of a DHCP range where the netmask is given. This
# is needed for networks we reach the dnsmasq DHCP server via a relay
# agent. If you don't know what a DHCP relay agent is, you probably
@@ -439,9 +442,9 @@
# Magic number - needed before anything else is recognised
#dhcp-option-force=208,f1:00:74:7e
# Configuration file name
-#dhcp-option-force=209,configs/common
+dhcp-option-force=209,archiso_pxe.cfg
# Path prefix
-#dhcp-option-force=210,/tftpboot/pxelinux/files/
+dhcp-option-force=210,
# Reboot time. (Note 'i' to send 32-bit value)
#dhcp-option-force=211,30i

@@ -449,7 +452,7 @@
# this if you want to boot machines over the network and you will need
# a TFTP server; either dnsmasq's built-in TFTP server or an
# external one. (See below for how to enable the TFTP server.)
-#dhcp-boot=pxelinux.0
+dhcp-boot=/boot/syslinux/ipxe.pxe

# The same as above, but use custom tftp-server instead machine running dnsmasq
#dhcp-boot=pxelinux,server.name,192.168.1.100
@@ -458,8 +461,8 @@
# filenames, the first loads iPXE, and the second tells iPXE what to
# load. The dhcp-match sets the ipxe tag for requests from iPXE.
#dhcp-boot=undionly.kpxe
-#dhcp-match=set:ipxe,175 # iPXE sends a 175 option.
-#dhcp-boot=tag:ipxe,http://boot.ipxe.org/demo/boot.php
+dhcp-match=set:ipxe,175 # iPXE sends a 175 option.
+dhcp-boot=tag:ipxe,/boot/syslinux/lpxelinux.0

# Encapsulated options for iPXE. All the options are
# encapsulated within option 175
@@ -506,10 +509,10 @@


# Enable dnsmasq's built-in TFTP server
-#enable-tftp
+enable-tftp

# Set the root directory for files available via FTP.
-#tftp-root=/var/ftpd
+tftp-root=/tmp/pxe/archiso

# Do not abort if the tftp-root is unavailable
#tftp-no-fail
@@ -671,7 +674,7 @@
#log-queries

# Log lots of extra information about DHCP transactions.
-#log-dhcp
+log-dhcp

# Include another lot of configuration options.
#conf-file=/etc/dnsmasq.more.conf

工作目录为 /tmp/pxe,下面是目录结构 archiso 目录是 archlinux-2023.12.01-x86_64.iso 解压后的文件夹

1
2
3
4
5
6
7
8
9
10
/tmp/pxe
├── archiso
│   ├── arch
│   ├── boot
│   ├── EFI
│   ├── shellia32.efi
│   └── shellx64.efi
├── archlinux-2023.12.01-x86_64.iso
└── dnsmasq.conf

dnsmasq 启动命令为 (-d 是为了看输出)

1
sudo dnsmasq -C dnsmasq.conf -d

http server 的启动命令为

1
sudo darkhttpd /tmp/pxe/archiso --port 80

然后我们从 qemu 建立一个虚拟机,走 pxe 启动,就能进入 livecd 了。

qemu 启动命令

1
2
sudo qemu-system-x86_64 -boot n -netdev tap,id=mynet0,ifname=tap0,script=no,downscript=no -device e1000,netdev=mynet0,mac=52:55:00:d1:55:01 -nographic -curses

自定义 initramfs

1
find . 2>/dev/null | cpio -o  -R root:root -H newc | xz -3 --format=lzma > ../initramfs-linux.img

自定义 rootfs

1
pacstrap -K NEWROOT base base-devel

然后打包成 squashfs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sudo mksquashfs . ../airootfs.sfs \
-not-reproducible \
-xattrs \
-wildcards \
-noappend \
-progress \
-mem 5G \
-e \
var/cache/pacman/pkg \
var/lib/pacman/sync \
var/log/journal \
efi \
boot/grub \
boot/initramfs-linux"*".img \
boot/vmlinuz-linux

qemu 调试

1
2
3
4
5
6
7
8
9
10
qemu-system-x86_64 \
-m 8G \
-chardev stdio,id=char0,logfile=serial.log,signal=off \
-serial chardev:char0 \
-vga virtio \
-net nic -net user \
-device nec-usb-xhci,id=xhci,addr=0x1b \
-device usb-tablet,id=tablet,bus=xhci.0,port=1 \
-device usb-kbd,id=keyboard,bus=xhci.0,port=2 \
-smp 4,cores=4 -kernel vmlinuz-linux -initrd initramfs-linux.img -append 'ip=:::::eth0:dhcp'

参考资料

  1. Preboot Execution Environment
  2. PXE network boot methods

PXE 启动 archlinux
https://blog.askk.cc/2023/12/24/archlinux-pxeboot/
作者
sukanka
发布于
2023年12月24日
许可协议