The emergency boot protocol is a protocol that allows you to download a kernel for emergency booting. This protocol is useful if your internal kernel is corrupted or if you want to boot a another kernel.
The emergency_server.py
script is a Python script that allows you to upload a kernel to the bootloader. This script is used by the emergency_boot
command.
This secion will not explain how to use the emergency_server.py
script (which is explained in the HOWTO.md file). Instead, this section will explain how the script works.
The protocol is like a tiny-TCP network over serial.
The server split the file to send into chunks and then send them to the bootloader using packets.
Here is a C struct that represents a packet:
struct emergency_packet
{
u8 ctrl_c;
u64 size;
u32 crc;
char data[PACKET_MAX_SIZE];
};
The protocol uses acknowledgment to ensure that the pairs receive the packets correctly.
A packet is considered as acknowledged if its CRC32 is correct and if the ctrl_c
field is set to NUL
. Else, the packet is considered as not acknowledged (NAK
).
If a pair receives a NAK
, it will resend the packet until it receives an ACK
.
The ctrl_c
field is used to communicate acknowledgment.
When a packet is sent, the ctrl_c
field is set to NUL
(the only exception is the first hello packet, which set ctrl_c
to ENQ
).
The size
field is used to communicate the size of the data field.
It can be between 0 and PACKET_MAX_SIZE
. If the size
field is not in this range, the packet is considered as NAK
.
The crc
field is used to communicate the CRC32 of the data field.
It is used to ensure that the data field is not corrupted.
The data[]
field is used to communicate the data.
It size is size
bytes.
Let's say you want to send a file of n
bytes on a serial port.
-
The server sends a hello packet to the bootloader :
ctrl_c
is set toENQ
size
is set to 0crc
is set tocrc32(0)
data[]
is empty
-
The bootloader receives the hello packet and sends an
ACK
packet :ctrl_c
is set toACK
size
is set to 0crc
is set tocrc32(0)
data[]
is empty
-
The server (after receiving the
ACK
packet) sends the size of the file :ctrl_c
is set toNUL
size
is set tosizeof(u64)
crc
is set tocrc32(data, size)
data[]
is set ton
(as au64
)
-
The bootloader receives the size packet and sends an
ACK
packet :ctrl_c
is set toACK
size
is set to 0crc
is set tocrc32(0)
data[]
is empty
This file size is used to permit the bootloader to allocate the memory needed to store the file.
-
The server (after receiving the
ACK
packet) sends the file in chunks ofPACKET_MAX_SIZE
bytes until the file is fully sent :ctrl_c
is set toNUL
size
is set tomin(PACKET_MAX_SIZE, n - i * PACKET_MAX_SIZE)
(wherei
is the chunk number)crc
is set tocrc32(data, size)
data[]
contains the chunk of data
Of course every packet need to be acknowledged.
-
The bootloader receives the last chunk and sends an
EOT
packet to terminate the transmission :ctrl_c
is set toEOT
size
is set to 0crc
is set tocrc32(0)
data[]
is empty