web-dev-qa-db-ja.com

printkは内部的にどのように機能しますか?

私はprintfがその仕事をするためにOSからの助けを必要としていることを知っています。

また、ライブラリがないため、Linuxソースコードではprintfが機能しないことも知っています。したがって、デバッグ用にprintkがあります。

OSがまだ起動しているときにprintkはどのように機能しますか?

10
gpuguy

このリファレンスには、次のタイトルの質問に対する回答があるようです: Linux Kernel Development Second Edition

抜粋

printk()

カーネル印刷関数printk()は、Cライブラリprintf()関数とほぼ同じように動作します。実際、この本全体を通して、私たちは実際の違いを利用していません。ほとんどの場合、これは問題ありません。 printk()は、単にカーネルのフォーマットされた印刷関数の名前です。ただし、いくつかの違いがあります。

Printk()の堅牢性

すぐに当然のことと思われるprintk()の1つの特性は、その堅牢性です。 printk()関数は、カーネル内のほぼどこからでもいつでも呼び出すことができます。割り込みまたはプロセスコンテキストから呼び出すことができます。ロックを保持したまま呼び出すことができます。複数のプロセッサで同時に呼び出すことができますが、呼び出し元がロックを保持する必要はありません。

弾力性のある機能です。 printk()の有用性は、常に存在し、常に機能するという事実に基づいているため、これは重要です。

Printk()の非堅牢性

printk()の堅牢性の欠けは存在します。コンソールの初期化前の、カーネルブートプロセスの特定のポイントの前では使用できません。実際、コンソールが初期化されていない場合、出力はどこに行くはずですか?

ブートプロセスの非常に早い段階(たとえば、アーキテクチャ固有の初期化を実行するsetup_Arch())で問題をデバッグしているのでない限り、これは通常問題ではありません。このようなデバッグはそもそも課題であり、印刷方法がないことは問題を悪化させるだけです。

いくつかの希望はありますが、多くはありません。ハードコアアーキテクチャハッカーは、外界と通信するために機能するハードウェア(たとえば、シリアルポート)を使用します。これはほとんどの人にとって楽しいことではないと私を信じてください。サポートされているアーキテクチャの中には、まともなソリューションを実装しているものもあれば、i386を含む他のアーキテクチャも、その日を節約できるパッチを用意しています。

解決策は、ブートプロセスの非常に早い段階でコンソールに出力できるprintk()バリアントです:early_printk()。動作はprintk()と同じですが、名前と以前に機能する機能のみが変更されています。ただし、サポートされているすべてのアーキテクチャにそのようなメソッドが実装されているわけではないため、これは移植可能なソリューションではありません。もしそうなら、それはあなたの親友になるかもしれません。

ブートプロセスの非常に早い段階でコンソールに書き込む必要がない限り、常に機能するようにprintk()を利用できます。

11
slm

OSがまだ起動している場合、printKはどのように機能しますか?

printk()は可能であればコンソールに移動し、優先度は十分に高いです。カーネルがどの時点でVTを初期化してそれを実現可能にするかはわかりませんが、明らかにかなり早い段階です。

[src]/kernel/printk/printk.cはかなりよく文書化されています。コンソールアクセスは、セマフォを介して制御されているようです。優先度に関係なく、メッセージは/dev/dmsgにも挿入されます。

4
goldilocks