2冊の本を3年間卒業した後、なぜTencent T8offerを入手したのですか?-Linuxカーネルインタビューの質問の手配(回答を含む)

1. Linuxにはどのような種類のカーネルロックがありますか?

Linuxの同期メカニズムは継続的に開発され、2.0から2.6に改善されています。最初のアトミック操作から後のセマフォまで、大きなカーネルロックから今日のスピンロックまで。これらの同期メカニズムの開発には、Linuxのシングルプロセッサから対称型マルチプロセッサへの移行、および非プリエンプティブカーネルからプリエンプティブカーネルへの移行が伴います。Linuxのロックメカニズムは、より効果的かつ複雑になっています。

スピンロックは、最大で1つの実行可能スレッドによってのみ保持できます。実行スレッドが、満足されて保持されているスピンロックを要求しようとすると、このスレッドは常にビジーループスピン待機ロックが使用可能になります。再び。ロックが競合していない場合、ロックを要求した実行スレッドはすぐにロックを取得して続行できます。スピンロックは、いつでも複数の実行スレッドがクリティカルセクションに入るのを防ぐことができます。

セマフォのスリープ特性により、セマフォはロックが長時間保持される状況に適しています。割り込みコンテキストではスケジュールできないため、プロセスのコンテキストでのみ使用できます。さらに、コードはセマフォを保持しますが、スピンロックを再度保持することはできません。

Linuxカーネルの同期メカニズム:アトミック操作、セマフォ、読み取り/書き込みセマフォ、スピンロックのAPIその他の同期メカニズムには、大きなカーネルロック、読み取り/書き込みロック、大きなリーダーロック、RCU(名前としてRead-Copy Update)が含まれます。読み取りコピーの変更)、およびシーケンスロックを意味します。

2. Linuxのユーザーモードとカーネルモードの意味は何ですか?

MS-DOSなどのオペレーティングシステムはシングルCPUモードで実行されますが、一部のUnixライクなオペレーティングシステムはデュアルモードを使用しており、タイムシェアリングを効果的に実現できます。Linuxマシンでは、CPUはトラステッドカーネルモードまたは制限付きユーザーモードのいずれかです。カーネルモードのカーネル自体を除いて、すべてのユーザープロセスはユーザーモードで実行されています。

カーネルモードコードは、すべてのプロセッサ命令セットとすべてのメモリおよびI / Oスペースに無制限にアクセスできます。ユーザーモードプロセスがこの特権を享受したい場合は、システムコールを介してデバイスドライバーまたは他のカーネルモードコードに要求を発行する必要があります。さらに、ユーザーモードコードではページフォールトが許可されますが、カーネルモードコードでは許可されません。

以前のカーネルでは、ユーザーモードプロセスのみがコンテキストスイッチアウトされ、他のプロセスによってプリエンプトされました。次の2つの状況が発生しない限り、カーネルモードコードは常にCPUを独占できます。
(1)CPUを自発的に放棄する。
(2)割り込みまたは例外が発生する。
カーネルはカーネルプリエンプションを導入し、ほとんどのカーネルモードコードもプリエンプションできます。

3.カーネルメモリの大きなブロックを申請するにはどうすればよいですか?

Linuxカーネル環境では、システムの実行時間の増加に伴い、メモリの大きなブロックを適用する成功率が低下します。vmallocシリーズの呼び出しを通じて、物理的な不連続性はあるが仮想アドレスが連続しているメモリを適用することは可能ですが、その使用結局のところ、効率は高くありません。ビットシステム上のvmallocのメモリアドレス空間は限られています。したがって、一般的な推奨事項は、システムの起動フェーズ中に大きなメモリブロックを適用することですが、成功の確率は比較的高く、100%ではありません。プログラムがこのアプリケーションの成功を本当に気にかけている場合は、「ブートメモリ」にのみ後退できます。以下は、スタートアップメモリ​​を適用およびエクスポートするためのサンプルコードです。

void* x_bootmem = NULL; EXPORT_SYMBOL(x_bootmem); 
unsigned long x_bootmem_size = 0; EXPORT_SYMBOL(x_bootmem_size); 
static int init x_bootmem_setup(char *str) 
{ 
x_bootmem_size = memparse(str, &str); x_bootmem = alloc_bootmem(x_bootmem_size); 
printk("Reserved %lu bytes from %p for x\n", x_bootmem_size, x_bootmem); return 1; 
} 
  setup("x-bootmem=", x_bootmem_setup); 
 

そのアプリケーションは比較的単純であることがわかりますが、長所と短所は常に共生的であり、必然的に独自の制限があります。
メモリアプリケーションコードはカーネルにのみ接続でき、モジュールでは使用できません。割り当てられたメモリは、ページアロケータとスラブアロケータによって使用およびカウントされません。つまり、将来どこかで解放したとしても、システムの可視メモリの外にあります。
一般ユーザーは、メモリの大きなブロックにのみ申請します。複雑なメモリ管理を実装する必要がある場合は、自分で実装する必要があります。メモリ割り当ての失敗が許可されていない場合は、メモリを起動してメモリスペースを予約することが唯一の選択肢になります。

4.ユーザープロセス間の通信の主な方法は何ですか?

1)パイプ):パイプは、親和性のあるプロセス間の通信に使用でき、プロセスと、プロセスと共通の祖先を持つ別のプロセスとの間の通信を可能にします
。2)名前付きパイプ):名前付きパイプは、名前のないパイプを克服します。パイプが持つ機能は、無関係なプロセス間の通信も可能にします。名前付きパイプには、ファイルシステム内で対応するファイル名があります。名前付きパイプは、コマンドmkfifoまたはシステムコールmkfifoによって作成されます。
3)シグナル):シグナルは、特定のイベントが発生したことを受信プロセスに通知するために使用される、より複雑な通信方法です。プロセス間通信に加えて、プロセスは、
Unixのサポートに加えて、プロセス自体にシグナルを送信することもできます。初期のシグナルセマンティック関数sigalに加えて、セマンティクスがPosix.1標準に準拠するシグナル関数
sigactionもサポートします。実際、この関数はBSDに基づいています。信頼性の高いシグナルメカニズムを実現するために、BSDは外部を統合できます。信号機能をsigaction関数とインターフェースして再実装します)。
4)メッセージキュー:メッセージキューは、Posixメッセージキューシステムを含むメッセージのリンクリストです
。5)メッセージキュー。十分なアクセス許可を持つプロセスはメッセージをキューに追加でき、読み取りアクセス許可を持つプロセスはキュー内のメッセージを読み取ることができます。メッセージキューは信号伝送情報の不足を克服し、パイプラインはフォーマットされていないバイトストリームのみを伝送でき、バッファサイズは制限されます
。6)セマフォ:主にプロセスと同じプロセスの異なるスレッド間の同期手段として使用されます。
7)ソケット):異なるマシン間のプロセス間通信に使用できる、より一般的なプロセス間通信メカニズム。もともとはUnixシステムのBSDブランチによって開発されましたが、現在では一般的に他のUnixライクなシステムに移植できます。LinuxおよびSystemVバリアントはソケットをサポートしています。

5.パートナーシステムを介してカーネルメモリに適用する機能は何ですか?

物理ページ管理では、ゾーンベースのバディシステムが実装されています。別のバディシステムを使用してさまざまな領域のメモリを管理し、空きページを個別に監視します。対応するインターフェースalloc_pages(gfp_mask、order)、_ _get_free_pages(gfp_mask、
order)など。補足知識:
1。原理の説明

  • ページグローバルディレクトリ
  • ページミドルディレクトリ(ページミドルディレクトリ)
    ページグローバルディレクトリには、いくつかのページ上位ディレクトリのアドレスが含まれ、次に、いくつかのページミドルディレクトリのアドレスが含まれ、ページミドルディレクトリには、いくつかのページテーブルのアドレスが含まれます。ページテーブルエントリは、ページフレームを指します。
    Linuxは、4KBのページフレームを標準のメモリアロケーションユニットとして使用します。

5.1。
バディシステムアルゴリズムこの状況を回避するために、バディシステムアルゴリズム(バディシステム)がLinuxカーネルに導入されています。すべての空きページフレームを11個のブロックリンクリストにグループ化します。各ブロックリンクリストには、サイズが1、2、4、8、16、32、64、128、256、512、および1024の連続するページフレームのページフレームブロックが含まれます。4MBの連続メモリに対応する最大1024の連続ページフレームを申請できます。各ページフレームブロックの最初のページフレームの物理アドレスは、ブロックサイズの整数倍です。
ページフレームブロックが解放されると、2つの連続するページフレームブロックが1つの大きなページフレームブロックにアクティブにマージされます。
スラブアロケータは、Solaris 2.4の割り当てアルゴリズムから派生しています。これは、物理メモリのページフレームアロケータで機能して、特定のサイズのオブジェクトのキャッシュを管理し、高速で効率的なメモリ割り当てを実行します。

5.2。共通メモリ割り当て関数
unsignedlong get_free_pages(gfp_t gfp_mask、unsigned int order)
get_free_pages関数は、パートナーシステムから元のページフレームを直接取得する最も基本的なメモリ割り当て方法であり、戻り値はの開始アドレスです。最初のページフレーム。get_free_pagesは、実装時にalloc_pages関数のみをカプセル化します。コード分析から、alloc_pages関数は1 <struct kmem_cache * kmem_cache_create(const char * name、size_t size void(ctor)(void、struct kmem_cache *、unsigned long)、
void * kmem_cache_alloc(struct kmem_cache * c、gfp_t flags)kmem_cache_create / kmem_cache_allocは、スラブアロケータに基づくメモリ割り当て方法です。同じサイズのメモリブロックを繰り返し割り当てて解放するのに適しています。まず、kmem_cache_createを使用してキャッシュ領域を作成します。 、次にkmem_cache_allocを使用します。キャッシュ領域から新しいメモリブロックを取得します
。kmem_cache_allocが一度に割り当てることができる最大メモリは、mm / slab.cファイルのMAX_OBJ_ORDERマクロによって定義されます。デフォルトの2.6.18カーネルバージョンでは、これはマクロは5として定義されているので、一度

最大1 << 5 * 4KB、つまり128KBの連続物理メモリを申請できます。カーネルのソースコードを分析する
と、kmem_cache_create関数のサイズパラメータが128KBより大きい場合、BUG()が呼び出されることがわかりましたテスト結果は分析結果を検証し、kmem_cache_createを使用して128KBを超えるメモリを割り当てると、カーネルがクラッシュします。void * kmalloc(size_t size、gfp_t flags)

5.3。vmallocの
以前のメモリ割り当て方法は物理的に連続しているため、平均アクセス時間を短くすることができます。ただし、場合によっては、メモリ領域の要求があまり頻繁ではなく、より長いメモリアクセス時間が許容されることがあります。これは、線形に連続した物理的に不連続なアドレスを割り当てることです。利点は、一度に割り当てることができることです。メモリの大きなチャンク。図3-1は、vmallocによって割り当てられたメモリによって使用されるアドレス範囲を示しています。vmallocには、一度に割り当てることができるメモリのサイズに明確な制限はありません。パフォーマンス上の理由から、vmalloc関数の使用には注意が必要です。テスト中、一度に最大1GBのスペースを割り当てることができます。

5.4.dma_alloc_coherent
ma_addr_t * dma_handle、gfp_t gfp)

5.5。
ioremap ioremapより直接的なメモリ「割り当て」方法である。使用する場合は、直接物理的開始アドレスと割り当てられるメモリのサイズを指定し、カーネルアドレス空間に物理アドレスをマッピングします。ioremapが使用する物理アドレス空間は事前に決定されており、上記のいくつかのメモリ割り当て方法と同じではなく、新しい物理メモリ割り当てではありません。Ioremapは主にデバイスドライバーに使用され、CPUが外部デバイスのIOスペースに直接アクセスできるようにします。ioremapがマップできるメモリは、元の物理メモリスペースによって決定されるため、テストはありません。
連続した大量の物理メモリを割り当てる場合、上記の割り当て機能のいずれも満たすことができないため、Linuxカーネルのブートフェーズ中にメモリの一部を予約するための特別な方法しか使用できません。
void * alloc_bootmem(unsigned long size)

5.6カーネルブートパラメータを介してトップメモリ​​を予約する

3.いくつかの割り当て関数の比較
get_free_pagesはページフレームで直接動作します4MB大量の連続物理メモリの割り当てに適しています
kmallocはkmem_cache_allocに基づいて128KBを達成します最も一般的な割り当て方法は、メモリが必要なときにalloc_pagesに基づいて達成するためにdma_alloc_coherentを使用できますページフレームサイズよりも小さい4MBはDMA操作に適していますalloc_bootmemカーネルを起動すると、カーネルからは見えず、高度なメモリ管理が必要な物理メモリサイズよりも小さいメモリのセクションが予約されます。

6. Linux仮想ファイルシステムの主要なデータ構造は何ですか?(少なくとも4つ書く)

struct super_block、struct inode、struct file、struct dentry;

7.ファイルまたはデバイスの操作機能はどのデータ構造に格納されていますか?

struct file_operations

8. Linuxのファイルは何ですか?

実行ファイル、通常ファイル、カタログファイル、リンクファイルとデバイスファイル、パイプラインファイル。

9.プロセスを作成するためのシステムコールは何ですか?

clone()、fork()、vfork();システムコールサービスルーチン:sys_clone、sys_fork、sys_vfork;

10.プロセス切り替えのためにschedule()を呼び出す方法はいくつかありますか?

1.システムコールdo_fork();
2.タイミング割り込みdo_timer();
3.プロセスをウェイクアップしますwake_up_process
4.プロセスsetscheduler();のスケジューリング戦略を変更します。5
。システムコール丁寧なsys_sched_yield();

11. Linuxスケジューラーは、動的優先度または静的優先度に従ってプロセスをスケジュールしますか?

Liunxスケジューラーは、プロセスの動的優先度に従ってプロセスをスケジュールしますが、動的優先度は静的優先度に従ってアルゴリズムに従って計算され、2つは2つの関連する値です。優先度の高いプロセスは常に優先度の低いプロセスの前にスケジュールされるため、優先度の高い複数のプロセスがCPUリソースを占有し、他のプロセスがCPUを占有しないようにするために、動的優先度の概念が引用されています。

12.プロセススケジューリングのコアデータ構造は何ですか?

struct runqueue、struct task_struct、struct sched_struct

13.モジュールをロードおよびアンロードする方法は?

insmodロード、rmmodアンロード

14.モジュールとアプリケーションはそれぞれどのスペースで実行されていますか?

モジュールはカーネル空間で実行され、アプリケーションはユーザー空間で実行されます

15. Linuxの浮動小数点演算は、アプリケーションまたはカーネルによって実装されていますか?

アプリケーションプログラムの実装Linuxの浮動小数点演算は、数学ライブラリ関数を使用して実装されます。ライブラリ関数は、アプリケーションがリンクされた後に呼び出すことができますが、カーネルリンクから呼び出すことはできません。これらの計算はアプリケーションで実行され、結果はシステムにフィードバックされます。Linuxカーネルが浮動小数点演算を実行する必要がある場合は、カーネルを構築するときにmath-emuを選択し、ソフトウェアを使用して浮動小数点演算をシミュレートする必要があります。これには2つのコストがあると言われています。ユーザーは次の場合にカーネルを再構築する必要があります。影響を与える可能性のあるドライバーのインストール他のアプリケーションでは、これらのアプリケーションは浮動小数点演算を実行するときにmath-emuも使用するため、効率が大幅に低下します。

16.モジュールプログラムはリンク可能なライブラリ関数を使用できますか?

モジュールプログラムはカーネル空間で実行され、ライブラリ関数をリンクできません。

17. TLBには何がキャッシュされていますか?

TLB、ページテーブルキャッシュ、線形アドレスが初めて物理アドレスに変換されるとき、線形アドレスと物理アドレスの間の対応はTLBに配置されます。これは、線形アドレスが次の場合に変換を高速化するために使用されます。次回アクセス。

18. Linuxにはどのような種類のデバイスがありますか?

キャラクターデバイスとブロックデバイス。例外は、デバイスファイルに直接対応していないネットワークカードです。mknodシステムコールは、デバイスファイルの作成に使用されます。

19.キャラクターデバイスドライバーの主要なデータ構造は何ですか?

文字デバイス記述子structcdev、cdev_alloc()はcdev記述子を動的に割り当てるために使用され、
cdev_add()はcdev記述子を登録するために使用され、cdevにはstructkobjectタイプが含まれます

データ構造コアデータ構造です

20.デバイスドライバーにはどのような機能が含まれていますか?

open()、read()、write()、llseek()、realse();

21.デバイスを一意に識別する方法は?

Linuxは、デバイス番号を使用してデバイスを一意に識別します。デバイス番号は、メジャーデバイス番号とマイナーデバイス番号に分けられます。通常、メジャーデバイス番号はデバイスに対応するドライバーを示し、マイナーデバイス番号は指定されたデバイスに対応します。カーネルで使用されるデバイスファイルによって、dev_tはデバイス番号を表します。通常、長さは32ビットで、そのうち12ビットはメジャーデバイス番号を表し、20ビットはマイナーデバイスを表します。数値、MKDEV(int major、int minor)を使用して、dev_tタイプのオブジェクトを生成するために使用されます。

22. Linuxはどのようにシステムコールを実装しますか?

これはソフトウェア割り込みによって実現されます。最初に、ユーザープログラムがシステムコールのパラメータを設定します。番号の1つはシステムコール番号です。パラメータ設定が完了すると、プログラムはシステムコール命令を実行します。x86のソフト割り込みはintによって生成されます。この命令により、例外が発生します。これにより、プロセッサはカーネルモードにジャンプし、新しいアドレスにジャンプします。そしてそこで例外ハンドラーの処理を開始します。この時点での例外ハンドラーはシステムコールプログラムです。

23. Linuxソフト割り込みとワークキューの機能は何ですか?

Linuxのソフト割り込みとワークキューは割り込み処理です。

1.ソフト割り込みは、一般に「遅延機能」の総称です。スリープまたはブロックすることはできません。割り込みコンテキストにあり、都市に切り替えることはできません。ソフト割り込みは、それ自体で中断することはできませんが、中断することしかできません。ハードウェア割り込み(上半分)によって)、複数のCPUで同時に実行できます。したがって、ソフト割り込みはリエントラント関数として設計する必要があるため、データ構造を保護するためにスピンロックも必要です。
2.ワークキュー内の機能はプロセスコンテキストにあります。スリープまたはブロックすることができ、異なるプロセスを切り替えることができます。さまざまなタスクが完了しました。

延期可能な関数もワークキューもユーザーのプロセススペースにアクセスできません。延期可能な関数は実行中に実行中のプロセスを持つことができません。ワークキューの関数はカーネルプロセスによって実行され、ユーザースペースのアドレスにアクセスできません。

最近、一連のインタビューを要約します。興味のある友達は小さな波に注意を払うことができます。感謝!
テクノロジー、面接、就職活動に興味のある友達は、私の技術交流グループに参加できます。このグループは後で有料グループにアップグレードされ、全員が一緒にテクノロジーを交換します〜(202432010)事前に参加してください(グループは私が編集したいくつかの面接の質問、電子書籍、技術的なビデオチュートリアルなど、それらを拾うことを歓迎します)
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_28581269/article/details/113058228