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", "description": "Label for the file system",
"type": "integer", "type": "integer",
"enum": [12, 16, 32] "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"] volid = options["volid"]
label = options.get("label") label = options.get("label")
fatsize = options.get("fat-size") fatsize = options.get("fat-size")
geometry = options.get("geometry")
opts = ["mkfs.fat", "-I", "-i", volid] opts = ["mkfs.fat", "-I", "-i", volid]
if label: if label:
@ -66,6 +83,9 @@ def main(devices, options):
if fatsize: if fatsize:
opts += ["-F", str(fatsize)] opts += ["-F", str(fatsize)]
if geometry:
opts += ["-g", f"{geometry['heads']}/{geometry['sectors-per-track']}"]
subprocess.run(opts + [device], encoding='utf8', check=True) 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 unittest
import xml import xml
from collections.abc import Mapping 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 osbuild.util import checksum, selinux
from .test_assemblers import mount from .test_assemblers import mount
@ -595,3 +595,49 @@ class TestStages(test.TestBase):
assert len(subvols) == 2 assert len(subvols) == 2
assert "path root" in subvols[0] assert "path root" in subvols[0]
assert "path home" in subvols[1] 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