2012年2月2日木曜日

ARM Linux カーネルエントリー

組み込みLinux勉強中につき、メモ。

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 件のコメント:

コメントを投稿