Create additional option to setup FS geometry

Some platforms like the TI AM62 require a particular FAT geometry for
their CPU to read the file system (and thus the bootloader). Failing
that the CPU will simply not boot and keep looking for a bootloader.

Let's add some options to enforce a particular filesystem geometry
through the -g option of mkfs.fat.

Signed-off-by: Maxime Ripard <mripard@kernel.org>
This commit is contained in:
Maxime Ripard 2023-09-25 14:51:58 +02:00 committed by Achilleas Koutsou
parent e58fc3d289
commit 7af2f1a5c1
4 changed files with 128 additions and 1 deletions

View file

@ -46,6 +46,22 @@ SCHEMA_2 = r"""
"description": "Label for the file system",
"type": "integer",
"enum": [12, 16, 32]
},
"geometry": {
"description": "Disk Geometry for the file system",
"type": "object",
"additionalProperties": false,
"required": ["heads", "sectors-per-track"],
"properties": {
"heads": {
"description": "Number of Heads",
"type": "integer"
},
"sectors-per-track": {
"description": "Number of Sectors per Track",
"type": "integer"
}
}
}
}
}
@ -58,6 +74,7 @@ def main(devices, options):
volid = options["volid"]
label = options.get("label")
fatsize = options.get("fat-size")
geometry = options.get("geometry")
opts = ["mkfs.fat", "-I", "-i", volid]
if label:
@ -66,6 +83,9 @@ def main(devices, options):
if fatsize:
opts += ["-F", str(fatsize)]
if geometry:
opts += ["-g", f"{geometry['heads']}/{geometry['sectors-per-track']}"]
subprocess.run(opts + [device], encoding='utf8', check=True)

View file

@ -0,0 +1,41 @@
{
"version": "2",
"pipelines": [
{
"name": "image",
"stages": [
{
"type": "org.osbuild.truncate",
"options": {
"filename": "disk.img",
"size": "64M"
}
},
{
"type": "org.osbuild.mkfs.fat",
"options": {
"volid": "7B7795E7",
"geometry": {
"heads": 12,
"sectors-per-track": 42
}
},
"devices": {
"device": {
"type": "org.osbuild.loopback",
"options": {
"filename": "disk.img",
"lock": true
}
}
}
}
]
}
],
"sources": {
"org.osbuild.curl": {
"items": {}
}
}
}

View file

@ -0,0 +1,20 @@
version: '2'
pipelines:
- name: image
stages:
- type: org.osbuild.truncate
options:
filename: disk.img
size: '64M'
- type: org.osbuild.mkfs.fat
options:
volid: 7B7795E7
geometry:
heads: 12
sectors-per-track: 42
devices:
device:
type: org.osbuild.loopback
options:
filename: disk.img
lock: true

View file

@ -16,7 +16,7 @@ import tempfile
import unittest
import xml
from collections.abc import Mapping
from typing import Callable, Dict, Optional
from typing import Callable, Dict, List, Optional
from osbuild.util import checksum, selinux
from .test_assemblers import mount
@ -595,3 +595,49 @@ class TestStages(test.TestBase):
assert len(subvols) == 2
assert "path root" in subvols[0]
assert "path home" in subvols[1]
@unittest.skipUnless(test.TestBase.has_filesystem_support("fat"), "FAT needed")
def test_fat(self):
def _get_file_fields(image: str) -> List[str]:
r = subprocess.run(
[
"file",
"--special-files",
image
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
encoding="utf8",
check=True,
)
return [field.strip() for field in r.stdout.split(',')]
datadir = self.locate_test_data()
testdir = os.path.join(datadir, "stages", "fat")
with self.osbuild as osb, tempfile.TemporaryDirectory(dir="/var/tmp") as outdir:
osb.compile_file(os.path.join(testdir, "manifest.json"), exports=["image"], output_dir=outdir)
image = os.path.join(outdir, "image", "disk.img")
assert os.path.isfile(image)
# check that it's indeed FAT
r = subprocess.run(
[
"blkid",
"--output", "export",
image
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
encoding="utf8",
check=True,
)
assert "TYPE=vfat" in r.stdout.splitlines()
# Check that our custom geometry was enforced
fields = _get_file_fields(image)
assert "heads 12" in fields
assert "sectors/track 42" in fields