コンピュータが生の低レベルのテキストとグラフィックスを表示する方法


46

私のコンピューターへの関心はますます高まっており、私はもう質問する必要がないように、より深い質問をしています。私たちのコンピュータは、ブート時に、限り私はそれを理解し、中にあるテキストモードの文字がソフトウェア割り込みを使用して表示することができます、。どのコンピューターが起動していても、常に同じように見える有名な起動フォントを見てきました。0x10AH=0x0e

それでは、いったいどのようにコンピューターはOSの下など、最低レベルのグラフィックスを出力するのでしょうか?また、ソフトウェア割り込みを使用してグラフィックスが一度に1ピクセルずつ出力されることはありません。

頂点、ポリゴン、フォントなどの基本的な出力を定義する標準はありますか(たとえば、OpenGLの下では、OpenGLが使用する可能性があります)。私が尋ねるのは、OSが公式ドライバーがインストールされていなくても問題ないことが多い理由です。彼らはどうやってそれをしますか?

私の仮定が間違っている場合はおApび申し上げます。これらのトピックについて詳しく説明してくれて非常に感謝しています!


すべてのコンピューターではなく、ディスプレイのハードウェアに依存します。IBMの進化ラインに基づいたPCには元々テキストモードがあり、その後さまざまなグラフィックモードが追加されました。まだその遺産があります。古いコンピュータには、多くの場合、テキストモードしかありませんでした。AmigaやオリジナルのMacintoshなど、他のコンピューターにはグラフィックモードのみがありました。
ヒッピートレール

回答:


25

それが(部分的に)BIOSの役割です。

コンピューターの基本入出力システムは、実際のコンピューター間のこのような違いにもかかわらず、オペレーティングシステムに共通のインターフェイスを提供する役割を果たします。

とはいえ、特にグラフィックスについては、画面に描画するさまざまな方法があります。BIOSに送信できるTTYコマンドがありますが、それはリアルモードのみです。プロテクトモードで何かを描画する場合は、VGAを使用して描画する必要があります。OSDevよりもうまく説明できないので、ここで詳細を探してください。しかし、基本的には、アドレス0xB8000に始まるメモリに書き込み(ビデオメモリはメモリマップ)して、画面に描画することができます。

VGAよりも高い解像度が必要な場合は、VESA BIOS拡張機能を使用する必要があります。私はそれに詳しくはありませんが、詳細についてはGRUBソースコードを見てみてください。

便利なリファレンス:


あなたがたまたまDに精通しているなら-私はしばらく前に小さなブートローダーを書いたが、それは画面に書き込むことができた(テキストのみ)。興味のある方は、次のコードをご覧ください。

align(2) struct Cell { char ch; ubyte flags = 0x07; }

@property Cell[] vram()
{ return (cast(Cell*)0xB8000)[0 .. CONSOLE_WIDTH * CONSOLE_HEIGHT]; }

void putc(char c)
{
    if (isBochs) { _outp(0xE9, c); }  // Output to the Bochs terminal!

    bool isNewline = c == '\n';
    while (cursorPos + (isNewline ? 0 : 1) > vram.length)
    {
        for (short column = CONSOLE_WIDTH - 1; column >= 0; column--)
        {
            foreach (row; 0 .. CONSOLE_HEIGHT - 1)
            {
                uint cell = column + cast(uint)row * CONSOLE_WIDTH;
                vram[cell] = vram[cell + CONSOLE_WIDTH];
            }
            vram[column + (CONSOLE_HEIGHT - 1) * CONSOLE_WIDTH].ch = ' ';
        }
        cursorPos = cast(ushort)(cursorPos - CONSOLE_WIDTH);
    }
    if (isNewline)
        cursorPos = cast(ushort)
            ((1 + cursorPos / CONSOLE_WIDTH) * CONSOLE_WIDTH);
    else vram[cursorPos++].ch = c;
}

void putc(char c, ubyte attrib) { vram[cursorPos] = Cell(c, attrib); }

void memdump(void* pMem, size_t length)
{
    foreach (i; 0 .. length)
        putc((cast(char*)pMem)[i]);
}

void clear(char clear_to = '\0', ubyte attrib = DEFAULT_ATTRIBUTES)
{
    foreach (pos; 0 .. vram.length)
        vram[pos] = Cell(clear_to, attrib);
    cursorPos = 0;
}

@property ushort cursorPos()
{
    ushort result = 0;
    _outp(0x3D4, 14);
    result += _inp(0x3D5) << 8;
    _outp(0x3D4, 15);
    result += _inp(0x3D5);
    return result;
}

@property void cursorPos(ushort position)
{
    _outp(0x3D4, 14);
    _outp(0x3D5, (position >> 8) & 0xFF);
    _outp(0x3D4, 15);
    _outp(0x3D5, position & 0xFF);
}

答えてくれてありがとう。なぜGRUBソースコードなのか?GRUBがグラフィックス自体に関係していることは知りませんでした。
ドディ

2
@panic Grub2は、OS選択メニューで画像を背景として表示するなど、いくつかの興味深いことを実行できます。グラブについては定かではありません。
イズカタ

@panic:GRUBかGRUB2かはわかりませんが(一般的に「GRUB」を使用しました)、モニターでネイティブの1600x900解像度に確実に切り替えることができるので、調べることができるものがあると確信しています。(私はしばらく前にそれらを調べましたが、彼らが役立っていたことを覚えていますが、私はしばらくしていたので、どのファイルを調べるべきかを正確に覚えていません。)
Mehrdad

この用語memory-mappedは、グラフィックスカードとディスプレイに書き込もうとするプログラムの両方のために、CPU(または別のDMAユニットが)が読み書きできるRAMに「バッファ」領域があることを意味しますか?
n611x007

1
@naxa:良い質問です...通常、メモリにマップされたハードウェアは、実際にはRAMに対応しないアドレスがメモリにあることを意味します。むしろ、それに対する読み取りまたは書き込みは、一部のハードウェアで何らかのアクションを実行することに対応します。とはいえ、実際のRAMとメモリのブロックをRAMのように見せるためのハードウェアをどのように区別できるかはわかりません...ハードウェアによって。
Mehrdad

25

IBM PCとそのクローンの初期から、ディスプレイアダプタハードウェアは非常にシンプルでした。小さなメモリブロックが文字セル(標準モードでは80x25文字)のグリッド専用で、各セルに2バイトのメモリがありました。 。1バイトが文字を選択し、もう1バイトがその「属性」を選択しました-前景色と背景色に加えて、カラーアダプタの点滅制御。モノクロアダプターの場合、太字、下線、点滅、または反転表示。ハードウェアは、文字メモリの内容に従って、文字形状のROMテーブルからピクセルを検索しました。

ある程度のハードウェアの独立性を提供するために、文字マップへのBIOSインターフェイスでは、画面に単一の文字セルを設定するためにソフトウェア割り込みを実行する必要がありました。これは遅く、非効率的でした。ただし、文字メモリもCPUによって直接アドレス指定できるため、どのハードウェアが存在するかを知っていれば、代わりにメモリに直接書き込むことができます。いずれにせよ、一度設定すると、文字は変更されるまで画面上に残り、作業に必要な文字メモリの合計は4000バイトでした-単一の32x32フルカラーテクスチャのサイズです!

グラフィックモードでは、状況は似ていました。画面上の各ピクセルはメモリ内の特定の場所に関連付けられており、BIOSセットピクセルインターフェイスがありましたが、高性能な作業にはメモリへの直接書き込みが必要でした。VESAのような後の標準では、システムがBIOSベースの低速クエリをいくつか実行してハードウェアのメモリレイアウトを学習し、メモリを直接操作します。これは、特殊なドライバーなしでOSがグラフィックを表示する方法ですが、最新のOSには、主要なGPUメーカーのハードウェアすべての基本ドライバーも含まれています。最新のNVidiaカードでさえ、いくつかの異なる下位互換モードをサポートします。おそらく、IBM CGAにまでさかのぼります。

3Dグラフィックスと2Dの重要な違いの1つは、2Dでは通常、フレームごとに画面全体を再描画する必要がないことです。3Dでは、カメラが少しでも移動すると、画面上のすべてのピクセルが変化する可能性があります。2Dでは、スクロールしていない場合、画面のほとんどはフレーム間で変更されません。スクロールしている場合でも、通常、シーン全体を再構成する代わりに、高速のメモリ間コピーを実行できます。したがって、すべてのフレーム、すべてのピクセルに対してINT 10hを実行する必要はありません。

ソース:私は本当に古いです


非常に有益な、ありがとう。私は複数を受け入れることができればいいのに!
ドディ

8

ブート中に、システムBIOSはビデオアダプターを探します。特に、ビデオアダプタに組み込まれたBIOSプログラムを探して実行します。このBIOSは通常、メモリのC000hの場所にあります。システムBIOSは、ビデオ BIOSを実行し、ビデオアダプタを初期化します。

BIOSがOSまたはドライバーなしでネイティブに表示できるビデオ/グラフィックスのレベルまたはモードは、主にビデオBIOS自体に依存しています。

ソース/詳細はこちら -「システムブートシーケンス」


6

私の知る限り、ブート時のコンピューターはテキストモードで、AH = 0x0eのときにソフトウェア割り込み0x10を使用してキャラクターを表示できます

レガシーBIOS機能について話しています。実際、そのような関数を使用する必要はまったくありません。ビデオメモリに直接書き込みます。

コンピューターは、OSの下など、最低レベルでグラフィックスをどのように出力しますか?

これは、OSの動作方法に強く関係しています。とにかく、操作はハードウェアレベルで同じです。ビデオカードにはビデオRAMがあり、画面に描画される次の画像を保存(単純化)します。各アドレスは、ピクセルを表すバイトであると考えることができます(実際には、通常、ピクセルごとに複数のバイトが必要です)。次に、ビデオコントローラーがこれをモニターが理解できる信号に変換します。

頂点、ポリゴン、フォントなどの基本的な出力を定義する標準はありますか(たとえば、OpenGLの下では、OpenGLが使用する可能性があります)。

知らない 論理的なグラフィック表現に関する標準はありません。

私が尋ねるのは、OSが公式ドライバーがインストールされていなくても問題ないことが多い理由です。彼らはどうやってそれをしますか?

既にOSにバンドルされているドライバーがあるためです。

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