feat: add cross-platform customer fs generator
This commit is contained in:
Executable
+76
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate a disk-2.0 LittleFS customer_fs image on macOS."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from littlefs import LittleFS, UserContext
|
||||
|
||||
|
||||
IMAGE_SIZE = 589824
|
||||
BLOCK_SIZE = 4096
|
||||
BLOCK_COUNT = 144
|
||||
DISK_VERSION = 0x00020000
|
||||
|
||||
|
||||
def fail(message: str) -> None:
|
||||
raise SystemExit(f"customer_fs generation failed: {message}")
|
||||
|
||||
|
||||
def collect_source_files(source: Path) -> list[Path]:
|
||||
if not source.is_dir():
|
||||
fail(f"source directory does not exist: {source}")
|
||||
entries = sorted(source.iterdir(), key=lambda path: path.name.encode("utf-8"))
|
||||
if not entries:
|
||||
fail(f"source directory is empty: {source}")
|
||||
invalid = [entry.name for entry in entries if not entry.is_file() or entry.name.startswith(".")]
|
||||
if invalid:
|
||||
fail(
|
||||
"source must contain only visible root-level files; invalid entries: "
|
||||
+ ", ".join(invalid)
|
||||
)
|
||||
return entries
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--source", required=True, type=Path)
|
||||
parser.add_argument("--output", required=True, type=Path)
|
||||
args = parser.parse_args()
|
||||
|
||||
files = collect_source_files(args.source)
|
||||
context = UserContext(buffsize=IMAGE_SIZE)
|
||||
fs = LittleFS(
|
||||
context=context,
|
||||
mount=False,
|
||||
block_size=BLOCK_SIZE,
|
||||
block_count=BLOCK_COUNT,
|
||||
read_size=16,
|
||||
prog_size=16,
|
||||
cache_size=256,
|
||||
lookahead_size=32,
|
||||
block_cycles=500,
|
||||
disk_version=DISK_VERSION,
|
||||
)
|
||||
fs.format()
|
||||
fs.mount()
|
||||
try:
|
||||
for source_file in files:
|
||||
with source_file.open("rb") as source_handle:
|
||||
with fs.open("/" + source_file.name, "wb") as image_handle:
|
||||
while chunk := source_handle.read(64 * 1024):
|
||||
image_handle.write(chunk)
|
||||
finally:
|
||||
fs.unmount()
|
||||
|
||||
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.output.write_bytes(context.buffer)
|
||||
print(f"generated {args.output} from {len(files)} files")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user