Skip to content

Commit 28f9185

Browse files
Create new file for network booting
1 parent df0423c commit 28f9185

File tree

1 file changed

+142
-0
lines changed
  • hardware/raspberrypi/bootmodes

1 file changed

+142
-0
lines changed

hardware/raspberrypi/bootmodes/net.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# Network booting
2+
3+
To network boot the bootrom does the following:
4+
5+
* Initialise LAN9500
6+
* Send DHCP request
7+
* Receive DHCP reply
8+
* (optional) Receive DHCP proxy reply
9+
* ARP to tftpboot server
10+
* ARP reply includes tftpboot server ethernet address
11+
* TFTP RRQ 'bootcode.bin'
12+
* File not found: Server replies with TFTP error response with textual error message
13+
* File exists: Server will reply with the first block (512 bytes) of data for the file with a block number in the header
14+
* Pi replys with TFTP ACK packet containing the block number, repeats until the last block which is not 512 bytes
15+
* TFTP RRQ 'bootsig.bin'
16+
* This will normally result in an error file not found...
17+
18+
From this point the bootcode.bin code continues to load the system, the first file it will try to access is [`serial_number`]/start.elf if this does __not__ result in a error then any other files to be read will be pre-pended with the `serial_number`. This is useful because if enables you to create separate directories with separate start.elf / kernels for your Pis
19+
To get the serial number for the device you can either try this boot mode and see what file is accessed using tcpdump / wireshark or you can run a standard Raspbian SD card and `cat /proc/cpuinfo`
20+
21+
If you put all your files into the root of your tftp directory then all following files will be accessed from there.
22+
23+
# Setting up a DHCP / TFTP server
24+
25+
This tutorial is written to explain how to set up a simple DHCP / TFTP server to boot a Raspberry Pi 3 from the network. This first tutorial assumes you only have a Raspberry Pi for the SERVER and a Pi 3 as a CLIENT to be booted.
26+
27+
Install a standard Raspbian lite (or heavy if you want) from the [Downloads page](https://www.raspberrypi.org/downloads/raspbian/) onto an SD card using whatever process you like (dd or Win32DiskImager or something similar). Before booting the Client edit the config.txt and add the following to config.txt
28+
29+
```
30+
program_usb_boot_mode=1
31+
```
32+
33+
Now copy [start.elf](start.elf) and [bootcode.bin](bootcode.bin) to the sdcard overwriting the currently existing start.elf and bootcode.bin, you should also:
34+
35+
```
36+
rm start_* fixup*
37+
```
38+
39+
Plug the SD card into the CLIENT and boot it with a keyboard and HDMI connected. When it boots, log in and check that the OTP is correctly programmed
40+
41+
```
42+
$ vcgencmd otp_dump | grep 17:
43+
17:3020000a
44+
```
45+
46+
Make sure the 0x3020000a is correct.
47+
48+
Now, shutdown the Pi gracefully and re-edit the config.txt file to remove the `program_usb_boot_mode` (you don't actually have to do this, it will enable USB boot modes but shouldn't break anything.)
49+
50+
Plug the SD card into the SERVER and boot the server, with it connected to the internet install some useful applications:
51+
52+
```
53+
sudo apt-get install tcpdump
54+
sudo apt-get install dnsmasq
55+
echo "denyinterfaces eth0" | sudo tee -a /etc/dhcpcd.conf
56+
```
57+
58+
After this we'll need to fix DNS because dnsmasq breaks it a bit...
59+
60+
```
61+
sudo rm /etc/resolvconf/update.d/dnsmasq
62+
sudo reboot
63+
```
64+
65+
Now Take an ethernet cable and plug it directly between the SERVER and the CLIENT and set a static IP address on the SERVER:
66+
67+
```
68+
sudo ifconfig eth0 down
69+
sudo ifconfig eth0 up 192.168.1.1 netmask 255.255.255.0 broadcast 192.168.1.255
70+
sudo tcpdump -i eth0
71+
```
72+
Now power the CLIENT
73+
74+
Check that the LEDs illuminate on the CLIENT after around 10 seconds, then you get a packet from the CLIENT "DHCP/BOOTP, Request from ..."
75+
76+
Now we need to modify the dnsmasq configuration to enable DHCP to reply to the device ...
77+
78+
```
79+
sudo echo | sudo tee /etc/dnsmasq.conf
80+
sudo nano /etc/dnsmasq.conf
81+
```
82+
83+
Then replace the contents of dnsmasq.conf with:
84+
85+
```
86+
port=0
87+
log-dhcp
88+
enable-tftp
89+
tftp-root=/tftpboot
90+
dhcp-range=eth0,192.168.1.100,192.168.1.150,12h
91+
pxe-service=0,"Raspberry Pi Boot"
92+
```
93+
94+
It's important that the 192.168.1.x matches the subnet you used in the static IP settings, the range is what it'll share
95+
96+
Now create a /tftpboot directory
97+
98+
```
99+
$ sudo mkdir /tftpboot
100+
$ sudo chmod 777 /tftpboot
101+
$ sudo systemctl restart dnsmasq.service
102+
```
103+
104+
Next we can try the tcpdump again...
105+
106+
```
107+
sudo tcpdump -i eth0
108+
```
109+
110+
You should see a DHCP REPLY packet and a TFTP read request packet, for "bootcode.bin"
111+
112+
Next, you will need to copy [bootcode.bin](bootcode.bin) and [start.elf](start.elf) into the /tftpboot directory, you should be able to do this by just copying the files from /boot since they are the right ones...
113+
114+
```
115+
cp /boot/bootcode.bin /tftpboot
116+
cp /boot/start.elf /tftpboot
117+
```
118+
119+
Now when you power off and then power on the CLIENT tcpdump should give lots of data and the result should be the green LED flashing (this means it couldn't find the kernel, not surprising since we didn't give it one...)
120+
121+
Next, we need to provide the other files (kernel and dt overlays etc) which are currently stored on the SERVER's boot directory, so:
122+
123+
```
124+
cp -r /boot/* /tftpboot
125+
```
126+
127+
This should now allow your Pi to boot through until it tried to load a root filesystem (which it doesn't have)... This is the point where you need to provide a filing system which is beyond this tutorial... Although I'll give you some clues for sharing the SERVERS filesystem with the client...
128+
129+
* Reboot SERVER with a normal ethernet connection (you'll probably need to remove the dhcpcd.conf line to re-enable the client)
130+
* `sudo apt-get install nfs-kernel-server`
131+
* `sudo vi /etc/exports`
132+
* Add the line "/ *(rw,sync,no_subtree_check)" to exports
133+
* sudo systemctl restart rpcbind.service
134+
* sudo systemctl restart nfs-kernel-server.service
135+
* Reboot with the ethernet connected to the CLIENT and do the static IP thing again
136+
* Check the mount is working using something like `sudo mount 192.168.1.1:/ tmp`
137+
* edit /tftpboot/cmdline.txt and change to
138+
* "root=/dev/nfs nfsroot=192.168.1.1:/ rw ip=dhcp rootwait"
139+
* edit /etc/fstab and remove the /dev/mmcblkp1 and p2 lines
140+
* edit /boot/cmdline.txt (the SERVER's cmdline) and add "rw" to the line
141+
142+
Think that's it... Good luck...

0 commit comments

Comments
 (0)