2 * Dump DMI information in a way hopefully compatible with dmidecode
20 struct smbios_header
{
30 struct dmi_header dmi
;
33 static uint8_t checksum(const void *buf
, size_t len
)
35 const uint8_t *p
= buf
;
44 static bool is_old_dmi(size_t dptr
)
46 const struct dmi_header
*dmi
= (void *)dptr
;
48 return !memcmp(dmi
->signature
, "_DMI_", 5) &&
53 static bool is_smbios(size_t dptr
)
55 const struct smbios_header
*smb
= (void *)dptr
;
57 return !memcmp(smb
->signature
, "_SM_", 4) &&
58 !checksum(smb
, smb
->len
) &&
62 static void dump_smbios(struct upload_backend
*be
, size_t dptr
)
64 const struct smbios_header
*smb
= (void *)dptr
;
65 struct smbios_header smx
= *smb
;
68 snprintf(filename
, sizeof filename
, "dmi/%05x.%08x",
69 dptr
, smb
->dmi
.tbladdr
);
70 cpio_hdr(be
, MODE_FILE
, smb
->dmi
.tbllen
+ 32, filename
);
73 * Adjust the address of the smbios table to be 32, to
74 * make dmidecode happy. The checksum on the smbios table is unchanged,
75 * since it includes the checksum on the dmi table.
77 smx
.dmi
.tbladdr
= sizeof smx
;
78 smx
.dmi
.csum
-= checksum(&smx
.dmi
, 0x0f);
80 write_data(be
, &smx
, sizeof smx
);
81 write_data(be
, (const void *)smb
->dmi
.tbladdr
, smb
->dmi
.tbllen
);
84 static void dump_old_dmi(struct upload_backend
*be
, size_t dptr
)
86 const struct dmi_header
*dmi
= (void *)dptr
;
88 struct dmi_header dmi
;
93 snprintf(filename
, sizeof filename
, "dmi/%05x.%08x",
95 cpio_hdr(be
, MODE_FILE
, dmi
->tbllen
+ 32, filename
);
98 * Adjust the address of the smbios table to be 32, to
99 * make dmidecode happy.
102 memset(&fake
.pad
, 0, sizeof fake
.pad
);
103 fake
.dmi
.tbladdr
= sizeof fake
;
104 fake
.dmi
.csum
-= checksum(&fake
.dmi
, 0x0f);
106 write_data(be
, &fake
, sizeof fake
);
107 write_data(be
, (const void *)dmi
->tbladdr
, dmi
->tbllen
);
110 void dump_dmi(struct upload_backend
*be
)
114 cpio_mkdir(be
, "dmi");
116 /* Search for _SM_ or _DMI_ structure */
117 for (dptr
= 0xf0000 ; dptr
< 0x100000 ; dptr
+= 16) {
118 if (is_smbios(dptr
)) {
119 dump_smbios(be
, dptr
);
120 dptr
+= 16; /* Skip the subsequent DMI header */
121 } else if (is_old_dmi(dptr
)) {
122 dump_old_dmi(be
, dptr
);