/var/log/messages

debugging with sixth sense

Pi-baremetal 確認など

空き時間を利用してとりあえず start.s から確認開始。

コメントから確認してみます。

  • kernel.img は 0x8000 に load される
  • その前の 0x4000-0x7fff は 1MB なページテーブル
  • さらにその前の 0x3c00-0x3fff はカーネルデータな粗い (?) ページテーブル (initsys.c を見れ、とあります)
  • その下はスタックでスタックは下に伸びる
  • スタックのアドレスは MMU が on になってなくても 0x80000000 足された番地になる

イメージてきには以下なカンジなのかどうか。

       +----------------------------+
       |                            |
       +----------------------------+
       |                            |
       |                            |
       |         kernel.img         |
0x8000 |                            |
       +----------------------------+
0x7fff |                            |
       |  1MB memory page table     |
0x4000 |                            |
       +----------------------------+
0x3fff |                            |
       | kernel coarse page table   |
       |                            |
0x3c00 +----------------------------+
       |                            |
       | User/system stack          |
       |                            |
0x2c00 +----------------------------+
       |                            |
       | IRQ stack                  |
       |                            |
0x2800 +----------------------------+
       |                            |
       | Abort stack                |
       |                            |
0x2400 +----------------------------+
       |                            |
       | Supervisor (SWI/SVC) stack |
       |                            |
0x2000 +----------------------------+
       |                            |
       |                            |
0x0000 +----------------------------+

スタックは下向きに伸びます、備忘まで。

で、start.s では cps という命令で processor mode を変えつつスタックポインタの値を設定しています。以下なカンジ。

mov r4, #0x80000000

/* SVC stack (for SWIs) at 0x2000 */
/* The processor appears to start in this mode, but change to it
 * anyway
 */
cps #0x13       /* Change to supervisor (SVC) mode */
add sp, r4, #0x2400

processor mode が云々、というあたりとかモード毎にスタックポインタが、というあたり含め、マニュアル確認必要。

あと、最後に以下なことをして

/* Turn on unaligned memory access */
mrc p15, #0, r4, c1, c0, #0
orr r4, #0x400000   /* 1<22 */
mcr p15, #0, r4, c1, c0, #0

initsys 手続きに jmp しています。

/* Jump to memory map initialisation code */
b initsys

mrc とか mcr とか、確認必要ですね。p15 て確か特別なレジスタだった記憶あり。レジスタに読みだして何かをして戻しているのかどうか。

とりあえずここまでの部分をマニュアルで確認してみる方向。

System boot sequence

2-8 に The Secure OS code at the reset vector must: という記述があり、その中の 1.c に Set up the run time environment and program for each processor mode. という記述があります。

あと、2-37 に CPS という命令の説明がありますね。CPSR というレジスタがあるのか。つうか 2-20 に妙な図があるんですが processor mode 毎にレジスタが用意されているのかな。

2-28 に mode bit な説明がありますね。

  • b10011 (0x13) が Supervisor
  • b10111 (0x17) が Abort
  • b10010 (0x12) が IRQ
  • b11111 (0x1f) が System

mrc とか mcr とか

Move to ARM reg from coproc とか Move to coproc from ARM reg とかってありますね (1-37)。あるいは 3-12 で CP15 レジスタの操作に関する説明が出ております。あ、これマシン語のソレですね。

命令は以下とのことですが (MRC もフォーマットは同様)

MCR{cond} P15, <Opcode_1>, <Rd>, <CRn>, <CRm>, Opcode_2>

使ってる命令としては以下になってて

mrc p15, #0, r4, c1, c0, #0

これは Control というヤツで page 3-44 に説明が、とのこと。これは U bit というヤツなのかな。1 なら Unaligned data access support enabled. とのことです。ちなみに orr ってのは bit な or してる、って理解で良いのかな。

まだ時間あるので次に行ってみます。

initsys.c

最後で mcr してるんですがこれ

  • XP bit を 1 に (Subpage AP bits disabled.)
  • M bit を 1 に (MMU enabled.)

なんスけど、extended page table て何でしょ。とりあえず先頭から確認します。コメントに Virtual memory layout な説明あり。

           +----------------------------+
0xffffffff |                            |
           | kernel code                |
0xf0000000 |                            |
           +----------------------------+
0xefffffff |                            |
           | kernel heap/stack          |
0xc0000000 |                            |
           +----------------------------+
0xa0ffffff |                            |
           | physical memory            |
           |  include peripherals       |
0x80000000 |                            |
           +----------------------------+
0x7fffffff |                            |
           | user process memory        |
0x00000000 |                            |
           +----------------------------+

あと、0x80000000 より上は user process からはアクセスできない、とありますね。ちょっとコメントの確認中心でコード読んだ方が良さげです。

とりあえず r0 から r2 までをバックアップして以降。

/* Save r0-r2 as they contain the start values used by the kernel */
asm volatile("push {r0, r1, r2}");

以下にメモを列挙します。

  • MMU は二つの変換テーブルを持つ
  • 変換テーブル 0 はアドレス空間の 0x0 から始まる bottom な部分をカバーして 32MB から 4GB の間の仮想アドレス空間を扱う
  • 変換テーブル 1 はメモリの残りをカバーする
  • 今のところ両方の変換テーブルは同じものが設定される
  • そして、初期設定としてテーブル 0 は仮想アドレス空間全体を管理する
  • 後でテーブル 0 はユーザプロセスのプロセス固有のテーブルとして登録される

あと、6-39 な記述のフォローがありますね。

  • メモリは 1MB な section で 4096 に分割される
  • それらのほとんどは 0x80000000-0xa0ffffff を除いて unmapped な状態
  • 上記は 0x00000000-0x2a000000 (物理メモリおよび peripherals) に map される
  • kernel code および data も除くってことで良いのかどうか

あとは

  • そのページに付与される特権を表現する APX/AP bits の解説
  • eXecute Never bit の解説
  • 0 および 1 な bit の解説

になっています。0 か 3 なら変換エラーで 1 なら coarse page table で 2 なら section あるいは super section とあります。マニュアルも同様。

もう少し見てみます

最初、0x80000000 から 0xa0ffffff までの間のページテーブルが初期化されます。上で列挙した通りですね。まず physical memory なソレを初期化するのか。

        /* Map physical memory to virtual
         * Read/write for priviledged modes, no execute
         */
        initpagetable[x] = (x-2048)<<20 | 0x0410 | 2;

section base address に、ってなんで 2048 引いてるのか。つうかこれ

  • 末端ビット b10
  • XN が on (not executable)
  • APX が 0 で AP が b10 (Read/write for priviledged, Read-only for User)

て理解ってことで良いのかどうか。

Comments

Copyright © 2017 - YAMANE Toshiaki - Powered by Octopress