mirror of
https://git.jff.email/cgit/dmidecode.git
synced 2026-08-08 18:54:08 +00:00
Imported Upstream version 2.12
This commit is contained in:
commit
723024faf0
86
AUTHORS
Normal file
86
AUTHORS
Normal file
@ -0,0 +1,86 @@
|
||||
DEVELOPER AND MAINTAINER
|
||||
Anton Arapov <anton@redhat.com>
|
||||
|
||||
ORIGINAL AUTHORS
|
||||
Alan Cox <alan@redhat.com>
|
||||
Jean Delvare <khali@linux-fr.org>
|
||||
|
||||
CODE CONTRIBUTORS (IN CHRONOLOGICAL ORDER)
|
||||
Matt Domsch <Matt_Domsch@dell.com>
|
||||
Arjan van de Ven <arjanv@redhat.com>
|
||||
Mark D. Studebaker <mds@paradyne.com>
|
||||
Larry Lile <llile@dreamworks.com>
|
||||
Dave Johnson <ddj@cascv.brown.edu>
|
||||
Petter Reinholdtsen <pere@hungry.com>
|
||||
Roberto Nibali <ratz@tac.ch>
|
||||
John Cagle <jcagle@kernel.org>
|
||||
Jens Elkner <elkner@linofee.org>
|
||||
Jarod Wilson <jarod@redhat.com>
|
||||
|
||||
MANY THANKS TO (IN CHRONOLOGICAL ORDER)
|
||||
Werner Heuser
|
||||
Alexandre Duret-Lutz
|
||||
Xavier Roche
|
||||
Pamela Huntley
|
||||
Gael Stephan
|
||||
Sebastian Henschel
|
||||
Richard Sharpe
|
||||
David Wilson
|
||||
Glen Foster
|
||||
Chad Smith
|
||||
Joshua Goldenhar
|
||||
Luc Van de Velde
|
||||
Mario Lang
|
||||
Hugues Lepesant
|
||||
Sergey Leonovich
|
||||
Mike Cooper
|
||||
Marc Rieffel
|
||||
Jeff Moyer
|
||||
Josef Moellers
|
||||
Zing Zing Shishak
|
||||
Rafael Avila de Espindola
|
||||
Roger Koot
|
||||
Martin Pool
|
||||
Doug Brenner
|
||||
Alex Williamson
|
||||
Durval Menezes
|
||||
Raphael Raimbault
|
||||
Raul Nunez de Arenas Coronado
|
||||
Francois Revol
|
||||
Dominik Klein
|
||||
Erwan Velu
|
||||
Don Howard
|
||||
Frans Pop
|
||||
Tomek Mateja
|
||||
Myke Olson
|
||||
Torsten Seemann
|
||||
Garry Belka
|
||||
Klaus Muth
|
||||
Antoine Fuselier
|
||||
Matthew Garrett
|
||||
Landry Breuil
|
||||
Luke Suchocki
|
||||
Attila Nagy
|
||||
Alex Iribarren
|
||||
Sebastien Douche
|
||||
William Lallemand
|
||||
Olivier Guerrier
|
||||
Pascal Terjan
|
||||
Stuart Hayes
|
||||
Sofian Brabez
|
||||
Vincent Pelletier
|
||||
Andreas Gruenbacher
|
||||
Lin Li
|
||||
Thomas Hiller
|
||||
Paul Flo Williams
|
||||
Olof Johansson
|
||||
Alexandre Lissy
|
||||
Michal Svec
|
||||
Vojtech Pavlik
|
||||
Murlin Wenzel
|
||||
Harald Mueller-Ney
|
||||
Lars Mueller
|
||||
Thomas Mingarelli
|
||||
Andrey Matveyev
|
||||
Stefan Tauner
|
||||
Naga Chumbalkar
|
||||
340
LICENSE
Normal file
340
LICENSE
Normal file
@ -0,0 +1,340 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
140
Makefile
Normal file
140
Makefile
Normal file
@ -0,0 +1,140 @@
|
||||
#
|
||||
# DMI Decode
|
||||
# BIOS Decode
|
||||
# VPD Decode
|
||||
#
|
||||
# Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
|
||||
# Copyright (C) 2002-2007 Jean Delvare <khali@linux-fr.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual \
|
||||
-Wcast-align -Wwrite-strings -Wmissing-prototypes -Winline -Wundef
|
||||
#CFLAGS += -DBIGENDIAN
|
||||
#CFLAGS += -DALIGNMENT_WORKAROUND
|
||||
|
||||
# When debugging, disable -O2 and enable -g.
|
||||
CFLAGS += -O2
|
||||
#CFLAGS += -g
|
||||
|
||||
# Pass linker flags here
|
||||
LDFLAGS =
|
||||
|
||||
DESTDIR =
|
||||
prefix = /usr/local
|
||||
sbindir = $(prefix)/sbin
|
||||
mandir = $(prefix)/share/man
|
||||
man8dir = $(mandir)/man8
|
||||
docdir = $(prefix)/share/doc/dmidecode
|
||||
|
||||
INSTALL := install
|
||||
INSTALL_DATA := $(INSTALL) -m 644
|
||||
INSTALL_DIR := $(INSTALL) -m 755 -d
|
||||
INSTALL_PROGRAM := $(INSTALL) -m 755
|
||||
RM := rm -f
|
||||
|
||||
# BSD make provides $MACHINE, but GNU make doesn't
|
||||
MACHINE ?= $(shell uname -m 2>/dev/null)
|
||||
|
||||
# These programs are only useful on x86
|
||||
PROGRAMS-i386 := biosdecode ownership vpddecode
|
||||
PROGRAMS-i486 := $(PROGRAMS-i386)
|
||||
PROGRAMS-i586 := $(PROGRAMS-i386)
|
||||
PROGRAMS-i686 := $(PROGRAMS-i386)
|
||||
PROGRAMS-x86_64 := biosdecode ownership vpddecode
|
||||
PROGRAMS-amd64 := $(PROGRAMS-x86_64)
|
||||
|
||||
PROGRAMS := dmidecode $(PROGRAMS-$(MACHINE))
|
||||
|
||||
all : $(PROGRAMS)
|
||||
|
||||
#
|
||||
# Programs
|
||||
#
|
||||
|
||||
dmidecode : dmidecode.o dmiopt.o dmioem.o util.o
|
||||
$(CC) $(LDFLAGS) dmidecode.o dmiopt.o dmioem.o util.o -o $@
|
||||
|
||||
biosdecode : biosdecode.o util.o
|
||||
$(CC) $(LDFLAGS) biosdecode.o util.o -o $@
|
||||
|
||||
ownership : ownership.o util.o
|
||||
$(CC) $(LDFLAGS) ownership.o util.o -o $@
|
||||
|
||||
vpddecode : vpddecode.o vpdopt.o util.o
|
||||
$(CC) $(LDFLAGS) vpddecode.o vpdopt.o util.o -o $@
|
||||
|
||||
#
|
||||
# Objects
|
||||
#
|
||||
|
||||
dmidecode.o : dmidecode.c version.h types.h util.h config.h dmidecode.h \
|
||||
dmiopt.h dmioem.h
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
dmiopt.o : dmiopt.c config.h types.h util.h dmidecode.h dmiopt.h
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
dmioem.o : dmioem.c types.h dmidecode.h dmioem.h
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
biosdecode.o : biosdecode.c version.h types.h util.h config.h
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
ownership.o : ownership.c version.h types.h util.h config.h
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
vpddecode.o : vpddecode.c version.h types.h util.h config.h vpdopt.h
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
vpdopt.o : vpdopt.c config.h util.h vpdopt.h
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
util.o : util.c types.h util.h config.h
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
#
|
||||
# Commands
|
||||
#
|
||||
|
||||
strip : $(PROGRAMS)
|
||||
strip $(PROGRAMS)
|
||||
|
||||
install : install-bin install-man install-doc
|
||||
|
||||
uninstall : uninstall-bin uninstall-man uninstall-doc
|
||||
|
||||
install-bin : $(PROGRAMS)
|
||||
$(INSTALL_DIR) $(DESTDIR)$(sbindir)
|
||||
for program in $(PROGRAMS) ; do \
|
||||
$(INSTALL_PROGRAM) $$program $(DESTDIR)$(sbindir) ; done
|
||||
|
||||
uninstall-bin :
|
||||
for program in $(PROGRAMS) ; do \
|
||||
$(RM) $(DESTDIR)$(sbindir)/$$program ; done
|
||||
|
||||
install-man :
|
||||
$(INSTALL_DIR) $(DESTDIR)$(man8dir)
|
||||
for program in $(PROGRAMS) ; do \
|
||||
$(INSTALL_DATA) man/$$program.8 $(DESTDIR)$(man8dir) ; done
|
||||
|
||||
uninstall-man :
|
||||
for program in $(PROGRAMS) ; do \
|
||||
$(RM) $(DESTDIR)$(man8dir)/$$program.8 ; done
|
||||
|
||||
install-doc :
|
||||
$(INSTALL_DIR) $(DESTDIR)$(docdir)
|
||||
$(INSTALL_DATA) README $(DESTDIR)$(docdir)
|
||||
$(INSTALL_DATA) CHANGELOG $(DESTDIR)$(docdir)
|
||||
$(INSTALL_DATA) AUTHORS $(DESTDIR)$(docdir)
|
||||
|
||||
uninstall-doc :
|
||||
$(RM) -r $(DESTDIR)$(docdir)
|
||||
|
||||
clean :
|
||||
$(RM) *.o $(PROGRAMS) core
|
||||
116
README
Normal file
116
README
Normal file
@ -0,0 +1,116 @@
|
||||
** INTRODUCTION **
|
||||
|
||||
Dmidecode reports information about your system's hardware as described in
|
||||
your 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).
|
||||
|
||||
DMI data can be used to enable or disable specific portions of kernel code
|
||||
depending on the specific hardware. Thus, one use of dmidecode is for kernel
|
||||
developers to detect system "signatures" and add them to the kernel source
|
||||
code when needed.
|
||||
|
||||
Beware that DMI data have proven to be too unreliable to be blindly trusted.
|
||||
Dmidecode does not scan your hardware, it only reports what the BIOS told it
|
||||
to.
|
||||
|
||||
|
||||
** INSTALLATION **
|
||||
|
||||
The home web page for dmidecode is hosted on Savannah:
|
||||
http://www.nongnu.org/dmidecode/
|
||||
You will find the latest version (including CVS) there, as well as fresh news
|
||||
and other interesting material, such as a list of related projects and
|
||||
articles.
|
||||
|
||||
This program was first written for Linux, and has since been reported to work
|
||||
on FreeBSD, NetBSD, OpenBSD, BeOS, Cygwin and Solaris as well.
|
||||
|
||||
There's no configure script, so simply run "make" to build dmidecode, and
|
||||
"make install" to install it. You also can use "make uninstall" to remove
|
||||
all the files you installed. By default, files are installed in /usr/local
|
||||
but you can change this behavior by editing the Makefile file and setting
|
||||
prefix to wherever you want. You may change the C compiler and the
|
||||
compilation flags as well.
|
||||
|
||||
Optionally, you can run "make strip" prior to "make install" if you want
|
||||
smaller binaries. However, be aware that this will prevent any further
|
||||
attempt to debug the programs.
|
||||
|
||||
Two parameters can be set in the Makefile file to make dmidecode work on
|
||||
non-i386 systems. They should be used if your system uses the big endian
|
||||
byte ordering (Motorola) or doesn't support unaligned memory accesses,
|
||||
respectively. For example, compiling for a SPARC processor would require
|
||||
both (but I am not aware of SPARC-based systems implementing SMBIOS).
|
||||
Compiling for an IA64 processor requires the memory alignment workaround,
|
||||
and it is enabled automatically.
|
||||
|
||||
|
||||
** DOCUMENTATION **
|
||||
|
||||
Each tool has a manual page, found in the "man" subdirectory. Manual pages
|
||||
are installed by "make install". See these manual pages for command line
|
||||
interface details and tool specific information.
|
||||
|
||||
For an history of the changes made to dmidecode, see the CHANGELOG file.
|
||||
|
||||
If you need help, your best chances are to visit the web page (see the
|
||||
INSTALLATION section above) or to get in touch with the developers directly.
|
||||
Have a look at the AUTHORS file and contact one of the maintainers.
|
||||
|
||||
If you want to help with the development of dmidecode, please consider
|
||||
joining the dmidecode-devel discussion list:
|
||||
http://lists.nongnu.org/mailman/listinfo/dmidecode-devel
|
||||
|
||||
|
||||
** COMMON PROBLEMS **
|
||||
|
||||
IA-64
|
||||
|
||||
Non-Linux systems are not yet supported.
|
||||
|
||||
MMAP
|
||||
|
||||
Note that mmap() is now used by default wherever possible, since this seems
|
||||
to solve a number of problems. This default behavior can be changed in
|
||||
config.h. Just to make sure this is clear, mmap() is not used for performance
|
||||
reasons but to increase the number of systems on which dmidecode can be
|
||||
successfully run.
|
||||
|
||||
CYGWIN
|
||||
|
||||
Dmidecode was reported to work under Cygwin. It seems that /dev/mem doesn't
|
||||
work properly before version 1.5.10 though, so you will need to use at least
|
||||
this version.
|
||||
|
||||
|
||||
** MISCELLANEOUS TOOLS **
|
||||
|
||||
Three other tools come along with dmidecode: biosdecode, ownership and
|
||||
vpddecode. These tools are only useful on systems with a BIOS, so they
|
||||
are not built on IA-64 by default.
|
||||
|
||||
BIOSDECODE
|
||||
|
||||
This one prints all BIOS related information it can find in /dev/mem.
|
||||
It used to be part of dmidecode itself, but as dmidecode was growing,
|
||||
we felt that the non-DMI part had to be moved to a separate tool.
|
||||
|
||||
OWNERSHIP
|
||||
|
||||
This tool was written on a request by Luc Van de Velde for use with Novell
|
||||
tools in his company. It retrieves the "ownership tag" that can be set on
|
||||
most Compaq computers. Since it uses the same mechanisms dmidecode and
|
||||
biosdecode use, and could be of some use for other people as well, we
|
||||
decided to make it part of the project.
|
||||
|
||||
VPDDECODE
|
||||
|
||||
This tool prints the contents of the "vital product data" structure as
|
||||
found in most IBM and Lenovo computers. It used to have a lookup table
|
||||
for the machine name, but it was unreliable and hard to maintain so it
|
||||
was ultimately dropped. It has a command line interface.
|
||||
669
biosdecode.c
Normal file
669
biosdecode.c
Normal file
@ -0,0 +1,669 @@
|
||||
/*
|
||||
* BIOS Decode
|
||||
*
|
||||
* Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
|
||||
* Copyright (C) 2002-2008 Jean Delvare <khali@linux-fr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* For the avoidance of doubt the "preferred form" of this code is one which
|
||||
* is in an open unpatent encumbered format. Where cryptographic key signing
|
||||
* forms part of the process of creating an executable the information
|
||||
* including keys needed to generate an equivalently functional executable
|
||||
* are deemed to be part of the source code.
|
||||
*
|
||||
* References:
|
||||
* - DMTF "System Management BIOS Reference Specification"
|
||||
* Version 2.3.4
|
||||
* http://www.dmtf.org/standards/smbios
|
||||
* - Intel "Preboot Execution Environment (PXE) Specification"
|
||||
* Version 2.1
|
||||
* http://www.intel.com/labs/manage/wfm/wfmspecs.htm
|
||||
* - ACPI "Advanced Configuration and Power Interface Specification"
|
||||
* Revision 2.0
|
||||
* http://www.acpi.info/spec20.htm
|
||||
* - Phoenix "BIOS32 Service Directory"
|
||||
* Revision 0.4
|
||||
* http://www.phoenix.com/en/support/white+papers-specs/
|
||||
* - Microsoft "Plug and Play BIOS Specification"
|
||||
* Version 1.0A
|
||||
* http://www.microsoft.com/hwdev/tech/PnP/
|
||||
* - Microsoft "PCI IRQ Routing Table Specification"
|
||||
* Version 1.0
|
||||
* http://www.microsoft.com/hwdev/archive/BUSBIOS/pciirq.asp
|
||||
* - Compaq "Technical Reference Guide for Compaq Deskpro 4000 and 6000"
|
||||
* First Edition
|
||||
* http://h18000.www1.hp.com/support/techpubs/technical_reference_guides/113a1097.html
|
||||
* - IBM "Using the BIOS Build ID to identify Thinkpad systems"
|
||||
* Revision 2005-09-19
|
||||
* http://www-307.ibm.com/pc/support/site.wss/MIGR-45120.html
|
||||
* - Fujitsu application panel technical details
|
||||
* As of July 23rd, 2004
|
||||
* http://apanel.sourceforge.net/tech.php
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Options are global */
|
||||
struct opt
|
||||
{
|
||||
const char *devmem;
|
||||
unsigned int flags;
|
||||
};
|
||||
static struct opt opt;
|
||||
|
||||
#define FLAG_VERSION (1 << 0)
|
||||
#define FLAG_HELP (1 << 1)
|
||||
|
||||
struct bios_entry {
|
||||
const char *anchor;
|
||||
size_t anchor_len; /* computed */
|
||||
off_t low_address;
|
||||
off_t high_address;
|
||||
size_t (*length)(const u8 *);
|
||||
int (*decode)(const u8*, size_t);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* SMBIOS
|
||||
*/
|
||||
|
||||
static size_t smbios_length(const u8 *p)
|
||||
{
|
||||
return p[0x05] == 0x1E ? 0x1F : p[0x05];
|
||||
}
|
||||
|
||||
static int smbios_decode(const u8 *p, size_t len)
|
||||
{
|
||||
if (len < 0x1F || !checksum(p, p[0x05])
|
||||
|| memcmp("_DMI_", p + 0x10, 5) != 0
|
||||
|| !checksum(p + 0x10, 0x0F))
|
||||
return 0;
|
||||
|
||||
printf("SMBIOS %u.%u present.\n",
|
||||
p[0x06], p[0x07]);
|
||||
printf("\tStructure Table Length: %u bytes\n",
|
||||
WORD(p+0x16));
|
||||
printf("\tStructure Table Address: 0x%08X\n",
|
||||
DWORD(p + 0x18));
|
||||
printf("\tNumber Of Structures: %u\n",
|
||||
WORD(p + 0x1C));
|
||||
printf("\tMaximum Structure Size: %u bytes\n",
|
||||
WORD(p + 0x08));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static size_t dmi_length(const u8 *p)
|
||||
{
|
||||
(void) p;
|
||||
|
||||
return 0x0F;
|
||||
}
|
||||
|
||||
static int dmi_decode(const u8 *p, size_t len)
|
||||
{
|
||||
if (len < 0x0F || !checksum(p, len))
|
||||
return 0;
|
||||
|
||||
printf("Legacy DMI %u.%u present.\n",
|
||||
p[0x0E]>>4, p[0x0E] & 0x0F);
|
||||
printf("\tStructure Table Length: %u bytes\n",
|
||||
WORD(p + 0x06));
|
||||
printf("\tStructure Table Address: 0x%08X\n",
|
||||
DWORD(p + 0x08));
|
||||
printf("\tNumber Of Structures: %u\n",
|
||||
WORD(p + 0x0C));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* SYSID
|
||||
*/
|
||||
|
||||
static size_t sysid_length(const u8 *p)
|
||||
{
|
||||
return WORD(p + 0x08);
|
||||
}
|
||||
|
||||
static int sysid_decode(const u8 *p, size_t len)
|
||||
{
|
||||
if (len < 0x11 || !checksum(p, WORD(p + 0x08)))
|
||||
return 0;
|
||||
|
||||
printf("SYSID present.\n");
|
||||
printf("\tRevision: %u\n",
|
||||
p[0x10]);
|
||||
printf("\tStructure Table Address: 0x%08X\n",
|
||||
DWORD(p + 0x0A));
|
||||
printf("\tNumber Of Structures: %u\n",
|
||||
WORD(p + 0x0E));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* PnP
|
||||
*/
|
||||
|
||||
static size_t pnp_length(const u8 *p)
|
||||
{
|
||||
return p[0x05];
|
||||
}
|
||||
|
||||
static const char *pnp_event_notification(u8 code)
|
||||
{
|
||||
static const char *notification[] = {
|
||||
"Not Supported", /* 0x0 */
|
||||
"Polling",
|
||||
"Asynchronous",
|
||||
"Unknown" /* 0x3 */
|
||||
};
|
||||
|
||||
return notification[code];
|
||||
}
|
||||
|
||||
static int pnp_decode(const u8 *p, size_t len)
|
||||
{
|
||||
if (len < 0x21 || !checksum(p, p[0x05]))
|
||||
return 0;
|
||||
|
||||
printf("PNP BIOS %u.%u present.\n",
|
||||
p[0x04] >> 4, p[0x04] & 0x0F);
|
||||
printf("\tEvent Notification: %s\n",
|
||||
pnp_event_notification(WORD(p + 0x06) & 0x03));
|
||||
if ((WORD(p + 0x06) & 0x03) == 0x01)
|
||||
printf("\tEvent Notification Flag Address: 0x%08X\n",
|
||||
DWORD(p + 0x09));
|
||||
printf("\tReal Mode 16-bit Code Address: %04X:%04X\n",
|
||||
WORD(p + 0x0F), WORD(p + 0x0D));
|
||||
printf("\tReal Mode 16-bit Data Address: %04X:0000\n",
|
||||
WORD(p + 0x1B));
|
||||
printf("\t16-bit Protected Mode Code Address: 0x%08X\n",
|
||||
DWORD(p + 0x13) + WORD(p + 0x11));
|
||||
printf("\t16-bit Protected Mode Data Address: 0x%08X\n",
|
||||
DWORD(p + 0x1D));
|
||||
if (DWORD(p + 0x17) != 0)
|
||||
printf("\tOEM Device Identifier: %c%c%c%02X%02X\n",
|
||||
0x40 + ((p[0x17] >> 2) & 0x1F),
|
||||
0x40 + ((p[0x17] & 0x03) << 3) + ((p[0x18] >> 5) & 0x07),
|
||||
0x40 + (p[0x18] & 0x1F), p[0x19], p[0x20]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* ACPI
|
||||
*/
|
||||
|
||||
static size_t acpi_length(const u8 *p)
|
||||
{
|
||||
return p[15] == 2 ? 36 : 20;
|
||||
}
|
||||
|
||||
static const char *acpi_revision(u8 code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case 0:
|
||||
return " 1.0";
|
||||
case 2:
|
||||
return " 2.0";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
static int acpi_decode(const u8 *p, size_t len)
|
||||
{
|
||||
if (len < 20 || !checksum(p, 20))
|
||||
return 0;
|
||||
|
||||
printf("ACPI%s present.\n",
|
||||
acpi_revision(p[15]));
|
||||
printf("\tOEM Identifier: %c%c%c%c%c%c\n",
|
||||
p[9], p[10], p[11], p[12], p[13], p[14]);
|
||||
printf("\tRSD Table 32-bit Address: 0x%08X\n",
|
||||
DWORD(p + 16));
|
||||
|
||||
if (len < 36)
|
||||
return 1;
|
||||
|
||||
if (DWORD(p + 20) > len || !checksum(p, DWORD(p + 20)))
|
||||
return 0;
|
||||
|
||||
if (DWORD(p + 20) < 32) return 1;
|
||||
|
||||
printf("\tXSD Table 64-bit Address: 0x%08X%08X\n",
|
||||
QWORD(p + 24).h, QWORD(p + 24).l);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sony
|
||||
*/
|
||||
|
||||
static size_t sony_length(const u8 *p)
|
||||
{
|
||||
return p[0x05];
|
||||
}
|
||||
|
||||
static int sony_decode(const u8 *p, size_t len)
|
||||
{
|
||||
if (!checksum(p, len))
|
||||
return 0;
|
||||
|
||||
printf("Sony system detected.\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* BIOS32
|
||||
*/
|
||||
|
||||
static size_t bios32_length(const u8 *p)
|
||||
{
|
||||
return p[0x09] << 4;
|
||||
}
|
||||
|
||||
static int bios32_decode(const u8 *p, size_t len)
|
||||
{
|
||||
if (len < 0x0A || !checksum(p, p[0x09] << 4))
|
||||
return 0;
|
||||
|
||||
printf("BIOS32 Service Directory present.\n");
|
||||
printf("\tRevision: %u\n",
|
||||
p[0x08]);
|
||||
printf("\tCalling Interface Address: 0x%08X\n",
|
||||
DWORD(p + 0x04));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* PIR
|
||||
*/
|
||||
|
||||
static void pir_irqs(u16 code)
|
||||
{
|
||||
if (code == 0)
|
||||
printf(" None");
|
||||
else
|
||||
{
|
||||
u8 i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
if (code & (1 << i))
|
||||
printf(" %u", i);
|
||||
}
|
||||
}
|
||||
|
||||
static void pir_slot_number(u8 code)
|
||||
{
|
||||
if (code == 0)
|
||||
printf(" on-board");
|
||||
else
|
||||
printf(" slot number %u", code);
|
||||
}
|
||||
|
||||
static size_t pir_length(const u8 *p)
|
||||
{
|
||||
return WORD(p + 6);
|
||||
}
|
||||
|
||||
static int pir_decode(const u8 *p, size_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (len < 32 || !checksum(p, WORD(p + 6)))
|
||||
return 0;
|
||||
|
||||
printf("PCI Interrupt Routing %u.%u present.\n",
|
||||
p[5], p[4]);
|
||||
printf("\tRouter ID: %02x:%02x.%1x\n",
|
||||
p[8], p[9]>>3, p[9] & 0x07);
|
||||
printf("\tExclusive IRQs:");
|
||||
pir_irqs(WORD(p + 10));
|
||||
printf("\n");
|
||||
if (DWORD(p + 12) != 0)
|
||||
printf("\tCompatible Router: %04x:%04x\n",
|
||||
WORD(p + 12), WORD(p + 14));
|
||||
if (DWORD(p + 16) != 0)
|
||||
printf("\tMiniport Data: 0x%08X\n",
|
||||
DWORD(p + 16));
|
||||
|
||||
for (i = 1; i <= (WORD(p + 6) - 32) / 16; i++)
|
||||
{
|
||||
printf("\tSlot Entry %u: ID %02x:%02x,",
|
||||
i, p[(i + 1) * 16], p[(i + 1) * 16 + 1] >> 3);
|
||||
pir_slot_number(p[(i + 1) * 16 + 14]);
|
||||
printf("\n");
|
||||
/* printf("\tSlot Entry %u\n", i);
|
||||
printf("\t\tID: %02x:%02x\n",
|
||||
p[(i + 1) * 16], p[(i + 1) * 16 + 1] >> 3);
|
||||
printf("\t\tLink Value for INTA#: %u\n",
|
||||
p[(i + 1) * 16 + 2]);
|
||||
printf("\t\tIRQ Bitmap for INTA#:");
|
||||
pir_irqs(WORD(p + (i + 1) * 16 + 3));
|
||||
printf("\n");
|
||||
printf("\t\tLink Value for INTB#: %u\n",
|
||||
p[(i + 1) * 16 + 5]);
|
||||
printf("\t\tIRQ Bitmap for INTB#:");
|
||||
pir_irqs(WORD(p + (i + 1) * 16 + 6));
|
||||
printf("\n");
|
||||
printf("\t\tLink Value for INTC#: %u\n",
|
||||
p[(i + 1) * 16 + 8]);
|
||||
printf("\t\tIRQ Bitmap for INTC#:");
|
||||
pir_irqs(WORD(p + (i + 1) * 16 + 9));
|
||||
printf("\n");
|
||||
printf("\t\tLink Value for INTD#: %u\n",
|
||||
p[(i + 1) * 16 + 11]);
|
||||
printf("\t\tIRQ Bitmap for INTD#:");
|
||||
pir_irqs(WORD(p + (i + 1) * 16 + 12));
|
||||
printf("\n");
|
||||
printf("\t\tSlot Number:");
|
||||
pir_slot_number(p[(i + 1) * 16 + 14]);
|
||||
printf("\n");*/
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compaq-specific entries
|
||||
*/
|
||||
|
||||
static size_t compaq_length(const u8 *p)
|
||||
{
|
||||
return p[4] * 10 + 5;
|
||||
}
|
||||
|
||||
static int compaq_decode(const u8 *p, size_t len)
|
||||
{
|
||||
unsigned int i;
|
||||
(void) len;
|
||||
|
||||
printf("Compaq-specific entries present.\n");
|
||||
|
||||
/* integrity checking (lack of checksum) */
|
||||
for (i = 0; i < p[4]; i++)
|
||||
{
|
||||
/*
|
||||
* We do not check for truncated entries, because the length
|
||||
* was computed from the number of records in compaq_length
|
||||
* right above, so it can't be wrong.
|
||||
*/
|
||||
if (p[5 + i * 10] != '$'
|
||||
|| !(p[6 + i * 10] >= 'A' && p[6 + i * 10] <= 'Z')
|
||||
|| !(p[7 + i * 10] >= 'A' && p[7 + i * 10] <= 'Z')
|
||||
|| !(p[8 + i * 10] >= 'A' && p[8 + i * 10] <= 'Z'))
|
||||
{
|
||||
printf("\t Abnormal entry! Please report. [%02X %02X "
|
||||
"%02X %02X]\n", p[5 + i * 10], p[6 + i * 10],
|
||||
p[7 + i * 10], p[8 + i * 10]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < p[4]; i++)
|
||||
{
|
||||
printf("\tEntry %u: %c%c%c%c at 0x%08X (%u bytes)\n",
|
||||
i + 1, p[5 + i * 10], p[6 + i * 10], p[7 + i * 10],
|
||||
p[8 + i * 10], DWORD(p + 9 + i * 10),
|
||||
WORD(p + 13 + i * 10));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* VPD (vital product data, IBM-specific)
|
||||
*/
|
||||
|
||||
static void vpd_print_entry(const char *name, const u8 *p, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
printf("\t%s: ", name);
|
||||
for (i = 0; i < len; i++)
|
||||
if (p[i] >= 32 && p[i] < 127)
|
||||
printf("%c", p[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static size_t vpd_length(const u8 *p)
|
||||
{
|
||||
return p[5];
|
||||
}
|
||||
|
||||
static int vpd_decode(const u8 *p, size_t len)
|
||||
{
|
||||
if (len < 0x30)
|
||||
return 0;
|
||||
|
||||
/* XSeries have longer records. */
|
||||
if (!(len >= 0x45 && checksum(p, len))
|
||||
/* Some Netvista seem to work with this. */
|
||||
&& !checksum(p, 0x30)
|
||||
/* The Thinkpad checksum does *not* include the first 13 bytes. */
|
||||
&& !checksum(p + 0x0D, 0x30 - 0x0D))
|
||||
return 0;
|
||||
|
||||
printf("VPD present.\n");
|
||||
|
||||
vpd_print_entry("BIOS Build ID", p + 0x0D, 9);
|
||||
vpd_print_entry("Box Serial Number", p + 0x16, 7);
|
||||
vpd_print_entry("Motherboard Serial Number", p + 0x1D, 11);
|
||||
vpd_print_entry("Machine Type/Model", p + 0x28, 7);
|
||||
|
||||
if (len < 0x45)
|
||||
return 1;
|
||||
|
||||
vpd_print_entry("BIOS Release Date", p + 0x30, 8);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fujitsu application panel
|
||||
*/
|
||||
|
||||
static size_t fjkeyinf_length(const u8 *p)
|
||||
{
|
||||
(void) p;
|
||||
/*
|
||||
* We don't know at this point, it's somewhere between 12 and 32.
|
||||
* So we return the max, it shouldn't hurt.
|
||||
*/
|
||||
return 32;
|
||||
}
|
||||
|
||||
static int fjkeyinf_decode(const u8 *p, size_t len)
|
||||
{
|
||||
int i;
|
||||
(void) len;
|
||||
|
||||
printf("Fujitsu application panel present.\n");
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
if (*(p + 8 + i * 4) == 0)
|
||||
return 1;
|
||||
printf("\tDevice %d: type %u, chip %u", i + 1,
|
||||
*(p + 8 + i * 4), *(p + 8 + i * 4 + 2));
|
||||
if (*(p+8+i*4+1)) /* Access method */
|
||||
printf(", SMBus address 0x%x",
|
||||
*(p + 8 + i * 4 + 3) >> 1);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main
|
||||
*/
|
||||
|
||||
static struct bios_entry bios_entries[] = {
|
||||
{ "_SM_", 0, 0xF0000, 0xFFFFF, smbios_length, smbios_decode },
|
||||
{ "_DMI_", 0, 0xF0000, 0xFFFFF, dmi_length, dmi_decode },
|
||||
{ "_SYSID_", 0, 0xE0000, 0xFFFFF, sysid_length, sysid_decode },
|
||||
{ "$PnP", 0, 0xF0000, 0xFFFFF, pnp_length, pnp_decode },
|
||||
{ "RSD PTR ", 0, 0xE0000, 0xFFFFF, acpi_length, acpi_decode },
|
||||
{ "$SNY", 0, 0xE0000, 0xFFFFF, sony_length, sony_decode },
|
||||
{ "_32_", 0, 0xE0000, 0xFFFFF, bios32_length, bios32_decode },
|
||||
{ "$PIR", 0, 0xF0000, 0xFFFFF, pir_length, pir_decode },
|
||||
{ "32OS", 0, 0xE0000, 0xFFFFF, compaq_length, compaq_decode },
|
||||
{ "\252\125VPD", 0, 0xF0000, 0xFFFFF, vpd_length, vpd_decode },
|
||||
{ "FJKEYINF", 0, 0xF0000, 0xFFFFF, fjkeyinf_length, fjkeyinf_decode },
|
||||
{ NULL, 0, 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
/* Believe it or not, this is significantly faster than memcmp */
|
||||
static int anchor_match(const struct bios_entry *entry, const char *p)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < entry->anchor_len; i++)
|
||||
if (entry->anchor[i] != p[i])
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return -1 on error, 0 on success */
|
||||
static int parse_command_line(int argc, char * const argv[])
|
||||
{
|
||||
int option;
|
||||
const char *optstring = "d:hV";
|
||||
struct option longopts[] = {
|
||||
{ "dev-mem", required_argument, NULL, 'd' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
while ((option = getopt_long(argc, argv, optstring, longopts, NULL)) != -1)
|
||||
switch (option)
|
||||
{
|
||||
case 'd':
|
||||
opt.devmem = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
opt.flags |= FLAG_HELP;
|
||||
break;
|
||||
case 'V':
|
||||
opt.flags |= FLAG_VERSION;
|
||||
break;
|
||||
case '?':
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_help(void)
|
||||
{
|
||||
static const char *help =
|
||||
"Usage: biosdecode [OPTIONS]\n"
|
||||
"Options are:\n"
|
||||
" -d, --dev-mem FILE Read memory from device FILE (default: " DEFAULT_MEM_DEV ")\n"
|
||||
" -h, --help Display this help text and exit\n"
|
||||
" -V, --version Display the version and exit\n";
|
||||
|
||||
printf("%s", help);
|
||||
}
|
||||
|
||||
int main(int argc, char * const argv[])
|
||||
{
|
||||
u8 *buf;
|
||||
off_t fp;
|
||||
int i;
|
||||
|
||||
if (sizeof(u8) != 1 || sizeof(u16) != 2 || sizeof(u32) != 4)
|
||||
{
|
||||
fprintf(stderr, "%s: compiler incompatibility\n", argv[0]);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
/* Set default option values */
|
||||
opt.devmem = DEFAULT_MEM_DEV;
|
||||
opt.flags = 0;
|
||||
|
||||
if (parse_command_line(argc, argv) < 0)
|
||||
exit(2);
|
||||
|
||||
if (opt.flags & FLAG_HELP)
|
||||
{
|
||||
print_help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (opt.flags & FLAG_VERSION)
|
||||
{
|
||||
printf("%s\n", VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("# biosdecode %s\n", VERSION);
|
||||
|
||||
if ((buf = mem_chunk(0xE0000, 0x20000, opt.devmem)) == NULL)
|
||||
exit(1);
|
||||
|
||||
/* Compute anchor lengths once and for all */
|
||||
for (i = 0; bios_entries[i].anchor != NULL; i++)
|
||||
bios_entries[i].anchor_len = strlen(bios_entries[i].anchor);
|
||||
|
||||
for (fp = 0xE0000; fp <= 0xFFFF0; fp += 16)
|
||||
{
|
||||
u8 *p = buf + fp - 0xE0000;
|
||||
|
||||
for (i = 0; bios_entries[i].anchor != NULL; i++)
|
||||
{
|
||||
if (anchor_match(&bios_entries[i], (char *)p)
|
||||
&& fp >= bios_entries[i].low_address
|
||||
&& fp < bios_entries[i].high_address)
|
||||
{
|
||||
off_t len = bios_entries[i].length(p);
|
||||
|
||||
if (fp + len - 1 <= bios_entries[i].high_address)
|
||||
{
|
||||
if (bios_entries[i].decode(p, len))
|
||||
{
|
||||
fp += (((len - 1) >> 4) << 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
29
config.h
Normal file
29
config.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Configuration
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
/* Default memory device file */
|
||||
#if defined(__BEOS__) || defined(__HAIKU__)
|
||||
#define DEFAULT_MEM_DEV "/dev/misc/mem"
|
||||
#else
|
||||
#ifdef __sun
|
||||
#define DEFAULT_MEM_DEV "/dev/xsvc"
|
||||
#else
|
||||
#define DEFAULT_MEM_DEV "/dev/mem"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Use mmap or not */
|
||||
#ifndef __BEOS__
|
||||
#define USE_MMAP
|
||||
#endif
|
||||
|
||||
/* Use memory alignment workaround or not */
|
||||
#ifdef __ia64__
|
||||
#define ALIGNMENT_WORKAROUND
|
||||
#endif
|
||||
|
||||
#endif
|
||||
4704
dmidecode.c
Normal file
4704
dmidecode.c
Normal file
File diff suppressed because it is too large
Load Diff
29
dmidecode.h
Normal file
29
dmidecode.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2005-2008 Jean Delvare <khali@linux-fr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
struct dmi_header
|
||||
{
|
||||
u8 type;
|
||||
u8 length;
|
||||
u16 handle;
|
||||
u8 *data;
|
||||
};
|
||||
|
||||
const char *dmi_string(const struct dmi_header *dm, u8 s);
|
||||
129
dmioem.c
Normal file
129
dmioem.c
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Decoding of OEM-specific entries
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2007-2008 Jean Delvare <khali@linux-fr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "dmidecode.h"
|
||||
#include "dmioem.h"
|
||||
|
||||
/*
|
||||
* Globals for vendor-specific decodes
|
||||
*/
|
||||
|
||||
enum DMI_VENDORS { VENDOR_UNKNOWN, VENDOR_HP };
|
||||
|
||||
static enum DMI_VENDORS dmi_vendor = VENDOR_UNKNOWN;
|
||||
|
||||
/*
|
||||
* Remember the system vendor for later use. We only actually store the
|
||||
* value if we know how to decode at least one specific entry type for
|
||||
* that vendor.
|
||||
*/
|
||||
void dmi_set_vendor(const char *s)
|
||||
{
|
||||
if (strcmp(s, "HP") == 0 || strcmp(s, "Hewlett-Packard") == 0)
|
||||
dmi_vendor = VENDOR_HP;
|
||||
}
|
||||
|
||||
/*
|
||||
* HP-specific data structures are decoded here.
|
||||
*
|
||||
* Code contributed by John Cagle.
|
||||
*/
|
||||
|
||||
static int dmi_decode_hp(const struct dmi_header *h)
|
||||
{
|
||||
u8 *data = h->data;
|
||||
int nic, ptr;
|
||||
|
||||
switch (h->type)
|
||||
{
|
||||
case 204:
|
||||
/*
|
||||
* Vendor Specific: HP ProLiant System/Rack Locator
|
||||
*/
|
||||
printf("HP ProLiant System/Rack Locator\n");
|
||||
if (h->length < 0x0B) break;
|
||||
printf("\tRack Name: %s\n", dmi_string(h, data[0x04]));
|
||||
printf("\tEnclosure Name: %s\n", dmi_string(h, data[0x05]));
|
||||
printf("\tEnclosure Model: %s\n", dmi_string(h, data[0x06]));
|
||||
printf("\tEnclosure Serial: %s\n", dmi_string(h, data[0x0A]));
|
||||
printf("\tEnclosure Bays: %d\n", data[0x08]);
|
||||
printf("\tServer Bay: %s\n", dmi_string(h, data[0x07]));
|
||||
printf("\tBays Filled: %d\n", data[0x09]);
|
||||
break;
|
||||
|
||||
case 209:
|
||||
case 221:
|
||||
/*
|
||||
* Vendor Specific: HP ProLiant NIC MAC Information
|
||||
*
|
||||
* This prints the BIOS NIC number,
|
||||
* PCI bus/device/function, and MAC address
|
||||
*/
|
||||
printf(h->type == 221 ?
|
||||
"HP BIOS iSCSI NIC PCI and MAC Information\n" :
|
||||
"HP BIOS PXE NIC PCI and MAC Information\n");
|
||||
nic = 1;
|
||||
ptr = 4;
|
||||
while (h->length >= ptr + 8)
|
||||
{
|
||||
if (data[ptr] == 0x00 && data[ptr + 1] == 0x00)
|
||||
printf("\tNIC %d: Disabled\n", nic);
|
||||
else if (data[ptr] == 0xFF && data[ptr + 1] == 0xFF)
|
||||
printf("\tNIC %d: Not Installed\n", nic);
|
||||
else
|
||||
{
|
||||
printf("\tNIC %d: PCI device %02x:%02x.%x, "
|
||||
"MAC address %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
nic, data[ptr + 1],
|
||||
data[ptr] >> 3, data[ptr] & 7,
|
||||
data[ptr + 2], data[ptr + 3],
|
||||
data[ptr + 4], data[ptr + 5],
|
||||
data[ptr + 6], data[ptr + 7]);
|
||||
}
|
||||
nic++;
|
||||
ptr += 8;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dispatch vendor-specific entries decoding
|
||||
* Return 1 if decoding was successful, 0 otherwise
|
||||
*/
|
||||
int dmi_decode_oem(const struct dmi_header *h)
|
||||
{
|
||||
switch (dmi_vendor)
|
||||
{
|
||||
case VENDOR_HP:
|
||||
return dmi_decode_hp(h);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
25
dmioem.h
Normal file
25
dmioem.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Decoding of OEM-specific entries
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2007-2008 Jean Delvare <khali@linux-fr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
struct dmi_header;
|
||||
|
||||
void dmi_set_vendor(const char *s);
|
||||
int dmi_decode_oem(const struct dmi_header *h);
|
||||
316
dmiopt.c
Normal file
316
dmiopt.c
Normal file
@ -0,0 +1,316 @@
|
||||
/*
|
||||
* Command line handling of dmidecode
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2005-2008 Jean Delvare <khali@linux-fr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
#include "dmidecode.h"
|
||||
#include "dmiopt.h"
|
||||
|
||||
|
||||
/* Options are global */
|
||||
struct opt opt;
|
||||
|
||||
|
||||
/*
|
||||
* Handling of option --type
|
||||
*/
|
||||
|
||||
struct type_keyword
|
||||
{
|
||||
const char *keyword;
|
||||
const u8 *type;
|
||||
};
|
||||
|
||||
static const u8 opt_type_bios[] = { 0, 13, 255 };
|
||||
static const u8 opt_type_system[] = { 1, 12, 15, 23, 32, 255 };
|
||||
static const u8 opt_type_baseboard[] = { 2, 10, 41, 255 };
|
||||
static const u8 opt_type_chassis[] = { 3, 255 };
|
||||
static const u8 opt_type_processor[] = { 4, 255 };
|
||||
static const u8 opt_type_memory[] = { 5, 6, 16, 17, 255 };
|
||||
static const u8 opt_type_cache[] = { 7, 255 };
|
||||
static const u8 opt_type_connector[] = { 8, 255 };
|
||||
static const u8 opt_type_slot[] = { 9, 255 };
|
||||
|
||||
static const struct type_keyword opt_type_keyword[] = {
|
||||
{ "bios", opt_type_bios },
|
||||
{ "system", opt_type_system },
|
||||
{ "baseboard", opt_type_baseboard },
|
||||
{ "chassis", opt_type_chassis },
|
||||
{ "processor", opt_type_processor },
|
||||
{ "memory", opt_type_memory },
|
||||
{ "cache", opt_type_cache },
|
||||
{ "connector", opt_type_connector },
|
||||
{ "slot", opt_type_slot },
|
||||
};
|
||||
|
||||
static void print_opt_type_list(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
fprintf(stderr, "Valid type keywords are:\n");
|
||||
for (i = 0; i < ARRAY_SIZE(opt_type_keyword); i++)
|
||||
{
|
||||
fprintf(stderr, " %s\n", opt_type_keyword[i].keyword);
|
||||
}
|
||||
}
|
||||
|
||||
static u8 *parse_opt_type(u8 *p, const char *arg)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* Allocate memory on first call only */
|
||||
if (p == NULL)
|
||||
{
|
||||
p = (u8 *)calloc(256, sizeof(u8));
|
||||
if (p == NULL)
|
||||
{
|
||||
perror("calloc");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* First try as a keyword */
|
||||
for (i = 0; i < ARRAY_SIZE(opt_type_keyword); i++)
|
||||
{
|
||||
if (!strcasecmp(arg, opt_type_keyword[i].keyword))
|
||||
{
|
||||
int j = 0;
|
||||
while (opt_type_keyword[i].type[j] != 255)
|
||||
p[opt_type_keyword[i].type[j++]] = 1;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
/* Else try as a number */
|
||||
while (*arg != '\0')
|
||||
{
|
||||
unsigned long val;
|
||||
char *next;
|
||||
|
||||
val = strtoul(arg, &next, 0);
|
||||
if (next == arg)
|
||||
{
|
||||
fprintf(stderr, "Invalid type keyword: %s\n", arg);
|
||||
print_opt_type_list();
|
||||
goto exit_free;
|
||||
}
|
||||
if (val > 0xff)
|
||||
{
|
||||
fprintf(stderr, "Invalid type number: %lu\n", val);
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
p[val] = 1;
|
||||
arg = next;
|
||||
while (*arg == ',' || *arg == ' ')
|
||||
arg++;
|
||||
}
|
||||
|
||||
found:
|
||||
return p;
|
||||
|
||||
exit_free:
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handling of option --string
|
||||
*/
|
||||
|
||||
/* This lookup table could admittedly be reworked for improved performance.
|
||||
Due to the low count of items in there at the moment, it did not seem
|
||||
worth the additional code complexity though. */
|
||||
static const struct string_keyword opt_string_keyword[] = {
|
||||
{ "bios-vendor", 0, 0x04 },
|
||||
{ "bios-version", 0, 0x05 },
|
||||
{ "bios-release-date", 0, 0x08 },
|
||||
{ "system-manufacturer", 1, 0x04 },
|
||||
{ "system-product-name", 1, 0x05 },
|
||||
{ "system-version", 1, 0x06 },
|
||||
{ "system-serial-number", 1, 0x07 },
|
||||
{ "system-uuid", 1, 0x08 }, /* dmi_system_uuid() */
|
||||
{ "baseboard-manufacturer", 2, 0x04 },
|
||||
{ "baseboard-product-name", 2, 0x05 },
|
||||
{ "baseboard-version", 2, 0x06 },
|
||||
{ "baseboard-serial-number", 2, 0x07 },
|
||||
{ "baseboard-asset-tag", 2, 0x08 },
|
||||
{ "chassis-manufacturer", 3, 0x04 },
|
||||
{ "chassis-type", 3, 0x05 }, /* dmi_chassis_type() */
|
||||
{ "chassis-version", 3, 0x06 },
|
||||
{ "chassis-serial-number", 3, 0x07 },
|
||||
{ "chassis-asset-tag", 3, 0x08 },
|
||||
{ "processor-family", 4, 0x06 }, /* dmi_processor_family() */
|
||||
{ "processor-manufacturer", 4, 0x07 },
|
||||
{ "processor-version", 4, 0x10 },
|
||||
{ "processor-frequency", 4, 0x16 }, /* dmi_processor_frequency() */
|
||||
};
|
||||
|
||||
static void print_opt_string_list(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
fprintf(stderr, "Valid string keywords are:\n");
|
||||
for (i = 0; i < ARRAY_SIZE(opt_string_keyword); i++)
|
||||
{
|
||||
fprintf(stderr, " %s\n", opt_string_keyword[i].keyword);
|
||||
}
|
||||
}
|
||||
|
||||
static int parse_opt_string(const char *arg)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (opt.string)
|
||||
{
|
||||
fprintf(stderr, "Only one string can be specified\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(opt_string_keyword); i++)
|
||||
{
|
||||
if (!strcasecmp(arg, opt_string_keyword[i].keyword))
|
||||
{
|
||||
opt.string = &opt_string_keyword[i];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "Invalid string keyword: %s\n", arg);
|
||||
print_opt_string_list();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Command line options handling
|
||||
*/
|
||||
|
||||
/* Return -1 on error, 0 on success */
|
||||
int parse_command_line(int argc, char * const argv[])
|
||||
{
|
||||
int option;
|
||||
const char *optstring = "d:hqs:t:uV";
|
||||
struct option longopts[] = {
|
||||
{ "dev-mem", required_argument, NULL, 'd' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "quiet", no_argument, NULL, 'q' },
|
||||
{ "string", required_argument, NULL, 's' },
|
||||
{ "type", required_argument, NULL, 't' },
|
||||
{ "dump", no_argument, NULL, 'u' },
|
||||
{ "dump-bin", required_argument, NULL, 'B' },
|
||||
{ "from-dump", required_argument, NULL, 'F' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
while ((option = getopt_long(argc, argv, optstring, longopts, NULL)) != -1)
|
||||
switch (option)
|
||||
{
|
||||
case 'B':
|
||||
opt.flags |= FLAG_DUMP_BIN;
|
||||
opt.dumpfile = optarg;
|
||||
break;
|
||||
case 'F':
|
||||
opt.flags |= FLAG_FROM_DUMP;
|
||||
opt.dumpfile = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
opt.devmem = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
opt.flags |= FLAG_HELP;
|
||||
break;
|
||||
case 'q':
|
||||
opt.flags |= FLAG_QUIET;
|
||||
break;
|
||||
case 's':
|
||||
if (parse_opt_string(optarg) < 0)
|
||||
return -1;
|
||||
opt.flags |= FLAG_QUIET;
|
||||
break;
|
||||
case 't':
|
||||
opt.type = parse_opt_type(opt.type, optarg);
|
||||
if (opt.type == NULL)
|
||||
return -1;
|
||||
break;
|
||||
case 'u':
|
||||
opt.flags |= FLAG_DUMP;
|
||||
break;
|
||||
case 'V':
|
||||
opt.flags |= FLAG_VERSION;
|
||||
break;
|
||||
case '?':
|
||||
switch (optopt)
|
||||
{
|
||||
case 's':
|
||||
fprintf(stderr, "String keyword expected\n");
|
||||
print_opt_string_list();
|
||||
break;
|
||||
case 't':
|
||||
fprintf(stderr, "Type number or keyword expected\n");
|
||||
print_opt_type_list();
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check for mutually exclusive output format options */
|
||||
if ((opt.string != NULL) + (opt.type != NULL)
|
||||
+ !!(opt.flags & FLAG_DUMP_BIN) > 1)
|
||||
{
|
||||
fprintf(stderr, "Options --string, --type and --dump-bin are mutually exclusive\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((opt.flags & FLAG_FROM_DUMP) && (opt.flags & FLAG_DUMP_BIN))
|
||||
{
|
||||
fprintf(stderr, "Options --from-dump and --dump-bin are mutually exclusive\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_help(void)
|
||||
{
|
||||
static const char *help =
|
||||
"Usage: dmidecode [OPTIONS]\n"
|
||||
"Options are:\n"
|
||||
" -d, --dev-mem FILE Read memory from device FILE (default: " DEFAULT_MEM_DEV ")\n"
|
||||
" -h, --help Display this help text and exit\n"
|
||||
" -q, --quiet Less verbose output\n"
|
||||
" -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 binary file\n"
|
||||
" --from-dump FILE Read the DMI data from a binary file\n"
|
||||
" -V, --version Display the version and exit\n";
|
||||
|
||||
printf("%s", help);
|
||||
}
|
||||
47
dmiopt.h
Normal file
47
dmiopt.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Command line handling of dmidecode
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2005-2008 Jean Delvare <khali@linux-fr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
struct string_keyword
|
||||
{
|
||||
const char *keyword;
|
||||
u8 type;
|
||||
u8 offset;
|
||||
};
|
||||
|
||||
struct opt
|
||||
{
|
||||
const char *devmem;
|
||||
unsigned int flags;
|
||||
u8 *type;
|
||||
const struct string_keyword *string;
|
||||
char *dumpfile;
|
||||
};
|
||||
extern struct opt opt;
|
||||
|
||||
#define FLAG_VERSION (1 << 0)
|
||||
#define FLAG_HELP (1 << 1)
|
||||
#define FLAG_DUMP (1 << 2)
|
||||
#define FLAG_QUIET (1 << 3)
|
||||
#define FLAG_DUMP_BIN (1 << 4)
|
||||
#define FLAG_FROM_DUMP (1 << 5)
|
||||
|
||||
int parse_command_line(int argc, char * const argv[]);
|
||||
void print_help(void);
|
||||
83
man/biosdecode.8
Normal file
83
man/biosdecode.8
Normal file
@ -0,0 +1,83 @@
|
||||
.TH BIOSDECODE 8 "February 2007" "dmidecode"
|
||||
.SH NAME
|
||||
biosdecode \- \s-1BIOS\s0 information decoder
|
||||
.SH SYNOPSIS
|
||||
.B biosdecode
|
||||
.RB [ OPTIONS ]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B biosdecode
|
||||
parses the \s-1BIOS\s0 memory and prints information about all structures (or
|
||||
entry points) it knows of. Currently known entry point types are:
|
||||
.IP \(bu "\w'\(bu'u+1n"
|
||||
\s-1SMBIOS\s0 (System Management \s-1BIOS\s0)
|
||||
.br
|
||||
Use
|
||||
.B dmidecode
|
||||
for a more detailed output.
|
||||
.IP \(bu
|
||||
\s-1DMI\s0 (Desktop Management Interface, a legacy version of \s-1SMBIOS\s0)
|
||||
.br
|
||||
Use
|
||||
.B dmidecode
|
||||
for a more detailed output.
|
||||
.IP \(bu
|
||||
\s-1SYSID\s0
|
||||
.IP \(bu
|
||||
\s-1PNP\s0 (Plug and Play)
|
||||
.IP \(bu
|
||||
\s-1ACPI\s0 (Advanced Configuration and Power Interface)
|
||||
.IP \(bu
|
||||
\s-1BIOS32\s0 (\s-1BIOS32\s0 Service Directory)
|
||||
.IP \(bu
|
||||
\s-1PIR\s0 (\s-1PCI\s0 \s-1IRQ\s0 Routing)
|
||||
.IP \(bu
|
||||
\s-132OS\s0 (\s-1BIOS32\s0 Extension, Compaq-specific)
|
||||
.br
|
||||
See
|
||||
.B ownership
|
||||
for a Compaq ownership tag retrieval tool.
|
||||
.IP \(bu
|
||||
\s-1SNY\s0 (Sony-specific, not decoded)
|
||||
.IP \(bu
|
||||
\s-1VPD\s0 (Vital Product Data, IBM-specific)
|
||||
.br
|
||||
Use
|
||||
.B vpddecode
|
||||
for a more detailed output.
|
||||
.IP \(bu
|
||||
\s-1FJKEYINF\s0 (Application Panel, Fujitsu-specific)
|
||||
|
||||
.PP
|
||||
.B biosdecode
|
||||
started its life as a part of
|
||||
.B dmidecode
|
||||
but as more entry point types were added, if was moved to a different
|
||||
program.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR "-d" ", " "--dev-mem FILE"
|
||||
Read memory from device \fBFILE\fR (default: \fB/dev/mem\fR)
|
||||
.TP
|
||||
.BR "-h" ", " "--help"
|
||||
Display usage information and exit
|
||||
.TP
|
||||
.BR "-V" ", " "--version"
|
||||
Display the version and exit
|
||||
|
||||
.SH FILES
|
||||
.I /dev/mem
|
||||
.SH BUGS
|
||||
Most of the time,
|
||||
.B biosdecode
|
||||
prints too much information (you don't really care about addresses)
|
||||
or not enough (because it doesn't follow pointers and has no lookup
|
||||
tables).
|
||||
.SH AUTHORS
|
||||
Alan Cox, Jean Delvare
|
||||
.SH "SEE ALSO"
|
||||
.BR dmidecode (8),
|
||||
.BR mem (4),
|
||||
.BR ownership (8),
|
||||
.BR vpddecode (8)
|
||||
246
man/dmidecode.8
Normal file
246
man/dmidecode.8
Normal file
@ -0,0 +1,246 @@
|
||||
.TH DMIDECODE 8 "March 2012" "dmidecode"
|
||||
.SH NAME
|
||||
dmidecode \- \s-1DMI\s0 table decoder
|
||||
.SH SYNOPSIS
|
||||
.B dmidecode
|
||||
.RB [ OPTIONS ]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B dmidecode
|
||||
is a tool for dumping a computer's \s-1DMI\s0 (some say \s-1SMBIOS\s0) table
|
||||
contents in a human-readable format. This table contains a description of the
|
||||
system's hardware components, as well as other useful pieces of information
|
||||
such as serial numbers and \s-1BIOS\s0 revision. Thanks to this table, you can
|
||||
retrieve this information without having to probe for the actual hardware.
|
||||
While this is a good point in terms of report speed and safeness, this also
|
||||
makes the presented information possibly unreliable.
|
||||
|
||||
The \s-1DMI\s0 table doesn't only describe what the system is currently made
|
||||
of, it also can report the possible evolutions (such as the fastest supported
|
||||
\s-1CPU\s0 or the maximal amount of memory supported).
|
||||
|
||||
\s-1SMBIOS\s0 stands for System Management \s-1BIOS\s0, while \s-1DMI\s0
|
||||
stands for Desktop Management Interface. Both standards are tightly related
|
||||
and developed by the \s-1DMTF\s0 (Desktop Management Task Force).
|
||||
|
||||
As you run it,
|
||||
.B dmidecode
|
||||
will try to locate the \s-1DMI\s0 table. If it succeeds, it will then parse
|
||||
this table and display a list of records like this one:
|
||||
|
||||
Handle 0x0002, DMI type 2, 8 bytes.
|
||||
Base Board Information
|
||||
Manufacturer: Intel
|
||||
Product Name: C440GX+
|
||||
Version: 727281-001
|
||||
Serial Number: INCY92700942
|
||||
|
||||
Each record has:
|
||||
.IP \(bu "\w'\(bu'u+1n"
|
||||
A handle. This is a unique identifier, which allows records to
|
||||
reference each other. For example, processor records usually reference
|
||||
cache memory records using their handles.
|
||||
.IP \(bu
|
||||
A type. The \s-1SMBIOS\s0 specification defines different types of elements
|
||||
a computer can be made of. In this example, the type is 2, which
|
||||
means that the record contains "Base Board Information".
|
||||
.IP \(bu
|
||||
A size. Each record has a 4-byte header (2 for the handle, 1 for the type,
|
||||
1 for the size), the rest is used by the record data. This value doesn't
|
||||
take text strings into account (these are placed at the end of the record),
|
||||
so the actual length of the record may be (and is often) greater than the
|
||||
displayed value.
|
||||
.IP \(bu
|
||||
Decoded values. The information presented of course depends on the type
|
||||
of record. Here, we learn about the board's manufacturer, model, version
|
||||
and serial number.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR "-d" ", " "--dev-mem FILE"
|
||||
Read memory from device \fBFILE\fR (default: \fB/dev/mem\fR)
|
||||
.TP
|
||||
.BR "-q" ", " "--quiet"
|
||||
Be less verbose. Unknown, inactive and \s-1OEM\s0-specific entries are not
|
||||
displayed. Meta-data and handle references are hidden.
|
||||
.TP
|
||||
.BR "-s" ", " "--string KEYWORD"
|
||||
Only display the value of the \s-1DMI\s0 string identified by \fBKEYWORD\fR.
|
||||
\fBKEYWORD\fR must be a keyword from the following list: \fBbios-vendor\fR,
|
||||
\fBbios-version\fR, \fBbios-release-date\fR,
|
||||
\fBsystem-manufacturer\fR, \fBsystem-product-name\fR,
|
||||
\fBsystem-version\fR, \fBsystem-serial-number\fR,
|
||||
\fBsystem-uuid\fR,
|
||||
\fBbaseboard-manufacturer\fR, \fBbaseboard-product-name\fR,
|
||||
\fBbaseboard-version\fR, \fBbaseboard-serial-number\fR,
|
||||
\fBbaseboard-asset-tag\fR, \fBchassis-manufacturer\fR,
|
||||
\fBchassis-type\fR,
|
||||
\fBchassis-version\fR, \fBchassis-serial-number\fR,
|
||||
\fBchassis-asset-tag\fR, \fBprocessor-family\fR,
|
||||
\fBprocessor-manufacturer\fR,
|
||||
\fBprocessor-version\fR, \fBprocessor-frequency\fR.
|
||||
Each keyword corresponds to a given \s-1DMI\s0 type and a given offset
|
||||
within this entry type.
|
||||
Not all strings may be meaningful or even defined on all systems. Some
|
||||
keywords may return more than one result on some systems (e.g.
|
||||
\fBprocessor-version\fR on a multi-processor system).
|
||||
If \fBKEYWORD\fR is not provided or not valid, a list of all valid
|
||||
keywords is printed and
|
||||
.B dmidecode
|
||||
exits with an error.
|
||||
This option cannot be used more than once.
|
||||
.TP
|
||||
.BR "-t" ", " "--type TYPE"
|
||||
Only display the entries of type \fBTYPE\fR. \fBTYPE\fR can be either a
|
||||
\s-1DMI\s0 type number, or a comma-separated list of type numbers, or a
|
||||
keyword from the following list: \fBbios\fR, \fBsystem\fR,
|
||||
\fBbaseboard\fR, \fBchassis\fR, \fBprocessor\fR, \fBmemory\fR,
|
||||
\fBcache\fR, \fBconnector\fR, \fBslot\fR. Refer to the DMI TYPES section
|
||||
below for details.
|
||||
If this option is used more than once, the set of displayed entries will be
|
||||
the union of all the given types.
|
||||
If \fBTYPE\fR is not provided or not valid, a list of all valid keywords
|
||||
is printed and
|
||||
.B dmidecode
|
||||
exits with an error.
|
||||
.TP
|
||||
.BR "-u" ", " "--dump"
|
||||
Do not decode the entries, dump their contents as hexadecimal instead.
|
||||
Note that this is still a text output, no binary data will be thrown upon
|
||||
you. The strings attached to each entry are displayed as both
|
||||
hexadecimal and \s-1ASCII\s0. This option is mainly useful for debugging.
|
||||
.TP
|
||||
.BR " " " " "--dump-bin FILE"
|
||||
Do not decode the entries, instead dump the DMI data to a file in binary
|
||||
form. The generated file is suitable to pass to \fB--from-dump\fR
|
||||
later.
|
||||
.TP
|
||||
.BR " " " " "--from-dump FILE"
|
||||
Read the DMI data from a binary file previously generated using
|
||||
\fB--dump-bin\fR.
|
||||
.TP
|
||||
.BR "-h" ", " "--help"
|
||||
Display usage information and exit
|
||||
.TP
|
||||
.BR "-V" ", " "--version"
|
||||
Display the version and exit
|
||||
.P
|
||||
Options --string, --type and --dump-bin
|
||||
determine the output format and are mutually exclusive.
|
||||
.P
|
||||
Please note in case of
|
||||
.B dmidecode
|
||||
is run on a system with BIOS that boasts new SMBIOS specification, which
|
||||
is not supported by the tool yet, it will print out relevant message in
|
||||
addition to requested data on the very top of the output. Thus informs the
|
||||
output data is not reliable.
|
||||
|
||||
.SH "DMI TYPES"
|
||||
The \s-1SMBIOS\s0 specification defines the following \s-1DMI\s0 types:
|
||||
|
||||
.TS
|
||||
r l
|
||||
__
|
||||
r l.
|
||||
Type Information
|
||||
0 BIOS
|
||||
1 System
|
||||
2 Baseboard
|
||||
3 Chassis
|
||||
4 Processor
|
||||
5 Memory Controller
|
||||
6 Memory Module
|
||||
7 Cache
|
||||
8 Port Connector
|
||||
9 System Slots
|
||||
10 On Board Devices
|
||||
11 OEM Strings
|
||||
12 System Configuration Options
|
||||
13 BIOS Language
|
||||
14 Group Associations
|
||||
15 System Event Log
|
||||
16 Physical Memory Array
|
||||
17 Memory Device
|
||||
18 32-bit Memory Error
|
||||
19 Memory Array Mapped Address
|
||||
20 Memory Device Mapped Address
|
||||
21 Built-in Pointing Device
|
||||
22 Portable Battery
|
||||
23 System Reset
|
||||
24 Hardware Security
|
||||
25 System Power Controls
|
||||
26 Voltage Probe
|
||||
27 Cooling Device
|
||||
28 Temperature Probe
|
||||
29 Electrical Current Probe
|
||||
30 Out-of-band Remote Access
|
||||
31 Boot Integrity Services
|
||||
32 System Boot
|
||||
33 64-bit Memory Error
|
||||
34 Management Device
|
||||
35 Management Device Component
|
||||
36 Management Device Threshold Data
|
||||
37 Memory Channel
|
||||
38 IPMI Device
|
||||
39 Power Supply
|
||||
40 Additional Information
|
||||
41 Onboard Devices Extended Information
|
||||
42 Management Controller Host Interface
|
||||
.TE
|
||||
|
||||
Additionally, type 126 is used for disabled entries and type 127 is an
|
||||
end-of-table marker. Types 128 to 255 are for \s-1OEM\s0-specific data.
|
||||
.B dmidecode
|
||||
will display these entries by default, but it can only decode them
|
||||
when the vendors have contributed documentation or code for them.
|
||||
|
||||
Keywords can be used instead of type numbers with \fB--type\fR.
|
||||
Each keyword is equivalent to a list of type numbers:
|
||||
|
||||
.TS
|
||||
l l
|
||||
__
|
||||
l l.
|
||||
Keyword Types
|
||||
bios 0, 13
|
||||
system 1, 12, 15, 23, 32
|
||||
baseboard 2, 10, 41
|
||||
chassis 3
|
||||
processor 4
|
||||
memory 5, 6, 16, 17
|
||||
cache 7
|
||||
connector 8
|
||||
slot 9
|
||||
.TE
|
||||
|
||||
Keywords are matched case-insensitively. The following command lines are equivalent:
|
||||
.IP \(bu "\w'\(bu'u+1n"
|
||||
dmidecode --type 0 --type 13
|
||||
.IP \(bu
|
||||
dmidecode --type 0,13
|
||||
.IP \(bu
|
||||
dmidecode --type bios
|
||||
.IP \(bu
|
||||
dmidecode --type BIOS
|
||||
|
||||
.SH BINARY DUMP FILE FORMAT
|
||||
The binary dump files generated by --dump-bin and read using --from-dump
|
||||
are formatted as follows:
|
||||
.IP \(bu "\w'\(bu'u+1n"
|
||||
The SMBIOS or DMI entry point is located at offset 0x00.
|
||||
It is crafted to hard-code the table address at offset 0x20.
|
||||
.IP \(bu "\w'\(bu'u+1n"
|
||||
The DMI table is located at offset 0x20.
|
||||
|
||||
.SH FILES
|
||||
.I /dev/mem
|
||||
.SH BUGS
|
||||
More often than not, information contained in the \s-1DMI\s0 tables is inaccurate,
|
||||
incomplete or simply wrong.
|
||||
.SH AUTHORS
|
||||
Alan Cox, Jean Delvare
|
||||
.SH "SEE ALSO"
|
||||
.BR biosdecode (8),
|
||||
.BR mem (4),
|
||||
.BR ownership (8),
|
||||
.BR vpddecode (8)
|
||||
37
man/ownership.8
Normal file
37
man/ownership.8
Normal file
@ -0,0 +1,37 @@
|
||||
.TH OWNERSHIP 8 "February 2005" "dmidecode"
|
||||
.SH NAME
|
||||
ownership \- Compaq ownership tag retriever
|
||||
.SH SYNOPSIS
|
||||
.B ownership
|
||||
.RB [ OPTIONS ]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B ownership
|
||||
retrieves and prints the "ownership tag" that can be set on Compaq
|
||||
computers. Contrary to all other programs of the
|
||||
.B dmidecode
|
||||
package,
|
||||
.B ownership
|
||||
doesn't print any version information, nor labels, but only the raw
|
||||
ownership tag. This should help its integration in scripts.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR "-d" ", " "--dev-mem FILE"
|
||||
Read memory from device \fBFILE\fR (default: \fB/dev/mem\fR)
|
||||
.TP
|
||||
.BR "-h" ", " "--help"
|
||||
Display usage information and exit
|
||||
.TP
|
||||
.BR "-V" ", " "--version"
|
||||
Display the version and exit
|
||||
|
||||
.SH FILES
|
||||
.I /dev/mem
|
||||
.SH AUTHOR
|
||||
Jean Delvare
|
||||
.SH "SEE ALSO"
|
||||
.BR biosdecode (8),
|
||||
.BR dmidecode (8),
|
||||
.BR mem (4),
|
||||
.BR vpddecode (8)
|
||||
74
man/vpddecode.8
Normal file
74
man/vpddecode.8
Normal file
@ -0,0 +1,74 @@
|
||||
.TH VPDDECODE 8 "February 2007" "dmidecode"
|
||||
.SH NAME
|
||||
vpddecode \- \s-1VPD\s0 structure decoder
|
||||
.SH SYNOPSIS
|
||||
.B vpddecode
|
||||
.RB [ OPTIONS ]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B vpddecode
|
||||
prints the "vital product data" information that can be found in almost
|
||||
all IBM and Lenovo computers. Available items are:
|
||||
.IP \(bu "\w'\(bu'u+1n"
|
||||
\s-1BIOS\s0 Build \s-1ID\s0
|
||||
.IP \(bu
|
||||
Box Serial Number
|
||||
.IP \(bu
|
||||
Motherboard Serial Number
|
||||
.IP \(bu
|
||||
Machine Type/Model
|
||||
|
||||
.PP
|
||||
Some systems have these additional items:
|
||||
.IP \(bu "\w'\(bu'u+1n"
|
||||
BIOS Release Date
|
||||
.IP \(bu
|
||||
Default Flash Image File Name
|
||||
|
||||
.PP
|
||||
Note that these additional items are not documented by IBM, so this is
|
||||
guess work, and as such should not be blindly trusted. Feedback about
|
||||
the accuracy of these labels is welcome.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR "-d" ", " "--dev-mem FILE"
|
||||
Read memory from device \fBFILE\fR (default: \fB/dev/mem\fR)
|
||||
.TP
|
||||
.BR "-s" ", " "--string KEYWORD"
|
||||
Only display the value of the \s-1VPD\s0 string identified by \fBKEYWORD\fR.
|
||||
\fBKEYWORD\fR must be a keyword from the following list: \fBbios-build-id\fR,
|
||||
\fBbox-serial-number\fR, \fBmotherboard-serial-number\fR,
|
||||
\fBmachine-type-model\fR, \fBbios-release-date\fR.
|
||||
Each keyword corresponds to an offset and a length within the \s-1VPD\s0
|
||||
record.
|
||||
Not all strings may be defined on all \s-1VPD\s0-enabled systems.
|
||||
If \fBKEYWORD\fR is not provided or not valid, a list of all valid
|
||||
keywords is printed and
|
||||
.B vpddecode
|
||||
exits with an error.
|
||||
This option cannot be used more than once.
|
||||
Mutually exclusive with \fB--dump\fR.
|
||||
.TP
|
||||
.BR "-u" ", " "--dump"
|
||||
Do not decode the VPD records, dump their contents as hexadecimal instead.
|
||||
Note that this is still a text output, no binary data will be thrown upon
|
||||
you. ASCII equivalent is displayed when possible. This option is mainly
|
||||
useful for debugging.
|
||||
Mutually exclusive with \fB--string\fR.
|
||||
.TP
|
||||
.BR "-h" ", " "--help"
|
||||
Display usage information and exit
|
||||
.TP
|
||||
.BR "-V" ", " "--version"
|
||||
Display the version and exit
|
||||
|
||||
.SH FILES
|
||||
.I /dev/mem
|
||||
.SH AUTHOR
|
||||
Jean Delvare
|
||||
.SH "SEE ALSO"
|
||||
.BR biosdecode (8),
|
||||
.BR dmidecode (8),
|
||||
.BR mem (4),
|
||||
.BR ownership (8)
|
||||
214
ownership.c
Normal file
214
ownership.c
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Compaq Ownership Tag
|
||||
*
|
||||
* Copyright (C) 2003-2005 Jean Delvare <khali@linux-fr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* For the avoidance of doubt the "preferred form" of this code is one which
|
||||
* is in an open unpatent encumbered format. Where cryptographic key signing
|
||||
* forms part of the process of creating an executable the information
|
||||
* including keys needed to generate an equivalently functional executable
|
||||
* are deemed to be part of the source code.
|
||||
*
|
||||
* References:
|
||||
* - Compaq "Technical Reference Guide for Compaq Deskpro 4000 and 6000"
|
||||
* First Edition
|
||||
* http://h18000.www1.hp.com/support/techpubs/technical_reference_guides/113a1097.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Options are global */
|
||||
struct opt
|
||||
{
|
||||
const char *devmem;
|
||||
unsigned int flags;
|
||||
};
|
||||
static struct opt opt;
|
||||
|
||||
#define FLAG_VERSION (1 << 0)
|
||||
#define FLAG_HELP (1 << 1)
|
||||
|
||||
static void ownership(u32 base, const char *pname, const char *devmem)
|
||||
{
|
||||
u8 *buf;
|
||||
int i;
|
||||
|
||||
/* read the ownership tag */
|
||||
if ((buf = mem_chunk(base, 0x51, devmem)) == NULL)
|
||||
{
|
||||
perror(pname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* chop the trailing garbage */
|
||||
i = 0x4f;
|
||||
while (i >= 0 && (buf[i] == 0x20 || buf[i] == 0x00))
|
||||
i--;
|
||||
buf[i + 1] = '\0';
|
||||
|
||||
/* filter and print */
|
||||
if (i >= 0)
|
||||
{
|
||||
for (; i >= 0; i--)
|
||||
{
|
||||
if (buf[i] < 32 || (buf[i] >= 127 && buf[i] < 160))
|
||||
buf[i] = '?';
|
||||
}
|
||||
printf("%s\n", (char *)buf);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static u32 decode(const u8 *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* integrity checking (lack of checksum) */
|
||||
for (i = 0; i < p[4]; i++)
|
||||
{
|
||||
if (p[5 + i * 10] != '$'
|
||||
|| !(p[6 + i * 10] >= 'A' && p[6 + i * 10] <= 'Z')
|
||||
|| !(p[7 + i * 10] >= 'A' && p[7 + i * 10] <= 'Z')
|
||||
|| !(p[8 + i * 10] >= 'A' && p[8 + i * 10] <= 'Z'))
|
||||
{
|
||||
printf("\t Abnormal Entry! Please report. [%02x %02x %02x %02x]\n",
|
||||
p[5 + i * 10], p[6 + i * 10],
|
||||
p[7 + i * 10], p[8 + i * 10]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* search for the right entry */
|
||||
for (i = 0; i < p[4]; i++)
|
||||
if (memcmp(p + 5 + i * 10, "$ERB", 4) == 0)
|
||||
return DWORD(p + 9 + i * 10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return -1 on error, 0 on success */
|
||||
static int parse_command_line(int argc, char * const argv[])
|
||||
{
|
||||
int option;
|
||||
const char *optstring = "d:hV";
|
||||
struct option longopts[] = {
|
||||
{ "dev-mem", required_argument, NULL, 'd' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
while ((option = getopt_long(argc, argv, optstring, longopts, NULL)) != -1)
|
||||
switch (option)
|
||||
{
|
||||
case 'd':
|
||||
opt.devmem = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
opt.flags |= FLAG_HELP;
|
||||
break;
|
||||
case 'V':
|
||||
opt.flags |= FLAG_VERSION;
|
||||
break;
|
||||
case '?':
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_help(void)
|
||||
{
|
||||
static const char *help =
|
||||
"Usage: ownership [OPTIONS]\n"
|
||||
"Options are:\n"
|
||||
" -d, --dev-mem FILE Read memory from device FILE (default: " DEFAULT_MEM_DEV ")\n"
|
||||
" -h, --help Display this help text and exit\n"
|
||||
" -V, --version Display the version and exit\n";
|
||||
|
||||
printf("%s", help);
|
||||
}
|
||||
|
||||
int main(int argc, char * const argv[])
|
||||
{
|
||||
u8 *buf;
|
||||
off_t fp;
|
||||
int ok = 0;
|
||||
|
||||
if (sizeof(u8) != 1 || sizeof(u32) != 4)
|
||||
{
|
||||
fprintf(stderr, "%s: compiler incompatibility\n", argv[0]);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
/* Set default option values */
|
||||
opt.devmem = DEFAULT_MEM_DEV;
|
||||
opt.flags = 0;
|
||||
|
||||
if (parse_command_line(argc, argv)<0)
|
||||
exit(2);
|
||||
|
||||
if (opt.flags & FLAG_HELP)
|
||||
{
|
||||
print_help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (opt.flags & FLAG_VERSION)
|
||||
{
|
||||
printf("%s\n", VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((buf = mem_chunk(0xE0000, 0x20000, opt.devmem)) == NULL)
|
||||
exit(1);
|
||||
|
||||
for (fp = 0; !ok && fp <= 0x1FFF0; fp += 16)
|
||||
{
|
||||
u8 *p = buf + fp;
|
||||
|
||||
if (memcmp((char *)p, "32OS", 4) == 0)
|
||||
{
|
||||
off_t len = p[4] * 10 + 5;
|
||||
|
||||
if (fp + len - 1 <= 0x1FFFF)
|
||||
{
|
||||
u32 base;
|
||||
|
||||
if ((base = decode(p)))
|
||||
{
|
||||
ok = 1;
|
||||
ownership(base, argv[0], opt.devmem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
62
types.h
Normal file
62
types.h
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short i16;
|
||||
typedef unsigned int u32;
|
||||
|
||||
/*
|
||||
* You may use the following defines to adjust the type definitions
|
||||
* depending on the architecture:
|
||||
* - Define BIGENDIAN on big-endian systems. Untested, as all target
|
||||
* systems to date are little-endian.
|
||||
* - Define ALIGNMENT_WORKAROUND if your system doesn't support
|
||||
* non-aligned memory access. In this case, we use a slower, but safer,
|
||||
* memory access method. This should be done automatically in config.h
|
||||
* for architectures which need it.
|
||||
*/
|
||||
|
||||
#ifdef BIGENDIAN
|
||||
typedef struct {
|
||||
u32 h;
|
||||
u32 l;
|
||||
} u64;
|
||||
#else
|
||||
typedef struct {
|
||||
u32 l;
|
||||
u32 h;
|
||||
} u64;
|
||||
#endif
|
||||
|
||||
#ifdef ALIGNMENT_WORKAROUND
|
||||
static inline u64 U64(u32 low, u32 high)
|
||||
{
|
||||
u64 self;
|
||||
|
||||
self.l = low;
|
||||
self.h = high;
|
||||
|
||||
return self;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ALIGNMENT_WORKAROUND
|
||||
# ifdef BIGENDIAN
|
||||
# define WORD(x) (u16)((x)[1] + ((x)[0] << 8))
|
||||
# define DWORD(x) (u32)((x)[3] + ((x)[2] << 8) + ((x)[1] << 16) + ((x)[0] << 24))
|
||||
# define QWORD(x) (U64(DWORD(x + 4), DWORD(x)))
|
||||
# else /* BIGENDIAN */
|
||||
# define WORD(x) (u16)((x)[0] + ((x)[1] << 8))
|
||||
# define DWORD(x) (u32)((x)[0] + ((x)[1] << 8) + ((x)[2] << 16) + ((x)[3] << 24))
|
||||
# define QWORD(x) (U64(DWORD(x), DWORD(x + 4)))
|
||||
# endif /* BIGENDIAN */
|
||||
#else /* ALIGNMENT_WORKAROUND */
|
||||
#define WORD(x) (u16)(*(const u16 *)(x))
|
||||
#define DWORD(x) (u32)(*(const u32 *)(x))
|
||||
#define QWORD(x) (*(const u64 *)(x))
|
||||
#endif /* ALIGNMENT_WORKAROUND */
|
||||
|
||||
#endif
|
||||
219
util.c
Normal file
219
util.c
Normal file
@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Common "util" functions
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2002-2010 Jean Delvare <khali@linux-fr>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* For the avoidance of doubt the "preferred form" of this code is one which
|
||||
* is in an open unpatent encumbered format. Where cryptographic key signing
|
||||
* forms part of the process of creating an executable the information
|
||||
* including keys needed to generate an equivalently functional executable
|
||||
* are deemed to be part of the source code.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef USE_MMAP
|
||||
#include <sys/mman.h>
|
||||
#ifndef MAP_FAILED
|
||||
#define MAP_FAILED ((void *) -1)
|
||||
#endif /* !MAP_FAILED */
|
||||
#endif /* USE MMAP */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
|
||||
static int myread(int fd, u8 *buf, size_t count, const char *prefix)
|
||||
{
|
||||
ssize_t r = 1;
|
||||
size_t r2 = 0;
|
||||
|
||||
while (r2 != count && r != 0)
|
||||
{
|
||||
r = read(fd, buf + r2, count - r2);
|
||||
if (r == -1)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
{
|
||||
close(fd);
|
||||
perror(prefix);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
r2 += r;
|
||||
}
|
||||
|
||||
if (r2 != count)
|
||||
{
|
||||
close(fd);
|
||||
fprintf(stderr, "%s: Unexpected end of file\n", prefix);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int checksum(const u8 *buf, size_t len)
|
||||
{
|
||||
u8 sum = 0;
|
||||
size_t a;
|
||||
|
||||
for (a = 0; a < len; a++)
|
||||
sum += buf[a];
|
||||
return (sum == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a physical memory chunk into a memory buffer.
|
||||
* This function allocates memory.
|
||||
*/
|
||||
void *mem_chunk(size_t base, size_t len, const char *devmem)
|
||||
{
|
||||
void *p;
|
||||
int fd;
|
||||
#ifdef USE_MMAP
|
||||
size_t mmoffset;
|
||||
void *mmp;
|
||||
#endif
|
||||
|
||||
if ((fd = open(devmem, O_RDONLY)) == -1)
|
||||
{
|
||||
perror(devmem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((p = malloc(len)) == NULL)
|
||||
{
|
||||
perror("malloc");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef USE_MMAP
|
||||
#ifdef _SC_PAGESIZE
|
||||
mmoffset = base % sysconf(_SC_PAGESIZE);
|
||||
#else
|
||||
mmoffset = base % getpagesize();
|
||||
#endif /* _SC_PAGESIZE */
|
||||
/*
|
||||
* Please note that we don't use mmap() for performance reasons here,
|
||||
* but to workaround problems many people encountered when trying
|
||||
* to read from /dev/mem using regular read() calls.
|
||||
*/
|
||||
mmp = mmap(0, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset);
|
||||
if (mmp == MAP_FAILED)
|
||||
goto try_read;
|
||||
|
||||
memcpy(p, (u8 *)mmp + mmoffset, len);
|
||||
|
||||
if (munmap(mmp, mmoffset + len) == -1)
|
||||
{
|
||||
fprintf(stderr, "%s: ", devmem);
|
||||
perror("munmap");
|
||||
}
|
||||
|
||||
goto out;
|
||||
|
||||
#endif /* USE_MMAP */
|
||||
|
||||
try_read:
|
||||
if (lseek(fd, base, SEEK_SET) == -1)
|
||||
{
|
||||
fprintf(stderr, "%s: ", devmem);
|
||||
perror("lseek");
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (myread(fd, p, len, devmem) == -1)
|
||||
{
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
if (close(fd) == -1)
|
||||
perror(devmem);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
f = fopen(dumpfile, add ? "r+b" : "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;
|
||||
}
|
||||
|
||||
/* Returns end - start + 1, assuming start < end */
|
||||
u64 u64_range(u64 start, u64 end)
|
||||
{
|
||||
u64 res;
|
||||
|
||||
res.h = end.h - start.h;
|
||||
res.l = end.l - start.l;
|
||||
|
||||
if (end.l < start.l)
|
||||
res.h--;
|
||||
if (++res.l == 0)
|
||||
res.h++;
|
||||
|
||||
return res;
|
||||
}
|
||||
30
util.h
Normal file
30
util.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
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, int add);
|
||||
u64 u64_range(u64 start, u64 end);
|
||||
201
vpddecode.c
Normal file
201
vpddecode.c
Normal file
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* IBM Vital Product Data decoder
|
||||
*
|
||||
* Copyright (C) 2003-2007 Jean Delvare <khali@linux-fr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* For the avoidance of doubt the "preferred form" of this code is one which
|
||||
* is in an open unpatent encumbered format. Where cryptographic key signing
|
||||
* forms part of the process of creating an executable the information
|
||||
* including keys needed to generate an equivalently functional executable
|
||||
* are deemed to be part of the source code.
|
||||
*
|
||||
* References:
|
||||
* - IBM "Using the BIOS Build ID to identify Thinkpad systems"
|
||||
* Revision 2006-01-31
|
||||
* http://www-307.ibm.com/pc/support/site.wss/MIGR-45120.html
|
||||
*
|
||||
* Notes:
|
||||
* - Main part of the code is taken directly from biosdecode, with an
|
||||
* additional command line interface and a few experimental features.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
#include "vpdopt.h"
|
||||
|
||||
static void print_entry(const char *name, const u8 *p, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (name != NULL)
|
||||
printf("%s: ", name);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
/* ASCII filtering */
|
||||
if (p[i] >= 32 && p[i] < 127)
|
||||
printf("%c", p[i]);
|
||||
else if (p[i] != 0)
|
||||
printf(".");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void dump(const u8 *p, u8 len)
|
||||
{
|
||||
int done, i, min;
|
||||
|
||||
for (done = 0; done < len; done += 16)
|
||||
{
|
||||
printf("%02X:", done);
|
||||
min = (len - done < 16) ? len - done : 16;
|
||||
|
||||
/* As hexadecimal first */
|
||||
for (i = 0; i < min; i++)
|
||||
printf(" %02X", p[done + i]);
|
||||
for (; i < 16; i++) /* Complete line if needed */
|
||||
printf(" ");
|
||||
printf(" ");
|
||||
|
||||
/* And now as text, with ASCII filtering */
|
||||
for (i = 0; i < min; i++)
|
||||
printf("%c", (p[done + i] >= 32 && p[done + i] < 127) ?
|
||||
p[done + i] : '.');
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int decode(const u8 *p)
|
||||
{
|
||||
if (p[5] < 0x30)
|
||||
return 0;
|
||||
|
||||
/* XSeries have longer records, exact length seems to vary. */
|
||||
if (!(p[5] >= 0x45 && checksum(p, p[5]))
|
||||
/* Some Netvista seem to work with this. */
|
||||
&& !(checksum(p, 0x30))
|
||||
/* The Thinkpad/Thinkcentre checksum does *not* include the first
|
||||
13 bytes. */
|
||||
&& !(checksum(p + 0x0D, 0x30 - 0x0D)))
|
||||
{
|
||||
/* A few systems have a bad checksum (xSeries 325, 330, 335
|
||||
and 345 with early BIOS) but the record is otherwise
|
||||
valid. */
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
printf("# Bad checksum!\n");
|
||||
}
|
||||
|
||||
if (opt.string != NULL)
|
||||
{
|
||||
if (opt.string->offset + opt.string->len < p[5])
|
||||
print_entry(NULL, p + opt.string->offset,
|
||||
opt.string->len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_entry("BIOS Build ID", p + 0x0D, 9);
|
||||
print_entry("Box Serial Number", p + 0x16, 7);
|
||||
print_entry("Motherboard Serial Number", p + 0x1D, 11);
|
||||
print_entry("Machine Type/Model", p + 0x28, 7);
|
||||
|
||||
if (p[5] < 0x44)
|
||||
return 1;
|
||||
|
||||
print_entry("BIOS Release Date", p + 0x30, 8);
|
||||
print_entry("Default Flash Image File Name", p + 0x38, 12);
|
||||
|
||||
if (p[5] >= 0x46 && p[0x44] != 0x00)
|
||||
{
|
||||
printf("%s: %u\n", "BIOS Revision", p[0x44]);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char * const argv[])
|
||||
{
|
||||
u8 *buf;
|
||||
int found = 0;
|
||||
unsigned int fp;
|
||||
|
||||
if (sizeof(u8) != 1)
|
||||
{
|
||||
fprintf(stderr, "%s: compiler incompatibility\n", argv[0]);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
/* Set default option values */
|
||||
opt.devmem = DEFAULT_MEM_DEV;
|
||||
opt.flags = 0;
|
||||
|
||||
if (parse_command_line(argc, argv)<0)
|
||||
exit(2);
|
||||
|
||||
if (opt.flags & FLAG_HELP)
|
||||
{
|
||||
print_help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (opt.flags & FLAG_VERSION)
|
||||
{
|
||||
printf("%s\n", VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
printf("# vpddecode %s\n", VERSION);
|
||||
|
||||
if ((buf = mem_chunk(0xF0000, 0x10000, opt.devmem)) == NULL)
|
||||
exit(1);
|
||||
|
||||
for (fp = 0; fp <= 0xFFF0; fp += 4)
|
||||
{
|
||||
u8 *p = buf + fp;
|
||||
|
||||
if (memcmp((char *)p, "\252\125VPD", 5) == 0
|
||||
&& fp + p[5] - 1 <= 0xFFFF)
|
||||
{
|
||||
if (fp % 16 && !(opt.flags & FLAG_QUIET))
|
||||
printf("# Unaligned address (%#x)\n",
|
||||
0xf0000 + fp);
|
||||
if (opt.flags & FLAG_DUMP)
|
||||
{
|
||||
dump(p, p[5]);
|
||||
found++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (decode(p))
|
||||
found++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
if (!found && !(opt.flags & FLAG_QUIET))
|
||||
printf("# No VPD structure found, sorry.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
157
vpdopt.c
Normal file
157
vpdopt.c
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Command line handling of vpddecode
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2005-2007 Jean Delvare <khali@linux-fr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "util.h"
|
||||
#include "vpdopt.h"
|
||||
|
||||
|
||||
/* Options are global */
|
||||
struct opt opt;
|
||||
|
||||
|
||||
/*
|
||||
* Handling of option --string
|
||||
*/
|
||||
|
||||
/* This lookup table could admittedly be reworked for improved performance.
|
||||
Due to the low count of items in there at the moment, it did not seem
|
||||
worth the additional code complexity though. */
|
||||
static const struct string_keyword opt_string_keyword[] = {
|
||||
{ "bios-build-id", 0x0D, 9 },
|
||||
{ "box-serial-number", 0x16, 7 },
|
||||
{ "motherboard-serial-number", 0x1D, 11 },
|
||||
{ "machine-type-model", 0x28, 7 },
|
||||
{ "bios-release-date", 0x30, 8 },
|
||||
};
|
||||
|
||||
static void print_opt_string_list(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
fprintf(stderr, "Valid string keywords are:\n");
|
||||
for (i = 0; i < ARRAY_SIZE(opt_string_keyword); i++)
|
||||
{
|
||||
fprintf(stderr, " %s\n", opt_string_keyword[i].keyword);
|
||||
}
|
||||
}
|
||||
|
||||
static int parse_opt_string(const char *arg)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (opt.string)
|
||||
{
|
||||
fprintf(stderr, "Only one string can be specified\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i<ARRAY_SIZE(opt_string_keyword); i++)
|
||||
{
|
||||
if (!strcasecmp(arg, opt_string_keyword[i].keyword))
|
||||
{
|
||||
opt.string = &opt_string_keyword[i];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "Invalid string keyword: %s\n", arg);
|
||||
print_opt_string_list();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Command line options handling
|
||||
*/
|
||||
|
||||
/* Return -1 on error, 0 on success */
|
||||
int parse_command_line(int argc, char * const argv[])
|
||||
{
|
||||
int option;
|
||||
const char *optstring = "d:hs:uV";
|
||||
struct option longopts[] = {
|
||||
{ "dev-mem", required_argument, NULL, 'd' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "string", required_argument, NULL, 's' },
|
||||
{ "dump", no_argument, NULL, 'u' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
while ((option = getopt_long(argc, argv, optstring, longopts, NULL)) != -1)
|
||||
switch (option)
|
||||
{
|
||||
case 'd':
|
||||
opt.devmem = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
opt.flags |= FLAG_HELP;
|
||||
break;
|
||||
case 's':
|
||||
if (parse_opt_string(optarg) < 0)
|
||||
return -1;
|
||||
opt.flags |= FLAG_QUIET;
|
||||
break;
|
||||
case 'u':
|
||||
opt.flags |= FLAG_DUMP;
|
||||
break;
|
||||
case 'V':
|
||||
opt.flags |= FLAG_VERSION;
|
||||
break;
|
||||
case '?':
|
||||
switch (optopt)
|
||||
{
|
||||
case 's':
|
||||
fprintf(stderr, "String keyword expected\n");
|
||||
print_opt_string_list();
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((opt.flags & FLAG_DUMP) && opt.string != NULL)
|
||||
{
|
||||
fprintf(stderr, "Options --string and --dump are mutually exclusive\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_help(void)
|
||||
{
|
||||
static const char *help =
|
||||
"Usage: vpddecode [OPTIONS]\n"
|
||||
"Options are:\n"
|
||||
" -d, --dev-mem FILE Read memory from device FILE (default: " DEFAULT_MEM_DEV ")\n"
|
||||
" -h, --help Display this help text and exit\n"
|
||||
" -s, --string KEYWORD Only display the value of the given VPD string\n"
|
||||
" -u, --dump Do not decode the VPD records\n"
|
||||
" -V, --version Display the version and exit\n";
|
||||
|
||||
printf("%s", help);
|
||||
}
|
||||
45
vpdopt.h
Normal file
45
vpdopt.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Command line handling of vpddecode
|
||||
* This file is part of the dmidecode project.
|
||||
*
|
||||
* Copyright (C) 2005-2006 Jean Delvare <khali@linux-fr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
struct string_keyword
|
||||
{
|
||||
const char *keyword;
|
||||
off_t offset;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
struct opt
|
||||
{
|
||||
const char *devmem;
|
||||
unsigned int flags;
|
||||
const struct string_keyword *string;
|
||||
};
|
||||
extern struct opt opt;
|
||||
|
||||
#define FLAG_VERSION (1 << 0)
|
||||
#define FLAG_HELP (1 << 1)
|
||||
#define FLAG_DUMP (1 << 2)
|
||||
#define FLAG_QUIET (1 << 3)
|
||||
|
||||
int parse_command_line(int argc, char * const argv[]);
|
||||
void print_help(void);
|
||||
Loading…
Reference in New Issue
Block a user