q_and_aの過去ログ(0004)

  • (by K, 2006.07.02)

ログ

  • ちょっと長いのですが、セグメントについて質問させて下さい。P106のputfonts_asc()の引数の"ABC 123"などのデータは.rodataセクションに置かれて、実行時に参照する際はデータセグメントレジスタが参照されますよね?で、データセグメントのベースアドレスは0x0になっているわけですが、この文字列自体はbootpackと共に0x280000以降にロードされているので、データセグメントのベースアドレスが0x280000でないとアクセスできないと思うのですが、なぜ問題なく表示できているのでしょう?もしくは、私の認識に何か誤りがあるんでしょうか... -- まさ 2006-05-24 (水) 19:21:50
  • 追記です。上の質問の背景をお話しておきますと、当方OS自作入門を読みながら、Linux/gcc/gasで自作しておりまして、セグメントレジスタの設定はまったく同じようにしています。で、文字列を表示しようとしたところなぜか何も表示できず、試しに文字列のアドレスに0x280000を加算すると表示できたためです。 -- まさ 2006-05-24 (水) 19:22:18
  • ご質問ありがとうございます。あらかじめ申し上げますが、以下の回答は本書を読破した後ではないと混乱するような内容を含んでいるかもしれません。ご了承ください。・・・まず、本書に出てくる「はりぼてOS」においては.rodataというセクションはなく、リードオンリー、リードライト共に、.dataセクションに置かれます。これはtolsetにバンドルされているgcc(cc1.exe)の仕様です。さてこのデータはメモリのどこに置かれるのかといいますと、0x280000〜ではなく、0x310000〜に置かれます。p.171のメモリマップでいうとちょうど「スタックなど(1MB)」の中です。 -- K 2006-05-24 (水) 19:55:30
  • そしてご指摘のとおりデータセグメントのベースアドレスは0になっています。この食い違いはマズイのでこれを解消するために、obj2bim.exeが.dataの開始番地を0x310000になるようにリンクしています。Makefileを見ると stack:3136k という記述が見つかると思いますが、これはスタック用に3136KB=0x310000バイトを指定することで、.dataの開始番地を0x310000にしているのです。 -- K 2006-05-24 (水) 20:00:20
  • なるほど!謎が解けました^^丁寧で素早いご回答ありがとうございました。ちなみに、コードセグメントだけベースアドレスを違う値にするのは、何か特別な理由があるのでしょうか?(本の中でご説明済みでしたらごめんなさい。) -- 名無しさん 2006-05-24 (水) 23:07:26
  • 発想はむしろ逆です。本当はコードのベースを0x280000に、データのベースを0x310000などに指定し、.textも.dataもセクションの番地は0にしたいところなのです。しかしデータのベースを変更するとVRAMの番地などが全部ずれて見えることになり、非常にやっかいです。それを回避するためにデータのベースを無理矢理0にして、代わりに.dataセクションの開始番地を0x310000にしているのです。.textの開始番地を0x280000にすることで、もちろんコードのベースも0にできますが、これだと実際にコードがない部分もコードセグメントに含まれることになり、バグがあっても例外が起きずに暴走する可能性が高まります。・・・まあ言ってしまえば、このデータセグメントのごまかしも全く同じ問題を抱えているので、OSの中にポインタなどに関するバグがあっても例外で止めることはできず、暴走の危険は結構あります。このせいで開発中は(=バグが多かった頃は)、それなりに苦労しました。 -- K 2006-05-25 (木) 02:04:53
  • なるほど、勉強になります。Kさんも苦労した時期があったんですね^^; 問題の件についてはリンカスクリプトの設定で回避できました。ありがとうございました。-- まさ 2006-05-25 (木) 13:35:39
  • おはようございます。Cloverです。最近本を振り返って見ました。そこで本の中にある宣言があったのです。それは、第1版の第4刷のp.366の「cmdline[cursor_x / 8 - 2] = 0;」です。これはどんな意味を持つのでしょうか?いくら読んでも分かりませんでした。この宣言をわたしのOSのXDOSにも生かしたいので。誰か教えてください。では。 -- Clover 2006-05-28 (日) 05:50:42
  • そこは宣言ではありません。ただの代入文です。あまり難しくないところだと思うので、その文を消してみてどんな問題が起こるかを実験してみてはどうでしょうか?そのほうが勉強になります。・・・どうしても分からなければまた聞いてください。 -- K 2006-05-28 (日) 11:25:31
  • Kさんへ。分かりました。変更してもわかんなかったらもう一度質問させていただきます。早いご回答ありがとうございました。 -- Clover 2006-05-28 (日) 16:38:55
  • いろいろとやってみたら文字を入力したところをcmdlineに入れてるのを忘れているだけでした。すいませんでした。 -- Clover 2006-05-29 (月) 07:49:14
  • フロッピーへの書き込みについての質問です:本では直接フロッピーに書き込んでいますが。CDイメージ(isoなど)やフロッピーのイメージを生成して、VMwareなどで読み込んで起動したいのですが何か方法ありませんか? -- 7誌 2006-05-31 (水) 11:22:52
  • uchan の「VMware Playerを使うときのファイル」が参考になりますよ>7誌さん -- 名無しさん 2006-05-31 (水) 13:38:26
  • イメージ生産方法については、30−6のCDROMで起動するを真似して作ってみてください。VMWareでの起動方法は名無しさんが答えてくれたページに乗ってますよ。 -- Clover 2006-05-31 (水) 17:06:23
  • 質問させていただきます。第2版p.134の最後で、「C言語ではDSもESもSSも同じセグメントを指しているという思い込みがある」という記述がありますが、これはどうしてこのような思い込みが必要なのでしょうか。また、これらレジスタの値を同じにせずにC言語関数を呼び出した場合、どのような現象が発生するのでしょうか。調べてみたところ、「ES!=DS問題」というものに関係しているようですが、詳しくはわかりませんでした。よろしくお願いします。 -- R.Z. 2006-06-06 (火) 17:48:25
  • お答えします。思い込みがなぜ必要かというと、そういう前提を置くことでコンパイラが機械語を生成するときにラクできるから、ということにつきます。正しく設定しない場合どのような現象が発生するかですが、たとえばDS:1234番地のメモリを読み込んでほしい状況で、SS:1234番地のメモリを読み取ることになるので、データの読み書きで誤動作します。たとえば以下のコードは期待通りに動きません。 -- K 2006-06-06 (火) 18:37:09
    void func(void)
    {
        int i;
        int *p = &i;
        i = 1; /* コンパイラはこの代入文でSSを使うようにコンパイルする */
        *p = 2; /* pにはiの番地が入っているので、iはこれで2になるはず */
            /* ↑コンパイラはこの代入文でDSを使うようにコンパイルする */
        if (i == 1) {
            処理A
        } else {
            処理B
        }
        return;
    }
    /* SSとDSが等しいセグメントをさす場合は、正常にiが2になるので、処理Bが実行される */
    /* SSとDSが等しいセグメントをささない場合は、iが1のままになるので、処理Aが実行されてしまう */
  • ありがとうございました。連続質問で申し訳ありません。現在、6日目の割り込み処理で詰まっています。キーボードを押すとCPUの使用率が最大まで跳ね上がって、そのあとメモリの変な領域を参照して、OSが落ちます。多分GDTR, IDTRの設定が誤っていることが原因だと思います。これらレジスタの値を確認する方法は、何か無いでしょうか。(ここで質問するべき内容でなかったら、申し訳ありません。) -- R.Z. 2006-06-07 (水) 11:23:35
  • 質問の内容がよく分からなかったので確認させてください。6日目のどのプログラムがうまく動かないのでしょうか?ページなどを示していただきたいです。それともR.Z.さんは独自の改造をしていて、それで失敗しているのでしょうか?もし1文字でも改造している場合は、impressionsへお願いいたします。 -- K 2006-06-07 (水) 16:49:50
  • はじめまして。Windows2000Professional ServicePack4でやっているのですが、第1版の45頁のmake runでエミュレータが起動しません。ファイルは作成されます。フォルダはtolset配下にhelloosとz_toolsが置いてあります。何か操作、ファイルが足りないのでしょうか? -- 名無しさん 2006-06-07 (水) 21:00:02
  • まずは faq/qemu をご覧ください。 -- K 2006-06-07 (水) 23:49:45
  • Makefileを読むと、「haribote.img : ipl10.bin haribote.sys Makefile」と書いてあります。本の44ページによると、haribote.imgを作るのにipl10.binとharibote.sysとMakefileが揃っているかチェックするようです。いま、haribote.sysも作成されていないということですから、当然、haribote.imgはharibote.sysが無いので作成されなかったのです。では、haribote.sysはどうでしょうか?Makefileによると、「haribote.sys : asmhead.bin bootpack.hrb Makefile」と書いてあります。haribote.sysを作るにはasmhead.binとbootpack.hrbそしてMakefileが揃っている必要があるようです。揃っていますか?このようにして、どんどん、さかのぼって行くとよいと思います。 -- 名無しさん 2006-06-09 (金) 14:05:42
  • Makefileにある必要なファイルをそろえたのですが、haribote.sysがあってmake runを実行したところ同じエラーメッセージが表示されます。エラーメッセージと関係ないかもしれませんが、'C:Documents and Settings\・・・’は内部コマンドまたは外部コマンド操作可能なプログラムまたはバッチファイルとして認識されていません。という内容のものが表示されます。 -- 名無しさん 2006-06-09 (金) 14:49:56
  • 「エラーメッセージと関係ないかもしれませんが・・・」いえいえ、立派なエラーメッセージです。'C:Documents and Settings\・・・’の・・・の部分は省略されて表示されていますか?もし詳細が表示されていれば、・・・の部分を教えてください。そうでなければ、再びMakefileを見ていただいて、「# ファイル生成規則」の下の行から順に、「make ipl10.bin」、「make asmhead.bin」、「make bootpack.gas」、「make bootpack.nas」という具合に行って、そのエラーが何を実行したときに起こるかを教えていただけたらと思います。 -- 名無しさん 2006-06-09 (金) 15:25:48
  • 'C:Documents and Settings\・・・の・・・部分はログインユーザのフォルダです。make haribote.sysとmake haribote.imgだけがC:document and ・・・と..\z_tools\make.exe:***[haribote.sys]Error1が表示されます。他のコマンド(make bookpack.gas等)は問題なくファイルが作成されました。 -- 名無しさん 2006-06-09 (金) 16:08:22
  • (本筋と関係なくて申し訳ないのですが、名無しさんがいっぱいで非常に混乱しております。以後は何か適当な仮名でご発言いただけないでしょうか。) -- K 2006-06-09 (金) 16:29:55
  • なお、名無しさんへの名無しさんによるアドバイスは大変的確に思います(まずはどこまで無事に生成しているのかを確認しようとしていること)。 -- K 2006-06-09 (金) 16:32:00
  • qemuではなくmakeの問題のようですので、今度は faq/make に目を通されることをお勧めします。非常によく似たケースが記載されていますよ(「make run」しても実行されない。Cygwinは使ってない。のところなど)。 -- K 2006-06-09 (金) 16:46:51
  • 面倒な作業をしていただいて恐縮です。「make haribote.sys」ではじめてエラーが起こるようなので、Makefileの「haribote.sys : asmhead.bin bootpack.hrb Makefile」の次の行を見ますと、「copy /B asmhead.bin+bootpack.hrb haribote.sys」と書いてあります。これは本の64ページの太字で書かれた最後の項目である、「copyコマンドでasmhead.binとbootpack.hrbを・・・」という作業の命令です。さて、エラーはここで出ていますので上でKさんが指摘されているようにmakefile中に書かれたcopyコマンドによる障害の可能性が非常に高いですね。 -- N 2006-06-09 (金) 17:20:10
  • 一部問題は解決しました。ログインユーザが日本語でした。ありがとうございます。 -- 名無しさん 2006-06-09 (金) 19:38:40
  • 環境変数TMPに全角スペースが含まれていると、なぜかmakefile内でcopy,delといった一般的なコマンドプロンプト用のコマンドは利用できないようです。TMPにはユーザー名が含まれているので、ユーザー名が日本語の場合うまくいかないことがあるようです。私の場合はmake実行前に set TMP=C:\temp としています。なんとなくこの方法は危険な気がしますが一応正常にmakeが動作するようになります。 -- qwert 2006-06-10 (土) 14:51:31
  • tolsetをデスクトップに置いてinstall.batを実行しても、フロッピーディスクは空のままです。DOS窓にもエラーメッセージ等でていません。どうすればよいでしょうか。 -- 名無しさん 2006-06-28 (水) 10:55:23
  • デスクトップというのは、faq/c00-03の「Aドライブにきちんとディスクを入れているのにinstall.batの実行に失敗する。」に該当するように思うのですが、どうでしょうか? -- K 2006-06-28 (水) 12:39:24
  • tolsetフォルダをデスクトップにコピー→projectsフォルダからhelloos0フォルダをtolsetフォルダにコピー→フォーマットしたフロッピーディスクをセット→!icons_nt.batをダブルクリック→installと入力しenterキーを押す この手順で操作してもフロッピーディスクは空のままという状態なのですが・・・。 -- 名無しさん 2006-06-28 (水) 15:20:38
  • うーん、僕のアドバイスが理解されていないようです。tolsetをデスクトップに置くからうまくいっていないように思うのです。 C:¥ に置いたらいいと思うのですがどうですか。 -- K 2006-06-28 (水) 16:42:35
  • たびたび申し訳ありません。今度はtolsetフォルダをCドライブにコピー→projectsフォルダからhelloos0フォルダをtolsetフォルダにコピー→フォーマットしたフロッピーディスクをセット→!icons_nt.batをダブルクリック→installと入力しenterキーを押す でやってみましたが、フロッピーディスクには何もありません。因みにhelloosフォルダのルートはC:\tolset\helloos0です。フロッピーディスクは本日購入したもので、マイコンピュータからとコマンドプロンプトからformat a:を打ち込んでフォーマットの2パターンでやってみました。また、他のファイルの書き込みは出来ますので、フロッピーディスクドライブの故障等ではないと思うのですが。気になるのが、フォーマット後のフロッピーのプロパティを開くと、使用領域:0バイト、空き領域:1457664バイト となっています。ネットで検索してみましたが、boot領域と FAT領域およびdir領域で16896バイト使うようになっており、1474560バイトからの差し引きで1457664バイトになることは理解出来たのですが、これは関係あるのでしょうか。 -- 名無しさん 2006-06-28 (水) 18:44:44
  • ああもしかして、installしたあと、そのディスクで起動してみてないとかそんなことはありませんか?helloosはインストールしてもファイルができるわけではありません。つまり空っぽで正常ですよ。 -- K 2006-06-28 (水) 19:31:37
  • 申し訳ありませんでした。仰るとおり起動できました。最後の確認をせずに質問してしまいました。本当にごめんなさい。今後はこのような事がないように気をつけます。丁寧な解説ありがとうこざいます。また頑張ります。 -- 名無しさん 2006-06-28 (水) 19:42:35

リロード   新規 編集 差分 添付   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS
Last-modified: 2006-07-02 (日) 16:29:18 (4587d)