rpi_start.Sを読む (第12回)
2013/11/10(日) 15:21 NetBSD はてブ情報 はてブに登録 はてブ数

さて、今回読むのは次の部分です。冒頭のコメントでMMUを有効にするというのがわかります。
    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, , c1, c0, 0 ; Read Control Register configuration data」とあります。

コントロールレジスタを再掲します。
31-30292827-26252423222120-191817161514131211109876-43210
SBZFATRSBZEEVEXPUFISBZITSBZDTL4RRVIZFRSBSBOWCAM
    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-30292827-26252423222120-191817161514131211109876-43210
SBZFATRSBZEEVEXPUFISBZITSBZDTL4RRVIZFRSBSBOWCAM
Lcontrol_wax1 1111 1000001 10100000010000000000
Lcontrol_set0 0000 0000000 01010001000101111111
あ、ちがうか、両方が0のやつはクリアされるからLcontrol_waxの意味はあるのか。もしかして、waxって車のワックスのwaxなのかな。ワックスをかけて、きれいにする、余分なもの(ビット)を落として、きれいにする、みたいなニュアンスで。

次に進みます。
    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にするわけです。

名前:  非公開コメント   

  • TB-URL  http://www.tokuda.net/diary/0814/tb/