rpi_start.Sを読む (第12回)
さて、今回読むのは次の部分です。冒頭のコメントでMMUを有効にするというのがわかります。
マニュアルには「MRC p15, 0,, c1, c0, 0 ; Read Control Register configuration data」とあります。
コントロールレジスタを再掲します。
まずは、Lcontrol_waxをldrでロードし、r0とANDをとります。そのあと、Lcontrol_clrをロードし、r0のビットをクリア。その後、Lcontrol_setをロードし、r0とORをとります。Lcontorol_setではちゃんとMMU_ENABLEが立っています。
Lcontrol_waxは「/* bits to "write as existing" in the Control Register */」。
Lcontrol_clrは「/* bits to clear in the Control Register */」。
Lcontrol_setは「/* bits to set in the Control Register */」。
Lcontrol_clrは.word 0と定義されています。bicはNOTしてANDなので、すべてのビットが1になりますから、ANDを取ってもすべてのビットがONのまま、なにもクリアされない気がします。
で、下表をみると、最初が何であろうと、Lcontrol_wax, Lcontrol_setの両方に1が立っているビットがないので、結果的にはLcontrol_setしか残らないという気がしてきます。うーん。Lcontrol_setだけでも良かったような。
あ、ちがうか、両方が0のやつはクリアされるからLcontrol_waxの意味はあるのか。もしかして、waxって車のワックスのwaxなのかな。ワックスをかけて、きれいにする、余分なもの(ビット)を落として、きれいにする、みたいなニュアンスで。
次に進みます。
Lstartでは.word startと定義されており、これはきっとsrc/sys/arch/arm/arm32/locore.Sの以下の部分ではないかと。
@から始まるのは一行コメントかな。いよいよMMUをONにします。ってことですね。
しかし、align 5というのは何ビットアラインメントだ? と思って調べると、2の5乗、つまり32ビットアラインメントのようです。たしかに、MMUのようなアドレスを変換するような機能をONにするなら、中途半端な場所にいるとダメそうです。
さて、次に進みます。
221 /*
222 * Enable the MMU, etc.
223 */
224 mrc p15, 0, r0, c1, c0, 0
225
226 ldr r1, Lcontrol_wax
227 and r0, r0, r1
228 ldr r1, Lcontrol_clr
229 bic r0, r0, r1
230 ldr r1, Lcontrol_set
231 orr r0, r0, r1
232 ldr lr, Lstart
233
234 .align 5
235 @ turn mmu on!
236 mov r0, r0
237 mcr p15, 0, r0, c1, c0, 0
コメントを読んで盛り上がったところで、読み進めていきます。
224 mrc p15, 0, r0, c1, c0, 0
mrcでコントロールレジスタ設定の値を読み込みます。マニュアルには「MRC p15, 0,
コントロールレジスタを再掲します。
| 31-30 | 29 | 28 | 27-26 | 25 | 24 | 23 | 22 | 21 | 20-19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6-4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| SBZ | FA | TR | SBZ | EE | VE | XP | U | FI | SBZ | IT | SBZ | DT | L4 | RR | V | I | Z | F | R | S | B | SBO | W | C | A | M |
226 ldr r1, Lcontrol_wax
227 and r0, r0, r1
228 ldr r1, Lcontrol_clr
229 bic r0, r0, r1
230 ldr r1, Lcontrol_set
231 orr r0, r0, r1
ここでは、r0にロードされたコントロールレジスタに対して様々な操作を行います。まずは、Lcontrol_waxをldrでロードし、r0とANDをとります。そのあと、Lcontrol_clrをロードし、r0のビットをクリア。その後、Lcontrol_setをロードし、r0とORをとります。Lcontorol_setではちゃんとMMU_ENABLEが立っています。
Lcontrol_waxは「/* bits to "write as existing" in the Control Register */」。
Lcontrol_clrは「/* bits to clear in the Control Register */」。
Lcontrol_setは「/* bits to set in the Control Register */」。
Lcontrol_clrは.word 0と定義されています。bicはNOTしてANDなので、すべてのビットが1になりますから、ANDを取ってもすべてのビットがONのまま、なにもクリアされない気がします。
で、下表をみると、最初が何であろうと、Lcontrol_wax, Lcontrol_setの両方に1が立っているビットがないので、結果的にはLcontrol_setしか残らないという気がしてきます。うーん。Lcontrol_setだけでも良かったような。
| 定義 | 31-30 | 29 | 28 | 27-26 | 25 | 24 | 23 | 22 | 21 | 20-19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6-4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| SBZ | FA | TR | SBZ | EE | VE | XP | U | FI | SBZ | IT | SBZ | DT | L4 | RR | V | I | Z | F | R | S | B | SBO | W | C | A | M | |
| Lcontrol_wax | 1 1 | 1 | 1 | 1 1 | 0 | 0 | 0 | 0 | 0 | 1 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 000 | 0 | 0 | 0 | 0 |
| Lcontrol_set | 0 0 | 0 | 0 | 0 0 | 0 | 0 | 0 | 0 | 0 | 0 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 111 | 1 | 1 | 1 | 1 |
次に進みます。
232 ldr lr, Lstart
いきなりのlrです。lrはリンクレジスタでr14の別名で、今回はリンクレジスタlrにLstartのアドレスをロードしています。rpi_start.Sの最後で、このアドレスにジャンプするための下準備です。Lstartでは.word startと定義されており、これはきっとsrc/sys/arch/arm/arm32/locore.Sの以下の部分ではないかと。
ASENTRY_NP(start)さて、飛び先も決まったということで次の行に進みましょう。
234 .align 5
235 @ turn mmu on!
.align 5でアラインメントを整えます。@から始まるのは一行コメントかな。いよいよMMUをONにします。ってことですね。
しかし、align 5というのは何ビットアラインメントだ? と思って調べると、2の5乗、つまり32ビットアラインメントのようです。たしかに、MMUのようなアドレスを変換するような機能をONにするなら、中途半端な場所にいるとダメそうです。
さて、次に進みます。
236 mov r0, r0
237 mcr p15, 0, r0, c1, c0, 0
これまで色々とビットを操作してきたr0、つまり新しくコントロールレジスタに与えるべき値をmcrで書き込みます。コントロールレジスタの0ビット目に1を立てている、つまりMMUをENABLEにするわけです。コメント(0件)
- TB-URL http://www.tokuda.net/diary/0814/tb/