2016-04-05 27 views
3

私は、圧縮されたカーネル、ramdisk、およびdtbの組み合わせであるandroid boot.imgを扱っています。私は、ブートプロセスに関するubootからシリアルコンソールログから見ると、ここ14f00000 FDT、私の好奇心カーネルのアドレスは14008000ですなぜカーネルのロードアドレスは、ブートに重要なramdiskですか?

CPU: Freescale i.MX6Q rev1.2 at 792 MHz 
CPU: Temperature 27 C 
Reset cause: POR 
Board: MX6-SabreSD 
I2C: ready 
DRAM: 1 GiB 
PMIC: PFUZE100 ID=0x10 
MMC: FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2 
No panel detected: default to Hannstar-XGA 
Display: Hannstar-XGA (1024x768) 
In: serial 
Out: serial 
Err: serial 
check_and_clean: reg 0, flag_set 0 
Fastboot: Normal 
flash target is MMC:1 
Net: FEC [PRIME] 
Normal Boot 
Hit any key to stop autoboot: 3 2 1 0 
boota mmc1 
kernel @ 14008000 (7272352) 
ramdisk @ 15000000 (869937) 
fdt  @ 14f00000 (44072) 
## Booting Android Image at 0x12000000 ... 
Kernel load addr 0x14008000 size 7102 KiB 
Kernel command line: console=ttymxc0,115200 init=/init video=mxcfb0:dev=hdmi,[email protected],bpp=32 video=mxcfb1:off video=mxcfb:off video=mxcfb3:off vmalloc=256M androidboot.console=ttymxc0 consolebalank=0 androidboot.hardware=freescale cma=384M 
## Flattened Device Tree blob at 14f00000 
    Booting using the fdt blob at 0x14f00000 
    Loading Kernel Image ... OK 
    Using Device Tree in place at 14f00000, end 14f0dc27 
switch to ldo_bypass mode! 

Starting kernel ... 

、RAMディスク15000000をトリガー部分です。 私はこれらの値がboot.imgヘッダーに保存されていることを知りました。この値を手動で混乱させると、実際の内容が変更されていなくてもイメージは起動しません。

なぜこのアドレスは重要ですか?なぜそれはこれらの価値でなければならないのでしょうか?なぜ他の値はありませんか?

これらのロードアドレスの値はカーネル内でハードコードされているので、boot.imgヘッダーで変更すると副作用が発生します。私自身の理論を詳述するために、カーネルを 'modified' load addrにロードすることは問題にはなりません。しかし、実際に行を実行すると、これらのコードが適切な 'load addr'で動作するように修正されるため、重大な問題が発生します。

私の理論は間違っていますか?もしそうなら、あなたが私を正すことができるなら、私は感謝します。

+2

カーネルイメージはリロケータブルではないバイナリです。カーネルを構築するリンクフェーズでは、指定されたロードアドレスをベースにして、すべての再配置可能な非相対アドレスが絶対アドレスに変換されます。 Linux ARMカーネルの場合、このロードアドレスは物理メモリの先頭から0x8000です。 – sawdust

+0

これは答えに違いありません.1つのことを除いて - リンクアドレスを使用して絶対アドレス0xc0008000に変換されたアドレス –

答えて

1

Uブートが完了した後、カーネルが以降のすべてのプロセスを処理するように、それ以降の実行をカーネルに引き渡す必要があります。 Plus Kernelには、ボードを初期化するために必要な一連のルーチンがあります。
これらのルーチンセットは、エントリポイントstart_kernel()を持っています。この前に、start_kernelを実行するために他のルーチンも呼び出されます。これはlinker scriptとこのinit.Sで識別できます。

この手順でカーネルを実行するには、特定のアドレスからカーネルを起動する必要があります。また、データセグメントやその他のメモリも接続されているため、これらをすべて適切な方法でロードして実行する必要があります。提供されます。

このカーネルには、デバイスに接続されているデバイスを調べるためのデバイスツリーblobとユーザースペースを呼び出すためのrootfsが必要です。ここではデバイスツリーをロードし、rootfsには正確なオフセットが必要です。堕落したこれらすべての実行にはすべての1バイトが重要です。

安全にブートするために、これらの値はすべてブートローダの設定に保存されています。

関連する問題