ホームページ >システムチュートリアル >Linux >Linux カーネル空間とユーザー空間とは何ですか?
32 ビット オペレーティング システムの場合、そのアドレス空間 (仮想アドレス空間またはリニア アドレス空間とも呼ばれます) のサイズは 4G (つまり、2 の 32 乗) です。これは、プロセスが最大 4G のアドレス空間を持つことができることを意味します。
オペレーティング システムの中核はカーネルです。カーネルは通常のアプリケーションから分離されており、保護されたメモリ空間と基盤となるハードウェア デバイスにアクセスする権限を持っています。カーネルのセキュリティを確保するために、最新のオペレーティング システムでは通常、ユーザー プロセスがカーネルを直接操作することを制限しています。
通常、これは仮想アドレス空間をカーネル空間とユーザー空間の 2 つの部分に分割することによって実現されます。 Linux オペレーティング システムに関する限り、最上位 1G バイト (仮想アドレス 0xC0000000 から 0xFFFFFFFF) がカーネルによって使用され、カーネル空間と呼ばれます。下位 3G バイト (仮想アドレス 0x00000000 から 0xBFFFFFFF まで) は個々のプロセスによって使用され、ユーザー空間と呼ばれます。
つまり、各プロセスの4Gアドレス空間のうち、最上位の1G、つまりカーネル空間は同じです。残りの 3G のみがプロセス自体に使用可能なスペースです。
これは次のように理解できます: 「最高の 1G カーネル空間がすべてのプロセスで共有されます!」 次の図は、各プロセスへの 4G アドレス空間の割り当てを示しています (画像はインターネットから取得したものです)。
CPU のすべての命令の中には、メモリのクリアやクロックの設定など、誤って使用するとシステムのクラッシュを引き起こす非常に危険な命令もあります。すべてのプログラムがこれらの命令の使用を許可されている場合、システムがクラッシュする可能性が大幅に増加します。
つまり、CPU は命令を特権命令と非特権命令に分け、危険な命令についてはオペレーティング システムとその関連モジュールのみが使用を許可され、通常のアプリケーションは災害を引き起こさない命令のみを使用できます。 。
たとえば、Intel の CPU では、特権レベルが Ring0 ~ Ring3 の 4 つのレベルに分かれています。実際、Linux システムでは、Ring0 と Ring3 の 2 つの実行レベルのみが使用されます (Windows システムにも同じことが当てはまります)。
プロセスがリング 3 レベルで実行されている場合、プロセスはユーザー モードで実行されていると言われ、プロセスがリング 0 レベルで実行されている場合、プロセスはカーネル モードで実行されていると言われます。
さて、カーネル モードとユーザー モードとは何かを説明する必要があります。 "プロセスがカーネル空間で実行されているときはカーネル モードであり、プロセスがユーザー空間で実行されているときはカーネル モードです。ユーザーモード。"
カーネル モードでは、プロセスはカーネル アドレス空間で実行され、CPU はこの時点で任意の命令を実行できます。実行コードには制限がなく、有効なアドレスに自由にアクセスしたり、ポートに直接アクセスしたりできます。
ユーザー モードでは、プロセスはユーザー アドレス空間で実行されます。実行されたコードは CPU による多くのチェックの対象になります。アクセスできるのは、アドレス空間をマッピングするページ テーブル エントリで指定されている、ユーザー モードでアクセス可能なページのみです。仮想アドレスであり、タスク ステータス セグメント (TSS) の I/O 許可ビットマップで指定されたアクセス可能なポートにのみ直接アクセスできます。
以前の DOS オペレーティング システムには、カーネル空間、ユーザー空間、カーネル モード、およびユーザー モードの概念がありませんでした。すべてのコードはカーネル モードで実行されると考えられるため、ユーザーが作成したアプリケーション コードはオペレーティング システムを簡単にクラッシュさせる可能性があります。
Linux の場合、カーネル空間とユーザー空間を区別する設計により、オペレーティング システム コード (オペレーティング システム コードはアプリケーション コードよりもはるかに堅牢です) とアプリケーション コードが分離されます。
単一のアプリケーションでエラーが発生した場合でも、オペレーティング システムの安定性には影響しないため、他のプログラムは引き続き正常に実行できます (Linux はマルチタスク システムです!)。
「したがって、カーネル空間とユーザー空間を区別することは、本質的にオペレーティング システムの安定性と可用性を向上させることです。」
其實所有的系統資源管理都是在核心空間中完成的。例如讀寫磁碟文件,分配回收內存,從網路介面讀寫資料等等。
我們的應用程式是無法直接進行這樣的操作的。但是我們可以透過核心提供的介面來完成這樣的任務。
例如應用程式要讀取磁碟上的一個文件,它可以向核心發起一個 「系統呼叫」 告訴核心:」我要讀取磁碟上的某某文件」。
其實就是透過一個特殊的指令讓行程從用戶態進入到核心態(到了核心空間),在核心空間中,CPU 可以執行任何的指令,當然也包含從磁碟上讀取資料。具體過程是先把資料讀取到核心空間中,然後再把資料拷貝到使用者空間並從核心態切換到使用者態。
此時應用程式已經從系統呼叫中返回並且拿到了想要的數據,可以開開心心的往下執行了。簡單說就是應用程式把高科技的事情(從磁碟讀取檔案)外包給了系統內核,系統核心做這些事情既專業又有效率。
對於一個行程來講,從使用者空間進入核心空間並最終回到使用者空間,這個過程是十分複雜的。舉個例子,例如我們經常接觸的概念 “堆疊”,其實進程在內核態和用戶態各有一個堆疊。
運行在使用者空間時進程使用的是使用者空間中的堆疊,而運行在內核空間時,進程使用的是核心空間中的堆疊。所以說,Linux 中每個行程有兩個棧,分別用於用戶態和核心態。
下圖簡明的描述了使用者態與內核態之間的轉換:
既然用戶態的進程必須切換成核心態才能使用系統的資源,那麼我們接下來就看看進程一共有多少種方式可以從用戶態進入到內核態。
概括的說,有三種方式:系統呼叫、軟中斷和硬體中斷
。這三種方式每一種都涉及大量的作業系統知識,所以這裡不做展開。
接下來我們從核心空間和使用者空間的角度來看整個 Linux 系統的結構。它大體可以分為三個部分,從下往上依序為:硬體 -> 核心空間 -> 使用者空間。如下圖所示(此圖來自互聯網):
在硬體之上,核心空間中的程式碼控制了硬體資源的使用權,用戶空間中的程式碼只有透過核心暴露的系統呼叫介面(System Call Interface)才能使用到系統中的硬體資源。其實,不光是 Linux,Windows 作業系統的設計也是大同小異。
實際上我們可以將每個處理器在任何指定時間點上的活動概括為下列三者之一:
以上三點幾乎包含所有的情況,例如當 CPU 空閒時,核心會運行一個空進程,處於進程上下文,但運行在核心空間。
說明:Linux 系統的中斷服務程序不在程序的上下文中執行,它們在一個與所有程序都無關的、專門的中斷上下文中執行。
之所以存在一個專門的執行環境,就是為了確保中斷服務程序能夠在第一時間回應和處理中斷請求,然後快速地退出。
現代的作業系統大都透過核心空間和使用者空間的設計來保護作業系統本身的安全性和穩定性。所以在我們閱讀有關作業系統的資料時經常遇到核心空間、使用者空間和核心態、使用者態等概念,希望本文能幫助您理解這些基本的概念。
以上がLinux カーネル空間とユーザー空間とは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。