summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Delvare <jdelvare@suse.de>2008-02-16 18:12:35 +0000
committerJean Delvare <jdelvare@suse.de>2008-02-16 18:12:35 +0000
commit4e721204a471e64c041a4c260707d0d52d1811e6 (patch)
treebbc22a0b6ef4dd7315490a785cdaf0d1f5fc4c29
parent8c6bf0cea2a592591449c78e09570aa570987cc6 (diff)
downloaddmidecode-git-4e721204a471e64c041a4c260707d0d52d1811e6.tar.gz
New option --dump-bin, dump the DMI data to a sparse binary file.
-rw-r--r--CHANGELOG7
-rw-r--r--dmidecode.c41
-rw-r--r--dmiopt.c11
-rw-r--r--dmiopt.h2
-rw-r--r--man/dmidecode.87
-rw-r--r--util.c42
-rw-r--r--util.h1
7 files changed, 109 insertions, 2 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 1549bac..d0216ef 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,10 @@
+2008-02-16 Jean Delvare <khali@linux-fr.org>
+
+ * util.c, util.h: New helper function write_dump.
+ * dmidecode.c, dmiopt.c, dmiopt.h: New option --dump-bin, dump
+ the DMI data to a sparse binary file.
+ * dmidecode.8: Document the new option --dump-bin.
+
2007-06-30 Jean Delvare <khali@linux-fr.org>
* config.h: Add support for Solaris (x86 only, of course). Based
diff --git a/dmidecode.c b/dmidecode.c
index 51b4882..940b6fc 100644
--- a/dmidecode.c
+++ b/dmidecode.c
@@ -3847,12 +3847,39 @@ static void to_dmi_header(struct dmi_header *h, u8 *data)
h->data=data;
}
+static void dmi_table_dump(u32 base, u16 len, const char *devmem)
+{
+ u8 *buf;
+
+ if(base+len>0xFFFFF)
+ {
+ fprintf(stderr, "Table is too far away in memory, can't dump, sorry.\n");
+ return;
+ }
+
+ if((buf=mem_chunk(base, len, devmem))==NULL)
+ {
+ fprintf(stderr, "Failed to read table, sorry.\n");
+ return;
+ }
+
+ printf("# Writing %d bytes to %s.\n", len, opt.dumpfile);
+ write_dump(base, len, buf, opt.dumpfile);
+ free(buf);
+}
+
static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem)
{
u8 *buf;
u8 *data;
int i=0;
+ if(opt.flags & FLAG_DUMP_BIN)
+ {
+ dmi_table_dump(base, len, devmem);
+ return;
+ }
+
if(!(opt.flags & FLAG_QUIET))
{
if(opt.type==NULL)
@@ -4108,6 +4135,16 @@ memory_scan:
goto exit_free;
}
+ if(opt.flags & FLAG_DUMP_BIN)
+ {
+ printf("# Writing %d bytes to %s.\n", 0x10000, opt.dumpfile);
+ if(write_dump(0xF0000, 0x10000, buf, opt.dumpfile))
+ {
+ ret=2;
+ goto exit_free_buf;
+ }
+ }
+
for(fp=0; fp<=0xFFF0; fp+=16)
{
if(memcmp(buf+fp, "_SM_", 4)==0 && fp<=0xFFE0)
@@ -4126,11 +4163,11 @@ memory_scan:
}
done:
- free(buf);
-
if(!found && !(opt.flags & FLAG_QUIET))
printf("# No SMBIOS nor DMI entry point found, sorry.\n");
+exit_free_buf:
+ free(buf);
exit_free:
free(opt.type);
diff --git a/dmiopt.c b/dmiopt.c
index d571108..50ff0a3 100644
--- a/dmiopt.c
+++ b/dmiopt.c
@@ -223,6 +223,7 @@ int parse_command_line(int argc, char * const argv[])
{ "string", required_argument, NULL, 's' },
{ "type", required_argument, NULL, 't' },
{ "dump", no_argument, NULL, 'u' },
+ { "dump-bin", required_argument, NULL, 'B' },
{ "version", no_argument, NULL, 'V' },
{ 0, 0, 0, 0 }
};
@@ -230,6 +231,10 @@ int parse_command_line(int argc, char * const argv[])
while((option=getopt_long(argc, argv, optstring, longopts, NULL))!=-1)
switch(option)
{
+ case 'B':
+ opt.flags|=FLAG_DUMP_BIN;
+ opt.dumpfile=optarg;
+ break;
case 'd':
opt.devmem=optarg;
break;
@@ -287,6 +292,11 @@ int parse_command_line(int argc, char * const argv[])
fprintf(stderr, "Options --quiet and --dump are mutually exclusive\n");
return -1;
}
+ if((opt.flags & FLAG_DUMP_BIN) && (opt.type!=NULL || opt.string!=NULL))
+ {
+ fprintf(stderr, "Options --dump-bin, --string and --type are mutually exclusive\n");
+ return -1;
+ }
return 0;
}
@@ -302,6 +312,7 @@ void print_help(void)
" -s, --string KEYWORD Only display the value of the given DMI string\n"
" -t, --type TYPE Only display the entries of given type\n"
" -u, --dump Do not decode the entries\n"
+ " --dump-bin FILE Dump the DMI data to a sparse binary file\n"
" -V, --version Display the version and exit\n";
printf("%s", help);
diff --git a/dmiopt.h b/dmiopt.h
index fe8e193..52d83d5 100644
--- a/dmiopt.h
+++ b/dmiopt.h
@@ -34,6 +34,7 @@ struct opt
unsigned int flags;
u8 *type;
const struct string_keyword *string;
+ char *dumpfile;
};
extern struct opt opt;
@@ -41,6 +42,7 @@ extern struct opt opt;
#define FLAG_HELP (1<<1)
#define FLAG_DUMP (1<<2)
#define FLAG_QUIET (1<<3)
+#define FLAG_DUMP_BIN (1<<4)
int parse_command_line(int argc, char * const argv[]);
void print_help(void);
diff --git a/man/dmidecode.8 b/man/dmidecode.8
index d79781f..faff6db 100644
--- a/man/dmidecode.8
+++ b/man/dmidecode.8
@@ -114,6 +114,13 @@ you. The strings attached to each entry are displayed as both
hexadecimal and \s-1ASCII\s0. This option is mainly useful for debugging.
Mutually exclusive with \fB--quiet\fR and \fB--string\fR.
.TP
+.BR " " " " "--dump-bin FILE"
+Do not decode the entries, instead dump the DMI data to a sparse file
+in binary form. This is only supported when the DMI data lives in the
+first MB of memory, and only if the system doesn't use EFI to locate
+the DMI table. The generated file is suitable to pass to \fB--dev-mem\fR
+later. Mutually exclusive with \fB--type\fR and \fB--string\fR.
+.TP
.BR "-h" ", " "--help"
Display usage information and exit
.TP
diff --git a/util.c b/util.c
index 9eda714..9266b67 100644
--- a/util.c
+++ b/util.c
@@ -163,3 +163,45 @@ void *mem_chunk(size_t base, size_t len, const char *devmem)
return p;
}
+
+int write_dump(size_t base, size_t len, const void *data, const char *dumpfile)
+{
+ FILE *f;
+
+ f=fopen(dumpfile, "r+b");
+ if(!f && errno==ENOENT)
+ f=fopen(dumpfile, "wb");
+ if(!f)
+ {
+ fprintf(stderr, "%s: ", dumpfile);
+ perror("fopen");
+ return -1;
+ }
+
+ if(fseek(f, base, SEEK_SET)!=0)
+ {
+ fprintf(stderr, "%s: ", dumpfile);
+ perror("fseek");
+ goto err_close;
+ }
+
+ if(fwrite(data, len, 1, f)!=1)
+ {
+ fprintf(stderr, "%s: ", dumpfile);
+ perror("fwrite");
+ goto err_close;
+ }
+
+ if(fclose(f))
+ {
+ fprintf(stderr, "%s: ", dumpfile);
+ perror("fclose");
+ return -1;
+ }
+
+ return 0;
+
+err_close:
+ fclose(f);
+ return -1;
+}
diff --git a/util.h b/util.h
index b546f64..4a51ac7 100644
--- a/util.h
+++ b/util.h
@@ -6,3 +6,4 @@
int checksum(const u8 *buf, size_t len);
void *mem_chunk(size_t base, size_t len, const char *devmem);
+int write_dump(size_t base, size_t len, const void *data, const char *dumpfile);