Compresses rootfs image.
This commit is contained in:
parent
ad25a74ac0
commit
4a1993e75b
|
@ -15,8 +15,11 @@
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
packages = {
|
packages = let
|
||||||
default = import ./orange.nix { inherit pkgs; };
|
orange = import ./sd-card.nix { inherit pkgs; };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
default = orange;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
90
orange.nix
90
orange.nix
|
@ -1,90 +0,0 @@
|
||||||
{ pkgs }:
|
|
||||||
|
|
||||||
let
|
|
||||||
imageName = "orange";
|
|
||||||
firmwarePartition = {
|
|
||||||
offset = 8;
|
|
||||||
id = "0xfeed3425";
|
|
||||||
name = "FIRMWARE";
|
|
||||||
size = 512;
|
|
||||||
};
|
|
||||||
|
|
||||||
rootfsImage = import ./rootfs.nix { inherit pkgs; };
|
|
||||||
|
|
||||||
configTxt = pkgs.writeText "config.txt" (builtins.readFile ./config.txt);
|
|
||||||
populateFirmwareCommands = ''
|
|
||||||
# Add config.txt
|
|
||||||
cp ${configTxt} firmware/config.txt
|
|
||||||
|
|
||||||
# Copy the firmware files
|
|
||||||
cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/bootcode.bin firmware/
|
|
||||||
cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/fixup*.dat firmware/
|
|
||||||
cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/start*.elf firmware/
|
|
||||||
|
|
||||||
# Add pi3 specific files
|
|
||||||
cp ${pkgs.ubootRaspberryPi3_64bit}/u-boot.bin firmware/u-boot-rpi3.bin
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
pkgs.stdenv.mkDerivation {
|
|
||||||
name = imageName;
|
|
||||||
|
|
||||||
nativeBuildInputs = with pkgs; [ dosfstools e2fsprogs libfaketime mtools util-linux zstd ];
|
|
||||||
|
|
||||||
buildCommand = ''
|
|
||||||
mkdir -p $out/nix-support $out/sd-image
|
|
||||||
export img=$out/sd-image/${imageName}
|
|
||||||
echo "${pkgs.stdenv.buildPlatform.system}" > $out/nix-support/system
|
|
||||||
echo "file sd-image $img.zst" >> $out/nix-support/hydra-build-products
|
|
||||||
root_fs=${rootfsImage}
|
|
||||||
|
|
||||||
# Gap in front of the first partition, in MiB
|
|
||||||
gap=${toString firmwarePartition.offset}
|
|
||||||
|
|
||||||
# Create the image file sized to fit /boot/firmware and /, plus slack for the gap.
|
|
||||||
rootSizeBlocks=$(du -B 512 --apparent-size $root_fs | awk '{ print $1 }')
|
|
||||||
firmwareSizeBlocks=$((${toString firmwarePartition.size} * 1024 * 1024 / 512))
|
|
||||||
imageSize=$((rootSizeBlocks * 512 + firmwareSizeBlocks * 512 + gap * 1024 * 1024))
|
|
||||||
truncate -s $imageSize $img
|
|
||||||
|
|
||||||
# type=b is 'W95 FAT32', type=83 is 'Linux'.
|
|
||||||
# The "bootable" partition is where u-boot will look file for the bootloader
|
|
||||||
# information (dtbs, extlinux.conf file).
|
|
||||||
sfdisk $img <<EOF
|
|
||||||
label: dos
|
|
||||||
label-id: ${firmwarePartition.id}
|
|
||||||
start=''${gap}M, size=$firmwareSizeBlocks, type=b
|
|
||||||
start=$((gap + ${toString firmwarePartition.size}))M, type=83, bootable
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Copy the rootfs into the SD image
|
|
||||||
eval $(partx $img -o START,SECTORS --nr 2 --pairs)
|
|
||||||
dd conv=notrunc if=$root_fs of=$img seek=$START count=$SECTORS
|
|
||||||
|
|
||||||
# Create a FAT32 /boot/firmware partition of suitable size into firmware_part.img
|
|
||||||
eval $(partx $img -o START,SECTORS --nr 1 --pairs)
|
|
||||||
truncate -s $((SECTORS * 512)) firmware_part.img
|
|
||||||
mkfs.vfat --invariant -i ${toString firmwarePartition.size} -n ${firmwarePartition.name} firmware_part.img
|
|
||||||
|
|
||||||
# Populate the files intended for /boot/firmware
|
|
||||||
mkdir firmware
|
|
||||||
${populateFirmwareCommands}
|
|
||||||
find firmware -exec touch --date=2000-01-01 {} +
|
|
||||||
|
|
||||||
# Copy the populated /boot/firmware into the SD image
|
|
||||||
cd firmware
|
|
||||||
# Force a fixed order in mcopy for better determinism, and avoid file globbing
|
|
||||||
for d in $(find . -type d -mindepth 1 | sort); do
|
|
||||||
faketime "2000-01-01 00:00:00" mmd -i ../firmware_part.img "::/$d"
|
|
||||||
done
|
|
||||||
for f in $(find . -type f | sort); do
|
|
||||||
mcopy -pvm -i ../firmware_part.img "$f" "::/$f"
|
|
||||||
done
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
# Verify the FAT partition before copying it.
|
|
||||||
fsck.vfat -vn firmware_part.img
|
|
||||||
|
|
||||||
dd conv=notrunc if=firmware_part.img of=$img seek=$START count=$SECTORS
|
|
||||||
zstd -T$NIX_BUILD_CORES --rm $img
|
|
||||||
'';
|
|
||||||
}
|
|
11
rootfs.nix
11
rootfs.nix
|
@ -1,3 +1,12 @@
|
||||||
{ pkgs }:
|
{ pkgs }:
|
||||||
|
|
||||||
pkgs.runCommand "rootfs" {} "truncate -s 1M $out"
|
pkgs.stdenv.mkDerivation {
|
||||||
|
name = "orange-rootfs.img.zstd";
|
||||||
|
|
||||||
|
nativeBuildInputs = with pkgs; [ zstd ];
|
||||||
|
|
||||||
|
buildCommand = ''
|
||||||
|
truncate -s 1M ./rootfs.img
|
||||||
|
zstd -T$NIX_BUILD_CORES ./rootfs.img -o $out
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
89
sd-card.nix
Normal file
89
sd-card.nix
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
{ pkgs }:
|
||||||
|
|
||||||
|
let
|
||||||
|
firmwarePartition = {
|
||||||
|
offset = 8;
|
||||||
|
id = "0xfeed3425";
|
||||||
|
name = "FIRMWARE";
|
||||||
|
size = 512;
|
||||||
|
};
|
||||||
|
|
||||||
|
rootfsImage = import ./rootfs.nix { inherit pkgs; };
|
||||||
|
|
||||||
|
configTxt = pkgs.writeText "config.txt" (builtins.readFile ./config.txt);
|
||||||
|
populateFirmwareCommands = ''
|
||||||
|
# Add config.txt
|
||||||
|
cp ${configTxt} firmware/config.txt
|
||||||
|
|
||||||
|
# Copy the firmware files
|
||||||
|
cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/bootcode.bin firmware/
|
||||||
|
cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/fixup*.dat firmware/
|
||||||
|
cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/start*.elf firmware/
|
||||||
|
|
||||||
|
# Add pi3 specific files
|
||||||
|
cp ${pkgs.ubootRaspberryPi3_64bit}/u-boot.bin firmware/u-boot-rpi3.bin
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
pkgs.stdenv.mkDerivation {
|
||||||
|
name = "orange";
|
||||||
|
|
||||||
|
nativeBuildInputs = with pkgs; [ dosfstools e2fsprogs libfaketime mtools util-linux zstd ];
|
||||||
|
|
||||||
|
buildCommand = ''
|
||||||
|
img=./sd-card.img
|
||||||
|
root_fs=./rootfs.img
|
||||||
|
zstd -d --no-progress "${rootfsImage}" -o $root_fs
|
||||||
|
|
||||||
|
# Gap in front of the first partition, in MiB
|
||||||
|
gap=${toString firmwarePartition.offset}
|
||||||
|
|
||||||
|
# Create the image file sized to fit /boot/firmware and /, plus slack for the gap.
|
||||||
|
rootSizeBlocks=$(du -B 512 --apparent-size $root_fs | awk '{ print $1 }')
|
||||||
|
firmwareSizeBlocks=$((${toString firmwarePartition.size} * 1024 * 1024 / 512))
|
||||||
|
imageSize=$((rootSizeBlocks * 512 + firmwareSizeBlocks * 512 + gap * 1024 * 1024))
|
||||||
|
truncate -s $imageSize $img
|
||||||
|
|
||||||
|
# type=b is 'W95 FAT32', type=83 is 'Linux'.
|
||||||
|
# The "bootable" partition is where u-boot will look file for the bootloader
|
||||||
|
# information (dtbs, extlinux.conf file).
|
||||||
|
sfdisk $img <<EOF
|
||||||
|
label: dos
|
||||||
|
label-id: ${firmwarePartition.id}
|
||||||
|
start=''${gap}M, size=$firmwareSizeBlocks, type=b
|
||||||
|
start=$((gap + ${toString firmwarePartition.size}))M, type=83, bootable
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Copy the rootfs into the SD image
|
||||||
|
eval $(partx $img -o START,SECTORS --nr 2 --pairs)
|
||||||
|
dd conv=notrunc if=$root_fs of=$img seek=$START count=$SECTORS
|
||||||
|
|
||||||
|
# Create a FAT32 /boot/firmware partition of suitable size into firmware_part.img
|
||||||
|
eval $(partx $img -o START,SECTORS --nr 1 --pairs)
|
||||||
|
truncate -s $((SECTORS * 512)) firmware_part.img
|
||||||
|
mkfs.vfat --invariant -i ${toString firmwarePartition.size} -n ${firmwarePartition.name} firmware_part.img
|
||||||
|
|
||||||
|
# Populate the files intended for /boot/firmware
|
||||||
|
mkdir firmware
|
||||||
|
${populateFirmwareCommands}
|
||||||
|
find firmware -exec touch --date=2000-01-01 {} +
|
||||||
|
|
||||||
|
# Copy the populated /boot/firmware into the SD image
|
||||||
|
cd firmware
|
||||||
|
# Force a fixed order in mcopy for better determinism, and avoid file globbing
|
||||||
|
for d in $(find . -type d -mindepth 1 | sort); do
|
||||||
|
faketime "2000-01-01 00:00:00" mmd -i ../firmware_part.img "::/$d"
|
||||||
|
done
|
||||||
|
for f in $(find . -type f | sort); do
|
||||||
|
mcopy -pvm -i ../firmware_part.img "$f" "::/$f"
|
||||||
|
done
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Verify the FAT partition before copying it.
|
||||||
|
fsck.vfat -vn firmware_part.img
|
||||||
|
|
||||||
|
dd conv=notrunc if=firmware_part.img of=$img seek=$START count=$SECTORS
|
||||||
|
|
||||||
|
mkdir $out
|
||||||
|
zstd -T$NIX_BUILD_CORES $img -o $out/orange.img.zstd
|
||||||
|
'';
|
||||||
|
}
|
Loading…
Reference in a new issue