FDS/OS 1.0
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Real Pi 5 firmware configuration roundtrips without any hardware access."""
|
||||
import importlib.machinery
|
||||
import importlib.util
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
project=Path(__file__).resolve().parents[2]
|
||||
sys.path.insert(0,str(project/'tools'))
|
||||
from eeprom_inputs import prepare,sha256
|
||||
cache,pin=prepare()
|
||||
work=Path(tempfile.mkdtemp(prefix='m12-eeprom.',dir=project/'out'))
|
||||
base=cache/'pieeprom.bin';before=sha256(base)
|
||||
# Use the pinned upstream parser to compare immutable firmware payloads as well
|
||||
# as configuration text, including both AB slots where present.
|
||||
loader=importlib.machinery.SourceFileLoader('upstream_eeprom',str(cache/'rpi-eeprom-config'))
|
||||
spec=importlib.util.spec_from_loader(loader.name,loader);upstream=importlib.util.module_from_spec(spec);loader.exec_module(upstream)
|
||||
original=upstream.BootloaderImage(str(base))
|
||||
protected={s.filename:original.get_file(s.filename) for s in original._sections if s.filename and s.filename not in ['bootconf.txt','bootconf.sig']}
|
||||
|
||||
def run(arguments,ok=True):
|
||||
result=subprocess.run([str(project/'tools/configure-pi-eeprom'),*map(str,arguments)],capture_output=True,text=True,env={**os.environ,'FDS_OFFLINE':'1'})
|
||||
assert (result.returncode==0)==ok,(arguments,result.stdout,result.stderr)
|
||||
return result
|
||||
|
||||
for profile in ['production','development']:
|
||||
output=work/profile
|
||||
run(['--profile',profile,'--output-directory',output])
|
||||
manifest=json.loads((output/'manifest.json').read_text())
|
||||
assert manifest['hardware_modified'] is False and manifest['custom_inputs_provided'] is False
|
||||
for name,digest in manifest['files'].items():assert sha256(output/name)==digest
|
||||
image=upstream.BootloaderImage(str(output/'configured.bin'))
|
||||
for name,data in protected.items():assert image.get_file(name)==data,(profile,name)
|
||||
assert 'NET_INSTALL_ENABLED=0' in image.get_file('bootconf.txt').decode()
|
||||
second=work/(profile+'-repeat');run(['--profile',profile,'--output-directory',second])
|
||||
assert sha256(output/'configured.bin')==sha256(second/'configured.bin')
|
||||
assert sha256(output/'rollback.bin')==sha256(second/'rollback.bin')
|
||||
run(['--profile',profile,'--output-directory',output],ok=False)
|
||||
print(f'PASS: {profile}: actual Pi 5 firmware roundtrip, immutable payloads, deterministic files and overwrite refusal',flush=True)
|
||||
|
||||
saved=work/'board.conf'
|
||||
saved.write_text('[all]\nBOOT_ORDER=0xf461\nCUSTOM_BOARD_SETTING=retained\n[gpio8=0]\nBOOT_ORDER=0xf7\nNET_INSTALL_ENABLED=1\nOTHER_SETTING=unchanged\n')
|
||||
output=work/'custom'
|
||||
run(['--current-config',saved,'--output-directory',output])
|
||||
changed=(output/'configured.conf').read_text()
|
||||
assert changed.count('BOOT_ORDER=')==1 and 'BOOT_ORDER=0xf6' in changed
|
||||
assert 'CUSTOM_BOARD_SETTING=retained' in changed and '[gpio8=0]\nOTHER_SETTING=unchanged' in changed
|
||||
rollback=upstream.BootloaderImage(str(output/'rollback.bin')).get_file('bootconf.txt').decode()
|
||||
assert rollback==saved.read_text(),'Rollback lost the original conditional settings'
|
||||
bad=work/'bad.bin';bad.write_bytes(b'not firmware')
|
||||
run(['--base-image',bad,'--output-directory',work/'bad'],ok=False)
|
||||
run(['--base-image','/dev/null','--output-directory',work/'device'],ok=False)
|
||||
large=work/'large.conf';large.write_bytes(b'x'*5000)
|
||||
run(['--current-config',large,'--output-directory',work/'large'],ok=False)
|
||||
assert sha256(base)==before
|
||||
(work/'evidence.json').write_text(json.dumps({'format':1,'upstream_commit':pin['commit'],'base_sha256':before,'hardware_modified':False},indent=2)+'\n')
|
||||
link=project/'out/m12-eeprom-latest';link.unlink(missing_ok=True);link.symlink_to(work.name)
|
||||
print(f'PASS: preserved custom settings, exact rollback, invalid-input rejection and unchanged firmware input: {work}')
|
||||
print('SKIP: EEPROM application, physical boot order, PMIC and Pi timing')
|
||||
Reference in New Issue
Block a user