mp.c static struct mp* mpsearch1(uint a, int len)

トップページ
jupiteroak.hatenablog.com


mp.c
https://github.com/mit-pdos/xv6-public/blob/master/mp.c#L30

static struct mp* mpsearch1(uint a, int len)
{
  uchar *e, *p, *addr;

  addr = P2V(a);
  e = addr+len;
  for(p = addr; p < e; p += sizeof(struct mp))
    if(memcmp(p, "_MP_", 4) == 0 && sum(p, sizeof(struct mp)) == 0)
      return (struct mp*)p;
  return 0;
}

mpsearch1関数は、先頭アドレスが引数a・サイズが引数lenのメモリ領域から、MP Floating Pointer Structureを探索し取得します。

引数 uint a
メモリ領域の先頭アドレス(物理アドレス)です。

引数 int len
メモリ領域のサイズ(バイト単位)です。

戻り値 struct mp* p または 0
MP Floating Pointer Structureの探索に成功した場合、MP Floating Pointer Structureの先頭アドレスが戻り値となります。
MP Floating Pointer Structureの探索に失敗した場合、0が戻り値となります。


処理の内容

メモリ領域の先頭アドレスの値と終端アドレス+1の値を仮想アドレスとして求める。

addr = P2V(a);
e = addr+len;

引数aで指定されたアドレスは物理アドレスなので、P2Vマクロを使って物理アドレスaを仮想アドレスaddrに変換します。
アドレスaddrにlenを加算してe(終端アドレス+1の値)を求めます。

MP Floating Pointer Structureを探索する

for(p = addr; p < e; p += sizeof(struct mp))
    if(memcmp(p, "_MP_", 4) == 0 && sum(p, sizeof(struct mp)) == 0)
      return (struct mp*)p;

先頭アドレスaddr・サイズlenのメモリ領域において、mp構造体のデータサイズごとに、memcmp関数とsum関数を呼び出し、MP Floating Pointer Structureを探索します。

mp構造体について

mp構造体は、MP Floating Pointer Structureを表現したデータ構造です。

struct mp {             // floating pointer
  uchar signature[4];           // "_MP_"
  void *physaddr;               // phys addr of MP config table
  uchar length;                 // 1
  uchar specrev;                // [14]
  uchar checksum;               // all bytes must add up to 0
  uchar type;                   // MP system config type
  uchar imcrp;
  uchar reserved[3];
};

memcmp(p, "_MP_", 4)について

memcmp関数を呼び出して、先頭アドレスがp・サイズが4バイトのメモリ領域に"_MP_"(MP Floating Pointer Structureであることを示すシグネチャ)が格納されているかを調べます。"_MP_"が格納されていた場合は、0が戻り値となります。

sum(p, sizeof(struct mp))について

sum関数を呼び出して、先頭アドレスがp・サイズがsizeof(struct mp)のメモリ領域において、各メモリ(1バイト)に格納されている値の和を求めます。
先頭アドレスpがMP Floating Pointer Structureの先頭アドレスの場合、MP Floating Pointer StructureにはCHECKSUMフィールドがあるので、0が戻り値となります。

MP Floating Pointer Structureの探索に成功した場合

memcmp(p, "_MP_", 4) == 0 && sum(p, sizeof(struct mp)) == 0 が真となる場合→mp関数の戻り値が0、かつ、sum関数の戻り値が0の場合→MP Floating Pointer Structureの探索に成功した場合は、MP Floating Pointer Structureの先頭アドレスを戻り値として返します。

MP Floating Pointer Structureの探索に失敗した場合

return 0;

MP Floating Pointer Structureの探索に失敗した場合は、0を戻り値として返します。