rpi_start.Sを読む (第5回)
MMU_INITマクロの続編です。前回だいぶ解明したおかげで残りは順調に進みそうです。
二つ目のMMU_INITマクロを読み解きましょう。
最後の引数も新しいのはL1_S_B, L1_S_Cの二つです。
おなじみ、pte.hで定義されています。先ほどのL1_S_IMPの上にいました。
ということで、
さて、最後のMMU_INITマクロです。
コメントによると16MBのペリフェラルのマップとのこと。メモリマップI/Oされた周辺機器に関するエントリのようですね。
まずは、RPI_KERNEL_IO_VBASE, RPI_KERNEL_IO_PBASEです。
これは、arch/evbarm/rpi/rpi.hにある
RPI_KERNEL_IO_VBASEはBCM2835_IOPHYSTOVIRTというマクロを経由しますが、計算するとRPI_KERNEL_IO_VBASE = 0xF2000000になります。
三つ目のMMU_INITマクロである
番兵を除く、MMU_INITマクロを表にしてみましょう。
二つ目のMMU_INITマクロを読み解きましょう。
314 MMU_INIT(KERNEL_BASE, 0x0,
315 (_end - KERNEL_BASE + 2 * L1_S_SIZE - 1),
316 L1_S_PROTO | L1_S_AP_KRW | L1_S_B | L1_S_C)
三つめまでの引数は先ほどのほぼ同様ですね。KERNEL_BASEもわかっているので問題ありません。最後の引数も新しいのはL1_S_B, L1_S_Cの二つです。
おなじみ、pte.hで定義されています。先ほどのL1_S_IMPの上にいました。
/* L1 Section Descriptor */ #define L1_S_B 0x00000004 /* bufferable Section */ #define L1_S_C 0x00000008 /* cacheable Section */ #define L1_S_IMP 0x00000010 /* implementation defined */ですから、L1_S_PROTO | L1_S_AP_KRW | L1_S_B | L1_S_C = 0x0012 | 0x0400 | 0x0004 | 0x0008 = 0x041Eです。
ということで、
314 MMU_INIT(KERNEL_BASE, 0x0,
315 (_end - KERNEL_BASE + 2 * L1_S_SIZE - 1),
316 L1_S_PROTO | L1_S_AP_KRW | L1_S_B | L1_S_C)
というMMU_INITはva = 0xC0000000; pa = 0x0; n_sec = 0x643033; attr = 0x041E;と表現できることがわかります。
さて、最後のMMU_INITマクロです。
コメントによると16MBのペリフェラルのマップとのこと。メモリマップI/Oされた周辺機器に関するエントリのようですね。
318 /* Map the 16MB of peripherals */
319 MMU_INIT(RPI_KERNEL_IO_VBASE, RPI_KERNEL_IO_PBASE,
320 (RPI_KERNEL_IO_VSIZE + L1_S_SIZE - 1),
321 L1_S_PROTO | L1_S_AP_KRW)
これは、四つ目の引数が一つ目のMMU_INITマクロと同じですから最初の三つの引数が読み解ければよいですね。まずは、RPI_KERNEL_IO_VBASE, RPI_KERNEL_IO_PBASEです。
これは、arch/evbarm/rpi/rpi.hにある
#define RPI_KERNEL_IO_VBASE BCM2835_PERIPHERALS_VBASE #define RPI_KERNEL_IO_PBASE BCM2835_PERIPHERALS_BASE #define RPI_KERNEL_IO_VSIZE BCM2835_PERIPHERALS_SIZEからのarch/arm/broadcom/bcm2835reg.hにおいて定義されています。
#define BCM2835_PERIPHERALS_BASE 0x20000000
#define BCM2835_PERIPHERALS_SIZE 0x01000000 /* 16MBytes */
#define BCM2835_IOPHYSTOVIRT(a) \
((0xf0000000 | (((a) & 0xf0000000) >> 4)) + ((a) & ~0xf0000000))
#define BCM2835_PERIPHERALS_VBASE \
BCM2835_IOPHYSTOVIRT(BCM2835_PERIPHERALS_BASE)
RPI_KERNEL_IO_PBASEはそのままBCM2835_PERIPHERALS_BASEですから0x20000000になります。RPI_KERNEL_IO_VBASEはBCM2835_IOPHYSTOVIRTというマクロを経由しますが、計算するとRPI_KERNEL_IO_VBASE = 0xF2000000になります。
三つ目のMMU_INITマクロである
318 /* Map the 16MB of peripherals */
319 MMU_INIT(RPI_KERNEL_IO_VBASE, RPI_KERNEL_IO_PBASE,
320 (RPI_KERNEL_IO_VSIZE + L1_S_SIZE - 1),
321 L1_S_PROTO | L1_S_AP_KRW)
については次のように表現できます。va = 0xF2000000 pa = 0x20000000 n_sec = 0x01000000 + 0x00100000 - 1 = 0x010FFFFF attr = 0x0412最後のMMU_INITマクロは、
323 /* end of table */
324 MMU_INIT(0, 0, 0, 0)
ということで、テーブルの最後にすべてを0にしたものです。テーブルの最後を示す、番兵の役目ということでしょうか。番兵を除く、MMU_INITマクロを表にしてみましょう。
| va | pa | nsec | attr |
|---|---|---|---|
| 0x0 | 0x0 | 0x643033 | 0x412 |
| 0xC0000000 | 0x0 | 0x643033 | 0x041E |
| 0xF2000000 | 0x20000000 | 0x010FFFFF | 0x0412 |
コメント(0件)
- TB-URL http://www.tokuda.net/diary/0807/tb/