前回はMP Floating Pointer Structureを見て、その中にMP Configuration table Headerへのアドレスが入っていることを書いたので、
今回はMP Configuration table Headerを見ていく。見るといっても内容をすべて見るというよりは、minix2smp実装を理解するために必要な部分だけですが。
minix2smpのソースはここ。
http://gsd.unex.es/projects/minixsmp/
MP Configuration table Headerとは何かというと、「MP Configuration tableのヘッダです」というそのままな説明なんですがw
それだとアレなので、MP Configuration tableは何かっていうと、
これは1種類のテーブルではなく5種類あって、ENTRY TYPEと呼ばれる種別ごとにテーブルの構造が違うけど、
総称してMP Configuration tableと呼んでいるようです。
MPの仕様書で定義されているENTRY TYPEは5種類あり、名称と番号の関係は下のような感じです。
Entry Description Entry Type Code Processor 0 Bus 1 I/O APIC 2 I/O Interrupt Assignment 3 Local Interrupt Assignment 4
個別の内容は今度見るとして、今日はMP Configuration table Headerを見ていくお。
前述したようにMP Configuration table HeaderはMP Configuration tableのヘッダなので、
MP Configuration tableの内容を見ていくために必要な情報等も入っています。
minix2smpの実装では、下のような構造体で表現してます。
/* Describes the estruct of MP configuration table header */ struct mp_config_header { char mpch_signature[4]; /* must be "PCMP" */ u16_t mpch_length; /* base table size including header */ u8_t mpch_version; /* MP specification version number*/ u8_t mpch_checksum; /* base table + checksum must sum 0 */ char mpch_oem_id[8]; /* manufacturer id (space filled) */ char mpch_product_id[12]; /* product id (space filled) */ u32_t mpch_oem_table; /* optional manufacturer table address */ u16_t mpch_oem_table_size; /* manufacturer table size */ u16_t mpch_entry_count; /* entry count in MP table */ u32_t mpch_apic_addr; /* IO address for local APIC */ u16_t mpch_extended_length; /* extended table length */ u8_t mpch_extended_checksum; /* extended table checksum */ char mpch_reserved; /* unused */ };
フィールドは色々あるんですが、mpch_signature、mpch_lengthは読み込んだMP Configuration table Headerの正当性を検証するのに使います。
前回も書いたけど、検証方法はシグネチャ&&チェックサム方式です。
シグネチャはmpch_signatureの値を調べます。コメントにも書いてあるけど、MP Configuration table Headerのシグネチャは「PCMP」なので、mpch_signatureが"PCMP"でない場合は、何かが間違ってます。
そして、チェックサムの計算ですが、MP Floating Pointer Structureの場合はテーブルのサイズ分、1バイトずつ計算してったのですが、
今度はmpch_lengthで指定されたバイト数分、1バイトずつ計算していきます。
コードだとこんな感じになってます。
int test_mptable_checksum(void) { /* Cheks a MP table header structure for a valid signature and checksum. Return noncero on success */ unsigned char data, checksum; int i; /* first match the signature */ for (i=0; i<4; i++) if (mph.mpch_signature[i] != SIGN_MP_C_HEADER[i] ) return 0;
最初は、シグネチャのチェック。
/* then calculate checksum */ checksum=0; for (i=0; i<mph.mpch_length; i++) { /* the complete table is in another segment, so we need copy each byte into kernel address space (mph is only the header) */ phys_copy(fps.fp_mp_table+i, vir2phys(&data), 1); checksum +=data; } return (!checksum); /* checksum ok if sums 0 */ }
コメントに「セグメントが違うから、正しいアドレスからデータを引っ張るよ」的なことが書かれていますが、
結局は足し算していって結果が0ならチェックサムは問題ないということになります。
次に、mpch_lengthで示されたバイト数分のループで計算していきます。
この後、MP Configuration tableを読みにいくわけなんですが、実装の話はすでに書いたので、そちらを見てみてくださいな。
今度は、各MP Configuration tableの内容を見ていく予定なんですが、
実装上だと、これらの中身を使って何かをしている様子が見えないので、実はそんなに細かいことを調べなくても良い希ガス。