51 lines
1.5 KiB
Python
51 lines
1.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Split a raw SMBIOS structure table into one file per structure for QEMU.
|
|
|
|
Reads a dumped DMI table (/sys/firmware/dmi/tables/DMI on the real machine),
|
|
writes one `-smbios file=` blob per structure into OUTDIR, and prints the
|
|
ordered list of paths. A complete set through the type-127 end marker is what
|
|
lets QEMU build a well-formed entry point from a dump.
|
|
|
|
Each structure is a 4-byte header (type, length, handle:u16) + (length-4)
|
|
formatted bytes + a string set terminated by a double NUL; a structure with no
|
|
strings is still followed by 0x0000.
|
|
"""
|
|
import os
|
|
import sys
|
|
|
|
|
|
def split(data):
|
|
out, i, n = [], 0, len(data)
|
|
while i + 4 <= n:
|
|
stype, slen = data[i], data[i + 1]
|
|
if slen < 4:
|
|
break
|
|
j = i + slen
|
|
while j + 1 < n and not (data[j] == 0 and data[j + 1] == 0):
|
|
j += 1
|
|
j += 2
|
|
out.append((stype, data[i:j]))
|
|
i = j
|
|
if stype == 127:
|
|
break
|
|
return out
|
|
|
|
|
|
def main():
|
|
dmi, outdir = sys.argv[1], sys.argv[2]
|
|
data = open(dmi, "rb").read()
|
|
os.makedirs(outdir, exist_ok=True)
|
|
structs = split(data)
|
|
paths = []
|
|
for idx, (stype, blob) in enumerate(structs):
|
|
p = os.path.join(outdir, "sm_%02d_type%d.bin" % (idx, stype))
|
|
open(p, "wb").write(blob)
|
|
paths.append(p)
|
|
print("# %d structures: %s" % (len(structs), ",".join(str(t) for t, _ in structs)))
|
|
for p in paths:
|
|
print(p)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|