実行可能ファイルを実行するにはOSカーネルが必要ですか?


53

C ++などのソースコードがコンパイルされると、コンパイラからの出力はCPUへの直接の命令だと思ったマシンコード(実行可能ファイル)になることを知っています。最近、カーネルについて調べていたところ、プログラムはハードウェアに直接アクセスできず、カーネルを経由する必要があることがわかりました。

したがって、たとえばprintf()関数だけでいくつかの単純なソースコードをコンパイルし、コンパイルによって実行可能なマシンコードが生成されると、このマシンコードの各命令はメモリから直接実行されます(コードがOSによってメモリにロードされると)マシンコードの各コマンドは、OS(カーネル)を通過して実行する必要がありますか?

私は同様の質問を読みまし。コンパイル後に生成されるマシンコードがCPUへの直接の命令であるか、CPUの正しい命令を作成するためにカーネルを再度通過する必要があるかについては説明しませんでした。すなわち、マシンコードがメモリにロードされた後はどうなりますか?カーネルを経由するか、プロセッサと直接通信しますか?


29
Arduino用のコードを書いている場合、OSは必要ありません。
-stib

12
printf良い例ではありません。C仕様では、「ホスト型」実装でのみ使用可能な関数として明示的に定義されています(「自立型」ではなく、カーネル上で実行されることを意味します)。また、ほとんどのプラットフォームでprintfは、ユーザーlibcが提供する単なる機能であり、ユーザーに代わって一連の処理を行います(最終的には、stdoutに出力するsyscallが含まれます)。一部の実装は、追加の非標準s を追加せずにリンク可能であることが保証されていることを除き、libvlc_media_list_add_mediaorの呼び出しと実際には違いはありません。PyObject_GetAttrprintf-l
アバーナート

1
これは存在します!(提携していない、ちょうどそれがクールだと思った)erikyyy.de/invaders
Nonnyムース

9
これは、「実行可能」、「カーネル」、「実行」、「必要」、「会話」、および「通過」という用語の正確な定義に依存します。これらの用語の正確な定義がなければ、質問には答えられません。
ヨルグWミットタグ

3
@JörgWMittag-舌になりたいのなら、なぜこれらの用語だけを調べて、この質問だけを調べるのですか?定義が必要な真に顕著な用語は「オペレーティングシステム」であり、MS-DOS(および同様のシングルタスクランタイム環境)に疑いなく適用されます。PC BIOSがOSであると考える少数の(誤った情報を持っている)人がいる場合、すべてを手に入れることができますか?私はそうは思いません。OPは、これらの単語を、合理的(特に英語を母国語としない人)または技術的でないと思われる文脈で使用します。
おがくず

回答:


86

OSなしで実行するプログラムを書いた人として、私は決定的な答えを提供します。

実行可能ファイルを実行するにはOSカーネルが必要ですか?

それは、そのプログラムがどのように作成され構築されたかに依存します。
OSをまったく必要としない(知識があると仮定して)プログラムを作成できます。
このようなプログラムは、スタンドアロンとして記述されています。
ブートローダーと診断プログラムは、スタンドアロンプ​​ログラムの一般的な用途です。

ただし、ホストOS環境で作成およびビルドされた典型的なプログラムは、デフォルトで同じホストOS環境で実行されます。
スタンドアロンプ​​ログラムを作成およびビルドするには、非常に明確な決定とアクションが必要です。


...コンパイラからの出力は、CPUへの直接の命令だと思ったマシンコード(実行可能ファイル)です。

正しい。

最近、カーネルについて調べていたところ、プログラムはハードウェアに直接アクセスできず、カーネルを経由する必要があることがわかりました。

これは、OSがプログラムを実行するために使用するCPUモードによって課される制限であり、コンパイラーやライブラリーなどの特定のビルドツールによって促進されます。
これは、これまでに作成されたすべてのプログラムに固有の制限ではありません。


したがって、たとえばprintf()関数を使用して単純なソースコードをコンパイルし、コンパイルによって実行可能なマシンコードが生成されると、このマシンコードの各命令はメモリから直接実行されます(コードがOSによってメモリにロードされると) )またはマシンコードの各コマンドを実行するには、OS(カーネル)を通過する必要がありますか?

すべての命令はCPUによって実行されます。
サポートされていない、または違法な命令(たとえば、プロセスに十分な特権がない)は、即時例外を引き起こし、代わりにCPUはこの異常な状態を処理するルーチンを実行します。

printf()関数は、一例として使用されるべきではない「シンプルソースコード」
オブジェクト指向の高レベルプログラミング言語からマシンコードへの翻訳は、あなたが暗示するほど簡単ではないかもしれません。
そして、データ変換 I / O を実行するランタイムライブラリから最も複雑な関数の1つを選択します。

質問では、OS(およびランタイムライブラリ)を使用した環境が規定されていることに注意してください。
システムが起動され、OSがコンピューターの制御権を与えられると、プログラムが実行できることに対して制限が課せられます(たとえば、OSがI / Oを実行する必要があります)。
スタンドアロンプ​​ログラム(OSなし)を実行する場合は、OSを実行するためにコンピューターを起動しないでください。


...マシンコードがメモリにロードされた後はどうなりますか?

それは環境に依存します。

スタンドアロンプ​​ログラムの場合、実行できます。つまり、プログラムの開始アドレスにジャンプすることで制御が渡されます。

OSによってロードされたプログラムの場合、プログラムは依存している共有ライブラリと動的にリンクする必要があります。OSは、プログラムを実行するプロセスの実行スペースを作成する必要があります。

カーネルを経由するか、プロセッサと直接通信しますか?

マシンコードはCPUによって実行されます。
それらは「カーネルを通過する」のではなく、「プロセッサと通信する」のでもありません。
マシンコード(オペコードとオペランドで構成される)は、デコードされて操作が実行されるCPUへの命令です。

おそらく、調査すべき次のトピックはCPUモードです。


2
「スタンドアロンプ​​ログラム(OSなし)を実行する場合は、OSを実行するためにコンピューターを起動しないでください。」完全に正しいわけではありません。多くのDOSプログラムはDOSの後にロードされ、DOSサービスを完全に無視しました(直接ビットバンギングするか、BIOSを直接呼び出すことにより)。Win3.xは、DOSが存在することを無視した優れた例です(いくつかの興味深いコーナーケースを除く)。Win95 / 98 / Meもこれを行いました。スタンドアロンプ​​ログラムをサポートするOSの例は数多くあり、その多くは8/16ビット時代のものです。
エリックタワーズ

8
@EricTowers- 「DOS」とは、おそらくMS-DOSを意味します(MSやIntelに関係のないDOSを使用したため)。あなたは、OSの概念と設計に関する1970年代の大学の教科書の基準とさえ一致しない「OS」を引用しています。MS-DOSの起源は、(シアトルのコンピューター製品を通じて)CP / Mにまでさかのぼります。CP/ Mは、作者のGary KildallによってOSとは明示的に呼ばれていません。FWIWプログラムがシステムを引き継ぐことを許可するOSが、システムリソースを管理するという基本的な機能に失敗しました。 「スタンドアロンプ​​ログラムをサポートするOSの例はたくさんあります」 - 「サポート」または防止できない?
おがくず

5
...またはProDOSまたはPC-DOSまたはDR-DOSまたはCBM DOSまたはTRS DOSまたはFLEX ...
Eric Towers

3
GCCの「独立した」用語が好きです。英語の単語には、OSなしで実行されるコードの意味がすべて含まれており、「スタンドアロン」よりも優れている可能性があります。たとえばgcc -O2 -ffreestanding my_kernel.c special_sauce.S、通常のライブラリまたはOSのものが存在しないと想定しない実行可能ファイルを作成するためにコンパイルできます。(もちろん、ブートローダーがロードするファイル形式に便利にリンクするには、通常リンカースクリプトが必要です!)
Peter Cordes

4
@PeterCordes "standalone"はC標準で使用される用語で、IMOはやや信頼できると見なされます。(OSによってホストされているように)また良い用語はまた、「非ホスト型」である
ヤンDorniak

38

カーネルは「単なる」コードです。そのコードは、システムの最下部と実際のハードウェアの間に存在するレイヤーであるというだけです。

それはすべてCPU上で直接実行され、何でもできるようにそのレイヤーを介して移行します。

プログラムprintfは、最初にコマンドを使用するために標準Cライブラリを必要とするのと同じ方法でカーネルを「必要」にします。

プログラムの実際のコードはCPUで実行されますが、画面上に何かを印刷するためにコードが作成する分岐は、C printf関数のコード、さまざまな他のシステムおよびインタープリターを経由し、それぞれが独自の処理を実行して hello world!実際に画面に印刷されます。

デスクトップウィンドウマネージャーで実行されているターミナルプログラムがあり、カーネルで実行されており、さらにカーネルがハードウェアで実行されているとします。

さらに多くの機能がありますが、シンプルに保ちましょう...

  1. 端末プログラムで、プログラムを実行して印刷します hello world!
  2. 端末は、プログラムが(C出力ルーチンを介して)hello world!コンソールに書き込んだことを確認します。
  3. ターミナルプログラムは、デスクトップウィンドウマネージャーに移動し、「私にhello world!書かれました。お願いしますxyお願いします」
  4. デスクトップウィンドウマネージャーは、「私のプログラムの1つが、グラフィックデバイスにこの位置にテキストを配置して欲しいと思っています!」
  5. カーネルは要求をグラフィックスデバイスドライバーに渡し、グラフィックスカードが理解できるようにフォーマットします
  6. グラフィックカードの接続方法に応じて、他のカーネルデバイスドライバーを呼び出して、PCIeなどの物理デバイスバスにデータをプッシュする必要があります。正しいデバイスが選択されていることを確認し、データが関連するブリッジまたはコンバーター
  7. ハードウェアはものを表示します。

これは、説明のみを目的とした大規模な単純化です。ここにドラゴンがいます。

あなたはそれがハードウェアへのアクセスを必要としません効果的にすべてが、それはファイルまたはそのような何かのビット、メモリのブロックを表示することがあり、正確に動作するようにカーネルにいくつかのデバイスドライバを経由する方法、関連するデバイスに話をします。PCIeブリッ​​ジデバイスの上にあるSATAハードディスクコントローラードライバーの上にあるファイルシステムドライバーになります。

カーネルは、これらすべてのデバイスを結び付ける方法を知っており、これらすべてのことを自分で行う方法を知らなくても、プログラムが物事を行うための比較的単純なインターフェースを提供します。

デスクトップウィンドウマネージャーは、ウィンドウを描画する方法をプログラムが同時に知る必要がないことを意味するレイヤーを提供します。

最後に、ターミナルプログラムは、プログラムがウィンドウを描画する方法、カーネルグラフィックスカードドライバーと通信する方法、スクリーンバッファーと表示タイミングを処理するための複雑さのすべてを知る必要がないことを意味します。ディスプレイへのデータ行。

それはすべて、コードのレイヤー上のレイヤーによって処理されます。


ハードウェアアクセスだけでなくプログラム間のほとんどの通信もカーネルを経由します。通常、少なくともカーネルに関与しないものは、より直接的なチャネルを設定しています。ただし、質問の目的上、すべてのコードを単一のプログラムに凝縮することも可能であり、はるかに簡単な場合に実践されます。
クリスストラットン

実際、端末プログラムは、そこにデータを書き込んでいるプログラムと同じマシン上で実行する必要さえありません。
jamesqf

この質問で明示的に述べる必要があるかもしれないので-お互いに「話している」プログラムについて話すとき、それは比phor的であることに注意してください。
user253751

21

環境に依存します。IBM 1401などの多くの古い(そしてより単純な!)コンピューターでは、答えは「いいえ」です。コンパイラとリンカーは、オペレーティングシステムなしで実行されるスタンドアロンの「バイナリ」を出力しました。プログラムの実行が停止したときに、別のプログラムをロードしましたが、これもOSなしで実行されました。

一度に1つのプログラムだけを実行するわけではないため、現代の環境ではオペレーティングシステムが必要です。CPUコア、RAM、大容量記憶装置、キーボード、マウス、ディスプレイを複数のプログラムで一度に共有するには、調整が必要です。OSはそれを提供します。そのため、現代の環境では、プログラムはディスクまたはSSDの読み取りと書き込みを行うだけではなく、OSに代わってOSに要求する必要があります。OSは、ストレージデバイスにアクセスするすべてのプログラムからこのような要求を取得し、アクセス制御(一般ユーザーがOSのファイルに書き込むことを許可しない)などを実装し、デバイスのキューに入れて、返された情報を整理します。正しいプログラム(プロセス)へ。

さらに、最新のコンピューター(たとえば、1401とは異なります)は、IBMが昔販売していたものだけでなく、非常に多様なI / Oデバイスの接続をサポートします。コンパイラとリンカは、すべての可能性を知ることはできません。たとえば、キーボードはPS / 2またはUSBを介して接続されます。OSを使用すると、デバイス固有の「デバイスドライバー」をインストールできます。デバイス固有の「デバイスドライバー」は、それらのデバイスと通信する方法を知っていますが、デバイスクラスの共通インターフェースをOSに提示します。そのため、プログラム、さらにはOSでも、USBとPS / 2キーボードからキーストロークを取得したり、ローカルのSATAディスクとUSBストレージデバイスとストレージのいずれかにアクセスするために、別のことをする必要はありません。 NASまたはSAN上。これらの詳細は、さまざまなデバイスコントローラーのデバイスドライバーによって処理されます。

大容量記憶装置の場合、OSはそれらのすべての上に、ストレージがどこでどのように実装されているかに関係なく、ディレクトリとファイルに同じインターフェイスを提供するファイルシステムドライバーを提供します。また、OSはアクセス制御とシリアル化を心配しています。一般に、たとえば、いくつかのフープをジャンプせずに、一度に複数のプログラムで同じファイルを開いて書き込みを行うことはできません(ただし、通常、同時読み取りは問題ありません)。

そう、現代の汎用環境では、はい-あなたは本当にOSが必要です。しかし、今日でも、リアルタイムコントローラーなど、必要なほど複雑ではないコンピューターがあります。

たとえば、Arduino環境では、実際にはOSはありません。確かに、ビルド環境がビルドするすべての「バイナリ」に組み込むライブラリコードがたくさんあります。しかし、あるプログラムから次のプログラムへのコードの永続性はないため、OSではありません。


10

多くの答えが質問を誤解していると思います。

コンパイラはマシンコードを出力します。このマシンコードはCPUによって直接実行されますか、それともカーネルによって「解釈」されますか?

基本的に、CPUはマシンコードを直接実行します。カーネルにすべてのアプリケーションを実行させると、かなり遅くなります。ただし、いくつかの注意事項があります。

  1. OSが存在する場合、アプリケーションプログラムは通常、特定の命令の実行や特定のリソースへのアクセスを制限されます。たとえば、アプリケーションがシステム割り込みテーブルを変更する命令を実行すると、CPUは代わりにOS例外ハンドラーにジャンプして、問題のあるアプリケーションを終了します。また、アプリケーションは通常、デバイスメモリの読み取り/書き込みを許可されていません。(つまり、「ハードウェアと通信する」。)これらの特別なメモリ領域にアクセスすることは、OSがグラフィックスカード、ネットワークインターフェイス、システムクロックなどのデバイスと通信する方法です。

  2. OSがアプリケーションに課す制限は、特権モード、メモリ保護、割り込みなどのCPUの特別な機能によって実現されます。スマートフォンやPCにあるCPUにはこれらの機能がありますが、特定のCPUにはありません。これらのCPUには、必要な機能を実現するためにアプリケーションコードを「解釈」する特別なカーネルが実際に必要です。非常に興味深い例はGigatronです。これは、34命令のコンピューターをエミュレートするチップから構築できる8命令のコンピューターです。

  3. Javaのような一部の言語は、バイトコードと呼ばれるものに「コンパイル」されますが、これは実際にはマシンコードではありません。過去にはプログラムを実行するように解釈されていましたが、最近ではジャストインタイムコンパイルと呼ばれるものが通常使用されるため、最終的にはマシンコードとしてCPUで直接実行されます。

  4. Hypervisorと呼ばれるプログラムによってマシンコードを「解釈」する必要がある仮想マシンでソフトウェアを実行する。VMに対する業界の膨大な需要により、CPUメーカーはCPUにVTxなどの機能を追加して、ゲストシステムのほとんどの命令をCPUで直接実行できるようにしました。ただし、仮想マシンで互換性のない CPU 用に設計されたソフトウェアを実行する場合(たとえば、NESをエミュレートする場合)、マシンコードを解釈する必要があります。


1
通常、Javaのバイトコードはマシンコードではありませんが、Javaプロセッサはまだ存在しています
ルスラン

ハイパーバイザーは常にインタープリターではありませんでした。もちろん、ホストと互換性のない命令セットとして仮想マシンを使用する場合、解釈が必要ですが、同じアーキテクチャの実行では、初期のハイパーバイザーでさえCPUでコードを直接実行します(準仮想化カーネルの必要性、必要なハイパーバイザーのサポート)。
トビースパイト

5

コードをコンパイルすると、(ほとんどの場合)システムライブラリ(printfたとえば)に依存するいわゆる「オブジェクト」コードを作成し、特定のオペレーティングシステムが実行できるプログラムローダーの種類を追加するリンカーによってコードがラップされます。 (たとえばLinuxでWindows用にコンパイルされたプログラムを実行できない理由)を認識し、コードをアンラップして実行する方法を理解します。したがって、あなたのプログラムはサンドイッチの中の肉であり、全体としてバンドルとしてのみ食べることができます。

最近、カーネルについて調べていたところ、プログラムはハードウェアに直接アクセスできず、カーネルを経由する必要があることがわかりました。

まあそれは中途半端です。プログラムがカーネルモードドライバーである場合、ハードウェアと「対話」する方法を知っていれば実際に直接ハードウェアにアクセスできますが、通常(特に文書化されていない複雑なハードウェアの場合)カーネルライブラリーのドライバーを使用します。これにより、アドレス、レジスタ、タイミング、その他のことを知る必要なく、ほとんど人間が読める方法でハードウェアと通信する方法を知っているAPI関数を見つけることができます。

このマシンコードの各命令はメモリから直接実行されます(コードがOSによってメモリにロードされると)、またはマシンコードの各コマンドは実行されるOS(カーネル)を通過する必要があります

まあ、カーネルはウェイトレスのようなもので、その責任はあなたをテーブルに連れて行き、あなたに奉仕することです。それができない唯一のこと-それはあなたのために食べることです、あなたはそれを自分でやるべきです。コードと同じように、カーネルはプログラムをメモリにアンパックし、CPUによって直接実行されるマシンコードであるコードを開始します。カーネルはあなたを監視する必要があります。許可されていることと許可されていないことです。

コンパイル後に生成されるマシンコードが直接CPUへの命令であるか、またはCPUの正しい命令を作成するためにカーネルを再度通過する必要があるかどうかは説明されていませんか?

コンパイル後に生成されるマシンコードは、CPUへの直接の命令です。それについては間違いありません。覚えておく必要があるのは、コンパイルされたファイルのすべてのコードが実際のマシン/ CPUコードであるとは限らないことだけです。リンカーは、カーネルのみが解釈できるメタデータでプログラムをラップし、手がかりとして-プログラムをどうするか

マシンコードがメモリにロードされた後はどうなりますか?カーネルを経由するか、プロセッサと直接通信しますか。

コードが2つのレジスタの追加のような単純なオペコードである場合、カーネルの支援なしでCPUによって直接実行されますが、ライブラリの関数を使用するコードの場合、そのような呼び出しは、ウェイトレスの場合のように、カーネルによって支援されますレストランで食事をするために、彼らはあなたに道具を与えます-フォーク、スプーン(そしてそれでも彼らの資産)、しかしあなたはそれで何をしますか-それはあなたの「コード」次第です。

まあ、コメントで炎を防ぐために-OPが基本的な事柄を理解するのを助けることは本当に単純化されたモデルですが、この答えを改善するための良い提案は大歓迎です。


3

したがって、たとえばprintf()関数のみを使用して単純なソースコードをコンパイルし、コンパイルによって実行可能なマシンコードが生成されると、このマシンコードの各命令はメモリから直接実行されます(コードがメモリにロードされると) OSによる)またはマシンコード内の各コマンドは、OS(カーネル)を経由して実行する必要がありますか?

基本的に、システムコールのみがカーネルに送られます。I / Oまたはメモリの割り当て/割り当て解除に関係することは通常、最終的にはシステムコールになります。一部のinstructiosnはカーネルモードでのみ実行でき、CPUが例外をトリガーします。例外により、カーネルモードに切り替えられ、カーネルコードにジャンプします。

カーネルは、プログラム内のすべての命令を処理するわけではありません。システムコールを実行し、実行中のプログラムを切り替えてCPUを共有するだけです。

ユーザーモード(カーネルなし)でメモリ割り当てを行うことはできません。アクセスする権限のないメモリにアクセスすると、カーネルによって以前にプログラムされたMMUがCPUレベルの「セグメンテーションフォールト」例外を通知して引き起こします。 、カーネルをトリガーし、カーネルはプログラムを強制終了します。

ユーザーモード(カーネルなし)でI / Oを実行することはできません。デバイスのI / Oポートまたはレジスタ、またはデバイスに接続されたアドレス(I / Oの実行に必要な1つまたは両方)にアクセスすると、同じように例外。


実行可能ファイルを実行するにはOSカーネルが必要ですか?

実行可能ファイルのタイプに依存します。

カーネルは、RAMおよびハードウェアへの共有アクセスを仲介することに加えて、ローダー機能も実行します。

ELFやPEなどの多くの「実行可能形式」には、コードに加えて実行可能ファイルにメタデータがあり、それを処理するローダーのジョブがあります。詳細については、MicrosoftのPE形式についての詳細を読んでください。

これらの実行可能ファイルは、ライブラリ(Windows .dllまたはLinux共有オブジェクト.soファイル)も参照します-そのコードを含める必要があります。

コンパイラがオペレーティングシステムローダーによって処理されることを意図したファイルを生成し、そのローダーがそこにない場合、それは動作しません。

  • ローダーの仕事をするコードを含めることができますか?

承知しました。何らかの方法でメタデータを処理せずに生のコードを実行するようにOSを説得する必要があります。コードがカーネルAPIを呼び出す場合、まだ機能しません。

  • カーネルAPIを呼び出さないとどうなりますか?

この実行可能ファイルを何らかの方法でオペレーティングシステムから読み込む場合(つまり、生のコードを読み込んで実行できる場合)、ユーザーモードのままになります。割り当てられていないメモリやI / Oデバイスのアドレス/レジスタなど、カーネルモードではなくユーザーモードで禁止されているものにコードがアクセスすると、特権またはセグメント違反でクラッシュします(ここでも、例外はカーネルモードに移行して処理されます)そこに)、それでも動作しません。

  • カーネルモードから実行するとどうなりますか。

その後、動作します。



これは完全に正しいわけではありません。ハードウェアへのアクセスは、カーネルを通過することを要件は、あるいは存在していること、カーネル、今日の多くのシステムに肯定的に作られた設計上の決定ですが、また、多くの単純なシステム上で(でもこの日に)否定的に作られました。
クリスストラットン

A)カーネルがあり、B)それを強制するためにユーザー/スーパーバイザーモードとMMUを備えたCPUでコードを実行している場合の状況を説明しています。はい、MMUまたはユーザー/スーパーバイザーモードのないCPUとマイクロコントローラーがあり、一部のシステムはユーザー/スーパーバイザーインフラストラクチャ全体を使用せずに実行されます。Microsoftの最初のXboxはこのようなものでした-ユーザー/スーパーバイザーモードを備えた標準のx86 CPUでありながら、カーネルモードを離れることはないと理解していますが、読み込まれたゲームは何でもできます。
ローレンス

1
MacOS X以前のMacintoshシステムは、メモリ保護を使用しなかった数十年にわたるメモリ保護をサポートする汎用CPU(68000ファミリ、PowerPC)で動作する汎用コンピュータのOSでした。:任意のプログラムがメモリ内のすべてにアクセスできます。
curiousguy

3

TL; DR No.

Arduino開発は、OSがない現在の環境として頭に浮かびます。これらの赤ちゃんの 1人には、オペレーティングシステム用のスペースがありません。

同様に、Sega Genesisのゲームには、セガが提供するOSがありませんでした。68Kアセンブラーでゲームを作成し、ベアメタルに直接書き込みました。

または、Intel 8051で組み込み作業を行って歯を切ったところです。再び、2k * 8のフットプリントを持つ2716 epromがあれば、オペレーティングシステムのためのスペースがありません。

もちろん、これはアプリケーションという言葉の非常に広い用法を想定しています。修辞的な質問として、Arduinoスケッチが実際にアプリケーションであるかどうかを自問する価値があります。


3

他の答えがそれ自体では正しくないことを暗示したくはありませんが、それらはあまりにも多くの詳細を提供しているので、それはあなたにはまだ非常にあいまいです。

基本的な答えは、コードがプロセッサで直接実行されるということです。いいえ、マシンコードは誰とも「話す」ことはありません。逆です。プロセッサはアクティブなコンポーネントであり、コンピュータで行うことはすべてそのプロセッサによって行われます(ここでは少し簡略化していますが、今のところは大丈夫です)。プロセッサはコードを読み取って実行し、結果を吐き出します。マシンコードはプロセッサの餌にすぎません。

混乱は、ハードウェアという言葉の使用に起因します。部門は以前ほど明確ではありませんが、単にすべてをハードウェアと呼ぶよりも周辺機器の観点で考える方が良いでしょう。そのため、マシンにオペレーティングシステムなどがある場合、プログラムは周辺機器にアクセスするためにそのサービスを使用する必要がありますが、プロセッサ自体は周辺機器ではなく、プログラムが直接実行されるメイン処理ユニットです。

カーネル、オペレーティングシステム、および同様の介在層は通常、複数のプログラムが実行されることが予想され、これらのプログラムがコンピューターの周辺機器を使用する方法を管理するシステムが必要な大規模システムでのみ使用されます(非常に頻繁に同時)。これらの場合、実行中のプログラムは、それらの共有方法を決定し、競合がないことを確認するシステムを使用して、これらの周辺機器にのみアクセスできます。競合するプログラムが存在しないため、管理する必要がない小規模なシステムでは、多くの場合、基盤となるシステムがまったくなく、これらのシステムで通常実行される単一のプログラムは、周辺機器で何でも自由に実行できます。


2

電源投入時にコンピュータで実行されるBIOSは、ROMに格納されている実行可能コードです。これは、機械語命令とデータで構成されています。ソースコードからこのBIOSをアセンブルするコンパイラ(またはアセンブラー)があります。これは特別な場合です。

他の特殊なケースには、カーネルとカーネル自体をロードするブートストラッププログラムが含まれます。これらの特殊なケースは、通常、C ++以外の言語でコーディングされています。

一般的なケースでは、カーネルまたはライブラリルーチンによって提供されるシステムサービスを呼び出すいくつかの命令をコンパイラに生成させる方がはるかに実用的です。これにより、コンパイラがはるかに軽量になります。また、コンパイルされたコードがより軽量になります。

スペクトルのもう一方の端はJavaです。Javaでは、この用語は通常理解されているため、コンパイラはソースコードを機械語命令に変換しません。代わりに、ソースコードは、Java仮想マシンと呼ばれる架空のマシンの「マシンインストラクション」に変換されます。Javaプログラムを実行する前に、Java仮想マシン用のインタープリターを含むJavaランタイムと組み合わせる必要があります。


2

古き良き時代には、プログラムは、自分で実行するか、他の人がプログラムに書き込んだライブラリコードを追加することにより、プログラムの実行中に実行する必要のあるすべての処理を担当していました。それ以外にコンピューターで実行されているのは、コンパイルされたプログラムで読み取るコードだけでした(運がよければ)。一部のコンピューターでは、より多くの処理(元の「ブートストラップ」プロセス)を行う前に、スイッチを介してコードを入力するか、プログラム全体がこの方法で入力する必要がありました。

すぐに、プログラムをロードして実行できるコードを実行できると便利であることがわかりました。後で、特にハードウェアが役立つ場合は、CPUを切り替えることで複数のプログラムを同時に実行するのに十分なコンピューターが強力であることが判明しましたが、プログラムの複雑さは互いにつま先を踏んでいません(たとえば、 、一度にプリンタにデータを送信しようとする複数のプログラムをどのように処理しますか?)。

これにより、ユーザープログラムからヘルパーコードを呼び出す標準化された方法で、大量のヘルパーコードが個々のプログラムから「オペレーティングシステム」に移動しました。

そして、それが今日の私たちの居場所です。プログラムはフルスピードで実行されますが、オペレーティングシステムで管理されているものが必要な場合は、オペレーティングシステムが提供するヘルパールーチンを呼び出します。そのコードは不要であり、ユーザープログラム自体には存在しません。これには、ディスプレイへの書き込み、ファイルの保存、ネットワークへのアクセスなどが含まれます。

完全なオペレーティングシステムなしで特定のプログラムを実行するために必要なものだけを提供するマイクロカーネルが記述されています。これは、経験豊富なユーザーにはいくつかの利点がありますが、他のほとんどのユーザーには提供されません。詳細については、Wikipediaのページ(https://en.wikipedia.org/wiki/Microkernel)をご覧ください

Java Virtual Machineを実行できるMicrokernelで実験しましたが、後でその最適な場所がDockerであることがわかりました。


1

典型的なデスクトップOSでは、カーネル自体が実行可能ファイルです。(Windowsにありntoskrnl.exe、Linuxにvmlinuxあるなど)実行可能ファイルを実行するためにカーネルが必要な場合、それらのOSは存在できません。

カーネルに必要なのは、カーネルが行うことを行うことです。複数の実行可能ファイルを一度に実行したり、それらの間でレフェリーを実行したり、ハードウェアを抽象化したりすることができます。ほとんどのプログラムはそれ自体を有能に行うことができません。DOSの時代(ほとんどオペレーティングシステムそのものと呼ばれることもありました)では、ゲームは多くの場合、ローダーと同じようにOSを使用し、カーネルと同じようにハードウェアに直接アクセスしていました。しかし、ゲームを購入する前に、マシンに搭載されているハードウェアのブランドやモデルを知る必要がありました。多くのゲームは、ビデオとサウンドカードの特定のファミリのみをサポートしており、競合しているブランドではまったく機能していなかった場合、非常に貧弱に動作しました。それ'

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.