SMBIOS Detection

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
KieranFoot

SMBIOS Detection

Post 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...
User avatar
kataklinger
Member
Member
Posts: 381
Joined: Fri Nov 04, 2005 12:00 am
Location: Serbia

Re:SMBIOS Detection

Post 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_" ) )
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:SMBIOS Detection

Post 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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:SMBIOS Detection

Post 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_"))
?
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:SMBIOS Detection

Post 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.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:SMBIOS Detection

Post 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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
kataklinger
Member
Member
Posts: 381
Joined: Fri Nov 04, 2005 12:00 am
Location: Serbia

Re:SMBIOS Detection

Post 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 :)
KieranFoot

Re:SMBIOS Detection

Post by KieranFoot »

Thanks guys, im sure those pieces of code will come in verry handy. :o

----
Thanks
Kieran Foot
User avatar
kataklinger
Member
Member
Posts: 381
Joined: Fri Nov 04, 2005 12:00 am
Location: Serbia

Re:SMBIOS Detection

Post 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>
Kemp

Re:SMBIOS Detection

Post 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.
User avatar
kataklinger
Member
Member
Posts: 381
Joined: Fri Nov 04, 2005 12:00 am
Location: Serbia

Re:SMBIOS Detection

Post 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).
Post Reply