diff options
-rw-r--r-- | CHANGELOG | 7 | ||||
-rw-r--r-- | dmidecode.c | 41 | ||||
-rw-r--r-- | dmiopt.c | 11 | ||||
-rw-r--r-- | dmiopt.h | 2 | ||||
-rw-r--r-- | man/dmidecode.8 | 7 | ||||
-rw-r--r-- | util.c | 42 | ||||
-rw-r--r-- | util.h | 1 |
7 files changed, 109 insertions, 2 deletions
@@ -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); @@ -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); @@ -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 @@ -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; +} @@ -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); |