ARMのLinuxカーネルのエントリは arch/arm/kernel/head.S の ENTRY(stext)から始まる。
ブートローダーはメモリのどっかにカーネルイメージを置いてあげて、ENTRY(stext)の「物理アドレス」へジャンプする。「論理アドレス」ではない。
つまりカーネルの最初のあたりはPCは仮想アドレスを指しておらず、物理アドレスを指している。
This code is mostly position independent というコメントにあるように、基本的にposition independent なコードになっていて、必要な部分は仮想アドレス→物理アドレスに変換して動いてくれるようになっている。
ENTRY(stext) はカーネルイメージの先頭からある程度のオフセット(普通は0x8000)をつけたところから始まっている。
オフセット量を確認するにはカーネルのelf を逆アセしてもいいし、リンカースクリプトを見てもよい。
リンカースクリプトは
arch/arm/kernel/vmlinux.lds.S
をプリプロセッサに通して作られる
arch/arm/kernel/vmlinux.lds
だが、見てみると
例えば、
SECTIONS
{
. = 0xC0000000 + 0x00008000;
.text.head : {
_stext = .;
_sinittext = .;
*(.text.head)
}
みたいになっていれば、 オフセットは0x8000。
なので、ブートローダーはカーネルを置いた位置の先頭から + 0x8000のオフセット位置にジャンプすればよいことになる。
Kernelにjumpする前にブートローダーは
r0 = 0
r1 = machine nr
r2 = atags pointer
を設定しておく。
machine nr はmachineごとの固有の番号で、arch/arm/tools/mach-types に表がある。
atags pointerはよくわかりません。とりあえず0を入れておく。
0 件のコメント:
コメントを投稿