問題タブ [gdt]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
1 に答える
5584 参照

assembly - NASM アセンブリで 32 ビット保護モードに入るにはどうすればよいですか?

x86 アセンブリを学んでおり、NASM でおもちゃのオペレーティング システムを作成しようとしていますが、いくつかのことがわかりません。

カーネルを正常に起動するブートローダーを作成しました。

  1. カーネル ファイルを含むディスケットから 14 セクタをロードします。
  2. というラベルの付いたこれらのセクターでファイルを検索しますkernel.feo
  3. そのファイルをオフセットのメモリにロードします0x2000
  4. far jump を使用してカーネルを実行しますjmp 0x2000:0x0000

したがって0x2000:0、メモリ内にカーネルコードがあります。CSファージャンプを使用しているため、適切に設定されている可能性があります。このカーネル コードでは、32 ビット プロテクト モードに入りたいのですが、GDT がどのように機能しているかわかりません。以下のコードを仮想マシン(QEMU)で実行すると、何も実行されません。

32 ビット プロテクト モードに入るのを手伝ってください!

とはいえ、次の問題があります。

  1. 0x7c00:0が原因でコードが にロードされていると想定していますがorg 0、そうではない可能性があります。保証されるのは物理アドレスだけです。CS適切に設定されるように、エントリ ポイントへのファー ジャンプを使用する必要があります。
  2. 何らかの理由で、コードがデータをまったく検出しないように設定DSしています。matchに0x2000設定するか、どこでもオーバーライドを使用する必要があります (推奨されません)。DSCSCS
  3. プロテクト モードのコードはゼロから始まるセグメントを前提とorg 0x7c00しています。org 0x7c00および セグメントに切り替える必要があり0ます。
  4. VGA テキスト モード セグメントは0xb8000not 0xb80000(ゼロを 1 つ引いた値) です。
  5. 0x55 0xaaブート セクタの最後にブート署名バイトがありません。

コードで次のことを修正しました。

  1. [org 0x0]は に修正され[org 0x2000]、セグメントは に設定され0ます。
  2. DS0の代わりに に修正されたので、 ;0x2000と一致するようになりました。CS
  3. VGA テキスト モード セグメントは に修正されました0xb8000

しかし、コードはこれらの修正では機能しません。2 つの文字列を出力するはずですが、何もしません!

このカーネル コードは0x55 0xAA、ブート セクターではないため、ブート署名で終わらないように注意してください。

修正されたカーネル コードは次のとおりです (動作していません)。

0 投票する
1 に答える
746 参照

assembly - NASM 組織なしでロードアドレスに相対的なラベルアドレスを設定する方法

カーネル用のブートローダーを作成しようとしています。現時点ではアセンブリで GDT をロードしていますが、GDT (および IDT) を生成する C コードを書きたいと考えています。問題は、ブート セクタが常にアドレス 0x7c00 にロードされるため、ラベルをオフセットする方法が必要なことです。そのアドレスで。bin ファイルにアセンブルする場合は [org 0x7c00] を使用できますが、外部シンボルを使用できるように、ブートローダーをオブジェクト ファイル (この形式では NASM によってサポートされていない組織) にアセンブルしたいと考えています。組織がなければ、アセンブリ コードに次のように記述します。

組み立てると次のようになります。

いつあるべきか

gdt の開始位置がオフセットを考慮していないため、テーブル自体も間違っています。

自分でオフセットを手動で追加するために保存します(必要な場所がたくさんあります)。開始アドレスを設定するために使用できるディレクティブはありますか?

編集: 0xc700 から 0x7c00 に変更

0 投票する
1 に答える
505 参照

x86 - ビッグリアルモードでのアドレス変換

http://wiki.osdev.org/Unreal_Modeが言うように、大きなリアル モードでアドレス変換がどのように行われるかについていくつか質問があります。

アンリアル モードは、リアル モード セグメントの「64Kb」制限を破ることで構成されますが、ディスクリプタ キャッシュを微調整することで、16 ビットの命令とセグメント * 16 + オフセット アドレスの形成を維持します。

しかし、私の質問は、プロセスでgdtがどのように使用されるか、または線形アドレスへの変換中にまったく使用されるかです。ビッグ リアル モードに切り替えるための仕様やその他のリファレンスを誰かが指摘できれば、非常に役に立ちます。

よろしく、

アルカ

0 投票する
0 に答える
141 参照

linux - TLS セレクターに設定すると、64 ビット カーネルで ES と DS が最終的にゼロになるのはなぜですか?

以下の 32 ビット プログラムはset_thread_area(2)、GDT でエントリを作成するために呼び出します。これは、TLS に使用するためのものです。FS通常、結果のセレクターはorに入れられGS、正常に使用されます。DSしかし、64ビットカーネルで実行されているorに入れられた場合ES、最終的に(おそらくコンテキストスイッチの後)、このセレクターはゼロになります。

しかし、代わりにmodify_ldt(2)結果の LDT エントリのセレクタを使用してこれらのセグメント レジスタに入れると、それらは値を保持しているように見えます!

また、どちらも GDT を参照する64 ビット コード セグメント ( 0x33) または 32ビット コード セグメント ( ) のセレクタなどをorに配置すると、それらはゼロに設定されません。0x23DSES

これがソースです(fasmでコンパイル)、奇妙な動作を示しています:

これは、64 ビット プロセスがデフォルトでこれら 2 つのセグメント レジスタに NULL セレクタを持っているという事実に関係しているようです。

これは Linux 3.16.0 以前では発生しますが、4.2.0 以降では発生しません。

何が起きてる?ESTLS セレクターが含まれている場合にDSゼロアウトするのに、他のセレクターを使用しないのはなぜですか?

0 投票する
1 に答える
5324 参照

x86 - Intel x86 では、LDT と GDT はどのように異なる方法で使用されますか?

どちらのテーブルにも、ベース アドレス、タイプ、長さ、アクセス権など、各セグメントのアクセスの詳細を提供するセグメント記述子が含まれていることを理解しています。

このブログを見ると、次のように違いが説明されています。
1. GDT はシステム内に 1 つのコピーしかないのに対し、LDT は複数のコピーを持つことができます
2. GDT は実行中に変更されない場合がありますが、タスクの切り替え時に LDT が変更されることがよくあります
3. LDT のエントリは GDT に保存されます。GDT と LDT のエントリの構造は同じです。

システムは、実際のプログラムでこれらの構造をどのように異なる方法で使用しますか?

0 投票する
1 に答える
2120 参照

assembly - ロングモード中に GDT を変更し、CS を更新する

UEFI経由で起動する、単純な自家製の64ビットOSを作成しています。これは、私のコードが実行を開始したときに、ページングが有効になっているロング モードになっていることを意味します。

ここで、UEFI ブート サービスを終了した後、UEFI によって構築されたすべての制御構造を独自のものに置き換えたいと考えています。

CR3 (ページング構造) の内容を正常に変更した後、 を使用して新しい GDT を正常にロードしましたlgdt

問題は、この新しい GDT を正しく使用するには、新しい値を CS に移動する必要があることです。オンラインでは、32 ビットから 64 ビットに切り替える際にそれを行う方法に関するチュートリアルがたくさん見つかりましたが、ロング モードからロング モードへの切り替えについてはほとんど何もありませんでした。

ファージャンプを使用する必要があると思いますが、このコード (AT&T 構文) ではそれを行うことができませんでした:

IDT が設定されていないため、このコードは でトリプル フォールトしretfqます。

編集:ページング構造を確認しましたが、それらが問題の原因ではないと確信しています。実際、コードは最後の 3 つの命令がなくても正常に実行されます。問題は、私のコードでは UEFI によって構築された古いセグメントをまだ参照している CS を更新する方法が必要なことです。retfqこれを行う正しい方法はありますか?または、他のどの命令を使用する必要がありますか?

前もって感謝します。

0 投票する
0 に答える
515 参照

x86 - x86 でページングを有効にして UEFI で GDT を表示する方法

私の目標は、UEFI で x86 のページングを有効にすることです。私の教授は、最初に UEFI で GDT を表示しようとするかもしれないと言いました。そうすれば、ページングが機能するかどうかも確認できます。問題は、それを行う方法がわからないことです。

このチュートリアルを使用して、Visual Studio で EDK2 を有効にしました: http://uefi.blogspot.com/2013/06/how-to-set-up-edk2s-windows-hosted-uefi.html

チュートリアルを参照したり、何をすべきかを説明したりできますか?

0 投票する
0 に答える
871 参照

linux - グローバル記述子テーブルとローカル記述子テーブルの関係?

保護モードのメモリ管理

このリンクのセグメンテーションを行っていました。

両方の LDT と GDT は独立していますか、それとも互いに依存していますか?

(TIビット(セレクターの一部)は、どの記述子テーブルを使用するか(GDTまたは現在アクティブなLDT)を決定するため、独立していると思います)

図より GDTR-LDTR

GDT (Global Descriptor Table) とも呼ばれ、主にオペレーティング システム セグメントの記述子エントリを保持するために使用されます。カーネル スタックの例 --code_section/data_section?

LDT 2 番目のタイプは LDT (ローカル記述子テーブル) として知られており、通常のアプリケーション セグメントのエントリが含まれています (必須ではありません) ユーザー スタック --code_section/data_section ?

LDTRレジスタには、メモリ内で現在アクティブなLDTのサイズと位置が含まれていると言われています。これは、コンテキスト スイッチで、各プロセスの LDTR 値をそのプロセスの pcb に保存するということですか?

0 投票する
2 に答える
7879 参照

assembly - グローバル記述子テーブルを定義する用途は何ですか?

GDT (Global Descriptor Table) に関するチュートリアルを読みました。このチュートリアルでは、GDT を「メモリの特定の部分に対する基本アクセス権限を定義するもの」と定義しています。つまり、GDT がメモリ保護に使用されます。

上記以外のタスクを実行しますか?

オペレーティング システムに GDT を実装することは必須ですか?

要するに、誰かがGDTを理解しやすい方法で詳しく説明できるとよいでしょう.

ありがとう

0 投票する
0 に答える
610 参照

x86 - x86 プロセッサが GDT で NULL 記述子を必要とするのはなぜですか?

私は i386 で独自の OS を作成していますが、グローバル記述子テーブルの設定に関しては、NULL 記述子に困惑しています。

INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986では、

NULL_DES DESC <> ; ヌル記述子

NULL 記述子に関する唯一の言及です。

x86 プロセッサが GDT で NULL 記述子を必要とする理由を教えてくれる人はいますか?