2012-04-16 13 views
4

私はカーネルについて学習しようとしており、しばらくの間カーネルランドスケープを構成する基本的なデータ構造の一部を印刷しようとしていました。私の問題は、メモリアドレスが与えられた場合、そのアドレスの内容を印刷できるようにしたいということです。ポインタを指定してカーネル内からカーネルメモリにアクセスする

たとえば、私はIDTの位置を決定する関数を持っています。 (void *)0xffff81b8c0000fffのオーダで返します。しかし、そのアドレスにあるものがprintkになると、結果はカーネルパニックになります。私は、ユーザー空間からカーネルメモリにアクセスするのを防ぐための保護があることを理解していますが、私はstart_kernelの中​​から読み込み可能と考えていました。

コードは次のとおりです。

idt_ptr = sidt(); // returns (void *) 
printk(KERN_INFO "680: IDT TABLE, FIRST ENTRY\n"); 
//entry is 64 bits 
printk(KERN_INFO "680: %llx\n", *(unsigned long long *)idt_ptr); 

は、ここでは、この試みを行った後に発生するカーネルパニックのテールエンドです:

enter image description here

私が読み取りアクセスのためのセマフォを必要とするようだが、これはちょうど任意のアドレスではありませんか?

+0

OS開発の経験から、ページ違反を引き起こしているように見えます。これは、ページングされたメモリにアクセスしようとすると発生します。残念ながら、私はあなたを助けるためにもっと多くのことを知らない。 – user99545

答えて

5

例えば、私はIDTの位置を決定する関数を持っています。それは0xffff81b8c0000fff

の順

char*以外にないポインタに(void *型)を返す可能性が0x...ff等しい可能性 - そのアドレスが正しくchar S以外のものを含むデータ構造体へのポインタのために整列されていません。

結論:あなたのsidt機能が壊れて、偽のアドレスを返します。

+1

他のアドレスに基づいて、私は実際のアドレスはおそらく '0xffffffff81b8c000'だと言いたい - ' 0x0fff'は16ビットのIDT制限である可能性が高いです。 OPは、 'sidt'オペコードが10バイトの値を書き込むことに注意する必要があります。下位の2バイトは16ビットの制限で、上位の8バイトはアドレスです。 – caf

+0

私はこれが事実かもしれないことを恐れていました。私はユーザランドでテストしようとしていましたが、カーネルのメモリにアクセスできないため、アドレスが悪いのか、その内容にアクセスできないのかわかりませんでした。カフェが言ったことはかなり意味があり、私はできるだけ早くそれを試してみて、報告して戻します。ありがとう。 – fromClouds

1

kdbは、カーネル内部を突っ込んで行くことをお勧めします。

KVMまたはqemu VMをkdbでパッチしたカーネルでセットアップしてみてください。

+0

私はそれをお勧めします。 – fromClouds

関連する問題