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,
KieranFoot wrote:

Code: Select all

     unsigned short temp;
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. :o

----
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:

Code: Select all

if string1 <> string2 then ....
And if I recall correctly it is possible to write:

Code: Select all

istring1 :=  string1 + string2;
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).