メモ
- 電源ボタンを押す
- マザーボードの各種部位に電源が供給される
- PSUがPowerGoodシグナルをマザーボードに送る
- マザーボードがCPUを起動する
- CPUがリセットベクタ(CPU設計段階で定まっているエントリポイントのアドレス)(メモリコントローラはハードウェアレベルでいくつかの領域を特定のデバイスに接続されるようマッピングしており、リセットベクタアドレスはその1つでフラッシュメモリに接続する)からUEFIが起動
if x86の場合
-
x86の命令セットにはIN,OUTという命令がある。これにより、チップセット(I/Oポート)が使える。つまり、通常のメモリアクセス空間以外への命令を送れる。これを利用して、PCIeルートコンプレックスへアクセスでき、PCIeデバイスEnumerationができる。
elsif riscV, armの場合 -
デバイスツリーに、メモリコントローラに設定するべき値が入っている。つまり、どの物理アドレスとどのPCIeデバイスのレジスタのどのアドレスを対応させる必要があるか。これのおかげで、CPUはPCIeデバイスへアクセスできる。BDFのうちBの情報しかデバイスツリーには入っていないので、DFが全体として何があるのかをEnumerationする。
end -
列挙と同時にPCIeデバイスのコンフィギュレーションを取得
-
UEFIがデバイスのBAR領域に0xFFFFFFFFを設定するリクエスト
-
デバイスが要求するメモリサイズが返却される(0xFFFFF000なら、0が3つなので0x1000bit=4KB)
-
UEFIがMMIO用の物理アドレスを決定する(まだMMIOは実現していない)
-
UEFIがMMIOを設定することにしたベースアドレスを各PCIeデバイスに返却(BARへの設定リクエスト)
-
ハードウェア的にアドレスデコーダはBARと同期しているので、今後はデバイスへのメモリアクセスがアドレスデコーダによってデバイスへルーティングされるようになる(ここからMMIO開始)
以降、MMIO経由でPCIeデバイスのレジスタとPCIeパケット通信
- UEFIからカーネルに移譲
- カーネルはBARがマップされたメモリを見て、状況を把握(MMUは低レイヤーすぎるためアクセスしずらい)(カーネルはPCIサブシステムを通じてMMIO領域にアクセス)
メモのメモ
PCIeルートコンプレックスの中にはPCIeホストコントローラと呼ばれる物理的な部品があり、PCIeデバイスEnumerationなどを行う。
デバイスツリーのデータの意味
ranges = <0x81000000 0 0x50000000 0x50000000 0 0x100000>;
PCIeベースアドレス: 0x50000000(第3)
ホストベースアドレス: 0x50000000(第4)
マップメモリサイズ: 0x100000(第6)(=16MB)
の静的なMMIOのためのメモリマップがUTFIプログラムの中に入っている。
ページテーブル
論理アドレスと物理アドレスの変換テーブル(RAMに保存)
MMUが利用
メモリマップ
(MMUが物理アドレスに変換した後、)物理アドレスを具体的なデバイスへ転送する際に利用(メモリコントローラのレジスタに保存)
メモリコントローラが利用
アドレスの変換は行わない
SATAコントローラやUSBコントローラ
SATAコントローラやUSBコントローラは、PCIeデバイス側に存在する。PCIe経由で送られてきたPCIeパケットにより設定されるレジスタをもつハードウェア。
PCIe拡張スロットにこれらコントローラを指すと、普段使うHDDやUSBが使えるようになる。
ノートPCなどでUSBスロットがあってUSBを指せして使えるのは、PCIeスロットにすでにUSBコントローラを差し込んでいるから
知ったこと
メモリコントローラの存在と役割
x86のIN,OUT命令の存在と、RiscVやarmにそれらはないこと
SATAコントローラなどはPCIeデバイスとして、CPUから見てPCIeルートコンプレックスの反対側にある
PCIeパケットのこと
PCIeポートとUSBポート違い