その名のとおり、メモリを検出しているに違いありません。
arch/x86/boot/memory.c
======
int detect_memory(void)
{
int err = -1;
if (detect_memory_e820() > 0)
err = 0;
if (!detect_memory_e801())
err = 0;
if (!detect_memory_88())
err = 0;
return err;
}
======
それでは各サブ関数を見ていきましょう。
すべて同じファイル内にあります。
======
static int detect_memory_e820(void)
{
/* ~変数宣言~ */
do {
size = sizeof(struct e820entry);
/* システムのアドレスマップをBIOSに問い合わせる。 */
asm("int $0x15; setc %0"
: "=d" (err), "+b" (next), "=a" (id), "+c" (size),
"=m" (*desc)
: "D" (desc), "d" (SMAP), "a" (0xe820));
/* 失敗してたらループを抜ける*/
if (err)
break;
/* BIOSによってはこのループ中にSMAPを返すのをやめてしまいます。
こちらとしてはここまで成功してんだか失敗してんだか
ゴミまざってんだか分からないのでエントリ数0で
ループ抜けちゃいます */
if (id != SMAP) {
count = 0;
break;
}
/* アドレスマップのエントリ数を加算 */
count++;
desc++;
/* アドレスマップエントリの配列サイズ(=128)を越えてないか? */
} while (next && count < e820_entries =" count;">
======
SMAPとか出てきますがこれは「System Memoy mAP」の略です。
BIOSからもらえるメモリマップの情報です。
要約してしまうとこの関数はBIOSの機能を使ってシステムのメモリマップを取得しているのです。
次に「detect_memory_e801」を見てみます。
======
static int detect_memory_e801(void)
{
/* ~変数宣言~ */
/* BIOSから拡張メモリ領域サイズ(64MBを超える部分)を取得する */
bx = cx = dx = 0;
ax = 0xe801;
asm("stc; int $0x15; setc %0"
: "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
if (err)
return -1;
/* これ必要?(※原文まま)*/
if (cx || dx) {
ax = cx;
bx = dx;
}
/* とれてくる値が16MB超過していたらおかしい */
if (ax > 15*1024)
return -1; /* Bogus! */
/* とってきた64MBを超える分の拡張メモリサイズを格納しておく */
boot_params.alt_mem_k = (ax == 15*1024) ? (dx <<>
======
さっきから出てくる「int 0x15」というのはBIOSの機能を呼び出している部分で、
ファンクション表は英語のWikipediaが便利です。
あんまり難しい英語でもないのでなんとかいけます。
http://en.wikipedia.org/wiki/BIOS_call
他に親切な解説としては下記が詳しくて参考になります。
ブートローダー(その3) -ありえるえりあ
最後の方はコメントを無理やり訳してみましたが、正直よく理解できてません。
めげずに次へ
======
static int detect_memory_88(void)
{
u16 ax;
u8 err;
/* 拡張メモリサイズをとってくる */
ax = 0x8800;
asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
/* とってきたメモリサイズを格納しておく */
boot_params.screen_info.ext_mem_k = ax;
/* エラーの結果を返す */
return -err;
}
=======
というわけで「detect_memory」の内容をまとめると
1)「detect_memory_e820」でシステムメモリのアドレスマップエントリ数を取得
2)「detect_memory_e801」で64MBを超えた部分の拡張メモリサイズを取得
3)「detect_memory_88」で拡張メモリサイズを取得
ということをしているのです。
0 件のコメント:
コメントを投稿