パスワードを忘れた? アカウント作成
359302 journal

BAKの日記: OpenBlockS266 めも

日記 by BAK

ブートシーケンス

ひとまず,この段階で判明しているブースシーケンスについてまとめてみる.

  1. パワーオン→リセット割り込み
  2. 0xFFFFFFFC にジャンプ
  3. OpenBIOS にジャンプ
    OpenBIOS が RAM や各種デバイスを初期化しているものと思われる
  4. Linux 圧縮カーネルを 0x00500000 にロード・ジャンプ
  5. カーネルにリンクされている自己展開ルーチンが圧縮カーネルを展開
  6. 展開後のカーネルにジャンプ→起動

treeboot 形式

OpenBIOS で扱うターゲットブートファイルの形式を,ここでは仮に treeboot 形式と呼ぶことにする.

treeboot 形式のファイルは,elf 形式のファイルより mktree プログラム (linux-2.4.20/arch/ppc/boot/utils/mktree.c) により生成される.このプログラムで定義されている treeboot 形式ファイルのヘッダは以下の通り.

typedef struct boot_block {
                unsigned long bb_magic; /* 0x0052504F */
                unsigned long bb_dest; /* Target address of the image */
                unsigned long bb_num_512blocks; /* Size, rounded-up, in 512 byte blks */
                unsigned long bb_debug_flag; /* Run debugger or image after load */
                unsigned long bb_entry_point; /* The image address to start */
                unsigned long bb_checksum; /* 32 bit checksum including header */
                unsigned long reserved[2];
} boot_block_t;

(追記) linux-2.4.20/arch/ppc/boot/simple/head.S を見ると,先頭にこんな定義があった.

start:
                bl start_
#ifdef CONFIG_IBM_OPENBIOS
                /* The IBM OpenBIOS bootroms know that the address of the bootrom
                  * read only structure is 4 bytes after _start.
                  */
                .long 0x62726f6d # structure ID - "brom"
                .long 0x5f726f00 # - "_ro\0"
                .long 1 # structure version
                .long bootrom_cmdline # address of *bootrom_cmdline
#endif

これも「ヘッダの一部」と言えるかもしれない.(追記終わり)

で,カーネルコンパイル後に生成される linux-2.4.20/arch/ppc/boot/images/zImage.treeboot をダンプしてみると,たしかにこの通りの形式になっている.

0000000 5200 4f50 5000 0000 0000 7407 0000 0000
0000020 5000 0000 e1e4 f2d6 0000 0000 0000 0000
0000040 0048 1500 7262 6d6f 725f 006f 0000 0100
0000060 4000 804c 687c a602 6338 fcff 0048 0400
0000100 687c 781b 8b7c 7823 803c 4000 8460 0000
0000120 a03c 4e00 a560 f801 a538 0300 a47c 5028
0000140 a554 bef0 a77c 782b 037c 0020 8241 9c00
0000160 803c 4000 8460 0000 a03c 4e00 a560 f801
0000200 c47c 5028 c87c 1432 057c 0030 8141 0800
0000220 0048 0800 a67c 782b c638 0400 a038 0300

あ,ダンプは x86 上でやっているので,バイトオーダが入れ替わっています.注意.

一方,OpenBlockS266 上で /dev/mtdblock1 をダンプしてみると,

0000000 0052 504f 0050 0000 0000 0774 0000 0000
0000020 0050 0000 e4e1 d6f2 0000 0000 0000 0000
0000040 4800 0015 6272 6f6d 5f72 6f00 0000 0001
0000060 0040 4c80 7c68 02a6 3863 fffc 4800 0004
0000100 7c68 1b78 7c8b 2378 3c80 0040 6084 0000
0000120 3ca0 004e 60a5 01f8 38a5 0003 7ca4 2850
0000140 54a5 f0be 7ca7 2b78 7c03 2000 4182 009c
0000160 3c80 0040 6084 0000 3ca0 004e 60a5 01f8
0000200 7cc4 2850 7cc8 3214 7c05 3000 4181 0008
0000220 4800 0008 7ca6 2b78 38c6 0004 38a0 0003

となっている.先ほどの zImage.treeboot が先頭からべた書きになっていることがわかる.

アドレス周り

各オブジェクトのアドレス周りについて.

まずは linux-2.4.20/vmlinux.これは Linux 実行時の Linux カーネル本体で,elf フォーマットである.

[imai@JR0BAK linux-2.4.20]$ powerpc-redhat-linux-nm vmlinux | sort | head
                  w __start___kallsyms
                  w __stop___kallsyms
00000005 a LG_CACHELINE_BYTES
0000001f a CACHELINE_MASK
00000020 a CACHELINE_BYTES
c0000000 T _start
c0000000 T _stext
c000001c t turn_on_mmu
c0000100 t CriticalInterrupt
c0000200 t MachineCheck

エントリポイントは 0xc0000000 で,linux-2.4.20/arch/ppc/kernel/head_4xx.S にエントリポイント (_start) がある.

が,実はこのエントリポイントに飛んだ時点ではまだプログラムはこのアドレスでは動作していない(はずである).initial_mmu → turn_on_mmu で,MMU を初期化・カーネルを再配置・0xc0000000 の空間にジャンプ,という動作を行っている(ようである).で,スタックポインタを初期化した後に linux-2.4.20/arch/ppc/kernel/setup.c:early_init の C プログラムの世界へと突入する.

次に linux-2.4.20/arch/ppc/boot/images/zImage.elf.このファイルは,カーネル make 時に生成される zvmlinux がリネームされたものである.つまり,自己展開ルーチンと圧縮カーネルがリンクされたオブジェクトファイルである.

[imai@JR0BAK images]$ powerpc-redhat-linux-nm zImage.elf | sort | head
00400000 T start
00400014 t start_
00400020 T relocate
004000e8 t start_ldr
00400154 t get_root_parameter
004001ec t is_pushsw
00400210 T decompress_kernel
004006e4 T cursor
004006ec T scroll
004006f0 T CRT_tstc

こちらの方は物理アドレスのモード (PowerPC でも real mode と言うらしい) で書かれているようである.

エントリアドレスが treeboot ヘッダが示すアドレス (0x00500000) と一致していない.が,最初に relocate というルーチンで自己転送を行い,このアドレスで動作しているものと思われる(まだ読んでいないのだ.実は).

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

物事のやり方は一つではない -- Perlな人

読み込み中...