問題タブ [osdev]
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.
x86 - (カーネルの作成) 割り込み記述子テーブルを変更するにはどうすればよいですか?
低レベルのものを少しいじるために、小さなカーネルを書いています。現在、Virtual Box で起動し、画面にテキストを表示したり、メモリを割り当てたり、その他の非常に基本的なことを行うことができます。C++ と少しの asm で書かれています。
私が探求したかったことの 1 つは、マルチタスクの背後にあるメカニズムでした。私が理解しているように、それは次のようになります。
- カーネルは、割り込み記述子テーブルを初期化して、割り込みが定期的に (ミリ秒単位など) 発行されるようにし、カーネルで定義されたルーチンを呼び出します。
- ルーチンが呼び出されると、コード/データ セグメントとスタック ポインタを別のプログラムのコンテキスト (「コンテキスト スイッチ」) のセグメントに設定することができます。
ですから、コンセプトは単純に見えましたが、詳細はもっと複雑になることはわかっていました. オンラインでいくつかのものを見つけましたが、用語は大きく異なり、例は私が持っていないコンテキスト (Linux カーネル内など) からのもののようです。
ただし、記述子テーブルを設定する方法は次のようです。
- いくつかのデータを PIC (およびその他) に送信
outb
して初期化します。 - 必要なルーチンへの関数ポインターを使用して、メモリ内に割り込みテーブルを準備します。関数がシグナル ハンドラーになることができるように注意してください。
- でテーブルをロードします
lidt
。
ただし、これらのことを具体的に行うこと、またはこれが正しいかどうかについては、あまりわかりません。当惑したカーネルライターのためのリソースを持っている人はいますか?
assembly - CMPSB命令と混同
私はこのコードを見てきましたが、rep cmpsb行について混乱しています。
cmpsb cx 回繰り返すことは理解していますが、これは 2 つの文字列をどのように比較しますか? たとえば、"Hey\0" と "hey\0" を比較していて、このループで 4 つの文字列を比較していたとします。最初の文字が異なり、それに応じて EFlags レジスタが設定されます。ただし、cmpsb命令は繰り返され、次の文字は同じになります。cmpsbの仕組みを誤解しているかもしれませんが、このループは 2 つの文字列を正しく比較していないようです。このループは実際に機能しますか?
gcc - GCC クロス コンパイラ ツールチェーンのビルドに成功しました。環境変数を適切に設定するにはどうすればよいですか?
クロス コンパイル ツールチェーンの環境変数をセットアップする方法について、これが適切な場所であるかどうかはわかりません。ツールチェーンの目的は、OS を開発することです。Ubuntu 12.04 LTS を使用しています。問題は、ツールチェーンの環境変数をどのように設定するかです。クロス コンパイラ ツールチェーンのパスは次のとおりです。
GCC クロス コンパイラ ツールチェーンを使用できるようにしたいのですが、Ubuntu に付属の GCC ツールチェーンも引き続き使用できるようにしたいと考えています。よくわからない場合は、お気軽に質問してください。また、私が達成したいことについてさらに情報が必要な場合は、お気軽にお問い合わせください。
c - 単純なCブートストラップ/カーネルの問題
最近、私は自分自身の本当に本当に基本的なOSを書くことに興味を持つようになりました。私はスタックを確立し、いくつかの基本的なことを行ういくつかの基本的なアセンブリを作成しました(まあ、コピーしました)。これはうまくいくように見えましたが、Cをミックスに導入しようとするとすべてが台無しになりました。
2つの主要なプロジェクトファイルがあります。スタックを作成してC関数を呼び出すNASMであるloader.sと、基本的なC関数を含むkernel.cです。
現時点での私の問題は、基本的に、kernel.binファイルを実行するとQEMUがフリーズすることです。私のコードにはいくつもの問題があると思います-おそらくこの質問は、その極端な特異性のためにStackOverflow形式には実際には適切ではありません。私のプロジェクトファイルは次のとおりです。
loader.s:
kernel.c:
私はそのようにすべてをコンパイルします:
nasm -f elf -o loader.o loader.s
i386-elf-gcc -I / usr / include -o kernel.o -c kernel.c -Wall -nostdlib -fno-builtin -nostartfiles -nodefaultlibs
i386-elf-ld-Tリンカー.ld-okernel.binloader.o kernel.o
そして、そのようにテストします:
qemu-system-x86_64 -kernel kernel.bin
誰かが私のためにこれを見てくれることを願っています-コードスニペットはそれほど長くはありません。
ありがとう。
gcc - キューを使用したタスク切り替え
私は自分の趣味のOSを開発していますが、スケジューラ/タスクの切り替えに関する問題に悩まされています。
プロセスを保持するための構造として FIFO キューを使用することを計画しました。リンクリストを使用して実装しました。
また、タスクから別のタスクに切り替えるために iret メソッドを使用することにしました (そのため、os が iret の直前に割り込み要求を処理していたとき、新しいタスクに移動するために ESP レジスタを変更しました)。
しかし、私には問題があります。OS が起動すると、次の 2 つのタスクが起動します。
- アイドル
- シェル
そして、これら2つで問題はありません。しかし、他の 2 つのタスク (単純に printf を内部に含む) を起動しようとすると、タスク キューが破損しました。
その後、キューを印刷しようとすると、作成されたばかりの2つのタスクのみが印刷され、アイドル状態でシェルが消えますが、OSは引き続き機能します(特定の瞬間に新しいタスクのespフィールドが置き換えられたと思いますシェルのespコンテンツで)。
タスクのデータ構造は次のとおりです。
そしてtssは次のとおりです。
スケジューラ関数は次のとおりです。
tss は次の値で初期化されます。
新しいタスクを作成する関数は次のとおりです。
私は何かを忘れただけか、考慮事項を見逃していると確信しています。しかし、私は何が欠けているのか理解できません。
実際、私はカーネル モードで、同じアドレス空間内でのみ作業しています (ページングは有効になっていますが、実際にはすべてのタスクで同じ pagedir を使用しています)。
ISR マクロは、 https ://github.com/inuyasha82/DreamOs/blob/master/include/processore/handlers.h で定義されています。
ISR を処理するために、次の 4 種類の関数を宣言しました。
- 例外
- EXCEPTION_EC (エラー コード付きの例外)
- IRQ
- システムコール
明らかに、スケジューラは IRQ ルーチンによって呼び出されるため、マクロは次のようになります。
irq ハンドラ関数は次のとおりです。
これらは enqueue_task および dequeue_task 関数です。
詳細が必要な場合はお知らせください。
assembly - OSに依存しないアセンブリ言語でファイルを開く
アセンブリでハード ドライブからファイルを開く方法を理解しようとしています。シンプルなOSを構築しようとしているので、DOS割り込みやオペレーティングシステムを必要とするものを使用せずにこれを行いたいです。もちろん、BIOS 割り込みには問題ありません。
assembly - アセンブリ - 仮想ディスクの次のセクターを読み取る
人生で少なくとも一度は世界中のプログラマーとして、私は自分の「革命的」な新しい唯一のオペレーティング システムを作ろうとしています。:D
さて、私は仮想エミュレーター (Oracle VM Virtual Box) を使用しています。そのために、vmdk ディスクを使用して、新しい unknwon オペレーティング システムを作成します。私は vmdk が好きです。それらは単なるファイルなので、仮想ハードディスクの最初の 512 バイトにブートローダーを貼り付けることができます。
今、この仮想ディスクの次のセクターを読み取ろうとしています。そこに、メッセージを表示する単純なカーネルを貼り付けます。
2 つの質問があります。
2 番目のセグメント (最初の 512 バイトはブートローダによって占められています) を正しく読み取っていますか? コード:
ここで、CF を確認した後、エラー メッセージが表示されます。ただし、INT 13, 1 を使用して最後のステータス メッセージを取得すると、AL は 0 になるため、エラーは保存されません。
シンプルなカーネルを vmdk 内の正しい場所に貼り付けていますか? 私がしているのは、ファイルの 512 番目のバイトの後に貼り付けることです。最初の 512 バイトは、私が言ったように、ブートローダーです。ファイルは次のようになります。
/li>
これが、カーネルを 2 番目のセクターに追加しようとしている方法です。これの何が悪いと思いますか?ありがとう!
アップデート
OK、エラーは発生しませんが、ロードされたコードが実行されていません。ウィンドウにポイントが表示されます。
c - C における変数の場所
Cがグローバル変数にメモリを割り当てる方法を理解しようとしています。
私は単純なカーネルに取り組んでいます。これまでのところ、画面に出力して割り込みを有効にすること以上のことはできません。私は現在、基本的な物理メモリ マネージャーに取り組んでいます。
私のメモリ マネージャは、メモリが割り当てられているか使用可能な場合に 1 または 0 を設定するビットマップです。カーネルが使用しているメモリを「割り当て済み」としてビットマップに追加する必要があるため、何も上書きされません。
カーネルは 0x100000 に静的にロードされるため、カーネルの開始点を簡単に見つけることができます。長さを把握することもそれほど難しくありません。私がよくわからない部分は、グローバル変数がメモリに置かれている場所ですか?
私のカーネルが 12K だとしましょう。保護のために、これら 3 つの 4K ブロックのメモリをカーネルに割り当てることができます。使用する変数をカバーするために、さらに割り当てる必要がありますか? それとも、変数はその 12K の一部ですか?
助けてくれてありがとう、私は十分な意味を持っていることを願っています.
c - 単純なCカーネルのcharポインタが機能しない
Cを使用して単純なカーネルを作成しようとしています。すべてが正常に読み込まれ、動作し、ビデオメモリにアクセスして文字を表示できますが、何らかの理由で単純なputs関数を実装しようとすると動作しません。私は自分のコードと他のコードを試しました。また、関数の外部で宣言されている変数を使用しようとすると、機能しないようです。これは私自身のコードです:
(spos
開始位置)のものは、グローバル位置変数を作成できないためです。putc
正常に動作しますが、puts
動作しません。私もこれを試しました:
なぜこれが機能しないのですか?ネイティブGCC(色とsposデータなしで使用printf("%c")
)でputs実装を使用してみましたが、正常に機能しました。
c - 出力ファイルにデータを追加せずに C コードをコンパイルおよびリンクする
GCC と ld の使用に関する知識が不足しているため、専門家の助けを求めています。教育目的で OS を作成していますが、C コードのコンパイルとリンクに問題があります。正直なところ、問題はありませんが、GCC と LD のような出力ファイルに不要なデータが生成されて混乱しています。
などです。gcc と ld の両方でどのパラメーターを使用して、この (私の OS にとって) 役に立たないデータを削減するかを知る必要があります。
以前使用したパラメーター: -c -nostdlib -nostdinc -fno-builtin -fno-stack-protector -fstrength-reduce -finline-functions また、リンカー スクリプトを使用してセグメントを編成します。
出力から .comment や .note などのブロックを減らすために objcopy を試しましたが、私にとってはそれが最良の解決策でした