オペレーティングシステム
本書を読むには予備知識としてアセンブラの知識と、X86系CPUのレジスタなどのアーキテクチャの知識が必要である。
一般的にプログラミングにおいて、ハードウェアの制御は、コンパイラが対応していない命令(特権命令やIO命令など)はアセンブリ言語で記述する事になる。
もし知らなければwikibooks記事『X86アセンブラ』などで解説してある。特に『X86アセンブラ/GASでの文法』『X86アセンブラ/x86アーキテクチャ』『X86アセンブラ/x86アセンブラ』では初心者むけに説明してある。
本書では触れてないが「カーネル」とか「ユーザランド」とかの用語についてはwikibooks『高等学校工業/ソフトウェア技術』などで触れてある。
本書はタイトルが今のところは「オペレーティングシステム」だが、実際はコンピュータアーキテクチャ理論やデジタル回路理論など低レイヤーの理論や実務的知識が混在したものになっている(あとで整理する)。大学の科目の分類が縦割りのタコツボ・時代おくれで、全体像が分かりづらいので、予定では、今後の構成でも、意識的にコンピュータアーキテクチャなど関連分野の説明を、整理後にも、ある程度は残しておく予定。
なのでOSと言うタイトルなのにマイコンCPU(Z80など)にも触れているという状況である。
総論

オペレーティングシステムは、ユーザーがハードウェアレベルのプログラミングをする必要をなくし、パソコンをより使いやすくするために設計されています。UEFIを使用する場合、起動時にUEFIファームウェアがハードウェアを初期化し、UEFIブートローダーを使用してオペレーティングシステムを起動します。デバイスドライバは、オペレーティングシステム開発者が自分で作成する必要があります。
総論

BIOSは古くから使われてきたブートストラップ方式で、起動時にハードウェアを初期化し、オペレーティングシステムを起動していました。しかし、BIOSにはいくつかの制限があり、セキュリティや機能性の向上が必要とされるようになりました。そのため、UEFIが開発され、BIOSからUEFIに移行することが決定されました。UEFIは、より高度なセキュリティ機能、拡張性、性能の向上など、多数の利点を提供しています。現在、多くのPCはUEFIを使用しており、BIOSよりも優れたブートストラップ方式として認められています。
総論

ここでは、歴史的な経緯を紹介するためBIOSにも言及します。
総論

PCに電源を入れた瞬間から順に、以下のようなプロセスが起こります。
総論

UEFI/GPTの場合、PCに電源を入れた瞬間から順に、以下のようなプロセスが起こります。
総論

UEFI/GPTの場合は、UEFIがBIOSよりも高度な機能を提供するため、より高速で信頼性の高いブートプロセスを提供します。 また、GPTはMBRよりも多数のパーティションをサポートし、パーティションのサイズ制限も緩和されます。
総論

BIOSとUEFIは、システムの初期化やブートプロセスに必要なハードウェア情報の取得と管理を行うために、メモリマップを使用します。以下に、BIOSとUEFIのメモリマップの違いを説明します。
総論

UEFIのメモリマップは、より柔軟性があり、より高度な機能を提供します。UEFIは、物理メモリのアドレッシングやデバイスドライバの管理により高度な機能を提供するため、BIOSよりも多数のOSに対応することができます。また、UEFIのメモリマップは、UEFIサービスを介して、システムの状態の取得や変更を行うことができるため、BIOSよりも柔軟性があります。
総論

BIOSとUEFIは、ハードウェアの初期化やオペレーティングシステムの起動など、システムのブートプロセスに必要なタスクを実行するために、割り込みを使用します。以下に、BIOSとUEFIの割り込みの違いを説明します。
総論

U EFIの割り込みは、BIOSと比較して、より高度な機能を提供することができます。UEFIは、C言語で書かれたサービスを呼び出すことによって、より高度な機能を提供できます。これにより、UEFIは、BIOSよりも柔軟性があり、より多数のオペレーティングシステムやアプリケーションに対応することができます。
UEFIはなぜ必要になり何が優れているのか？

UEFI(Unified Extensible Firmware Interface)は、従来のBIOS(Basic Input/Output System)に代わる新しいファームウェア規格です。 UEFIは、従来のBIOSに比べていくつかの優れた機能を提供しています。本稿では、UEFIがなぜ必要になり、何が優れているのかについて説明します。
UEFIはなぜ必要になり何が優れているのか？

[UEFIとは何か、従来のBIOSとの違いは何かについて簡単に説明します。]
UEFIはなぜ必要になり何が優れているのか？

UEFI(Unified Extensible Firmware Interface)は、コンピュータの起動時に実行されるファームウェア規格です。従来のBIOS(Basic Input/Output System)に代わるものとして開発されました。BIOSは、1970年代に開発され、コンピュータの起動時に必要な基本的なハードウェア設定や起動ドライブの選択を行うために使用されていました。しかし、BIOSは時代遅れになり、UEFIが開発されるようになりました。
UEFIはなぜ必要になり何が優れているのか？

UEFIは、BIOSに比べて多数の優れた機能を提供しています。セキュリティ機能が強化されており、悪意のあるソフトウェアをブロックすることができます。拡張性が高く、ドライバーやアプリケーションをファームウェアに統合できるため、機能追加が容易になっています。起動時間の短縮や大容量ストレージのサポート、グラフィカルインターフェイスの向上なども特徴的です。
UEFIはなぜ必要になり何が優れているのか？

従来のBIOSは、16ビットのアセンブリ言語で開発されており、拡張性が低かったため、UEFIは64ビットのC言語で開発されました。また、UEFIはBIOSよりも起動時間が短く、セキュリティ面でも優れているため、現代のコンピュータに必要な要件を満たすようになっています。
UEFIはなぜ必要になり何が優れているのか？

UEFIは、現代のコンピュータにとって欠かせない規格となっています。UEFIの普及により、コンピュータの起動時間が短くなり、セキュリティや機能性も向上するとともに、グラフィカルインターフェイスによってユーザーエクスペリエンスも向上しています。
UEFIはなぜ必要になり何が優れているのか？

[UEFIは、セキュリティ機能が強化されています。Secure BootやUEFI Secure Flashなど、UEFIにはセキュリティ機能が多数実装されています。これらの機能は、コンピュータの起動時に悪意のあるソフトウェアをブロックすることができます。]
UEFIはなぜ必要になり何が優れているのか？

UEFIのセキュリティ機能の一つであるSecure Bootは、UEFIファームウェアが起動する前に、署名されたオペレーティングシステムやドライバーを認証することができます。これにより、起動時に悪意のあるソフトウェアが起動するのを防止し、システムのセキュリティを高めることができます。Secure Bootは、UEFIの機能の中でも特に重要なセキュリティ機能であり、WindowsやLinuxなどのオペレーティングシステムでもサポートされています。
UEFIはなぜ必要になり何が優れているのか？

また、UEFI Secure Flashは、UEFIファームウェアを保護する機能です。これにより、UEFIファームウェアが偽造されたり、マルウェアに感染したりすることを防止することができます。UEFI Secure Flashは、UEFIファームウェアの更新時にも役立ちます。署名されたファームウェアを使用することで、正当な更新プログラムであることを確認し、システムを保護することができます。
UEFIはなぜ必要になり何が優れているのか？

さらに、UEFIにはTrusted Platform Module(TPM)と呼ばれるセキュリティチップをサポートすることができます。TPMは、コンピュータに組み込まれた暗号キーを使用し、システムのセキュリティを強化するための機能です。TPMは、セキュリティに特に敏感な企業や政府機関などで広く使用されています。
UEFIはなぜ必要になり何が優れているのか？

TPMは、Windows 11 から必須要件となっています。
UEFIはなぜ必要になり何が優れているのか？

以上のように、UEFIはセキュリティ面でも優れた機能を提供しています。これらの機能により、悪意のあるソフトウェアからコンピュータを保護し、ユーザーの個人情報や重要なデータを守ることができます。
UEFIはなぜ必要になり何が優れているのか？

[UEFIは、BIOSよりも拡張性が高いです。UEFIは、ドライバーやアプリケーションをファームウェアに統合できるため、従来のBIOSよりも機能追加が容易になっています。]
UEFIはなぜ必要になり何が優れているのか？

UEFIの拡張性は、従来のBIOSと比べて大幅に向上しています。UEFIは、ドライバーやアプリケーションをファームウェアに統合できるため、従来のBIOSよりも機能追加が容易になっています。これにより、UEFIのファームウェアに新しい機能を追加することができ、コンピュータの機能を拡張することができます。
UEFIはなぜ必要になり何が優れているのか？

また、UEFIはファームウェアに対して、エクステンシブル・ファームウェア・インターフェース(EFI)と呼ばれる標準インターフェースを提供します。このインターフェースは、ハードウェアとソフトウェアの間の橋渡しを行う役割を果たし、システムの拡張性を高めることができます。EFIは、ドライバーやアプリケーションが互換性のある方法でインストール、実行されることを保証することができます。
UEFIはなぜ必要になり何が優れているのか？

さらに、UEFIは、ファームウェアを実行するプラットフォーム上で動作するアプリケーションのためのフレームワークを提供することができます。これにより、ファームウェア上で直接アプリケーションを実行することができ、オペレーティングシステムが起動する前に必要な処理を行うことができます。UEFIアプリケーションは、UEFIの拡張性を高め、システム管理やユーティリティなどの機能を提供することができます。
UEFIはなぜ必要になり何が優れているのか？

以上のように、UEFIは、従来のBIOSよりも拡張性が高く、ドライバーやアプリケーションをファームウェアに統合できるため、機能追加が容易になっています。さらに、UEFIはEFIやUEFIアプリケーションの提供により、システムの拡張性を高めることができます。
UEFIはなぜ必要になり何が優れているのか？

アーキテクチャ非依存のドライバとは、特定のCPUアーキテクチャに依存せず、複数のアーキテクチャに対応できるドライバのことです。これは、コンピュータのハードウェアが異なる場合でも、同じドライバを使用できるため、ドライバの開発や管理が簡素化され、互換性の向上につながります。
UEFIはなぜ必要になり何が優れているのか？

UEFIにおいても、アーキテクチャ非依存のドライバが使用されています。これらのドライバは、EDK II(EFI Development Kit II)に含まれており、プラットフォームのアーキテクチャに関係なく、UEFI上で動作することができます。
UEFIはなぜ必要になり何が優れているのか？

また、UEFIのアーキテクチャ依存のドライバと同様に、アーキテクチャ非依存のドライバもUEFIのドライバモデルに基づいて開発されています。UEFIのドライバモデルは、PEI(Pre-EFI Initialization)フェーズ、DXE(Driver Execution Environment)フェーズ、BDS(Boot Device Selection)フェーズ、そしてランタイムフェーズの4つのフェーズに分かれており、それぞれのフェーズで必要なドライバがロードされます。アーキテクチャ非依存のドライバは、これらのフェーズのうち、DXEフェーズでロードされます。
UEFIはなぜ必要になり何が優れているのか？

[UEFIは、BIOSよりも高速な起動時間を実現します。UEFIは、従来のBIOSに比べて、メモリの管理が効率的であるため、起動時間を短縮できます。]
UEFIはなぜ必要になり何が優れているのか？

UEFIは、BIOSよりも高速な起動時間を実現することができます。これは、UEFIが従来のBIOSに比べて、メモリの管理が効率的であるためです。UEFIは、BIOSと比べて、より多くのメモリをサポートすることができます。また、UEFIは、メモリ管理において、従来のBIOSよりも優れたアルゴリズムを採用しています。これにより、起動時のメモリ管理がより効率的に行われ、起動時間が短縮されます。
UEFIはなぜ必要になり何が優れているのか？

さらに、UEFIは、ブートローダーの読み込みにおいても優れた性能を発揮します。UEFIは、従来のBIOSよりも大きなディスク容量をサポートしており、UEFIファームウェアによるブートローダーの読み込み速度が速いため、起動時間を短縮することができます。
UEFIはなぜ必要になり何が優れているのか？

また、UEFIは、ファームウェアにおいて、並列処理を採用することができます。これにより、UEFIは、複数のタスクを同時に処理することができます。従来のBIOSでは、タスクを順次処理する必要がありましたが、UEFIでは、並列処理により、タスクを同時に処理することができるため、起動時間が短縮されます。
UEFIはなぜ必要になり何が優れているのか？

以上のように、UEFIは、BIOSよりも高速な起動時間を実現することができます。これは、UEFIがメモリの管理が効率的であり、ブートローダーの読み込みにおいても優れた性能を発揮するためです。さらに、UEFIは、並列処理を採用することができるため、起動時間を短縮することができます。
UEFIはなぜ必要になり何が優れているのか？

[UEFIは、BIOSよりも大容量ストレージのサポートが容易です。UEFIは、GUID Partition Table(GPT)をサポートしているため、2TB以上のHDDやSSDなどの大容量ストレージをサポートすることができます。]
UEFIはなぜ必要になり何が優れているのか？

UEFIは、BIOSよりも大容量ストレージのサポートが容易です。UEFIは、GUID Partition Table(GPT)をサポートしており、2TB以上のHDDやSSDなどの大容量ストレージをサポートすることができます。
UEFIはなぜ必要になり何が優れているのか？

従来のBIOSでは、Master Boot Record(MBR)を使用していたため、2TB以上のストレージをサポートすることができませんでした。MBRは、512バイトのサイズ制限があるため、2TB以上のストレージを使用する場合には、パーティションを複数に分割する必要がありました。しかし、UEFIは、GPTをサポートしているため、2TB以上のストレージを単一のパーティションとして認識することができます。これにより、大容量ストレージの管理が容易になり、ストレージの最適化がより簡単になります。
UEFIはなぜ必要になり何が優れているのか？

また、UEFIは、多くのストレージデバイスに対して、より高度な機能をサポートすることができます。UEFIは、Advanced Host Controller Interface(AHCI)やNVMeなどの高度なストレージインターフェースをサポートしており、SSDなどの高速なストレージデバイスの性能を最大限に引き出すことができます。
UEFIはなぜ必要になり何が優れているのか？

以上のように、UEFIは、BIOSよりも大容量ストレージのサポートが容易であるため、2TB以上のHDDやSSDなどの大容量ストレージをサポートすることができます。また、UEFIは、高度なストレージインターフェースをサポートすることができるため、ストレージデバイスの性能を最大限に引き出すことができます。
UEFIはなぜ必要になり何が優れているのか？

[UEFIには、BIOSよりも優れたグラフィカルインターフェイスがあります。これにより、BIOSよりも視覚的な操作が可能になり、ユーザーエクスペリエンスが向上します。]
UEFIはなぜ必要になり何が優れているのか？

UEFIには、BIOSよりも優れたグラフィカルインターフェイスがあります。従来のBIOSは、文字ベースのインターフェイスを使用しており、操作が限定されていました。しかし、UEFIは、グラフィカルインターフェイスを使用することができます。これにより、視覚的な操作が可能になり、ユーザーエクスペリエンスが向上します。
UEFIはなぜ必要になり何が優れているのか？

UEFIのグラフィカルインターフェイスは、通常、マウスやタッチパッドを使用して操作することができます。また、キーボードでも操作することができます。グラフィカルインターフェイスを使用することで、UEFIの設定や構成をより簡単に行うことができます。また、グラフィカルインターフェイスを使用することで、BIOSよりも視覚的な情報を提供することができます。
UEFIはなぜ必要になり何が優れているのか？

さらに、UEFIのグラフィカルインターフェイスは、スクリーンリーダーや拡張性の高いアシスト技術をサポートすることができます。これにより、視覚障害者などのユーザーでも、UEFIを使用することができます。
UEFIはなぜ必要になり何が優れているのか？

以上のように、UEFIには、BIOSよりも優れたグラフィカルインターフェイスがあります。グラフィカルインターフェイスを使用することで、UEFIの設定や構成をより簡単に行うことができ、視覚的な情報を提供することができます。また、スクリーンリーダーや拡張性の高いアシスト技術をサポートすることができるため、視覚障害者などのユーザーでもUEFIを使用することができます。
UEFIはなぜ必要になり何が優れているのか？

UEFI Shellとは、UEFIベースのシステムにおいて、UEFIファームウェアが提供するコマンドラインシェルのことです。UEFI Shellは、UEFIファームウェアによって提供される機能の一部であり、ユーザーがUEFIファームウェアを直接制御することができます。
UEFIはなぜ必要になり何が優れているのか？

UEFI Shellは、UEFIファームウェアによって提供されるため、UEFIベースのシステムにはすべて搭載されています。UEFI Shellは、UEFIの拡張性の高さを示す代表的な例であり、ドライバーやアプリケーションをシェルに統合することができます。また、UEFI Shellは、UEFIのセキュリティ機能を使用してシステムのセキュリティを確保することもできます。
UEFIはなぜ必要になり何が優れているのか？

UEFI Shellは、UEFIベースのシステムの設定やデバッグ、トラブルシューティングなどに使用されます。ユーザーは、UEFI Shellを使用して、ストレージデバイスの操作、ファイルシステムの操作、ネットワークの設定などを行うことができます。UEFI Shellは、コマンドラインインターフェースを提供するため、一般的なコマンドやスクリプトを使用してタスクを自動化することもできます。
UEFIはなぜ必要になり何が優れているのか？

UEFI Shellは、UEFIの機能を理解するために必要な知識を持つエンジニアや開発者にとって、非常に便利なツールです。UEFI Shellを使用することで、システムの動作やパフォーマンスを最適化することができます。
UEFIはなぜ必要になり何が優れているのか？

UEFIは、ネットワークブートに必要なプロトコルとサービスを提供することにより、ネットワークサポートを強化しています。UEFIネットワークスタックには、以下のようなプロトコルやサービスが含まれています。
UEFIはなぜ必要になり何が優れているのか？

UEFIのネットワークサポートは、OSに依存しないため、UEFI自体がネットワーク接続を確立でき、ネットワーク上のリソースにアクセスできることを意味しています。これにより、ネットワーク上のリモートサーバーからOSをブートすることができます。
UEFIはなぜ必要になり何が優れているのか？

UEFIは、複数のファイルシステムをサポートしており、主要なものとしてFAT32、NTFS、ISO 9660、UDFなどがあります。UEFIファームウェアには、これらのファイルシステムにアクセスするためのドライバーが組み込まれています。
UEFIはなぜ必要になり何が優れているのか？

特に、UEFIはFAT32ファイルシステムを必須としており、UEFIシステムパーティションにはFAT32が使用されます。このパーティションには、UEFIファームウェアや起動ローダー、設定ファイルなどが含まれています。UEFIファームウェアは、このパーティションを自動的に認識し、必要なファイルを読み込んでシステムを起動することができます。
UEFIはなぜ必要になり何が優れているのか？

また、UEFIはネットワークファイルシステムにも対応しており、PXEブートなどを利用して、ネットワーク上のサーバーからOSを起動することができます。これにより、大規模なサーバー環境でのOSのデプロイやメンテナンスが容易になります。
UEFIはなぜ必要になり何が優れているのか？

Macintoshは、UEFIの前身であるEFI(Extensible Firmware Interface)を採用しています。EFIは、Appleが1998年に開発したプラットフォームファームウェアで、Intelと共同で開発されました。当初はMacintoshのプラットフォームファームウェアとして採用され、後にUEFIの基礎となりました。
UEFIはなぜ必要になり何が優れているのか？

MacintoshのEFIは、標準的なPCのUEFIとは異なり、Macintosh固有の仕様があります。たとえば、MacintoshのEFIは、GPTスキームに基づくブートデバイスの選択方法が異なります。また、MacintoshのEFIには、OS XやmacOSの起動時に使用されるBoot Campなどの固有の機能が含まれています。
UEFIはなぜ必要になり何が優れているのか？

Macintoshは、UEFIを正式にサポートするようになったのは、2015年以降のMacモデルからとなりました。これにより、Macintoshも他のPCと同様に、UEFIの機能やセキュリティを活用することができるようになりました。
UEFIはなぜ必要になり何が優れているのか？

IBMは、UEFIの策定において重要な役割を果たしました。IBMは、PC BIOSの標準化を提唱しており、1990年代初頭にPC/AT互換機向けのPC BIOS規格を開発しました。しかし、PC BIOSは、コンピュータの機能拡張に対応できなくなってきたことから、IBMは新しいファームウェア規格の策定を提唱しました。
UEFIはなぜ必要になり何が優れているのか？

その結果、UEFIが開発され、2005年にはUEFIフォーラムが設立されました。IBMはUEFIフォーラムの設立メンバーの1つであり、UEFIの開発において重要な役割を果たしました。また、IBMは、x86_64アーキテクチャにおけるUEFIの開発にも取り組んでいます。
UEFIはなぜ必要になり何が優れているのか？

PowerPCは、UEFIのサポートを提供するアーキテクチャの1つです。UEFIは、x86アーキテクチャだけでなく、ARMやPowerPCなどの様々なアーキテクチャをサポートしています。PowerPCにおいても、UEFIを使用することで、従来のBIOSよりも高速な起動時間や、セキュリティ機能の強化などの恩恵を受けることができます。また、UEFIを使用することで、PowerPCに対するソフトウェア開発の容易化も期待されています。
UEFIはなぜ必要になり何が優れているのか？

Power Architectureは、サーバーや組み込みシステムで使用されるプロセッサアーキテクチャのファミリーで、PowerPCプロセッサを含んでいます。UEFIは、x86アーキテクチャに最初に導入されたが、その後、他のアーキテクチャにも広がっていきました。Power Architectureに対するUEFIのサポートは、2012年にUEFI Forumによって標準化されました。
UEFIはなぜ必要になり何が優れているのか？

Power Architectureにおいて、UEFIを実装する際には、EFIファームウェアをPowerPCアーキテクチャ向けに移植する必要があります。Power Architecture向けのUEFIの実装には、オープンソースのOpenPOWER FoundationとIBMのOpen Firmwareが利用されています。また、UEFIの実装には、Linuxカーネルのようなオープンソースソフトウェアも使用されています。
UEFIはなぜ必要になり何が優れているのか？

[UEFIは、BIOSに比べてセキュリティや拡張性、起動時間の短縮など多数の優れた機能を提供しています。今後も、UEFIはコンピュータ業界で重要な役割を果たすことが予想されます。]
UEFIはなぜ必要になり何が優れているのか？

以上のように、UEFIはBIOSよりも優れた機能を持ち、より高度なセキュリティや拡張性、起動時間の短縮などの面で優れています。さらに、UEFIは大容量ストレージのサポートや、より視覚的なグラフィカルインターフェイスも提供しています。これらの機能は、現代の高度なコンピュータシステムにとって必要不可欠であり、UEFIはその要件を満たすために開発されました。 UEFIがBIOSを置き換えることにより、コンピュータ業界はますます効率的になり、コンピュータの起動時間が短縮され、より高度なセキュリティ機能を持つことができます。UEFIは、現在のコンピュータシステムの基盤となっており、今後もますます重要な役割を果たすことが予想されます。
UEFIはなぜ必要になり何が優れているのか？

一般に、エミューレーターを使って実験します。
UEFIはなぜ必要になり何が優れているのか？

無料のフリーソフトでも、w:QEMUなどのエミュレータを使えるので、アセンブラのw:NASM(無料ソフト)などで(アセンブリコード入力を経由して)機械語を入力していきます。
UEFIはなぜ必要になり何が優れているのか？

※ 次の節で、qemuの使い方を大まかに説明する。
UEFIはなぜ必要になり何が優れているのか？

原理的には、アセンブラを経由せずともバイナリエディタ(Hex editor)といわれるもので機械語を直接に書いてプログラムするのも、原理的には可能です。そもそもアセンブラ自体どうやって開発されたかを想像すれば、おそらくバイナリエディタを、流通しているCPU用のアセンブラ命令にあわせて特化してプログラミング用に作られたソフトウェア(がアセンブラ)なのでしょう。
UEFIはなぜ必要になり何が優れているのか？

原理の理解としてはバイナリエディタの存在に気づくことも重要ですが、しかしバイナリエディタによるプログラミングではコード記述が覚えづらく非現実的ですし、一目では内容が分かりづらいです。なので、一般にアセンブラで入力していくのが、OS製作では現実的でしょう。
UEFIはなぜ必要になり何が優れているのか？

さて、NASMは、あくまでエミュレーター上での仮想化なので、完全には仕組みを再現していませんが、しかし個人の学習では、止む(やむ)を得ません。 もしもエミュレータを使わずに、BIOSのブート設定を 毎回 書き換えて実機のパソコンでブートの実験などを毎回したとしたら、とてもメンドウです。なので、エミュレータを使って、手間を省きます。
UEFIはなぜ必要になり何が優れているのか？

なお、一般的なLinuxなどでは、リリース直前の開発の後半などで、確認のために最終的に開発者たちはDVDなどに書き込んでブートしてみたりするなどして、実験します(いわゆる「ベータテスト」などで、DVDのISOを無料配布している)。
UEFIはなぜ必要になり何が優れているのか？

なお余談ですが、OS自作でなくCPU自作をしたい場合、w:GNU Binutilsなどの無料のクロスアセンブラがありますので、そういうのを活用します。半導体製造工場などを個人は持ってないので、ソフト的にエミュレートするしかありません。
UEFIはなぜ必要になり何が優れているのか？

エミュレータにも種類や方式が色々とあります。
UEFIはなぜ必要になり何が優れているのか？

方式のひとつとして、ホストOSのインストールされているパソコンのCPUを間借りする方式があります。
UEFIはなぜ必要になり何が優れているのか？

別の方式として、ホスト側のCPUは間借りせずソフトウェア内に仮想のCPUを制作する方式のものなどもあります。
UEFIはなぜ必要になり何が優れているのか？

コミュニティ ベース の qemuやBochs というエミュレータは、(ホストCPUをあまり)間借りしないで、ソフト的に仮想のCPUを作る方式のものである
UEFIはなぜ必要になり何が優れているのか？

いっぽう、オラクル社のVirtual Box やヴイエムウェア社のVMWare というエミュレータは、ホストPCのCPUを間借りする方式のものである。
UEFIはなぜ必要になり何が優れているのか？

私たちの学習の目的には、VirtualBox 的に複数のCPUが混ざり合うと学習的に分かりづらくなるので、qemuのようなソフト的にCPUの機能を再現するほうが分かりやすいと考え、qemuを優先して紹介することにする。
UEFIはなぜ必要になり何が優れているのか？

また、qemu はオープンソースである。
UEFIはなぜ必要になり何が優れているのか？

なお、Virtual Box は昔は非オープンソースだったが、現在はオープンソース版のVirtual Box がある。
UEFIはなぜ必要になり何が優れているのか？

なお、オラクル社のようなホストCPUを間借りする方式にも長所はあり、仮想化の中では処理速度を速くしやすいという長所もある。
UEFIはなぜ必要になり何が優れているのか？

本書では、とりあえず qemu を前提として説明する。
qemuの設定方法と使用方法

前提として、ダウンロードとインストールは既に終わっていると仮定する。
qemuの設定方法と使用方法

qemuは、コマンドプロンプトから使うソフトウェアである。
qemuの設定方法と使用方法

なので、まずパス(Path)を通さないといけない。
qemuの設定方法と使用方法

具体的には、環境変数PATHにqemuのあるフォルダーを追加する。
qemuの設定方法と使用方法

さて、パスが追加し終わったら、はたして本当にパスが通ってるの確認のため、Windwosのコマンド プロンプトを起動して
qemuの設定方法と使用方法

というふうに、コマンド「qemu-img」でも入力してみよう。
qemuの設定方法と使用方法

なお、「qemu」というコマンドは無いので、「qemu」とコマンド入力しても。
qemuの設定方法と使用方法

さて qemu-imgコマンドは引数を指定して使用するコマンドなので、上記コマンド「qemu-img」を実行すれば、端末上で引数が足りないことをqemuから警告されるハズである。
qemuの設定方法と使用方法

のように、qemuから警告されれば、ひとまずqemuのインストールは成功である。
qemuの設定方法と使用方法

あらかじめ、起動したいファイルを機械語で作っておき、たとえば、testos.img とかの名前をつけて、ホームディレクトリーなどコマンド端末の認識できる場所に保存しておく。
qemuの設定方法と使用方法

そしてコマンド端末で
qemuの設定方法と使用方法

のようにコマンド qemu-system-i386 を使えばいい。
qemuの設定方法と使用方法

では、そのOSイメージをどうやって作るか。
qemuの設定方法と使用方法

原理は、
qemuの設定方法と使用方法

まず、アセンブラの nasm で書く。(nasm は Netwide Assembler ともいう。)
qemuの設定方法と使用方法

あらかじめアセンブラコード形式で、OSにしたいファイルをアセンブリコードで作っておいて、testos.asm などの名前で保存しておく必要がある。
qemuの設定方法と使用方法

nasmなら、testos.asm を(PEフォーマットでない、直訳の)機械語にするコマンドは
qemuの設定方法と使用方法

だけで終わる。
qemuの設定方法と使用方法

そして、こうして作成したブートイメージをqemuで起動する方法は、ホームファイルに先ほど作成した testos.img を置いた上で、
qemuの設定方法と使用方法

のコマンドだけで終わる。
qemuの設定方法と使用方法

では、元になるアセンブリコードをどうやって調達するか? とりあえず、ネットで読者の勉強用に(彼らの)自作OSのブートローダーのアセンブリコードを公開してくれている人がチラホラといるので、彼らのコードで実験するのが良いだろう。
Bochs の使い方

ネット上に Bochs の使い方の入門書がぜんぜん無いので、wikibook で教えることにする。
Bochs の使い方

Bochsでは、アセンブルはできない。
Bochs の使い方

Bochsの用途は、すでに別ツール(たとえば nasm んど)で作成ずみの img ファイルをBochsで起動するだけのものである。
Bochs の使い方

asmファイルからimgファイルへのアセンブルは、あらかじめ nasm などで行っておく。
Bochs の使い方

Bochsの利便性は、コマンドを覚えなくて言いことである。起動コマンドのBochsだけ押せばウィンドウが起動するので、あとはそのウィンドウ側でGUI的に操作してエミュレータの起動をできるという便利ツールなエミュレータが Bochs である。
Bochs の使い方

さて、Boshs をインストールしてから、環境変数(パス)の設定を終えれば、 コマンドプロンプトで、コマンド bochs で起動する。つまり
Bochs の使い方

のように「bochs」の部分を入力する。
Bochs の使い方

で、起動するとダイアログ画面が現れる。
Bochs の使い方

さて、これだけでは、そもそも何のファイルを起動するかすらも設定されてない。なので、これから、このダイアログ画面で、それを設定する。
Bochs の使い方

まず、真ん中の項目(中央ペイン)にある「Edit Option」 の「Disk & boot」をダブルクリックすると、画面が遷移して、
Bochs の使い方

オプション画面である「Bochs Disk Options」画面になる。この項目で、何のファイルを起動するかを設定できる。 そのためには、
Bochs の使い方

その「Bochs Disk Options」画面の中で、タブ「ATA Channel 0」> 子タブ「First HD/CD on Channel 0」 をクリックすると出てくる画面に、
Bochs の使い方

上から2段目あたりに
Bochs の使い方

という項目があるので、その のなかに、起動したいimgファイル名を入れる。
Bochs の使い方

たとえば、「testos.img」ファイルを起動したいなら、
Bochs の使い方

のようになる。
Bochs の使い方

こうして、(おそらく)あとはこのオプション画面を終了して(ダイアログ・ウィンドウの右上のクローズ用の×ボタンを押せばいい)メインメニュー画面に戻り、右ペインにあるStartボタンを押せばいい。
Bochs の使い方

Panic ウィンドウが表示されて Message 欄に「specified geometry doesn't fit on disk」 と書いてあるが、このまま左下の欄にある Continue をクリックして、OKを押せばいい。
Bochs の使い方

なお、Path or physical device name の設定をしてないで空欄のままにしておくと、Startの際に Message 欄に 「no bootable device」 と出る。
Bochs の使い方

BochsのDtart>OKの後のエミュレート起動後の終了方法は、ウインドウの上部にあるメニューバーの右側のほうに、○印の中にタテ線「|」のある終了ボタン「(|)」があるので、これを押せばいい。(右上の×ボタンは使えない。×ボタンをクリックしても反応しない。)
擬似命令を使ってブートローダを作ろう

一般的なアセンブラには DB 命令というのがあり、これはORG命令などで指定したメモリに値を書き込む命令であるが、これで機械語も書き込みできる。
擬似命令を使ってブートローダを作ろう

もし、機械語を書き込む先を、メモリではなく、ハードディスクやUSBメモリやフロッピーディスクなどのブート可能なメディアにすれば、原理的には、これでブートローダを作れる。
擬似命令を使ってブートローダを作ろう

なお、DB とは data byte の略だと言われている。
擬似命令を使ってブートローダを作ろう

さて、では、OSを作るためには、まず、ブートセクタを書き込めばいいのですが、では、どういう内容のことを書き込めばいいのでしょうか。
擬似命令を使ってブートローダを作ろう

まず、ブートローダを書き込むわけですが、
擬似命令を使ってブートローダを作ろう

規格により、
擬似命令を使ってブートローダを作ろう

また、
擬似命令を使ってブートローダを作ろう

と決まっている。
擬似命令を使ってブートローダを作ろう

なので、このために
擬似命令を使ってブートローダを作ろう

をどこかに書き込む必要があります。
擬似命令を使ってブートローダを作ろう

times とは、nasm の擬似命令のひとつで、繰り返し命令のことです。
擬似命令を使ってブートローダを作ろう

「aa55」の署名を書き込まずにQemu上で機械語を起動しても、いくつかのメッセージのあとに「No Bootable device」などと表示されるだけです。
擬似命令を使ってブートローダを作ろう

さて、上記コードの場合は
擬似命令を使ってブートローダを作ろう

という命令です。
擬似命令を使ってブートローダを作ろう

$ は、そのtimes命令が出されたときの現在のアドレスです。
擬似命令を使ってブートローダを作ろう

$$ は、現在のセクションの最初のアドレスです。
擬似命令を使ってブートローダを作ろう

間違えて、「55aa」(マチガイ!)を書き込まないようにしてください。詳しくは『w:リトルエンディアン』で調べてください。
擬似命令を使ってブートローダを作ろう

MBRのサイズは512バイトと決まっており、その末尾2バイトに「aa55」と書き込むので、times 繰り返し命令 では「510」と2バイトぶん、余らせています。
擬似命令を使ってブートローダを作ろう

なので、とりあえず下記のように書き込みましょう。
擬似命令を使ってブートローダを作ろう

成功すれば、 qemu上で、「H」と表示されます。
擬似命令を使ってブートローダを作ろう

int 0x10 とは、ディスプレイへの割り込み命令のひとつです。int でBIOSにより割り込み命令を指示しています。intの引数で、どんな割り込みをするかを指示しており、int 0x10 はビデオサービスの割り込みです。
擬似命令を使ってブートローダを作ろう

ですが、int 0x10 だけでは、ディスプレイに文字も画像も表示できません。
擬似命令を使ってブートローダを作ろう

int 0x10に加えて、さらに、何を割り込ませるかの指定を行う必要があり、 mov ah, 0x0e で文字割り込みを指定しています。(※ 詳しくは『en:w:INT 10H』(英語版ウィキペディア)などを参照してください。)
擬似命令を使ってブートローダを作ろう

int 0x10 の命令は、上記の手本コードのように、 アキュムレータ レジスタで指示しなければなりません。
擬似命令を使ってブートローダを作ろう

なお、学校などで、もしかしたら、情報科学・計算機科学の教育では「アキュムレータ」とは「加減乗除などのためのレジスタ」とか習うかもしれませんが、しかし実際のCPUでは、(上記コード例のように)設定などの一時保存にもアキュムレータが流用されています。
擬似命令を使ってブートローダを作ろう

。CR0の最下位ビットのが0ならリアルモードです。実際には、プロテクトモードの移行のためには、さらに グローバル デスクリプタ テーブル(GDT)というものを作成する必要があるが、初学者には当面は知らなくていいので、もうプロテウトモードの説明は後回しにする(※ 現時点では未記述)。
擬似命令を使ってブートローダを作ろう

さて、この場合での int 0x10 は、alレジスタにある文字を表示できます。
擬似命令を使ってブートローダを作ろう

「Hello 」と表示させたければ、「H」だけでなく、同様の操作を繰り返し、「e」「l」「l」「o」を追加で表示させればいいだけなので、
擬似命令を使ってブートローダを作ろう

でブート後に「Hello」と表示できます。
擬似命令を使ってブートローダを作ろう

ラベルやジャンプ命令を使うと、繰り返し命令を実装できる。
擬似命令を使ってブートローダを作ろう

上の「Hello」のプログラムを、ラベルなどによる繰り返し処理でプログラムするとするなら、下記のようになるl
擬似命令を使ってブートローダを作ろう

org 0x7c00 とは、このようなテキスト処理をするのにBIOSに予約されている領域が7c00 なので、そこから書き始める必要がある。 org は擬似命令であり、これからの書き込みのメモリ位置を指定する命令である。
擬似命令を使ってブートローダを作ろう

また、 mov si, greet は形式的には、あたかもラベルgreetの内容を代入するかのような表現ですが、
擬似命令を使ってブートローダを作ろう

実際は、単にgreet ラベルの先頭のメモリを代入するだけです。
擬似命令を使ってブートローダを作ろう

int 0x10 は、繰返し命令の中で、毎回、使用する必要がある。
擬似命令を使ってブートローダを作ろう

次のようlodsb 命令とsiレジスタを使っても良い。lodsbは[ds:si]からalに1バイト読込む(ロード load)命令であり、さらに使用後に自動的にsiレジスタの指し示す位置を1バイトぶんだけインクリメント(DF=0の場合、DF=1の場合はデクリメント)してくれるので、手間が省ける。
擬似命令を使ってブートローダを作ろう

※ 2022年現在のx86プロセッサは、x86命令セットをマイクロ命令に分解し、マイクロ命令の組合せによっては複合的なマイクロ命令に合成し実行しています。ところが、lodsbの様な複雑な命令はマイクロ命令に翻訳されず固定的なマイクロコードにより実行されます。このため、かつて命令読込みのオーバーヘッドがなくせるという理由で「最適化」の代表だった複雑な命令を使うことは、現在は実行速度を低下させることになります。
擬似命令を使ってブートローダを作ろう

解説
擬似命令を使ってブートローダを作ろう

lodsb の内容は
擬似命令を使ってブートローダを作ろう

と等価である(DF=0の場合、また OF, SF, ZF, AF, PF は inc si の結果により修飾されるので厳密には異なる)。
擬似命令を使ってブートローダを作ろう

の代わりに
擬似命令を使ってブートローダを作ろう

でも良い。
擬似命令を使ってブートローダを作ろう

また test の代わりに
擬似命令を使ってブートローダを作ろう

でも良い。
擬似命令を使ってブートローダを作ろう

※ かつては、定数とレジスタの比較はレジスタファイルの読出しハザードがありストールの原因になりましたが、Sandy Bridgeマイクロアーキテクチャ以降のプロセッサであればマイクロフュージョンの対象となり、test命令やor命令を使うメリットはなく、專ら可読性を損なうだけです。
擬似命令を使ってブートローダを作ろう

まず、設定として、
擬似命令を使ってブートローダを作ろう

というコードが必要です。
擬似命令を使ってブートローダを作ろう

int 0x10 はグラフィック割り込みです。
擬似命令を使ってブートローダを作ろう

グラフィック割り込みの場合、ahは0に固定するように規格で決まっています。
擬似命令を使ってブートローダを作ろう

alによって、ビデオモードを指定しています。
擬似命令を使ってブートローダを作ろう

alが0x13なら、320 x 200ドット x 16色モード(8bitカラー)
擬似命令を使ってブートローダを作ろう

という意味です。
擬似命令を使ってブートローダを作ろう

一般的なパソコンではグラフィック描画用のVRAMアドレスは 0xa0000 から 0xaffffの領域が割り当てられています。
擬似命令を使ってブートローダを作ろう

なので、mov命令で、このアドレスに書き込むと、VRAMに直書きできます。
擬似命令を使ってブートローダを作ろう

で、問題は、通常の16ビットCPUモードのmov命令では、 メモリ番号は4ケタまでしかアクセスできない。「a0000」や「affff」は5ケタであることに注目。
擬似命令を使ってブートローダを作ろう

で、しかも、ブートローダ起動中のリアルモードでは、この16ビットCPUのモードである(らしい)
擬似命令を使ってブートローダを作ろう

なので、ともかく、通常の方法ではアクセスできない。
擬似命令を使ってブートローダを作ろう

5ケタのメモリ番号にアクセスするためには、
擬似命令を使ってブートローダを作ろう

「セグメント方式」という手法を使う。
擬似命令を使ってブートローダを作ろう

簡単に言うと、
擬似命令を使ってブートローダを作ろう

なお、上式の数は十進数である。
擬似命令を使ってブートローダを作ろう

16進数になおすと、単にセグメントベース×16は、末尾に0をつけたすだけである。
擬似命令を使ってブートローダを作ろう

これらのセグメントベースを格納するために「セグメントレジスタ」と言う専用のレジスタを使う。
擬似命令を使ってブートローダを作ろう

16ビットCPUのセグメントレジスタには
擬似命令を使ってブートローダを作ろう

の4つがある。
擬似命令を使ってブートローダを作ろう

なおFSとGSは32ビットCPU以降のセグメントレジスタである。
擬似命令を使ってブートローダを作ろう

CSは、CPUが実行するプログラムを格納するためのセグメントとして、CPUに使用させる。
擬似命令を使ってブートローダを作ろう

DSは、メモリの読み書きといったデータ関係の手段のセグメントとして、CPUに使用させる。
擬似命令を使ってブートローダを作ろう

SSはスタック関係のセグメントで使用。
擬似命令を使ってブートローダを作ろう

「エクストラ」とは、「その他」とか「追加の」のような意味。
擬似命令を使ってブートローダを作ろう

よく分からなければ「セグメントベース」でググると、詳しく紹介してくれている親切なITブロガー日本人さんが何人かネットにいるので、それらのページを参照してください。
擬似命令を使ってブートローダを作ろう

で、書式は、[セグメントベース:オフセット]の書式である。
擬似命令を使ってブートローダを作ろう

下記のようなコードで、ブート直後の画面の任意の場所にピクセル単位で色をぬれる。
擬似命令を使ってブートローダを作ろう

さて、mov 命令でメモリに書き込むには mov BYTE [123], 0x4567 の書式で書き込みます。
擬似命令を使ってブートローダを作ろう

この場合、メモリの123番地に、数値(16進数で)4567を書き込むわけです。
擬似命令を使ってブートローダを作ろう

[ ] をつけると、メモリへの指示だとアセンブラなどが認識します。
擬似命令を使ってブートローダを作ろう

ここでの「BYTE」 は1バイト長で書き込め、という命令です。
擬似命令を使ってブートローダを作ろう

2バイト長なら(BYTE でなく) WORD になります。
擬似命令を使ってブートローダを作ろう

4バイト長さなら DWORD になります。
擬似命令を使ってブートローダを作ろう

なお
擬似命令を使ってブートローダを作ろう

のように書いた場合は、メモリ123番地にある内容をレジスタalに書き込め、という命令になります。
擬似命令を使ってブートローダを作ろう

このように、(書き込みだけでなく)メモリからの読み込みにも [ ] は使えます。
擬似命令を使ってブートローダを作ろう

つまり、 [ ] をつけると、メモリへの指示だとアセンブラなどが認識します。
擬似命令を使ってブートローダを作ろう

0xa0000は画面の左上だが、そこに色を塗っても見づらいので、
擬似命令を使ってブートローダを作ろう

上記コードでは 0xa1111 から色を塗り始めることにした。
擬似命令を使ってブートローダを作ろう

なお 0xaffff は画面の右下である。
擬似命令を使ってブートローダを作ろう

画面の真ん中の上のほうに、なんか緑色っぽい線が5ミリくらいの長さで水平に引かれている結果が表示されると思う。
擬似命令を使ってブートローダを作ろう

上記のコードでは、分かりやすさを重視して、あえて繰り返し命令(ラベルやジャンプ命令で実装できる)を使わなかったが、実際に図形を書きたい場合は、ラベルを活用して繰り返し命令で処理するのが効率的だろう。
擬似命令を使ってブートローダを作ろう

なお、上記コード例1で
擬似命令を使ってブートローダを作ろう

とあるが、
擬似命令を使ってブートローダを作ろう

これを、(下記はエラーになる)
擬似命令を使ってブートローダを作ろう

とまとめても、なぜかエラーになる。
擬似命令を使ってブートローダを作ろう

なので、手本のコードのように、レジスタを経由する必要がある。
擬似命令を使ってブートローダを作ろう

一般的名パソコンでは、英数字などのテキスト出力も、ブート直後の段階では、専用のメモリ領域が用意されるので、このメモリを書き換えることで、テキスト文字を出力できます。(ただし、漢字や平仮名・カタカナなどは無理。)
擬似命令を使ってブートローダを作ろう

ブートプログラムの確認作業などに、便利な機能でしょう。
擬似命令を使ってブートローダを作ろう

また、 int 命令によって、1文字ずつ書いていく方法は、原理は単純ですが、実装では、処理速度があまり速くないという問題があります。
擬似命令を使ってブートローダを作ろう

ラベル命令やジャンプ命令などを使ってコードの行数を減らしても、int命令で書き込みをするよりも、テキスト用メモリを直に書き換えするほうが処理速度が速くなります。
擬似命令を使ってブートローダを作ろう

一般的なパソコンでは 0xb800 からの領域がテキスト用メモリに割り当てられています。
擬似命令を使ってブートローダを作ろう

なので、まず
擬似命令を使ってブートローダを作ろう

と指定します。
擬似命令を使ってブートローダを作ろう

メモリ領域のうち、0xa0000 から0xfffff までの領域は通常のパソコンでは、BIOSがハードウェアを管理するために使用することになっています。
擬似命令を使ってブートローダを作ろう

このため、それらハード管理以外のソフトウェア的な処理をするためにメモリ使用したい場合は、この領域を避けてメモリを使用する必要があります。
擬似命令を使ってブートローダを作ろう

こういった用途には Linuxなどの現代のオープンソースOSでは、 メモリを使用する際には 0x100000 以降の領域を使うのが一般的です。
擬似命令を使ってブートローダを作ろう

原理的には 0xa0000 未満の領域も使用可能ですが、使いすぎ等のミスによって0xa0000以降にハミ出る恐れがあるので、なるべく 0x100000 以降の領域だけを使うほうが安全でしょう。
ハードディスクなどへのアクセス

まず、フロッピーディスクやハードディスクなどに読み書きのできる割り込み命令で、 int 0x13 というのがあります。
ハードディスクなどへのアクセス

2000年代の現代では、これを大容量デバイス用に拡張した拡張 int 0x13 というのがあります。
ハードディスクなどへのアクセス

どちらの int 0x13 とも、ドライブ番号は、DLレジスタ(データレジスタの下位(Low)の部分)で指定します。
ハードディスクなどへのアクセス

このように、int 0x13 では、割り込み時におけるレジスタの役割が決められています。
ハードディスクなどへのアクセス

さて、拡張 int 0x13 を使って、フロッピーディスクやハードディスクなどの記憶媒体に割り込みをできます。(USB対応については今後の見通しは不明。書き込みできるものもあるようだが、)
ハードディスクなどへのアクセス

int 13h は、レジスタなどの数値で 書き込みの方式や対象を指定します。拡張 int 13h と、非格調 int 13h では、レジスタの解釈が違っております。
ハードディスクなどへのアクセス

格調 int 0x13 のほうの方式を LBA方式といいます。
ハードディスクなどへのアクセス

格調 int 0x13 では、レジスタに収まりきらない様々な情報を、任にの Disk Addres Packet (DAP)という場所に配置しており、その形式も決まっています。
ハードディスクなどへのアクセス

※ 調査中
ハードディスクなどへのアクセス

なお、拡張されてない int 0x13 は、ハードディスク容量などの小さい時代の古い規格のものであり、現代では、読み書きに時間が掛かったり、あるいは不可能です。
ハードディスクなどへのアクセス

非拡張の int 0x13 では、ドライブ番号は、DLレジスタ(データレジスタの下位(Low)の部分)で指定します。
ハードディスクなどへのアクセス

AHレジスタが 0x02 なら 読込み、AHレジスタが 0x03 なら 書込み です。
ハードディスクなどへのアクセス

int 13hともいう。
キーボードサービス

まず、int命令で、キーボードサービスの割りこみがあり、 int 0x16 がキーボードサービスである。
キーボードサービス

さてint 0x16 を呼び出す際、
キーボードサービス

なら、ah = 0x00 は、キーボードのキー入力待ちである。ah = 0x10 だと拡張キーボード対応らしい 。
キーボードサービス

実は一般的なパソコンでは、アセンブリ言語の命令で、いくつかのハードウェアに読み書きのアクセスするための、専用の命令がある。
キーボードサービス

IN 命令と、 OUT命令である。
キーボードサービス

そして、キーボードなど、昔のどこのパソコンにも存在したハードウェアは、実はハードウェア番号が決められている(「I/Oポートアドレス」などという)。
キーボードサービス

たとえば、キーボードはハードウェア番号(I/Oポートアドレス)が十六進数で0x60 番である。(メモリマップとは別。メモリアドレスの0x0060などにdb命令で書き込んでも、目的のハードにはアクセスできない。 )
キーボードサービス

IN命令で、引数で指定したレジスタ(普通はALレジスタやAXレジスタを指定する)に、もうひとつの引数で指定した目的デバイスから送られた値が保存されます。(引数の順序はアセンブラの種類などによって異なるので、説明を除外。)
キーボードサービス

また、OUT命令で、引数で指定したレジスタ(普通はALレジスタやAXレジスタを指定する)に格納されている値が、もうひとつの引数で目的デバイスに送られます。
キーボードサービス

たとえば、下記のようなコードで、キーボードの文字「E」または前後のWかRを押すと、1行ぶん下の位置に文字「G」が表示される。
キーボードサービス

in al, 0x60 を使えば、キーボードコントローラーから送られてきたキーも al に入力されます。
キーボードサービス

in al, 0x60 とは、けっして「レジスタ al に 60 を代入しろ!」(×、マチガイ)という意味ではなく(そもそも定数の代入だけなら mov 命令だけで可能である)、「ポートアドレス 0x60番 のポートから送信されてきたデータを、レジスタalに代入しろ」という意味です。勘違いしないでください。
キーボードサービス

そして、キーボードコントローラーのポートアドレスが 0x60 なので、めでたく、上記コードでキーボードから押されたボタンの情報を受け取れます。
キーボードサービス

さて、キーボードを押したとき、押したボタンに対応するスキャンコードが、パソコン内部にあるキーボードコントローラー(KBC)という装置に送信される仕組みになっています。
キーボードサービス

このスキャンコードは、アスキーコードとは異なります。
キーボードサービス

上記コード例にある cmp al, 18 の数値「18」とは、スキャンコードでの番号です。だいたいスキャンコードで18番のあたりが文字 W,E,R のどれかのあたりです。
キーボードサービス

また、アスキーでは「2」と「"」とは別の文字ですが、しかし日本語キーボードの場合、「2」と「"」はボタンが同じなので、スキャンコードでは同一になります。
キーボードサービス

このように、物理的に同じ位置にあるかどうかで、スキャンコードは決まります(なお、JIS配列キーボードやUS配列キーボードのように言語が違うキーボードでも、位置が同じなら、ほとんどのボタンのスキャンコードの内容も同じ場合が多い)。
キーボードサービス

また、スキャンコードは、押されている時に送信されるコード(「メイク コード」という)と、離した瞬間に送信されるコード(「ブレイク コード」という)とが、それぞれ違うコードです。
キーボードサービス

日本語キーボードは OADG という規格にほぼ統一されています。
キーボードサービス

ですが、世界的にスキャンコードの規格は、古いものでも3種類くらいあり、さらにUSBキーボードの規格は別です。このため、日本語 OADG のスキャンコードも、現在でも3種類くらいあります。
キーボードサービス

下記のリンクが詳しいです。
キーボードサービス

なお、一般的に「メイクコード/ブレイクコード」の書式です。
キーボードサービス

たとえば、ボタン「1」(「!」と同じ)のスキャンコードが「16 / F0 16」とかかれていれば、メイクコードが「16」であり、ブレイクコードが「FD 16」という意味です。(ある規格では、ブレイクコードは、メイクコードの先頭にF0がついたものになっている。)
キーボードサービス

なお、キーボードコントローラーもインテルなどが製造していました。かつて Intel i8042 というキーボードコントローラーが有名でした。
キーボードサービス

より正確な仕組みとしては、シリアル通信(PS 2 信号)などで送られた信号をKBCあたりでスキャンコードに変換しているわけですが、CPUから見ればスキャンコードしか見えないので、あまり気にしなくていいでしょう。
キーボードサービス

0から作るOS開発 カーネルローダその3 プロテクティッドモードへの移行とA20
キーボードサービス

※ 本wikibooksの当ページが完成するまでの間、上記の参考サイトが分かりやすくて役立つと思いますので勉強してください。
キーボードサービス

次のようなコードを使えばledが点滅するらしいのだが、しかしエミュレータでの実験では分からなかった(Windows起動により、すでにLEDが点灯しているので、区別しづらい)。
キーボードサービス

0xED というのは、LED点灯に関する命令の番号。
キーボードサービス

一般的なブートローダのいくつかには、ブートセクタに BIOS Parameter Block (BPB)というものが書かれており、これは BIOS への指示や設定を出すブロックです。
キーボードサービス

パソコンの電源を投入して、まず最初に起動するのは BIOS なのですから、このブロックが必要です。少なくとも Windows系OSのブートローダーでは、そうなっていると言われています。
キーボードサービス

このように、ブートセクタは、書式がほぼ決まっています。
キーボードサービス

という構成になっています。
キーボードサービス

ジャンプしてしまうので、BPB はプログラムカウンタでは読み取れず、BPBはBIOSしか読み取れないことに注目しましょう。
キーボードサービス

市販のOS自作本にある、DB命令で書き込む冒頭の 「DB 0xeb」 と言うのも、このJMP命令のことです。
キーボードサービス

JMP命令はX86系CPUの機械語では eb です。
キーボードサービス

『IA-32 インテル®アーキテクチャソフトウェア・デベロッパーズ・マニュアル』『中巻A:命令セット・リファレンスA-M』3-411
プロテクトモード

プロテクトモードとは、CPUの32ビットモード(および32ビット以上のモード)のこと。
プロテクトモード

32ビットモードには、アクセス権の無い状態からのアクセスを禁止するという、特権レベルによる保護機能などがあるので、プロテクトモードという。
プロテクトモード

プロテクトモードにいこうするためのコードの一部を抜粋すると、おおむね書きのような感じになる。
プロテクトモード

cr0レジスタの最下位ビット(PEビットという)が1だとプロテクトモードである、という仕様である。
プロテクトモード

の3行の処理で、cr0レジスタの最下位ビットを1に設定している。なお、このcr0の最下位ビットのことをプロテクト・エネーブルド pr0tect enebled という意味でPEビットという。
プロテクトモード

設定後にわざわざジャンプ命令 jmp を通す理由は、CPUの先読みした命令を破棄するためである 。ジャンプ命令には、先読みを破棄する機能がある。
プロテクトモード

なお、パイプラインという仕組みにより、CPUは先読みしている。このパイプラインの先読みを破棄することをフラッシュという。
プロテクトモード

実はCPUは、いくつか先の命令をすでに先読みしている(これがパイプライン)。プロテクトモード以降では、それが不具合の原因になるので、いったんフラッシュする(カラにする)必要がある。
プロテクトモード

なので、CPUのパイプラインをフラッシュするためにジャンプ命令を使っている。
プロテクトモード

さて、一般にWindowsやLinuxなどのOSには、パーティションという、インストール時にハードディスクの使用領域を決める機能がある。
プロテクトモード

実はCPU側に、メモリに関する機能だが、似たような動作を機能がある。
プロテクトモード

GDT(グローバル ディスクリプタ テーブル Global Descriptor Table)といって、メモリのアドレスのどこからどこまでがそのCPUで使える領域を定義する機能がある。
プロテクトモード

で、プロテクトモードでは、あらかじめ、このGDTを設定しないと動作しない。そういう仕様で、むかしのインテルあたりの人が決めてしまったので、従うしかない。
プロテクトモード

で、実はCPUにGDTレジスタ(GDTR)という、GDTの場所を保管する専用レジスタがあるので、このGDTレジスタにGDTのアドレスなどの情報を入れる必要がある。
プロテクトモード

さらに、このGDTレジスタに書き込むための専用の命令 lgdt (ロードgdt)があるので、これを使う必要がある。(「書き込みだから save では?」という疑問も、わくかもしれないが、こういう名前に決まってしまってるので、従うしかない。)
プロテクトモード

同様に IDT(Interrupt Descriptor Table)というのがある。
プロテクトモード

さらに、16ビット時代の昔はCPUのアドレスバスが20本までだったので、リアルモードでは利用するアドレスバスが20本までという制限が掛かっており、A00からA19までを使用している。A20以降はマスクされている。
プロテクトモード

この制限のことを「A20のマスク」という。プロテクトモードに以降するためには、このA20のマスクを解除しないといけない。
プロテクトモード

下記の順序で作業しないといけない。そういう仕様である。
プロテクトモード

A20マスクの解除には複数の方法がある。
プロテクトモード

キーボードコントローラから解除できる理由は、単に昔のインテルかどこかの人が設計したとき、たまたまキーボードコントローラ用のアドレスバスが余ってたからだけと言う理由らしく、あまり技術的な深い意味は無い。
プロテクトモード

なお作業の順番について、A20のマスク解除の順場は多少前倒しになっても平気なようである。
Linuxのブートローダはkernelには無い

ある程度、理解が進むと、 Linux など実際に活用されているオープンソースOSのブートローダを調べたいと感じるかもしれません。
Linuxのブートローダはkernelには無い

まずOSの起動で最初に動くのはブートローダだからです。
Linuxのブートローダはkernelには無い

しかし Linux を開発している kernel.org のサイトには、ブートローダは無いのです。
Linuxのブートローダはkernelには無い

Linux で仕様されているブートローダは、Gnu(グニュー)というオープンソース・ソフトウェア団体の作っている GRUB (グラブ)というソフトウェアです。
Linuxのブートローダはkernelには無い

なのでブートローダをソースコードを探す場合も、Gru Grub のウェブサイトを探す必要があります。
Linuxのブートローダはkernelには無い

書籍だとアスキー出版『Linuxのブートプロセスを見る』などの題名の書籍で Grub を紹介してるので、ついつい何となく、ソースコードを読むためにリーナスの管理している kernel.org を探しがちですが、しかし、よくよく考えたら、Grub は Linux ではありません(実際、Windows版Grubもある)。
Linuxのブートローダはkernelには無い

もし『Grubのブートプロセスを見る』だと売れないので、出版社が「Linuxのブートプロセスを見る」という題名にしたのでしょう。
Linuxのブートローダはkernelには無い

私たちOS開発をしたい読者は、けっして出版社にマインド・コントロールされたままでは、イケません。真実「Grub は Linux ではない」に気がつきましょう。
Linuxのブートローダはkernelには無い

Grub のソースコードのダウンロードにgitコマンド(git clone などのコマンド)が必要なので、あらかじめインストールしておくか、Gitコマンドが最初から使える Ubuntu か Fedora などのLinuxをパソコンにインスト-ルしておきましょう。
Linuxのブートローダはkernelには無い

Git コマンドのインストールと、Git Hub などのウェブサイトとは別物ですので、混同しないようにしましょう。
Linuxのブートローダはkernelには無い

外部リンク: Gitの公式サイト
Linuxのブートローダはkernelには無い

なお Windows版のGitはVimエディターにしか対応してないとの情報がインストール時に出ますが、しかしわざわざvimを別途インストールしなくても、Win版GitをインストールすればWindwowsコマンドプロンプトでGitコマンドを使えるようになります。