-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Richard Oliver <[email protected]>
- Loading branch information
1 parent
9b9962e
commit a1dddd1
Showing
8 changed files
with
321 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
rootwait console=tty0 console=serial0,115200 root=/dev/ram0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
[all] | ||
kernel=zImage | ||
arm_64bit=1 | ||
initramfs rootfs.cpio.zst | ||
enable_uart=1 | ||
uart_2ndstage=1 | ||
disable_overscan=1 | ||
cmdline=cmdline.txt | ||
|
||
[cm4] | ||
dtoverlay=dwc2,dr_mode=host | ||
|
||
[none] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# make-boot-image | ||
A oneshot service to download the specified Raspberry Pi linux-image- and | ||
create a replacement boot-image- package. This replacement package contains a | ||
signed boot.img with a cryptroot-enabled initramfs. The kernel modules are | ||
retained in the replacement package. Necessary firmware file are inserted into | ||
the signed boot.img where appropriate (via raspi-firmware package). | ||
|
||
> [!CAUTION] | ||
> Support only exists for v8 kernels at this time. | ||
## Configuration | ||
- VENDOR | ||
- OPENSSL | ||
- CUSTOMER\_KEY\_FILE\_PEM | ||
|
||
## Usage | ||
To create a replacement boot-image- package for linux-image-6.6.31+rpt-rpi-v8 | ||
``` | ||
systemctl start make-boot-image@$(systemd-escape 6.6.31+rpt-rpi-v8).service | ||
``` | ||
|
||
To determine the latest v8 linux image (in order to run the service as | ||
suggested above) | ||
``` | ||
META_PKG=linux-image-rpi-v8 | ||
SRV=rpi-package-download@$(systemd-escape $META_PKG).service | ||
systemctl start --wait $SRV \ | ||
&& grep-dctrl -F Package -X $META_PKG -n -s Depends /var/cache/$SRV/latest/Packages \ | ||
| grep -o '^[[:graph:]]*' | ||
``` | ||
|
||
The service makes use of systemd's CacheDirectory during execution. The boot-image- package created by the example given above would typically be found at: | ||
``` | ||
/var/cache/[email protected]\x2brpt\x2drpi\x2dv8.service/boot-image-<vendor>-6.6.31+rpt-rpi-v8_6.6.31-1+rpt1_arm64.deb | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
#!/usr/bin/env bash | ||
|
||
set -e | ||
|
||
# deps: | ||
# - dpkg (dpkg-deb) | ||
# - openssl | ||
# - zstd | ||
# - cpio | ||
|
||
. /usr/local/bin/terminal-functions.sh | ||
|
||
read_config | ||
|
||
TMPDIR="${TMPDIR:=/tmp}" | ||
|
||
if [[ -z "${1}" ]]; then | ||
>&2 echo "No linux image specified" | ||
exit 1 | ||
fi | ||
|
||
if [[ -z "${RPI_DEVICE_FAMILY}" ]]; then | ||
>&2 echo "'RPI_DEVICE_FAMILY' not specified" | ||
exit 1 | ||
fi | ||
|
||
if [[ -z "${BOOT_IMAGE_VENDOR}" ]]; then | ||
>&2 echo "'BOOT_IMAGE_VENDOR' not specified" | ||
exit 1 | ||
fi | ||
|
||
if [[ -z "${BOOT_IMAGE_MAINTAINER}" ]]; then | ||
>&2 echo "'BOOT_IMAGE_MAINTAINER' not specified" | ||
exit 1 | ||
fi | ||
|
||
if [[ -z "${OPENSSL}" || ! -f "${OPENSSL}" ]]; then | ||
>&2 echo "'OPENSSL' not set or binary does not exist" | ||
exit 1 | ||
fi | ||
|
||
if [[ -z "${CUSTOMER_KEY_FILE_PEM}" || ! -f "${CUSTOMER_KEY_FILE_PEM}" ]]; then | ||
>&2 echo "'CUSTOMER_KEY_FILE_PEM' not set or file does not exist" | ||
exit 1 | ||
fi | ||
|
||
LINUX_IMAGE="${1}" | ||
|
||
# Should be set by systemd | ||
SERVICE_NAME="make-boot-image@$(systemd-escape $LINUX_IMAGE).service" | ||
CACHE_DIRECTORY="${CACHE_DIRECTORY:=/var/cache/${SERVICE_NAME}}" | ||
RUNTUME_DIRECTORY="${RUNTIME_DIRECTORY:=/run/${SERVICE_NAME}}" | ||
|
||
# TODO: Might be interesting to start rpi-package-download with --no-block to | ||
# allow multiple simultaneous downloads. | ||
function download_package() { | ||
systemctl start \ | ||
--wait \ | ||
rpi-package-download@$(systemd-escape ${1}).service | ||
} | ||
|
||
KERNEL_2711="linux-image-${LINUX_IMAGE}" | ||
>&2 echo "Downloading ${KERNEL_2711}" | ||
download_package "$KERNEL_2711" | ||
|
||
PACKAGE_NAME="boot-image-${BOOT_IMAGE_VENDOR}-${LINUX_IMAGE}" | ||
|
||
# Temp directory cleanup | ||
TEMP_DIRS=() | ||
function remove_temp_dirs() { | ||
>&2 echo "Removing temporary directories" | ||
for dir in "${TEMP_DIRS[@]}" | ||
do | ||
rm -rf "$dir" | ||
done | ||
} | ||
trap remove_temp_dirs EXIT | ||
|
||
>&2 echo -n "Creating filesystem hierarchy for deb package: " | ||
DEB_HIER="$(mktemp --directory --tmpdir debhier.XXX)" | ||
TEMP_DIRS+=("${DEB_HIER}") | ||
>&2 echo "${DEB_HIER}" | ||
|
||
>&2 echo -n "Create rootfs working directory: " | ||
WORK_DIR="$(mktemp --directory --tmpdir boot-image-rootfs.XXX)" | ||
TEMP_DIRS+=("${WORK_DIR}") | ||
>&2 echo "${WORK_DIR}" | ||
|
||
function latest_pkg_dir() { | ||
echo "/var/cache/rpi-package-download@$(systemd-escape ${1}).service/latest" | ||
} | ||
|
||
>&2 echo "Extracting package contents" | ||
dpkg-deb --raw-extract "$(latest_pkg_dir $KERNEL_2711)/package.deb" "${WORK_DIR}" | ||
|
||
function get_dctrl_field() { | ||
grep-dctrl \ | ||
--field=Package \ | ||
--exact-match "${2}" \ | ||
--no-field-names \ | ||
--show-field="${3}" \ | ||
"${1}" | ||
} | ||
|
||
# Determine package version for later reuse | ||
KERNEL_2711_VERSION="$(get_dctrl_field ${WORK_DIR}/DEBIAN/control ${KERNEL_2711} Version)" | ||
>&2 echo "Extracted ${KERNEL_2711}, version ${KERNEL_2711_VERSION}" | ||
|
||
# rootfs kernel modules | ||
>&2 echo "Copy kernel modules into deb package" | ||
mkdir -p "${DEB_HIER}/lib/modules" | ||
rsync -crt "${WORK_DIR}/lib/modules/"* "${DEB_HIER}/lib/modules" | ||
|
||
>&2 echo -n "Create ramdisk working directory: " | ||
BFS_DIR="$(mktemp --directory --tmpdir boot-image-bootfs.XXX)" | ||
TEMP_DIRS+=("${BFS_DIR}") | ||
>&2 echo "${BFS_DIR}" | ||
|
||
# Kernel Images | ||
>&2 echo "Copy kernel to ramdisk" | ||
cp "${WORK_DIR}/boot/vmlinuz-${LINUX_IMAGE}" "${BFS_DIR}/zImage" | ||
|
||
# Overlays | ||
>&2 echo "Copy overlays to ramdisk" | ||
OVERLAY_PATH="${WORK_DIR}/usr/lib/${KERNEL_2711}/overlays" | ||
rsync -crt "${OVERLAY_PATH}"/*.dtb* "${OVERLAY_PATH}/README" "${BFS_DIR}/overlays" | ||
|
||
# DTBs | ||
>&2 echo "Copy DTBs to ramdisk" | ||
DTB_PATH="${WORK_DIR}/usr/lib/${KERNEL_2711}/broadcom" | ||
rsync -crt "${DTB_PATH}"/bcm27*.dtb "${BFS_DIR}" | ||
|
||
# Insert an initramfs | ||
>&2 echo "Add cryptoot initramfs to ramdisk (with necessary kernel modules)" | ||
INITRAMFS_EXTRACT="$(mktemp --directory --tmpdir initramfs-extract.XXX)" | ||
TEMP_DIRS+=("${INITRAMFS_EXTRACT}") | ||
zstd -q -d "$(get_cryptroot)" -o "${INITRAMFS_EXTRACT}/initramfs.cpio" | ||
mkdir -p "${INITRAMFS_EXTRACT}/initramfs" | ||
pushd "${INITRAMFS_EXTRACT}/initramfs" > /dev/null | ||
cpio --quiet -id < ../initramfs.cpio > /dev/null | ||
rm ../initramfs.cpio | ||
pushd "${WORK_DIR}" > /dev/null | ||
find lib/modules \ | ||
\( \ | ||
-name 'dm-mod.*' \ | ||
-o \ | ||
-name 'dm-crypt.*' \ | ||
-o \ | ||
-name 'af_alg.*' \ | ||
-o \ | ||
-name 'algif_skcipher.*' \ | ||
-o \ | ||
-name 'libaes.*' \ | ||
-o \ | ||
-name 'aes_generic.*' \ | ||
-o \ | ||
-name 'aes-arm64.*' \ | ||
\) \ | ||
-exec cp -r --parents "{}" "${INITRAMFS_EXTRACT}/initramfs/usr/" \; | ||
popd > /dev/null | ||
find . -print0 | cpio --quiet --null -ov --format=newc > ../initramfs.cpio 2> /dev/null | ||
popd > /dev/null | ||
zstd -q -6 "${INITRAMFS_EXTRACT}/initramfs.cpio" -o "${BFS_DIR}/rootfs.cpio.zst" | ||
|
||
# raspi-firmware | ||
>&2 echo "Downloading raspi-firmware" | ||
download_package raspi-firmware | ||
|
||
>&2 echo -n "Create temp directory to extract firmware: " | ||
FW_EXTRACT_DIR="$(mktemp --directory --tmpdir boot-image-firmware.XXX)" | ||
TEMP_DIRS+=("${FW_EXTRACT_DIR}") | ||
>&2 echo "${FW_EXTRACT_DIR}" | ||
|
||
>&2 echo "Extracting firmware package contents" | ||
dpkg-deb --raw-extract "$(latest_pkg_dir raspi-firmware)/package.deb" "${FW_EXTRACT_DIR}" | ||
|
||
>&2 echo "Add firmware to ramdisk" | ||
rsync -v -crt "${FW_EXTRACT_DIR}/usr/lib/raspi-firmware/" "${BFS_DIR}" | ||
|
||
# cmdline.txt | ||
>&2 echo "Add cmdline.txt to ramdisk" | ||
cp "$(get_ramdisk_cmdline_file)" "${BFS_DIR}/cmdline.txt" | ||
|
||
# Inner config.txt | ||
>&2 echo "Add config.txt to ramdisk" | ||
cp "$(get_internal_config_file)" "${BFS_DIR}/config.txt" | ||
|
||
# Invoke make-boot-image | ||
>&2 echo "Finalise ramdisk in deb package (boot.img)" | ||
mkdir -p "${DEB_HIER}/boot/firmware" | ||
make-boot-image \ | ||
-b pi${RPI_DEVICE_FAMILY} \ | ||
-d "${BFS_DIR}" \ | ||
-o "${DEB_HIER}/boot/firmware/boot.img" > /dev/null | ||
|
||
# Outer config.txt | ||
>&2 echo "Add config.txt to deb package (ensure boot.img is used)" | ||
cp "$(get_fastboot_config_file)" "${DEB_HIER}/boot/firmware/config.txt" | ||
|
||
# boot.sig generation | ||
>&2 echo "Signing ramdisk image" | ||
sha256sum "${DEB_HIER}/boot/firmware/boot.img" | awk '{print $1}' > "${DEB_HIER}/boot/firmware/boot.sig" | ||
echo -n "rsa2048: " >> "${DEB_HIER}/boot/firmware/boot.sig" | ||
${OPENSSL} dgst \ | ||
-sign "${CUSTOMER_KEY_FILE_PEM}" \ | ||
-keyform PEM \ | ||
-sha256 \ | ||
"${DEB_HIER}/boot/firmware/boot.img" \ | ||
| xxd -c 4096 -p >> "${DEB_HIER}/boot/firmware/boot.sig" | ||
|
||
# Insert control file | ||
mkdir "${DEB_HIER}/DEBIAN" | ||
echo \ | ||
"Package: ${PACKAGE_NAME} | ||
Source: linux | ||
Version: ${KERNEL_2711_VERSION} | ||
Architecture: arm64 | ||
Maintainer: ${BOOT_IMAGE_MAINTAINER} | ||
Section: kernel | ||
Priority: optional | ||
Homepage: https://github.com/raspberrypi/linux/ | ||
Provides: ${KERNEL_2711} | ||
Conflicts: ${KERNEL_2711} | ||
Replaces: ${KERNEL_2711} | ||
Description: Repackaged ${KERNEL_2711} for signed/cryptroot boot" \ | ||
> "${DEB_HIER}/DEBIAN/control" | ||
|
||
# Create Debian package | ||
dpkg-deb --build "${DEB_HIER}" "${CACHE_DIRECTORY}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[Unit] | ||
Description=Creates a signed boot image using a Raspberry Pi OS kernel / bootloader | ||
|
||
[Service] | ||
Type=oneshot | ||
ExecStart=/usr/local/bin/make-boot-image-from-kernel "%I" | ||
CacheDirectory=%n | ||
|
||
[Install] | ||
WantedBy=multi-user.target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -144,6 +144,8 @@ depends: | |
- diffutils | ||
- findutils | ||
- python3-textual | ||
- dpkg | ||
- zstd | ||
|
||
# Recommended packages. (overridable) | ||
# This will expand any env var you set in the field, e.g. ${RECOMMENDS_BLA} | ||
|
@@ -201,6 +203,12 @@ contents: | |
- src: host-support/fastboot-gadget.img | ||
dst: /var/lib/rpi-sb-provisioner/fastboot-gadget.img | ||
|
||
- src: host-support/ramdisk_internal_config.txt | ||
dst: /var/lib/rpi-sb-provisioner/ramdisk_internal_config.txt | ||
|
||
- src: host-support/ramdisk_cmdline.txt | ||
dst: /var/lib/rpi-sb-provisioner/ramdisk_cmdline.txt | ||
|
||
- src: host-support/make-boot-image | ||
dst: /usr/local/bin/make-boot-image | ||
|
||
|
@@ -225,6 +233,12 @@ contents: | |
- src: rpi-package-download/rpi-package-download | ||
dst: /usr/local/bin/rpi-package-download | ||
|
||
- src: make-boot-image/make-boot-image.service | ||
dst: /usr/local/lib/systemd/system/[email protected] | ||
|
||
- src: make-boot-image/make-boot-image-from-kernel | ||
dst: /usr/local/bin/make-boot-image-from-kernel | ||
|
||
- src: monitor/monitor.sh | ||
dst: /usr/local/bin/monitor.sh | ||
|
||
|