int load_mph(void) { /* Find and load a valid MP config header struct. Return noncero on success */ unsigned addr; phys_copy ( fps.fp_mp_table , vir2phys(&mph) , sizeof(mph) ); if (test_mptable_checksum()) return 1; ADDS_MP_STATUS("MP config table checksum FAILLED!\n"); return 0; }
ここの処理は割と単純。fpsにはMP Configuration Table Headerのアドレスが入っているので、そのアドレスを読み込めば良い。
MPの仕様書ではMP Floating Pointer Structureの説明にある「PHYSICAL ADDRESS POINTER」フィールドで、長さは32bit。
そして、データを読み込んだらfpsの時と同様にシグネチャとチェックサムを確認する。
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 */ }
MP Configuration Table Structureのシグネチャは仕様で"PCMP"と定義されているので、SIGN_MP_C_HEADERの値は当然"PCMP"。
そして、チェックサムの計算なんだけど、これもfpsと同様のチェック方式になっているので、バイト毎に足し算していって結果が0になればチェックサムが正しかったことになる。
チェックサムが正しかったら、mp_start()では次に、process_mp_configuration()をコールして、MP Configurationに関する情報を読みに行く。
load_mph()はここまで。