

起動直後にBIOSプログラムを実行するためには、BIOS
ROMのアドレス0xffff0から起動する必要があります。AMDやintelの仕様書にはそう書かれていますが、私は納得していません。納得できないのは、CPUの初期信号を発行してから、BIOSの0xffff0を実行するまでの過程が書かれていないからです。どなたか、その間に何が起こっているのか教えてください。

私自身の考えでは、インとアウト命令でBIOSに行くことを考えましたが、それではセキュリティやパフォーマンスが低下してしまいます。CPUからBIOSへ直接つながる専用の回路も考えましたが、なぜlinuxやwindowsのosからbiosのアップデートやROMの内容が読み込みが可能なのかと考えました。上記の２つのパターンではないと思いました......  
BIOSをいじれないのは寂しいですね。


CC BY-SA 4.0
2021-12-12T05:49:03.840
84075
2021-12-14T01:17:15.910
2021-12-12T13:09:00.710
4236
question
x86 bios
起動直後のCPUはどのようにしてBIOSにたどり着くのでしょうか？


>
> 納得できないのは、CPUの初期信号を発行してから、BIOSの0xffff0を実行するまでの過程が書かれていないからです。どなたか、その間に何が起こっているのか教えてください。

何も起こっていません。[IA-32 インテル アーキテクチャ ソフトウェア・デベロッパーズ・マニュアル 下巻：
システム・プログラミング・ガイド](https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/IA32_Arh_Dev_Man_Vol3_i.pdf#page=369)には次のように記述されています。

> ## 第 9 章 プロセッサの管理と初期化
>
> ### 9.1. 初期化の概要
>
> #### 9.1.4. 最初に実行される命令
>
> ハードウェア・リセット後にフェッチされてから実行される最初の命令は、物理アドレス FFFFFFF0H
> に配置される。このアドレスは、プロセッサの最上位にある物理アドレスの 16 バイト下に位置している。ソフトウェア初期化コードをストアしている
> EPROMは、このアドレスに配置されなければならない。

と説明されている通りです。CPUはハードウェア・リセットされた場合、物理アドレス FFFFFFF0H
の命令を実行するように作られています。そのため、PCメーカーはこのアドレスにBIOSコードを配置する必要があります。  
（コメントには000FFFF0Hと書きましたが、これは486辺りの知識で古かったです）

「ハードウェア・リセット」については[同書9.1](https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/IA32_Arh_Dev_Man_Vol3_i.pdf#page=363)に

>
> 電源投入の後、またはRESET#ピンのアサーションの後、システムバス上の各プロセッサは、それぞれのハードウェアを初期化し（これをハードウェア・リセットと呼ぶ）、

と説明されています。

* * *

kunifさんのコメントより

> こんな情報 システムマネジメントモード - Wikipedia
> もあるので、理屈と言うかそう言いたい感覚は分かりますが、それを知ることが出来る/知っている必要があるのはインテルやx86互換CPUを開発するベンダーの関係者だけでしょう。

そんなことはありません。例に挙げておられますシステム管理モード（SMM: System Management Mode）についても[同書 第 13 章
システム管理](https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/IA32_Arh_Dev_Man_Vol3_i.pdf#page=511)に34ページにわたって解説されています。一定の情報は公開されています。

本題のCPUの初期化部分に関しても

> ハードウェアのリセット後、最初に CS
> レジスタに新しい値がロードされると、プロセッサは、実アドレスモードでアドレス変換に適用される通常の規則に従う（つまり、[CSベースアドレス =
> CSセグメント・セレクタ∗16]）。EPROMベースのソフトウェア初期化コードが完了するまで CS
> レジスタ内のベースアドレスが変更されないようにするため、コードに far ジャンプまたは far コールを入れてはならない。

等、常識と言っても過言ではないレベルまで丁寧に説明されていますし、BIOSが起動後に行うべき処理についても[9.10.
初期化とモード切り替えの例](https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/IA32_Arh_Dev_Man_Vol3_i.pdf#page=381)などで具体的なコード例も掲載されています。

これらを読んだと称する質問者さんが「納得できないのは、CPUの初期信号を発行してから、BIOSの0xffff0を実行するまでの過程が書かれていない」と書かれていますが、何に納得できないのか本当にわからないというのが正直なところです。


CC BY-SA 4.0
2021-12-12T10:23:13.160
84081
2021-12-13T23:18:01.393
2021-12-13T23:18:01.393
4236
4236
84075
answer


CPUにはプログラムカウンターまたはインストラクションポインターというレジスターがあります。  
これは現在実行中の命令のアドレスを示しています。現在実行中の命令を実行し終わるとプログラムカウンターのアドレスは次の命令のアドレスに変更され、その値に従ってメモリーから命令が読み出され実行されます。これを繰り返してプログラムが動作することになります。  
プログラムカウンターの値は命令がジャンプ命令等でなかった場合は、次の命令のアドレスになりますが、ジャンプ命令の場合はジャンプ先のアドレスになります。  
リセット直後もこれと同様にプログラムは実行されますが、リセット直後はプログラムカウンターの値が特定の値になります。  
これはCPUの種類により異なりますが、x86の場合は0xffff0となります。  
このため最初に実行される命令を0xffff0に置く必要があります。  
つまり、リセット直後特別なことをしているわけではなく、ただ単にプログラムカウンターの示すアドレスの命令を実行しているだけなのです。  
リセット直後のプログラムカウンターの値はCPUにより0番地になるものや0番地に書かれたアドレスになるものもあります。  
linuxやwindowsといったOSは通常ストレージに格納されており、ストレージからメモリにロードされて実行されます。この場合のメモリーは書き換え可能なRAMで無ければなりませんが、リセット直後の命令はRAMでは中身が不定ですので不揮発性のメモリ（ROM）である必要があります。


CC BY-SA 4.0
2021-12-14T01:09:45.740
84120
2021-12-14T01:17:15.910
2021-12-14T01:17:15.910
24490
24490
84075
answer