mirror of
https://github.com/NixOS/mobile-nixos.git
synced 2024-12-17 04:51:31 +03:00
ed10664fc9
It turns out the warnings it spits out when forcing FAT32 with too few clusters is not for nothing. At the very least the Raspberry Pi 3B does not like the forced FAT 32. Though, it was validated that a large enough FAT32 partition is fine with the Raspberry Pi 3B.
103 lines
2.9 KiB
Nix
103 lines
2.9 KiB
Nix
{ lib, imageBuilder, dosfstools, mtools, libfaketime}:
|
|
|
|
/* */ let scope = { "fileSystem.makeFAT32" =
|
|
|
|
let
|
|
inherit (lib.strings) splitString;
|
|
inherit (imageBuilder) makeFilesystem;
|
|
# The default from `mkfs.fat`.
|
|
reservedSectors = 32;
|
|
# The default from `mkfs.fat`.
|
|
hiddenSectors = 0;
|
|
|
|
# The default from `mkfs.fat`.
|
|
numberOfFats = 2;
|
|
# Extra padding per FAT, a constant in code
|
|
fatPadding = 4;
|
|
|
|
# I have not been able to validate that it could be different from 1 for FAT32.
|
|
# It seems the different values (e.g. 4) are for FAT12 and FAT16.
|
|
# This is the only "bad" assumption here.
|
|
clusterSize = 1;
|
|
|
|
# Bash doesn't do floating point representations. Multiplications and divisions
|
|
# are handled with enough precision that we can multiply and divide to get a precision.
|
|
precision = 1000;
|
|
|
|
first = list: lib.lists.last (lib.lists.reverseList list);
|
|
chopDecimal = f: first (splitString "." (toString f));
|
|
in
|
|
{ partitionID
|
|
# These defaults are assuming small~ish FAT32 filesystems are generated.
|
|
, blockSize ? 512
|
|
, sectorSize ? 512
|
|
, ... } @ args:
|
|
makeFilesystem (args // {
|
|
# FAT32 can be used for ESP. Let's make this obvious.
|
|
filesystemType = if args ? filesystemType then args.filesystemType else "FAT32";
|
|
|
|
inherit blockSize sectorSize;
|
|
minimumSize = imageBuilder.size.KiB 500;
|
|
|
|
nativeBuildInputs = [
|
|
libfaketime
|
|
dosfstools
|
|
mtools
|
|
];
|
|
|
|
computeMinimalSize = ''
|
|
# `local size` is in bytes.
|
|
|
|
# This amount is a static amount of reserved space.
|
|
local static_reserved=${toString ( (reservedSectors + hiddenSectors) * sectorSize )}
|
|
|
|
# This is a constant representing the relative reserved space ratio.
|
|
local relative_reserved=${
|
|
chopDecimal (
|
|
precision - (
|
|
1.0 * sectorSize / ((clusterSize * sectorSize) + (numberOfFats * fatPadding))
|
|
# ^ forces floating point
|
|
) * precision
|
|
)
|
|
}
|
|
# Rounds up the likely truncated result. At worst it's a bit more space.
|
|
(( relative_reserved++ ))
|
|
|
|
echo "static_reserved=$static_reserved" 1>&2
|
|
echo "relative_reserved=$relative_reserved" 1>&2
|
|
|
|
local reservedSize=$(( (static_reserved + size) * relative_reserved / ${toString precision} + static_reserved ))
|
|
|
|
echo -n "Adding reservedSize: $size + $reservedSize = " 1>&2
|
|
size=$((size + reservedSize))
|
|
echo "$size" 1>&2
|
|
'';
|
|
|
|
filesystemPhase = ''
|
|
faketime -f "1970-01-01 00:00:00" mkfs.vfat \
|
|
-R ${toString reservedSectors} \
|
|
-h ${toString hiddenSectors} \
|
|
-s ${toString (blockSize / sectorSize)} \
|
|
-S ${toString sectorSize} \
|
|
-i $partitionID \
|
|
-n $partName \
|
|
"$img"
|
|
'';
|
|
|
|
copyPhase = ''
|
|
for f in ./* ./.*; do
|
|
if [[ "$f" != "./." && "$f" != "./.." ]]; then
|
|
faketime -f "1970-01-01 00:00:00" \
|
|
mcopy -psv -i "$img" "$f" ::
|
|
fi
|
|
done
|
|
'';
|
|
|
|
checkPhase = ''
|
|
# Always verify FS
|
|
fsck.vfat -vn "$img"
|
|
'';
|
|
})
|
|
|
|
/* */ ;}; in scope."fileSystem.makeFAT32"
|