From 4f819755cb60272f0898b9fcc3bef46a9f1c99e7 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Jun 25 2015 13:17:48 +0000 Subject: import dmidecode-2.12-5.1.aa7a --- diff --git a/.dmidecode.metadata b/.dmidecode.metadata new file mode 100644 index 0000000..c7a91eb --- /dev/null +++ b/.dmidecode.metadata @@ -0,0 +1 @@ +d264591f27cc0e918f299feb3ef990ef122c609b SOURCES/dmidecode-2.12.tar.bz2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6c5093d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/dmidecode-2.12.tar.bz2 diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/Add-libdmifs-from-Linaro.patch b/SOURCES/Add-libdmifs-from-Linaro.patch new file mode 100644 index 0000000..5043fad --- /dev/null +++ b/SOURCES/Add-libdmifs-from-Linaro.patch @@ -0,0 +1,774 @@ +From a909f4e024bdb5b0a8ea11f9fde62a9c74438983 Mon Sep 17 00:00:00 2001 +From: Mark Salter +Date: Mon, 26 Jan 2015 12:42:42 -0500 +Subject: [PATCH] Add libdmifs from Linaro + +This library module comes from: + + git://git.linaro.org/people/ivan.khoronzhuk/libdmifs.git + +For now, it is being built in rather than as a shared lib. + +Signed-off-by: Mark Salter +--- + Makefile | 7 +- + dmidecode.c | 2 +- + libdmifs.c | 644 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + libdmifs.h | 56 ++++++ + 4 files changed, 706 insertions(+), 3 deletions(-) + create mode 100644 libdmifs.c + create mode 100644 libdmifs.h + +diff --git a/Makefile b/Makefile +index d8457da..805d08e 100644 +--- a/Makefile ++++ b/Makefile +@@ -57,8 +57,8 @@ all : $(PROGRAMS) + # Programs + # + +-dmidecode : dmidecode.o dmiopt.o dmioem.o util.o +- $(CC) $(LDFLAGS) dmidecode.o dmiopt.o dmioem.o util.o -ldmifs -o $@ ++dmidecode : dmidecode.o dmiopt.o dmioem.o util.o libdmifs.o ++ $(CC) $(LDFLAGS) dmidecode.o dmiopt.o dmioem.o util.o libdmifs.o -o $@ + + biosdecode : biosdecode.o util.o + $(CC) $(LDFLAGS) biosdecode.o util.o -o $@ +@@ -98,6 +98,9 @@ vpdopt.o : vpdopt.c config.h util.h vpdopt.h + util.o : util.c types.h util.h config.h + $(CC) $(CFLAGS) -c $< -o $@ + ++libdmifs.o: libdmifs.c libdmifs.h ++ $(CC) $(CFLAGS) -c $< -o $@ ++ + # + # Commands + # +diff --git a/dmidecode.c b/dmidecode.c +index 4663cc6..fee3af1 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -57,7 +57,7 @@ + #include + #include + #include +-#include ++#include "libdmifs.h" + + #include "version.h" + #include "config.h" +diff --git a/libdmifs.c b/libdmifs.c +new file mode 100644 +index 0000000..9ad2414 +--- /dev/null ++++ b/libdmifs.c +@@ -0,0 +1,644 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "libdmifs.h" ++ ++/* ++ * maximum number of entries can be calculated based on maximum table ++ * size and minimum size of structure (4 + 2 NULL symbols). ++ */ ++#define MIN_HEADER_SIZE 4 ++#define MIN_DMI_STRUCT_SIZE (MIN_HEADER_SIZE + 2) ++#define MAX_ENTRIES_COUNT (~0U/MIN_DMI_STRUCT_SIZE) ++#define POSITION_ERR (MAX_ENTRIES_COUNT + 1) ++ ++/* list of dmi entries */ ++ ++/** ++ * dmilist_insert - inserts new dmi entry to ordered dmi_list, ++ * sorting according to the position in dmi table ++ * @dmi_list: pointer on pointer to the first dmi entry in the list ++ * @new: new entry to be inserted in the ordered dmi_list. ++ * ++ * Returns 0 on success and -1 when error. ++ */ ++static int dmilist_insert(struct dmi_entry **dmi_list, struct dmi_entry *new) ++{ ++ struct dmi_entry *old; ++ struct dmi_entry *cur = *dmi_list; ++ ++ if (!cur) { ++ new->next = NULL; ++ *dmi_list = new; ++ return 0; ++ } ++ ++ old = NULL; ++ while (cur) { ++ if (cur->position < new->position) { ++ old = cur; ++ cur = cur->next; ++ continue; ++ } else if (cur->position > new->position) { ++ if (old) { ++ old->next = new; ++ new->next = cur; ++ return 0; ++ } ++ new->next = cur; ++ *dmi_list = new; ++ return 0; ++ } ++ ++ fprintf(stderr, "dmitable is broken"); ++ return -1; ++ } ++ ++ old->next = new; ++ new->next = NULL; ++ ++ return 0; ++} ++ ++static void dmilist_free_entry(struct dmi_entry *entry) ++{ ++ free(entry->d_name); ++ free(entry); ++} ++ ++static void dmilist_free(struct dmi_entry **dmi_list) ++{ ++ struct dmi_entry *old; ++ struct dmi_entry *cur = *dmi_list; ++ ++ if (!cur) ++ return; ++ ++ while (cur) { ++ old = cur; ++ cur = cur->next; ++ dmilist_free_entry(old); ++ } ++ ++ *dmi_list = NULL; ++} ++ ++/* dmi sysfs attribute reading */ ++ ++/** ++ * dmi_get_smbios - get smbios data ++ * @smbios: pointer on array to read raw smbios table in ++ * ++ * Returns read data size in bytes on success and 0 when error. ++ */ ++static int dmi_get_smbios(unsigned char *smbios) ++{ ++ FILE *file; ++ int count = 0; ++ enum {SMBIOS_SIZE = 32}; ++ ++ file = fopen("/sys/firmware/dmi/smbios_raw_header", "rb"); ++ if (!file) { ++ fprintf(stderr, "no \"smbios\" sysfs entry\n"); ++ return count; ++ } ++ ++ count = fread(smbios, sizeof(char), SMBIOS_SIZE, file); ++ if (!feof(file)) { ++ fprintf(stderr, "Error while reading a file\n"); ++ goto err; ++ } ++ ++err: ++ fclose(file); ++ return count; ++} ++ ++/** ++ * read_position - reads position of dmi entry as it's inside dmi table ++ * @dir: appropriate directory of dmi entry position ++ * ++ * returns dmi entry position in dmi table on success and POSITION_ERR when ++ * error occurred. ++ */ ++static unsigned int read_position(char *dir) ++{ ++ FILE *file; ++ char pos[10]; ++ unsigned int position; ++ ++ file = fopen("position", "r"); ++ if (!file) { ++ fprintf(stderr, "no \"position\" in \"%s\"\n", dir); ++ return POSITION_ERR; ++ } ++ ++ if (!fgets(pos, 10, file) && ferror(file)) { ++ fclose(file); ++ fprintf(stderr, "Error while working with \"position\" in %s\n", ++ dir); ++ return POSITION_ERR; ++ } ++ ++ fclose(file); ++ ++ position = strtoul(pos, NULL, 0); ++ /* position can't be more than number of entries */ ++ if (position > MAX_ENTRIES_COUNT) { ++ fprintf(stderr, "position is incorrect %d\n", position); ++ return POSITION_ERR; ++ } ++ ++ return position; ++} ++ ++/** ++ * read_raw - reads raw data of dmi entry ++ * @dir: appropriate directory of dmi entry position ++ * @data: pointer to the array where raw data will be read ++ * @max_size: maximum data size possible to read ++ * ++ * Returns read data size in bytes on success and 0 when error. ++ * In the same time return value < 6 is also error as at least header is ++ * 4 bytes in size + 2 NULLs. ++ */ ++static unsigned int read_raw(char *dir, ++ unsigned char *buf, unsigned int max_size) ++{ ++ FILE *file; ++ unsigned int count; ++ unsigned int size = 0; ++ ++ file = fopen("raw", "rb"); ++ if (!file) { ++ fprintf(stderr, "no \"raw\" in \"%s\"\n", dir); ++ return 0; ++ } ++ ++ count = fread(buf, sizeof(char), max_size, file); ++ if (!feof(file)) { ++ fprintf(stderr, "Error while reading \"raw\" file\n"); ++ goto err; ++ } ++ ++ if (count < MIN_DMI_STRUCT_SIZE) { ++ fprintf(stderr, "DMI header cannot be less than 4 bytes"); ++ goto err; ++ } ++ ++ /* check if structure is correct */ ++ if (buf[count - 1] || buf[count - 2]) { ++ fprintf(stderr, "Bad raw file of \"%s\"\n", dir); ++ goto err; ++ } ++ ++ size = count; ++err: ++ fclose(file); ++ return size; ++} ++ ++/** ++ * add_entry_to_dmilist - generates empty dmi entry and places it to dmi list ++ * @dmi_list: dmi list where allocated dmi entry will be put ++ * @dir: the directory name appropriate to dmi entry ++ * ++ * Returns 0 on success and -1 on error ++ */ ++static int add_entry_to_dmilist(struct dmi_entry **dmi_list, char *dir) ++{ ++ char *dir_name; ++ unsigned int position; ++ struct dmi_entry *entry; ++ ++ position = read_position(dir); ++ if (position == POSITION_ERR) { ++ fprintf(stderr, ++ "Cannot read smbios position for \"%s\"\n", dir); ++ return -1; ++ } ++ ++ dir_name = malloc(strlen(dir) + 1); ++ if (!dir_name) { ++ fprintf(stderr, "Cannot allocate memory for dir\n"); ++ return -1; ++ } ++ strcpy(dir_name, dir); ++ ++ entry = malloc(sizeof(struct dmi_entry)); ++ if (!entry) { ++ fprintf(stderr, "Cannot allocate memory for dmi struct\n"); ++ free(dir_name); ++ return -1; ++ } ++ ++ entry->d_name = dir_name; ++ entry->position = position; ++ ++ if (dmilist_insert(dmi_list, entry)) { ++ fprintf(stderr, "Cannot insert new dmientry in the list"); ++ dmilist_free_entry(entry); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++/** ++ * gather_entry_data - reads data from given dmi directory raw attribute end ++ * binds it with given dmi entry. ++ * @entry: dmi entry for what data will be read ++ * @rdata: pointer to array where data will be read in ++ * @max_size: maximum data size possible to read for now ++ * ++ * Returns read raw data size including two NULLs at the end ++ * On error returns 0 ++ */ ++static unsigned int gather_entry_data(struct dmi_entry *entry, ++ unsigned char *rdata, ++ unsigned int max_size) ++{ ++ unsigned int dsize; ++ ++ dsize = read_raw(entry->d_name, rdata, max_size); ++ if (dsize < MIN_DMI_STRUCT_SIZE) { ++ fprintf(stderr, ++ "Cannot read DMI raw for \"%s\"\n", entry->d_name); ++ return 0; ++ } ++ ++ entry->h.data = rdata; ++ entry->h.type = rdata[0]; ++ entry->h.length = rdata[1]; ++ entry->h.handle = le16toh(rdata[2] | (rdata[3] << 8)); ++ ++ return dsize; ++} ++ ++/** ++ * populate_dmilist - populate dmi entries in dmi list by raw data ++ * @dmi_list: dmi list with dmi entries to be populated ++ * @max_size: supposed size of whole dmi table. Can be taken from ++ * table SMBIOS entry. ++ * ++ * Returns dmi raw table size on success, otherwise 0. ++ */ ++static unsigned int populate_dmilist(struct dmi_entry *dmi_list, ++ unsigned int max_size) ++{ ++ unsigned int dsize; ++ struct dmi_entry *entry; ++ unsigned char *raw_table, *tp; ++ ++ /* allocate memory for whole dmi table */ ++ raw_table = malloc(max_size); ++ if (!raw_table) { ++ fprintf(stderr, "Cannot allocate memory for DMI table\n"); ++ return 0; ++ } ++ ++ tp = raw_table; ++ for (entry = dmi_list; entry; entry = entry->next) { ++ if (max_size < MIN_DMI_STRUCT_SIZE) { ++ fprintf(stderr, "Max size of DMI table is reached\n"); ++ goto err; ++ } ++ ++ if (chdir(entry->d_name)) { ++ fprintf(stderr, "Cannot change dir to %s\n", ++ entry->d_name); ++ goto err; ++ } ++ ++ dsize = gather_entry_data(entry, tp, max_size); ++ if (dsize < MIN_DMI_STRUCT_SIZE) { ++ if (chdir("../")) ++ fprintf(stderr, "Cannot change dir to ../\n"); ++ goto err; ++ } ++ ++ if (chdir("../")) { ++ fprintf(stderr, "Cannot change dir to ../\n"); ++ goto err; ++ } ++ ++ tp += dsize; ++ max_size -= dsize; ++ } ++ ++ return tp - raw_table; ++ ++err: ++ fprintf(stderr, "Cannot gather data for dir %s\n", entry->d_name); ++ free(raw_table); ++ return 0; ++} ++ ++/** ++ * create_dmilist - creates ordered linked dmi list with empty entries. ++ * The empty entry is entry with empty dmi header data ++ * @entry_count: pointer to dmi entry count to be updated while creating. ++ * ++ * On success returns dmi_entry pointer on first entry in the list ++ * Otherwise returns NULL. Updates entry_count. ++ */ ++static struct dmi_entry *create_dmilist(unsigned int *entry_count) ++{ ++ DIR *dmi; ++ char *cwd; ++ void *ret = NULL; ++ struct dirent *dir_entry; ++ struct dmi_entry *dmi_list = NULL; ++ ++ dmi = opendir("."); ++ if (!dmi) { ++ fprintf(stderr, "Cannot open cwd\n"); ++ return ret; ++ } ++ ++ *entry_count = 0; ++ readdir(dmi); /* miss "." */ ++ readdir(dmi); /* miss ".." */ ++ while ((dir_entry = readdir(dmi))) { ++ if (chdir(dir_entry->d_name)) { ++ fprintf(stderr, "Cannot change dir to %s\n", ++ dir_entry->d_name); ++ goto err; ++ } ++ ++ if (add_entry_to_dmilist(&dmi_list, dir_entry->d_name)) { ++ fprintf(stderr, "Cannot add \"%s\" to dmi_list\n", ++ dir_entry->d_name); ++ if (chdir("../")) ++ fprintf(stderr, "Cannot change dir to ../\n"); ++ goto err; ++ } ++ ++ if (chdir("../")) { ++ fprintf(stderr, "Cannot change dir to ../\n"); ++ goto err; ++ } ++ ++ (*entry_count)++; ++ } ++ /* now dmilist is complete */ ++ ret = dmi_list; ++err: ++ if (closedir(dmi)) { ++ cwd = getcwd(NULL, 1024); ++ fprintf(stderr, "Cannot close %s", cwd); ++ free(cwd); ++ ret = NULL; ++ } ++ ++ if (ret == dmi_list) ++ return dmi_list; ++ ++ dmilist_free(&dmi_list); ++ return ret; ++} ++ ++/** ++ * dmi_put_dmilist - frees dmi list alloted by dmi_get_dmilist() ++ * @dmi_list: dmi list to be free ++ * ++ * Returns 0 on success, -1 otherwise. ++ */ ++static int dmi_put_dmilist(struct dmi_entry *dmi_list) ++{ ++ unsigned char *raw_table; ++ ++ if (!dmi_list) { ++ fprintf(stderr, "Cannot free dmi_list NULL pointer\n"); ++ return -1; ++ } ++ ++ raw_table = dmi_list->h.data; ++ if (!raw_table) { ++ fprintf(stderr, "Cannot free raw_table NULL pointer\n"); ++ return -1; ++ } ++ ++ free(raw_table); ++ dmilist_free(&dmi_list); ++ ++ return 0; ++} ++ ++/** ++ * dmi_get_dmilist - creates ordered dmi list with all dmi entries present ++ * on dmi sysfs. All raw entries data are situated contiguously in the RAM. ++ * @entry_count: read count of dmi list entries, that's dmi structs in dmi table ++ * @dmi_size: read whole size in bytes of dmi table. ++ * @max_size: supposed size of whole dmi table. Can be taken from SMBIOS ++ * entry point table. ++ * ++ * Returns a pointer to first dmi entry in the list. When list is no longer ++ * needed it has to be freed with dmi_put_dmilist(). ++ * In case of error returns NULL. ++ */ ++static struct dmi_entry *dmi_get_dmilist(unsigned int *entry_count, ++ unsigned int *dmi_size, ++ unsigned int max_size) ++{ ++ char *cwd; ++ struct dmi_entry *dmi_list = NULL; ++ char root[] = "/sys/firmware/dmi/entries/"; ++ ++ cwd = getcwd(NULL, 1024); ++ if (!cwd) { ++ fprintf(stderr, "Cannot get current directory\n"); ++ return NULL; ++ } ++ ++ if (chdir(root)) { ++ fprintf(stderr, "Cannot change dir to %s\n", root); ++ goto err; ++ } ++ ++ /* ++ * Create dmi_list then fill it in. Do this in two steps to ++ * have contiguous raw data for whole table ++ */ ++ dmi_list = create_dmilist(entry_count); ++ if (!dmi_list) { ++ fprintf(stderr, "Cannot create dmi_list\n"); ++ goto err; ++ } ++ ++ *dmi_size = populate_dmilist(dmi_list, max_size); ++ if (*dmi_size == 0) { ++ dmilist_free(&dmi_list); ++ fprintf(stderr, "Cannot fill in dmi_list by data from raw\n"); ++ goto err; ++ } ++ ++err: ++ if (chdir(cwd)) { ++ fprintf(stderr, "Cannot change root dir to %s\n", cwd); ++ dmi_put_dmilist(dmi_list); ++ dmi_list = NULL; ++ } ++ ++ free(cwd); ++ return dmi_list; ++} ++ ++static int dmi_checksum(unsigned char *buf, unsigned char len) ++{ ++ int i; ++ unsigned char sum = 0; ++ ++ for (i = 0; i < len; i++) ++ sum += buf[i]; ++ ++ return sum == 0; ++} ++ ++/** ++ * dmi_get_expected_size - read dmi table size from SMBIOS entry point table. ++ * Verify SMBIOS entry point table checksum. ++ * ++ * Returns dmi table size read from SMBIOS entry point table. Return 0 on error. ++ */ ++static unsigned int dmi_get_expected_size(unsigned char *smbios) ++{ ++ if (!memcmp(smbios, "_SM3_", 5) && ++ dmi_checksum(smbios, smbios[0x06])) ++ return le32toh(smbios[0x0C] | (smbios[0x0D] << 8) | ++ (smbios[0x0E] << 16) | (smbios[0x0F] << 24)); ++ else if (!memcmp(smbios, "_SM_", 4) && ++ dmi_checksum(smbios, smbios[0x05]) && ++ dmi_checksum(smbios + 0x10, 0x0F)) ++ return le16toh(smbios[0x16] | (smbios[0x17] << 8)); ++ else if (!memcmp(smbios, "_DMI_", 5) && ++ dmi_checksum(smbios, 0x0F)) ++ return le16toh(smbios[0x06] | (smbios[0x07] << 8)); ++ ++ return 0; ++} ++ ++/* API */ ++ ++/** ++ * dmi_get_table - allocate dmi table ++ * ++ * Returns pointer on allocated dmi_table struct on success, ++ * otherwise returns NULL. When table is not needed it has to be ++ * put by dmi_put_table. ++ */ ++struct dmi_table *dmi_get_table(void) ++{ ++ struct dmi_table *dt; ++ unsigned int max_dmisize; ++ ++ dt = malloc(sizeof(struct dmi_table)); ++ ++ if (!dmi_get_smbios(dt->smbios)) ++ goto err; ++ ++ max_dmisize = dmi_get_expected_size(dt->smbios); ++ if (max_dmisize < MIN_DMI_STRUCT_SIZE) { ++ fprintf(stderr, "SMBIOS entry point is incorrect\n"); ++ goto err; ++ } ++ ++ dt->dmi_list = dmi_get_dmilist(&dt->dmi_count, ++ &dt->dmi_size, max_dmisize + 1); ++ if (!dt->dmi_list) ++ goto err; ++ ++ return dt; ++ ++err: ++ free(dt); ++ return NULL; ++} ++ ++/** ++ * dmi_put_table - used in pair with dmi_get_dmitable ++ * @dt: dmi table pointer taken by dmi_get_table ++ */ ++int dmi_put_table(struct dmi_table *dt) ++{ ++ int ret = -1; ++ ++ if (!dt) { ++ fprintf(stderr, "pointer for DMI table is incorrect\n"); ++ return ret; ++ } ++ ++ ret = dmi_put_dmilist(dt->dmi_list); ++ free(dt); ++ ++ return ret; ++} ++ ++/** ++ * dmi_get_raw_data - give a pointer to raw dmi table, all raw dmi entries are ++ * contiguously situated within this memory in original right order. ++ * @dmi_list: dmi list only taken by dmi_get_dmilist ++ */ ++void *dmi_get_raw_data(struct dmi_entry *dmi_list) ++{ ++ return dmi_list->h.data; ++} ++ ++/** ++ * dmi_get_entry_by_handle - searches an entry in dmi list by given handle ++ * @dmi_list: dmi list to search for ++ * @handle: handle to find entry with ++ * ++ * Returns entry with given handle on success and NULL otherwise ++ */ ++struct dmi_entry *dmi_get_entry_by_handle(struct dmi_entry *dmi_list, ++ int handle) ++{ ++ struct dmi_entry *entry; ++ ++ for (entry = dmi_list; entry; entry = entry->next) ++ if (handle == entry->h.handle) ++ return entry; ++ ++ return NULL; ++} ++ ++/** ++ * dmi_get_next_entry_by_type - searches a next entry in dmi list by type ++ * @dmi_entry: the dmi_entry in dmi list to search beginnig with ++ * @type: type of dmi entry to find ++ */ ++struct dmi_entry *dmi_get_next_entry_by_type(struct dmi_entry *dmi_entry, ++ unsigned char type) ++{ ++ struct dmi_entry *entry; ++ ++ for (entry = dmi_entry->next; entry; entry = entry->next) ++ if (type == entry->h.type) ++ return entry; ++ ++ return NULL; ++} ++ ++/** ++ * dmifs_is_exist - checks if dmi sysfs exists ++ * ++ * Returns 1 on success and 0 if no ++ */ ++int dmifs_is_exist(void) ++{ ++ int ret; ++ char dmi_cat[] = "/sys/firmware/dmi/entries/"; ++ DIR *dmi_dir = opendir(dmi_cat); ++ ++ ret = dmi_dir ? 1 : 0; ++ ++ if (closedir(dmi_dir)) ++ fprintf(stderr, "Cannot close %s", dmi_cat); ++ ++ return ret; ++} +diff --git a/libdmifs.h b/libdmifs.h +new file mode 100644 +index 0000000..218d07f +--- /dev/null ++++ b/libdmifs.h +@@ -0,0 +1,56 @@ ++#ifndef LIBDMIFS_H ++#define LIBDMIFS_H ++ ++/** ++ * dmi_hdata - information of dmi entry header ++ * type: type of dmi entry ++ * length: length of formated area of dmi entry ++ * data: pointer to whole raw dmi entry data ++ */ ++struct dmi_hdata { ++ unsigned char type; ++ unsigned char length; ++ unsigned short handle; ++ unsigned char *data; ++}; ++ ++/** ++ * dmi_entry - holds information about dmi entry ++ * next: internal in list pointer ++ * h: dmi header data, including raw data ++ * position: position within the dmi table ++ * d_name: dirctory entry name in sysfs ++ */ ++struct dmi_entry { ++ struct dmi_entry *next; ++ struct dmi_hdata h; ++ unsigned int position; ++ char *d_name; ++}; ++ ++/** ++ * dmi_table - contains whole information about smbios/dmi tables ++ * @smbios: pointer to raw data of smbios table ++ * @dmi_count: number of dmi entries in dmi table ++ * @dmi_size: length of dmi table in bytes ++ * @dmi_list: single list of dmi table entries, raw data of which contiguously ++ * situated in memnory. The list can be used to take a pointer to raw data ++ * of whole dmi table. ++ */ ++struct dmi_table { ++ unsigned char smbios[32]; ++ unsigned int dmi_count; ++ unsigned int dmi_size; ++ struct dmi_entry *dmi_list; ++}; ++ ++int dmifs_is_exist(void); ++struct dmi_table *dmi_get_table(void); ++int dmi_put_table(struct dmi_table *dt); ++void *dmi_get_raw_data(struct dmi_entry *dmi_list); ++struct dmi_entry *dmi_get_entry_by_handle(struct dmi_entry *dmi_list, ++ int handle); ++struct dmi_entry *dmi_get_next_entry_by_type(struct dmi_entry *dmi_entry, ++ unsigned char type); ++ ++#endif +-- +1.9.3 + diff --git a/SOURCES/Support-SMBIOS-3.0-64-bit-header.patch b/SOURCES/Support-SMBIOS-3.0-64-bit-header.patch new file mode 100644 index 0000000..20aeb9f --- /dev/null +++ b/SOURCES/Support-SMBIOS-3.0-64-bit-header.patch @@ -0,0 +1,269 @@ +From 59820aacf5f9bcfde98753fde79ca2c779d755aa Mon Sep 17 00:00:00 2001 +From: Mark Salter +Date: Tue, 24 Feb 2015 23:42:05 -0500 +Subject: [PATCH] Support SMBIOS 3.0 64-bit header + +The SMBIOS 64-bit header adds suport for a 64-bit base address for the +SMBIOS tables. This patch adds code to parse deal with older 32-bit +headers and well as the 64-bit header. It also fixes 32-bit address +assumptions in a number of places. + +Signed-off-by: Mark Salter +--- + dmidecode.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++------------- + 1 file changed, 112 insertions(+), 31 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index fee3af1..6865cd7 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -4277,7 +4277,10 @@ static u16 get_smbios_version(unsigned char *smbios) + { + u16 ver; + +- ver = (smbios[0x06] << 8) + smbios[0x07]; ++ if (!memcmp(smbios, "_SM3_", 5)) ++ ver = (smbios[0x07] << 8) + smbios[0x08]; ++ else ++ ver = (smbios[0x06] << 8) + smbios[0x07]; + + /* Some BIOS report weird SMBIOS version, fix that up */ + switch (ver) { +@@ -4348,7 +4351,33 @@ static void dmi_table_dump(u8 *buf, u16 len) + write_dump(32, len, buf, opt.dumpfile, 0); + } + +-static void dmi_table(u32 base, u8 *buf, u16 len, u16 num, u16 ver) ++static u16 dmi_table_count(u8 *buf, u16 len) ++{ ++ u8 *data; ++ u16 i = 0; ++ ++ data = buf; ++ while (data+4 <= buf + len) /* 4 is the length of an SMBIOS structure header */ ++ { ++ struct dmi_header h; ++ ++ ++i; ++ ++ to_dmi_header(&h, data); ++ ++ if (h.length < 4) ++ break; ++ ++ /* look for the next handle */ ++ data += h.length; ++ while (data - buf + 1 < len && (data[0] != 0 || data[1] != 0)) ++ data++; ++ data += 2; ++ } ++ return i; ++} ++ ++static void dmi_table(u64 base, u8 *buf, u16 len, u16 num, u16 ver) + { + u8 *data; + int i = 0; +@@ -4372,8 +4401,13 @@ static void dmi_table(u32 base, u8 *buf, u16 len, u16 num, u16 ver) + { + printf("%u structures occupying %u bytes.\n", + num, len); +- if (!(opt.flags & FLAG_FROM_DUMP)) +- printf("Table at 0x%08X.\n", base); ++ if (!(opt.flags & FLAG_FROM_DUMP)) { ++ if (base.h) ++ printf("Table at 0x%08X%08X.\n", ++ base.h, base.l); ++ else ++ printf("Table at 0x%08X.\n", base.l); ++ } + } + printf("\n"); + } +@@ -4460,15 +4494,19 @@ static void dmi_table(u32 base, u8 *buf, u16 len, u16 num, u16 ver) + /* + * Build a crafted entry point with table address hard-coded to 32, + * as this is where we will put it in the output file. We adjust the +- * DMI checksum appropriately. The SMBIOS checksum needs no adjustment. ++ * checksum appropriately. + */ +-static void overwrite_dmi_address(u8 *buf) ++static void overwrite_address(u8 *cksum, u8 *addr, int addr_len) + { +- buf[0x05] += buf[0x08] + buf[0x09] + buf[0x0A] + buf[0x0B] - 32; +- buf[0x08] = 32; +- buf[0x09] = 0; +- buf[0x0A] = 0; +- buf[0x0B] = 0; ++ int i; ++ ++ *cksum += addr[0] - 32; ++ addr[0] = 32; ++ ++ for (i = 1; i < addr_len; ++i) { ++ *cksum += addr[i]; ++ addr[i] = 0; ++ } + } + + /** +@@ -4478,36 +4516,51 @@ static void overwrite_dmi_address(u8 *buf) + static void smbios_in_dumpfile(unsigned char *smbios) + { + u8 crafted[32]; ++ u8 len; + + memcpy(crafted, smbios, 32); +- overwrite_dmi_address(crafted + 0x10); ++ if (!memcmp(smbios, "_SM3_", 5)) { ++ overwrite_address(crafted + 0x05, crafted + 0x10, 8); ++ len = crafted[0x06]; ++ } else { ++ overwrite_address(crafted + 0x15, crafted + 0x18, 4); ++ len = crafted[0x05]; ++ } + + if (!(opt.flags & FLAG_QUIET)) + printf("# Writing %d bytes to %s.\n", crafted[0x05], + opt.dumpfile); + +- write_dump(0, crafted[0x05], crafted, opt.dumpfile, 1); ++ write_dump(0, len, crafted, opt.dumpfile, 1); + } + + static int smbios_decode(u8 *buf, const char *devmem) + { + u16 ver; +- u16 len; +- u32 base; ++ u16 len, num; ++ u64 base; + u8 *dmibuf; + +- if (!checksum(buf, buf[0x05]) +- || memcmp(buf + 0x10, "_DMI_", 5) != 0 +- || !checksum(buf + 0x10, 0x0F)) +- return 0; ++ if (!memcmp(buf, "_SM3_", 5)) { ++ if (!checksum(buf, buf[0x06])) ++ return 0; ++ base = QWORD(buf + 0x10); ++ len = WORD(buf + 0x0C); ++ } else { ++ if (!checksum(buf, buf[0x05]) ++ || memcmp(buf + 0x10, "_DMI_", 5) != 0 ++ || !checksum(buf + 0x10, 0x0F)) ++ return 0; ++ base.h = 0; ++ base.l = DWORD(buf + 0x18); ++ len = WORD(buf + 0x16); ++ } + + ver = get_smbios_version(buf); +- +- base = DWORD(buf + 0x18); +- len = WORD(buf + 0x16); +- dmibuf = mem_chunk(base, len, devmem); ++ dmibuf = mem_chunk(base.l, len, devmem); + if (!dmibuf) { + fprintf(stderr, "Table is unreachable, sorry." ++ + #ifndef USE_MMAP + " Try compiling dmidecode with -DUSE_MMAP." + #endif +@@ -4515,7 +4568,13 @@ static int smbios_decode(u8 *buf, const char *devmem) + return 0; + } + +- dmi_table(base, dmibuf, len, WORD(buf + 0x1C), ver); ++ /* version 3 64-bit header doesn't have number of tables */ ++ if (!memcmp(buf, "_SM3_", 5)) ++ num = dmi_table_count(dmibuf, len); ++ else ++ num = WORD(buf + 0x1C); ++ ++ dmi_table(base, dmibuf, len, num, ver); + + free(dmibuf); + +@@ -4529,6 +4588,7 @@ static void dmifs_smbios_decode(void) + { + u16 ver; + u8 *smbios; ++ u64 base; + struct dmi_table *dt; + + dt = dmi_get_table(); +@@ -4538,8 +4598,28 @@ static void dmifs_smbios_decode(void) + smbios = dt->smbios; + + ver = get_smbios_version(dt->smbios); +- dmi_table(DWORD(smbios + 0x18), dmi_get_raw_data(dt->dmi_list), +- WORD(smbios + 0x16), WORD(smbios + 0x1C), ver); ++ ++ if (!memcmp(smbios, "_SM3_", 5)) { ++ base = QWORD(smbios + 0x10); ++ dmi_table(base, dmi_get_raw_data(dt->dmi_list), ++ dt->dmi_size, dt->dmi_count, ver); ++ if (opt.flags & FLAG_DUMP_BIN) { ++ /* ++ * Table length in SMBIOS 3.0 header is a maximum size. ++ * Make it exact to avoid warnings/errors when decoding ++ * from file we are dumping. ++ */ ++ dt->smbios[0x05] += dt->smbios[0x0c] + dt->smbios[0x0d]; ++ dt->smbios[0x0c] = dt->dmi_size; ++ dt->smbios[0x0d] = dt->dmi_size >> 8; ++ dt->smbios[0x05] -= dt->smbios[0x0c] + dt->smbios[0x0d]; ++ } ++ } else { ++ base.h = 0; ++ base.l = DWORD(smbios + 0x18); ++ dmi_table(base, dmi_get_raw_data(dt->dmi_list), ++ WORD(smbios + 0x16), WORD(smbios + 0x1C), ver); ++ } + + if (opt.flags & FLAG_DUMP_BIN) + smbios_in_dumpfile(dt->smbios); +@@ -4550,7 +4630,7 @@ static void dmifs_smbios_decode(void) + static int legacy_decode(u8 *buf, const char *devmem) + { + u16 len; +- u32 base; ++ u64 base; + u8 *dmibuf; + + if (!checksum(buf, 0x0F)) +@@ -4561,8 +4641,9 @@ static int legacy_decode(u8 *buf, const char *devmem) + buf[0x0E] >> 4, buf[0x0E] & 0x0F); + + len = WORD(buf + 0x06); +- base = DWORD(buf + 0x08); +- dmibuf = mem_chunk(base, len, devmem); ++ base.h = 0; ++ base.l = DWORD(buf + 0x08); ++ dmibuf = mem_chunk(base.l, len, devmem); + if (!dmibuf) { + fprintf(stderr, "Table is unreachable, sorry." + #ifndef USE_MMAP +@@ -4582,7 +4663,7 @@ static int legacy_decode(u8 *buf, const char *devmem) + u8 crafted[16]; + + memcpy(crafted, buf, 16); +- overwrite_dmi_address(crafted); ++ overwrite_address(crafted + 0x05, crafted + 0x08, 4); + + printf("# Writing %d bytes to %s.\n", 0x0F, opt.dumpfile); + write_dump(0, 0x0F, crafted, opt.dumpfile, 1); +@@ -4689,7 +4770,7 @@ int main(int argc, char * const argv[]) + goto exit_free; + } + +- if (memcmp(buf, "_SM_", 4) == 0) ++ if (memcmp(buf, "_SM_", 4) == 0 || memcmp(buf, "_SM3_", 5) == 0) + { + if (smbios_decode(buf, opt.dumpfile)) + found++; +-- +1.8.3.1 + diff --git a/SOURCES/dmidecode-2.12-smbios_fix.patch b/SOURCES/dmidecode-2.12-smbios_fix.patch new file mode 100644 index 0000000..f39205d --- /dev/null +++ b/SOURCES/dmidecode-2.12-smbios_fix.patch @@ -0,0 +1,86 @@ +diff -up dmidecode-2.12/CHANGELOG.smbios_fix dmidecode-2.12/CHANGELOG +--- dmidecode-2.12/CHANGELOG.smbios_fix 2013-05-09 09:44:35.668592078 +0200 ++++ dmidecode-2.12/CHANGELOG 2013-05-09 09:44:44.742610559 +0200 +@@ -1,3 +1,10 @@ ++2013-04-24 Jean Delvare ++ ++ * dmidecode.c: Strip trailig zeroes from memory voltage values ++ (DMI type 17). ++ * dmidecode.c: Fix support for new processor upgrade types (DMI ++ type 4) and new memory device type (DMI type 17.) ++ + 2013-04-17 Anton Arapov + + Update to support SMBIOS specification version 2.8.0. +diff -up dmidecode-2.12/dmidecode.c.smbios_fix dmidecode-2.12/dmidecode.c +--- dmidecode-2.12/dmidecode.c.smbios_fix 2013-05-09 09:44:26.404573273 +0200 ++++ dmidecode-2.12/dmidecode.c 2013-05-09 09:44:44.745610565 +0200 +@@ -69,7 +69,7 @@ + #define out_of_spec "" + static const char *bad_index = ""; + +-#define SUPPORTED_SMBIOS_VER 0x0207 ++#define SUPPORTED_SMBIOS_VER 0x0208 + + /* + * Type-independant Stuff +@@ -712,7 +712,6 @@ static const char *dmi_processor_family( + { 0x3D, "Opteron 6200" }, + { 0x3E, "Opteron 4200" }, + { 0x3F, "FX" }, +- + { 0x40, "MIPS" }, + { 0x41, "MIPS R4000" }, + { 0x42, "MIPS R4200" }, +@@ -729,7 +728,6 @@ static const char *dmi_processor_family( + { 0x4D, "Opteron 6300" }, + { 0x4E, "Opteron 3300" }, + { 0x4F, "FirePro" }, +- + { 0x50, "SPARC" }, + { 0x51, "SuperSPARC" }, + { 0x52, "MicroSPARC II" }, +@@ -1176,7 +1174,7 @@ static const char *dmi_processor_upgrade + "Socket LGA1356-3" /* 0x2C */ + }; + +- if (code >= 0x01 && code <= 0x2A) ++ if (code >= 0x01 && code <= 0x2C) + return upgrade[code - 0x01]; + return out_of_spec; + } +@@ -2236,7 +2234,7 @@ static void dmi_memory_voltage_value(u16 + if (code == 0) + printf(" Unknown"); + else +- printf(" %.3f V", (float)(i16)code / 1000); ++ printf(code % 100 ? " %g V" : " %.1f V", (float)code / 1000); + } + + static const char *dmi_memory_device_form_factor(u8 code) +@@ -2338,7 +2336,7 @@ static void dmi_memory_device_type_detai + { + int i; + +- for (i = 1; i <= 14; i++) ++ for (i = 1; i <= 15; i++) + if (code & (1 << i)) + printf(" %s", detail[i - 1]); + } +@@ -3657,13 +3655,13 @@ static void dmi_decode(const struct dmi_ + dmi_memory_device_speed(WORD(data + 0x20)); + printf("\n"); + if (h->length < 0x28) break; +- printf("\tMinimum voltage: "); ++ printf("\tMinimum Voltage: "); + dmi_memory_voltage_value(WORD(data + 0x22)); + printf("\n"); +- printf("\tMaximum voltage: "); ++ printf("\tMaximum Voltage: "); + dmi_memory_voltage_value(WORD(data + 0x24)); + printf("\n"); +- printf("\tConfigured voltage: "); ++ printf("\tConfigured Voltage: "); + dmi_memory_voltage_value(WORD(data + 0x26)); + printf("\n"); + break; diff --git a/SOURCES/dmidecode-add-dmi-sysfs-support.patch b/SOURCES/dmidecode-add-dmi-sysfs-support.patch new file mode 100644 index 0000000..245d965 --- /dev/null +++ b/SOURCES/dmidecode-add-dmi-sysfs-support.patch @@ -0,0 +1,100 @@ +From 1bd45ec19f7a2d4cdc293b7a5e705c6ee793953e Mon Sep 17 00:00:00 2001 +From: Ivan Khoronzhuk +Date: Thu, 15 Jan 2015 03:01:37 +0200 +Subject: [PATCH 4/4] dmidecode: add dmi sysfs support + +For working with newly introduced dmi sysfs the dmifs library +was used. It's needed by the systems that cannot use /dev/mem to +access hardware addresses and as result cannot read dmi table. +So another, more correct approach, can be used, it's to read +information from dmi sysfs. + +Currently we can use libdmifs library for that. + +Reported-by: Leif Lindholm +Signed-off-by: Ivan Khoronzhuk +--- + Makefile | 2 +- + dmidecode.c | 31 ++++++++++++++++++++++++++++++- + version.h | 2 +- + 3 files changed, 32 insertions(+), 3 deletions(-) + +diff --git a/Makefile b/Makefile +index 66c24d5..e3f5c49 100644 +--- a/Makefile ++++ b/Makefile +@@ -58,7 +58,7 @@ all : $(PROGRAMS) + # + + dmidecode : dmidecode.o dmiopt.o dmioem.o util.o +- $(CC) $(LDFLAGS) dmidecode.o dmiopt.o dmioem.o util.o -o $@ ++ $(CC) $(LDFLAGS) dmidecode.o dmiopt.o dmioem.o util.o -ldmifs -o $@ + + biosdecode : biosdecode.o util.o + $(CC) $(LDFLAGS) biosdecode.o util.o -o $@ +diff --git a/dmidecode.c b/dmidecode.c +index 2fedddc..7d3c133 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -57,6 +57,7 @@ + #include + #include + #include ++#include + + #include "version.h" + #include "config.h" +@@ -4535,6 +4536,28 @@ static int smbios_decode(u8 *buf, const char *devmem) + return 1; + } + ++static void dmifs_smbios_decode(void) ++{ ++ u16 ver; ++ u8 *smbios; ++ struct dmi_table *dt; ++ ++ dt = dmi_get_table(); ++ if (!dt) ++ return; ++ ++ smbios = dt->smbios; ++ ++ ver = get_smbios_version(dt->smbios); ++ dmi_table(DWORD(smbios + 0x18), dmi_get_raw_data(dt->dmi_list), ++ WORD(smbios + 0x16), WORD(smbios + 0x1C), ver); ++ ++ if (opt.flags & FLAG_DUMP_BIN) ++ smbios_in_dumpfile(dt->smbios); ++ ++ dmi_put_table(dt); ++} ++ + static int legacy_decode(u8 *buf, const char *devmem) + { + u16 len; +@@ -4692,7 +4715,13 @@ int main(int argc, char * const argv[]) + goto done; + } + +- /* First try EFI (ia64, Intel-based Mac) */ ++ /* First try dmi sysfs */ ++ if (dmifs_is_exist()) { ++ dmifs_smbios_decode(); ++ goto exit_free; ++ } ++ ++ /* Second try EFI (ia64, Intel-based Mac) */ + efi = address_from_efi(&fp); + switch (efi) + { +diff --git a/version.h b/version.h +index 140d334..ce7ffaf 100644 +--- a/version.h ++++ b/version.h +@@ -1 +1 @@ +-#define VERSION "2.12" ++#define VERSION "2.12-dmifs" +-- +1.9.3 + diff --git a/SOURCES/dmidecode-move-memory-map-function-from-dmi_decode.patch b/SOURCES/dmidecode-move-memory-map-function-from-dmi_decode.patch new file mode 100644 index 0000000..95f18fd --- /dev/null +++ b/SOURCES/dmidecode-move-memory-map-function-from-dmi_decode.patch @@ -0,0 +1,155 @@ +From 9967415630f6e58da27ebd33a32d1f1bb1f6ba78 Mon Sep 17 00:00:00 2001 +From: Ivan Khoronzhuk +Date: Thu, 15 Jan 2015 22:39:26 +0200 +Subject: [PATCH 3/4] dmidecode: move memory map function from dmi_decode + +There is no reason to allocate/copy/free memory for dmi_table inside +function. It's more convenient to do it outside. In this case we can +use dmi_decode function with already allocated memory like in case +with dmifs library. The same is for dmi_table_dump(). + +Signed-off-by: Ivan Khoronzhuk +--- + dmidecode.c | 70 ++++++++++++++++++++++++++++++++++++------------------------- + 1 file changed, 41 insertions(+), 29 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index 4e4a82f..2fedddc 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -4351,25 +4351,15 @@ static void dmi_table_string(const struct dmi_header *h, const u8 *data, u16 ver + } + } + +-static void dmi_table_dump(u32 base, u16 len, const char *devmem) ++static void dmi_table_dump(u8 *buf, u16 len) + { +- u8 *buf; +- +- if ((buf = mem_chunk(base, len, devmem)) == NULL) +- { +- fprintf(stderr, "Failed to read table, sorry.\n"); +- return; +- } +- + if (!(opt.flags & FLAG_QUIET)) + printf("# Writing %d bytes to %s.\n", len, opt.dumpfile); + write_dump(32, len, buf, opt.dumpfile, 0); +- free(buf); + } + +-static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem) ++static void dmi_table(u32 base, u8 *buf, u16 len, u16 num, u16 ver) + { +- u8 *buf; + u8 *data; + int i = 0; + +@@ -4382,7 +4372,7 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem) + + if (opt.flags & FLAG_DUMP_BIN) + { +- dmi_table_dump(base, len, devmem); ++ dmi_table_dump(buf, len); + return; + } + +@@ -4398,16 +4388,6 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem) + printf("\n"); + } + +- if ((buf = mem_chunk(base, len, devmem)) == NULL) +- { +- fprintf(stderr, "Table is unreachable, sorry." +-#ifndef USE_MMAP +- " Try compiling dmidecode with -DUSE_MMAP." +-#endif +- "\n"); +- return; +- } +- + data = buf; + while (i < num && data+4 <= buf + len) /* 4 is the length of an SMBIOS structure header */ + { +@@ -4485,8 +4465,6 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem) + "announced, structures occupy %d bytes.\n", + len, (unsigned int)(data - buf)); + } +- +- free(buf); + } + + /* +@@ -4524,6 +4502,9 @@ static void smbios_in_dumpfile(unsigned char *smbios) + static int smbios_decode(u8 *buf, const char *devmem) + { + u16 ver; ++ u16 len; ++ u32 base; ++ u8 *dmibuf; + + if (!checksum(buf, buf[0x05]) + || memcmp(buf + 0x10, "_DMI_", 5) != 0 +@@ -4532,8 +4513,21 @@ static int smbios_decode(u8 *buf, const char *devmem) + + ver = get_smbios_version(buf); + +- dmi_table(DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), +- ver, devmem); ++ base = DWORD(buf + 0x18); ++ len = WORD(buf + 0x16); ++ dmibuf = mem_chunk(base, len, devmem); ++ if (!dmibuf) { ++ fprintf(stderr, "Table is unreachable, sorry." ++#ifndef USE_MMAP ++ " Try compiling dmidecode with -DUSE_MMAP." ++#endif ++ "\n"); ++ return 0; ++ } ++ ++ dmi_table(base, dmibuf, len, WORD(buf + 0x1C), ver); ++ ++ free(dmibuf); + + if (opt.flags & FLAG_DUMP_BIN) + smbios_in_dumpfile(buf); +@@ -4543,6 +4537,10 @@ static int smbios_decode(u8 *buf, const char *devmem) + + static int legacy_decode(u8 *buf, const char *devmem) + { ++ u16 len; ++ u32 base; ++ u8 *dmibuf; ++ + if (!checksum(buf, 0x0F)) + return 0; + +@@ -4550,8 +4548,22 @@ static int legacy_decode(u8 *buf, const char *devmem) + printf("Legacy DMI %u.%u present.\n", + buf[0x0E] >> 4, buf[0x0E] & 0x0F); + +- dmi_table(DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), +- ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem); ++ len = WORD(buf + 0x06); ++ base = DWORD(buf + 0x08); ++ dmibuf = mem_chunk(base, len, devmem); ++ if (!dmibuf) { ++ fprintf(stderr, "Table is unreachable, sorry." ++#ifndef USE_MMAP ++ " Try compiling dmidecode with -DUSE_MMAP." ++#endif ++ "\n"); ++ return 0; ++ } ++ ++ dmi_table(base, dmibuf, len, WORD(buf + 0x0C), ++ ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F)); ++ ++ free(dmibuf); + + if (opt.flags & FLAG_DUMP_BIN) + { +-- +1.9.3 + diff --git a/SOURCES/dmidecode-use-common-function-to-get-SMBIOS-version.patch b/SOURCES/dmidecode-use-common-function-to-get-SMBIOS-version.patch new file mode 100644 index 0000000..476662f --- /dev/null +++ b/SOURCES/dmidecode-use-common-function-to-get-SMBIOS-version.patch @@ -0,0 +1,101 @@ +From db2e8e195c15ed0e56e6652c1b59fdd487d4fbb9 Mon Sep 17 00:00:00 2001 +From: Ivan Khoronzhuk +Date: Thu, 15 Jan 2015 01:14:43 +0200 +Subject: [PATCH 1/4] dmidecode: use common function to get SMBIOS version + +Move SMBIOS version code in separate function as it's more readable +and can be used by others when it's required. +In paticular, it can be used when dmi sysfs support is added. + +Signed-off-by: Ivan Khoronzhuk +--- + dmidecode.c | 59 +++++++++++++++++++++++++++++++++++++---------------------- + 1 file changed, 37 insertions(+), 22 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index a5304a7..c4b4fd1 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -4277,6 +4277,42 @@ static void dmi_decode(const struct dmi_header *h, u16 ver) + printf("\n"); + } + ++/** ++ * get_smbios_version - get SMBIOS version ++ * @smbios: pointer on SMBIOS entry point table ++ * ++ * Returns SMBIOS version ++ */ ++static u16 get_smbios_version(unsigned char *smbios) ++{ ++ u16 ver; ++ ++ ver = (smbios[0x06] << 8) + smbios[0x07]; ++ ++ /* Some BIOS report weird SMBIOS version, fix that up */ ++ switch (ver) { ++ case 0x021F: ++ case 0x0221: ++ if (!(opt.flags & FLAG_QUIET)) ++ printf("SMBIOS version fixup (2.%d -> 2.%d).\n", ++ ver & 0xFF, 3); ++ ver = 0x0203; ++ break; ++ case 0x0233: ++ if (!(opt.flags & FLAG_QUIET)) ++ printf("SMBIOS version fixup (2.%d -> 2.%d).\n", ++ 51, 6); ++ ver = 0x0206; ++ break; ++ } ++ ++ if (!(opt.flags & FLAG_QUIET)) ++ printf("SMBIOS %u.%u present.\n", ++ ver >> 8, ver & 0xFF); ++ ++ return ver; ++} ++ + static void to_dmi_header(struct dmi_header *h, u8 *data) + { + h->type = data[0]; +@@ -4453,7 +4489,6 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem) + free(buf); + } + +- + /* + * Build a crafted entry point with table address hard-coded to 32, + * as this is where we will put it in the output file. We adjust the +@@ -4477,27 +4512,7 @@ static int smbios_decode(u8 *buf, const char *devmem) + || !checksum(buf + 0x10, 0x0F)) + return 0; + +- ver = (buf[0x06] << 8) + buf[0x07]; +- /* Some BIOS report weird SMBIOS version, fix that up */ +- switch (ver) +- { +- case 0x021F: +- case 0x0221: +- if (!(opt.flags & FLAG_QUIET)) +- printf("SMBIOS version fixup (2.%d -> 2.%d).\n", +- ver & 0xFF, 3); +- ver = 0x0203; +- break; +- case 0x0233: +- if (!(opt.flags & FLAG_QUIET)) +- printf("SMBIOS version fixup (2.%d -> 2.%d).\n", +- 51, 6); +- ver = 0x0206; +- break; +- } +- if (!(opt.flags & FLAG_QUIET)) +- printf("SMBIOS %u.%u present.\n", +- ver >> 8, ver & 0xFF); ++ ver = get_smbios_version(buf); + + dmi_table(DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), + ver, devmem); +-- +1.9.3 + diff --git a/SOURCES/dmidecode-use-common-function-to-put-SMBIOS-in-dumpf.patch b/SOURCES/dmidecode-use-common-function-to-put-SMBIOS-in-dumpf.patch new file mode 100644 index 0000000..c8e9886 --- /dev/null +++ b/SOURCES/dmidecode-use-common-function-to-put-SMBIOS-in-dumpf.patch @@ -0,0 +1,64 @@ +From d4a148740afb211dc519945a8fc8b5eaa0adf280 Mon Sep 17 00:00:00 2001 +From: Ivan Khoronzhuk +Date: Thu, 15 Jan 2015 02:28:22 +0200 +Subject: [PATCH 2/4] dmidecode: use common function to put SMBIOS in dumpfile + +It's needed in order to generalize code before adding dmi sysfs +support. It' more convenient to hold common code in separate function. + +Signed-off-by: Ivan Khoronzhuk +--- + dmidecode.c | 30 +++++++++++++++++++----------- + 1 file changed, 19 insertions(+), 11 deletions(-) + +diff --git a/dmidecode.c b/dmidecode.c +index c4b4fd1..4e4a82f 100644 +--- a/dmidecode.c ++++ b/dmidecode.c +@@ -4503,6 +4503,24 @@ static void overwrite_dmi_address(u8 *buf) + buf[0x0B] = 0; + } + ++/** ++ * smbios_in_dumpfile - put SMBIOS entry table in dump file ++ * @smbios: pointer on SMBIOS entry table ++ */ ++static void smbios_in_dumpfile(unsigned char *smbios) ++{ ++ u8 crafted[32]; ++ ++ memcpy(crafted, smbios, 32); ++ overwrite_dmi_address(crafted + 0x10); ++ ++ if (!(opt.flags & FLAG_QUIET)) ++ printf("# Writing %d bytes to %s.\n", crafted[0x05], ++ opt.dumpfile); ++ ++ write_dump(0, crafted[0x05], crafted, opt.dumpfile, 1); ++} ++ + static int smbios_decode(u8 *buf, const char *devmem) + { + u16 ver; +@@ -4518,17 +4536,7 @@ static int smbios_decode(u8 *buf, const char *devmem) + ver, devmem); + + if (opt.flags & FLAG_DUMP_BIN) +- { +- u8 crafted[32]; +- +- memcpy(crafted, buf, 32); +- overwrite_dmi_address(crafted + 0x10); +- +- if (!(opt.flags & FLAG_QUIET)) +- printf("# Writing %d bytes to %s.\n", crafted[0x05], +- opt.dumpfile); +- write_dump(0, crafted[0x05], crafted, opt.dumpfile, 1); +- } ++ smbios_in_dumpfile(buf); + + return 1; + } +-- +1.9.3 + diff --git a/SPECS/dmidecode.spec b/SPECS/dmidecode.spec new file mode 100644 index 0000000..b9a9cad --- /dev/null +++ b/SPECS/dmidecode.spec @@ -0,0 +1,200 @@ +Summary: Tool to analyse BIOS DMI data +Name: dmidecode +Version: 2.12 +Release: 5.1%{?dist} +Epoch: 1 +Group: System Environment/Base +License: GPLv2+ +Source0: %{name}-%{version}.tar.bz2 +URL: http://www.nongnu.org/dmidecode/ +Patch0: dmidecode-2.12-smbios_fix.patch +Patch1: dmidecode-use-common-function-to-get-SMBIOS-version.patch +Patch2: dmidecode-use-common-function-to-put-SMBIOS-in-dumpf.patch +Patch3: dmidecode-move-memory-map-function-from-dmi_decode.patch +Patch4: dmidecode-add-dmi-sysfs-support.patch +Patch5: Add-libdmifs-from-Linaro.patch +Patch6: Support-SMBIOS-3.0-64-bit-header.patch +Buildroot: %{_tmppath}/%{name}-%{version}-root +BuildRequires: automake autoconf +ExclusiveArch: %{ix86} x86_64 ia64 aarch64 + +%description +dmidecode reports information about x86 & ia64 hardware as described in the +system BIOS according to the SMBIOS/DMI standard. This information +typically includes system manufacturer, model name, serial number, +BIOS version, asset tag as well as a lot of other details of varying +level of interest and reliability depending on the manufacturer. + +This will often include usage status for the CPU sockets, expansion +slots (e.g. AGP, PCI, ISA) and memory module slots, and the list of +I/O ports (e.g. serial, parallel, USB). + +%prep +%setup -q +%patch0 -p1 -b .smbios_fix +%patch1 -p1 -b .smbios_ver +%patch2 -p1 -b .smbios_dump +%patch3 -p1 -b .smbios_memmap +%patch4 -p1 -b .dmi_sysfs +%patch5 -p1 -b .libdmifs +%patch6 -p1 -b .smbios3 + +%build +make %{?_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" + +%install +rm -rf ${buildroot} +make %{?_smp_mflags} DESTDIR=%{buildroot} prefix=%{_prefix} install-bin install-man + +%clean +rm -rf ${buildroot} + +%files +%defattr(-,root,root) +%doc AUTHORS CHANGELOG LICENSE README +%{_sbindir}/dmidecode +%ifarch %{ix86} x86_64 +%{_sbindir}/vpddecode +%{_sbindir}/ownership +%{_sbindir}/biosdecode +%endif +%{_mandir}/man8/* + +%changelog +* Wed Feb 25 2015 Mark Salter - 1:2.12-5.1 +- Add preliminary support for SMBIOS 64-bit entry point + +* Fri Feb 21 2014 Anton Arapov - 2.12-5 +- Spec file fixes for the Aarch64. (John Feeney ) + +* Fri Dec 27 2013 Daniel Mach - 1:2.12-4 +- Mass rebuild 2013-12-27 + +* Thu May 09 2013 Anton Arapov - 1:2.12-3 +- Accomodate few more necesary, to enable SMBIOS v2.8, changes from upstream. + +* Fri Apr 26 2013 Anton Arapov - 1:2.12-2 +- Fixup, so that it actually read SMBIOS 2.8.0 table. + +* Wed Apr 17 2013 Anton Arapov - 1:2.12-1 +- Update to upstream 2.12 release. + +* Wed Feb 13 2013 Fedora Release Engineering - 1:2.11-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Wed Jul 18 2012 Fedora Release Engineering - 1:2.11-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Mon Mar 26 2012 Anton Arapov - 1:2.11-8 +- Update dmidecode.8 manpage + +* Mon Mar 12 2012 Anton Arapov - 1:2.11-7 +- Add "PXE" to HP OEM Type 209 record output +- Properly print the hexadecimal value of invalid string characters + +* Fri Jan 13 2012 Fedora Release Engineering - 1:2.11-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Mon Nov 14 2011 Anton Arapov - 1:2.11-5 +- Fix the wrong call of the dmi_chassis_type function call. Thus fix + an issue on the systems with the chassis lock available, application + doesn't fall out with the out of spec error anymore. + +* Tue May 03 2011 Anton Arapov - 1:2.11-4 +- Update to SMBIOS 2.7.1 +- Fix the boundaries check in type16 + +* Tue Feb 08 2011 Fedora Release Engineering - 1:2.11-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Wed Jan 19 2011 Anton Arapov - 1:2.11-2 +- Update to upstream 2.11 release. (#623047) + +* Wed Jan 19 2011 Anton Arapov - 1:2.11-1 +- Fix the changelog's NVR. + +* Mon Nov 08 2010 Prarit Bhargava - 1:2.10-3 +- updated kernel.spec for review [BZ 225698] + +* Fri Oct 15 2010 Anton Arapov - 1:2.10-2 +- Does not build with gnu make v3.82+ (#631407) + +* Fri Dec 18 2009 Prarit Bhargava - 1:2.10-1.40 +- Fix rpmlint errors in specfile + +* Fri Aug 28 2009 Jarod Wilson - 1:2.10-1.39 +- Fix cache associativity mapping (was missing some commas) + +* Mon Aug 24 2009 Jarod Wilson - 1:2.10-1.38 +- Add support for newer sockets, processors and pcie slot types + +* Fri Jul 24 2009 Fedora Release Engineering - 1:2.10-1.36.2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Fri Feb 27 2009 Matthias Clasen +- Build for i586 + +* Tue Feb 24 2009 Fedora Release Engineering - 1:2.10-1.34.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Mon Feb 09 2009 Prarit Bhargava 1:2.10 +- rebuild with version 2.10 + +* Wed Jan 28 2009 Prarit Bhargava 1:2.9-1.32 +- fix Summary field (BZ 225698) + +* Wed Jul 16 2008 Tom "spot" Callaway 1:2.9-1.30 +- fix license tag + +* Fri Mar 14 2008 Doug Chapman 1:2.9-1.29.1 +- Do not package vpddecode, ownership and biosdecode on ia64 since those are x86 only + +* Tue Feb 19 2008 Fedora Release Engineering - 1:2.9-1.27.1 +- Autorebuild for GCC 4.3 + +* Mon Oct 22 2007 Prarit Bhargava - 1:2.9 +- rebuild with version 2.9 +* Wed Jul 12 2006 Jesse Keating - 1:2.7-1.25.1 +- rebuild + +* Thu Feb 09 2006 Dave Jones +- rebuild. + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Mon Nov 28 2005 Dave Jones +- Integrate several specfile cleanups from Robert Scheck. (#172543) + +* Sat Sep 24 2005 Dave Jones +- Revert yesterdays patch, its unneeded in 2.7 + +* Fri Sep 23 2005 Dave Jones +- Don't try to modify areas mmap'd read-only. +- Don't build on ia64 any more. + (It breaks on some boxes very badly, and works on very few). + +* Mon Sep 12 2005 Dave Jones +- Update to upstream 2.7 + +* Fri Apr 15 2005 Florian La Roche +- remove empty scripts + +* Wed Mar 2 2005 Dave Jones +- Update to upstream 2.6 + +* Tue Mar 1 2005 Dave Jones +- Rebuild for gcc4 + +* Tue Feb 8 2005 Dave Jones +- Rebuild with -D_FORTIFY_SOURCE=2 + +* Tue Jan 11 2005 Dave Jones +- Add missing Obsoletes: kernel-utils + +* Mon Jan 10 2005 Dave Jones +- Update to upstream 2.5 release. + +* Sat Dec 18 2004 Dave Jones +- Initial packaging, based upon kernel-utils package. +