OSを作成します:問題1

この一連の記事は、低レベルプログラミング、つまり、コンピューターアーキテクチャ、オペレーティングシステムの設計、アセンブリ言語プログラミング、および関連分野を専門としています。 これまで、2人のhabrayuzerが執筆に携わっています-ileypehatです。 多くの高校生、学生、プロのプログラマーにとって、これらのトピックを学ぶことは非常に困難です。 低レベルプログラミングに関する多くの文献とコースがありますが、完全で包括的な図を得るのは困難です。 アセンブラとオペレーティングシステムに関する1冊または2冊の本を、少なくとも一般的には読むのは難しく、この鉄、シリコン、および多くのプログラムの複雑なシステムが実際にどのように機能するのかを想像することはできません。



それぞれが独自の方法で学習の問題を解決します。 誰かがたくさんの文学を読み、誰かが途中ですぐに練習と理解に切り替えようとし、誰かが勉強したことすべてを友人に説明しようとします。 そして、これらのアプローチを組み合わせることにしました。 したがって、この一連の記事では、簡単なオペレーティングシステムを作成する方法を順を追って説明します。 記事は概要的な性質のものです。つまり、包括的な理論情報はありませんが、常に優れた理論資料へのリンクを提供し、発生するすべての質問に答えようとします。 明確な計画はありませんので、フィードバックを考慮して、多くの重要な決定が途中で行われます。



おそらく、開発プロセスを意図的に停止させて、誤った決定の結果をすべて理解し、技術スキルを磨くことができるようにします。 ですから、私たちの決定を唯一の正しいものとしてとらえて、盲目的に私たちを信じないでください。 私たちは、読者が記事の議論に積極的に取り組むことを期待することを再度強調します。これは、後続の記事の全体的な開発と執筆に大きな影響を与えるはずです。 理想的には、読者の何人かが時間の経過とともにシステムの開発に参加してほしい。



読者は、コンピューターアーキテクチャの基本概念だけでなく、アセンブラーとC言語の基本についてもすでによく知っていると想定します。 つまり、レジスタ、つまり、ランダムアクセスメモリが何であるかについては説明しません。 十分な知識がない場合は、いつでも追加の文献を参照できます。 良い記事があるサイトへの参照とリンクの短いリストは、記事の最後にあります。 また、Linuxを使用できるようにすることをお勧めします。これは、すべてのコンパイル手順がこのシステム専用に提供されるためです。



そして今-ポイントに近い。 この記事の残りの部分では、古典的なHello Worldプログラムを作成します。 Hello Worldは少し具体的です。 どのオペレーティングシステムからも起動されませんが、いわば、ベアメタル上で直接起動されます。 コードを直接記述し始める前に、これをどのようにしようとしているかを正確に把握しましょう。 このためには、コンピューターをロードするプロセスを考慮する必要があります。



そこで、お気に入りのコンピューターを使用して、システムユニットの最大のボタンを押します。 面白いスクリーンセーバーが表示され、システムユニットがスピーカーからビープ音を鳴らし、しばらくするとオペレーティングシステムが起動します。 ご存知のように、オペレーティングシステムはハードドライブに保存されていますが、ここで疑問が生じます。オペレーティングシステムはどのようにして魔法のようにRAMから起動し、実行を開始したのでしょうか。



知っておいてください。コンピュータに存在するシステムがこれを担当し、その名前はあなたの言語のヒントであるWindowsではなく、NOです。これはBIOSと呼ばれます。 その名前は、基本入出力システム、つまり基本入出力システムとしてデコードされます。 BIOSはマザーボード上の小さなマイクロ回路上にあり、大きなONボタンを押すとすぐに起動します。 BIOSには3つの主なタスクがあります。
  1. 接続されているすべてのデバイス(プロセッサ、キーボード、モニター、RAM、ビデオカード、頭、腕、翼、脚、尾...)を検出し、適切な動作を確認します。 POSTプログラム(Power On Self Test)がこれを担当します。 バイタルアイロンが見つからない場合、ソフトウェアは役に立ちません。この時点で、システムスピーカーは不吉な何かをきしみ、OSに到達しません。 悲しいことについては話しましょう。完全に機能するコンピューターがあり、喜んで2番目のBIOS機能に進んだとします。
  2. ハードウェアを操作するための基本的な機能セットをオペレーティングシステムに提供します。 たとえば、BIOS機能を使用して、画面にテキストを表示したり、キーボードからデータを読み取ったりできます。 したがって、これは基本入出力システムと呼ばれます。 通常、オペレーティングシステムは割り込みを介してこれらの機能にアクセスします。
  3. オペレーティングシステムのブートローダーを起動しています。 この場合、原則として、ブートセクタ-記憶媒体の最初のセクタ(ディスケット、ハードドライブ、CD、フラッシュドライブ)が読み取られます。 メディアのポーリング順序は、BIOSセットアップで設定できます。 ブートセクターには、ブートローダーと呼ばれることもあるプログラムが含まれています。 大まかに言って、ブートローダーのタスクは、オペレーティングシステムの起動を開始することです。 オペレーティングシステムをロードするプロセスは、非常に具体的であり、その機能に大きく依存する場合があります。 したがって、プライマリブートローダーはOSの開発者によって直接書き込まれ、インストール中にブートセクターに書き込まれます。 ブートローダーが起動すると、プロセッサはリアルモードになります。


悲しいニュース:ブートローダーのサイズは512バイトでなければなりません。 なぜそんなに少ないのですか? これを行うには、デバイスのフロッピーディスクに精通する必要があります。 有益な画像を次に示します。







写真はディスクドライブの表面を示しています。 フロッピーディスクには2つの表面があります。 各表面にリング状のトラック(トラック)があります。 各トラックは、セクターと呼ばれる小さな円弧状の部分に分割されます。 したがって、歴史的に、ディスケットのセクターのサイズは512バイトです。 ディスクの最初のセクタであるブートセクタは、BIOSによってオフセット0x7C00のゼロメモリセグメントに読み込まれ、このアドレスに制御が渡されます。 ブートローダーは通常、OS自体ではなく、ディスクに保存されている別のブートローダープログラムをメモリにロードしますが、何らかの理由(おそらくこの理由がサイズである)が1つのセクターに収まりません。 そしてこれまでのところ、私たちのOSの役割は平凡なHelloWorldによって果たされてきたので、私たちの主な目標は、コンピューターに1つのセクターでさえもOSの存在を信じさせ、起動させることです。



ブートセクターはどのように配置されますか? PCでは、ブートセクタの唯一の要件は、最後の2バイトに値0x55および0xAA(ブートセクタの署名)を含めることです。 だから、私たちが何をする必要があるかは多かれ少なかれ明らかです。 コードを書きましょう! 上記のコードはyasmアセンブラ用に書かれています。



section .text
     use16
     org  0x7C00  ;      0x7C00
start:
     mov  ax, cs
     mov  ds, ax  ;   
 
     mov  si, message
     cld              ;    
     mov  ah, 0x0E    ;   BIOS
     mov  bh, 0x00    ;  
puts_loop:
     lodsb            ;     al
     test al, al      ;     
     jz   puts_loop_exit
     int  0x10        ;   BIOS
     jmp  puts_loop
puts_loop_exit:
     jmp  $           ;  
 
message:
     db   'Hello World!', 0
finish:
     times 0x1FE-finish+start db 0
     db   0x55, 0xAA  ;   

      
      







. org 0x7C00



, ( , ) (puts_loop, puts_loop_exit, message



). , 0x7C00.



    mov         ax, cs
    mov         ds, ax

      
      





(ds



) (cs



), , .



«Hello World!». 0x0E



0x10



. :

AH = 0x0E



( )

BH =



( , 0)

AL =



ASCII-



«jmp $



» . , . , .



«times 0x1FE-finish+start db 0



» ( ) . , .



, . , , — yasm. Linux. :



$ yasm -f bin -o hello.bin hello.asm
      
      







hello.bin . (, fd ).



$ dd if=hello.bin of=/dev/fd
      
      







, , , qemu VirtualBox. « ».

:



$ dd if=/dev/zero of=disk.img bs=1024 count=1440
      
      







:

$ dd if=hello.bin of=disk.img conv=notrunc
      
      







qemu:

$ qemu -fda disk.img -boot a
      
      







qemu «Hello World!». . .



  1. :
    • . . «Assembler DOS, Windows Unix»
    • DOS
  2. :
    • ., . « C»
    • . « C»
  3. :
  4. :
    • . « »
    • . « IBM PC. »
    • . «. »



All Articles