Page 1 of 1
SMBIOS Detection
Posted: Wed Jan 18, 2006 10:48 am
by KieranFoot
Hi guys, i know my BIOS is SMBIOS capable, but my code isnt detecting it...
Code: Select all
_smbios *smbios; ;SMBIOS Info structure
static unsigned short SEARCH_START=0xf0000L;
static const unsigned short SEARCH_LEN=((0xFFFL-sizeof(smbios))-1);
// seraches for smbios
void search_for_smbios(void) {
unsigned short temp;
for(temp=SEARCH_START;temp<=(SEARCH_START+SEARCH_LEN);temp++) {
temp++;
temp++;
temp++;
smbios=(_smbios *)temp;
if(smbios->Anchor[3]=="_SM_") {
kprintf("SMBIOS ANCHOR Found.\n");
if(smbios->_DMI_[4]=="_DMI_")
kprintf("_DMI_ Signature present.");
return;
}
}
}
if im right you start searching from 0xf0000L to 0xf0000L + 0xFFFL and if you fing the signature "_SM_" youve foind it...
Re:SMBIOS Detection
Posted: Wed Jan 18, 2006 11:17 am
by kataklinger
if(smbios->Anchor[3]=="_SM_")
and
if(smbios->_DMI_[4]=="_DMI_")
These two compare addresses of strings. You need something like this
:
if( !strcmp( smbios->Anchor[3], "_SM_" ) )
and
if( !strcmp( smbios->_DMI_[4], "_DMI_" ) )
Re:SMBIOS Detection
Posted: Wed Jan 18, 2006 11:43 am
by Brendan
Hi,
Just curious, but how big is an "unsigned short" for your compiler (are you sure the value 0xf0fffL will fit)?
In any case, you might want to try something like:
Code: Select all
void search_for_smbios(void) {
void *temp;
for(temp=(void *)SEARCH_START;temp<=(void *)(SEARCH_START+SEARCH_LEN);temp += 16) {
smbios=(_smbios *)temp;
if(smbios->Anchor[3]=="_SM_") {
kprintf("SMBIOS ANCHOR Found.\n");
if(smbios->_DMI_[4]=="_DMI_")
kprintf("_DMI_ Signature present.");
return;
}
}
}
I'm not sure if the compiler will actually accept this though - getting typecasts right is a little tricky when you're an assembly programmer, and I'm not sure if pointer arithmetic works on all C compilers...
KieranFoot wrote:if im right you start searching from 0xf0000L to 0xf0000L + 0xFFFL and if you fing the signature "_SM_" youve foind it...
You might want to double check this too - my copy of the specification says that the SMBIOS Structure Entry Point is on a 16 byte boundary within the area from 0x000F0000 to 0x000FFFFF (not from 0x000F0000 to 0x000F0FFF).
kataklinger wrote:These two compare addresses of strings. You need something like this
:
if( !strcmp( smbios->Anchor[3], "_SM_" ) )
and
if( !strcmp( smbios->_DMI_[4], "_DMI_" ) )
This makes my eyes bleed ::). Is there a way to do something like
cmp [esi+offset], '_SM_' in C?
Cheers,
Brendan
Re:SMBIOS Detection
Posted: Wed Jan 18, 2006 11:49 am
by Pype.Clicker
Brendan wrote:
kataklinger wrote:These two compare addresses of strings. You need something like this
:
if( !strcmp( smbios->Anchor[3], "_SM_" ) )
and
if( !strcmp( smbios->_DMI_[4], "_DMI_" ) )
This makes my eyes bleed ::). Is there a way to do something like
cmp [esi+offset], '_SM_' in C?
Cheers,
Brendan
You mean something like
Code: Select all
#define MAGIC(x) (unsigned)x[0] + ((unsigned)x[1]>>8 ) + ((unsigned)x[2]>>16) + ((unsigned)x[3]>>24)
if (smbios_magic == MAGIC("_SM_"))
?
Re:SMBIOS Detection
Posted: Wed Jan 18, 2006 12:10 pm
by Candy
Pype.Clicker wrote:
You mean something like
Code: Select all
#define MAGIC(x) (unsigned)x[0] + ((unsigned)x[1]>>8 ) + ((unsigned)x[2]>>16) + ((unsigned)x[3]>>24)
if (smbios_magic == MAGIC("_SM_"))
?
That's kind of ... not very nice. You just want to view what's there as an integer. So, do that then:
Code: Select all
#define MAGIC(x) (*((unsigned int *)x))
if (smbios_magic == MAGIC("_SM_")) {
The above code should give the same result but I consider this to be more legible. It does have problems transferring to non-byte based computers.
Re:SMBIOS Detection
Posted: Wed Jan 18, 2006 12:38 pm
by Brendan
Hi,
Thanks Pype and Candy - this is what I was looking for, and I think it may have also been what KieranFoot was trying to do to start with...
[Offtopic]
I ordered a copy of The C Programming Language, Second Edition by Brian W. Kernighan and Dennis M. Ritchie a few weeks ago. It arrived yesterday but I haven't picked it up from the bookshop yet :-[. Hopefully my assembly-oriented brain can learn some new tricks - without kataklinger's post I never would have noticed the comparisons.
[/Offtopic]
Cheers,
Brendan
Re:SMBIOS Detection
Posted: Wed Jan 18, 2006 1:16 pm
by kataklinger
Or maybe this:
Code: Select all
static char* magic = "_SM_";
if( *(unsigned long*)(smbios->Anchor[3]) == *(unsigned long*)magic ) ....
@Brendan:
When I wrote strcmp I was pointing the difference. And the book is great, I have learnd a lot from it. It isn't for beginers at programming, but for people like you is perfect
Re:SMBIOS Detection
Posted: Wed Jan 18, 2006 5:15 pm
by KieranFoot
Thanks guys, im sure those pieces of code will come in verry handy.
----
Thanks
Kieran Foot
Re:SMBIOS Detection
Posted: Wed Jan 18, 2006 5:33 pm
by kataklinger
Pascal has better string manipulation then C so it's possible to write:
And if I recall correctly it is possible to write:
If you are using C++ it is a good idea to encapsulate string manipulation in one
string class.
<edit>
And why do you have 4x
temp++ in your code?
</edit>
<another_edit>
Size of unsigned short is 16 bits on every compiler as far as I know and it is impossible to fit value 0xf0000 in it. So you have to use long type
</another_edit>
Re:SMBIOS Detection
Posted: Thu Jan 19, 2006 7:53 am
by Kemp
Well yes, Delphi has better string manipulation because the strings are essentially classes in Delphi. What we are dealing with here is not strings, it is pointers to chars which are handled as any pointer would be, otherwise there would be much more subtle and annoying problems.
Re:SMBIOS Detection
Posted: Thu Jan 19, 2006 8:01 am
by kataklinger
I guess that's why they choose short strings (4 chars) as a signatures ("_MP_","_SM_"...), because you can manipulate with 4 chars at once.
If you use MM and XMM registers you can speed your code when you are comparing and copying strings because you can manipulate with 8 or 16 bytes at once
This is also known as VECTORIZATION (well Intel calls this thing with that name).