While it is an RK3399 derivative, we'll identify all devices as their
manufacturer does. Meaning that this is an OP1.
Though this seems useless at first glance, this allows us to put
conditionals on OP1 specific features or misfeatures, if any.
This creates a disk image that acts *just about* like how the NixOS
sd_image acts. Though it is much less useful as there is no system, not
even an initrd.
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.
The algorithms inside `make_ext4fs` can be followed, but it ends up
being a bit complex. I did not figure out all variables, but the amount
of them made me reluctant to implement it as a complte formula.
Instead, I looked at the actual usable space using `df` and mapped it in
a spreadsheet. With the knowledge from actively looking at the source
code, and other data, it is known that the lookup table will work, while
not be ideal.
The fudge factor starting at 256MiB is about stable, but there is a
slight downward deviation at 512MiB, which is why 512MiB was used. The
downward deviation was not observed in other values.
Here's the table as computed.
```
MIB Fudge
5 0.84609375
8 0.5419921875
16 0.288818359375
32 0.1622314453125
64 0.09893798828125
128 0.067291259765625
256 0.0518646240234375
512 0.05208587646484375
1024 0.048187255859375
2048 0.04060554504394531
4096 0.03718090057373047
```
The difference from .52% to .37% is negligible for 0.5 vs. 4 GiB is
annoying me. The lookup table could be changed to include all known
values instead, I guess.
The factor was derived from first making a few test images, finding
there was a common thread, and then looking at what parts of FAT32 were
generated, and how they were generated. That was fun. (Yes, really.)
In addition, present the sector size as an option.
The sector size is required to set a block size in bytes, so giving the
option to the end-user is probably for the best.
The values here were chosen to keep the builder compatible with the
existing tests.
In addition, the values are quite optimized for smaller filesystem
images, e.g. building a FIRMWARE partition for the Raspberry Pi.
First of all, `du -s` will always combine the sizes into the multiple of
its given --block-size, so 4×1 byte files will show up as 1 block size
(assuming a block size > 4). The expected size would have been at least
one block size per file, so for 512, 512×4 thus 2048.
With this change, we sum the sizes ourselves.
This adds a new requirement to the filesystems, that they pass the block
size to the generic builder, though this is good, as it will increases
reproducibility. In addition, filesystems can present the option to
users, allowing the user to set their block sizes as expected.
The current code in <nixpkgs> is reproducible since the date/time comes
from the store. With my particular tests, the date/time is the current
one since I'm using `>` to create test files.