6

i.MX6 (CPU コアは ARM Cortex A9) を搭載したカスタム ボードで U-boot 経由で Linux を起動しようとしています。

Das U-Boot(2009.08)の移植に成功したようです。しかし、最後の U-Boot メッセージ「Starting kernel ...」で Linux の起動に失敗します。

関連する環境は次のとおりです。

bootargs=console=ttymxc1,115200 vmalloc=400M root=/dev/mmcblk0p1 rootwait consoleblank=0 earlyprintk video=mxcfb0:dev=lcd,LCD-ORTUS,if=RGB24 video=mxcfb1:dev=hdmi,1280x720M@60,if=RGB24 calibration tsdev=tsc2004 fbmem=10M,28M
bootcmd=ext2load mmc 0:1 10800000 /boot/uImage ; bootm 10800000

ブート出力は

Loading file "/boot/uImage" from mmc device 0:1 (xxa1)  
4043552 bytes read  
## Booting kernel from Legacy Image at 10800000 ...  
   Image Name:   Linux-3.0.35  
   Image Type:   ARM Linux Kernel Image (uncompressed)  
   Data Size:    4043488 Bytes =  3.9 MB  
   Load Address: 10008000  
   Entry Point:  10008000  
   Verifying Checksum ... OK  
   Loading Kernel Image ... OK  
OK  

Starting kernel ...  

アドレス 80008000 でカーネルを objdump すると、arch/arm/boot/compressed/head.S ではなく、arch/arm/kernel/head.S にエントリ ポイントが表示されます。

私が見ているのは、カーネルは解凍さえしていないということです。レジスタ操作コードを追加して、圧縮/head.S で GPIO を通知しようとしましたが、応答がありませんでした。

私の質問は、U-Boot が正しいエントリ ポイントを呼び出していることを確認するにはどうすればよいですか?

同じ U-Boot コマンドを使用して、まったく同じカーネル バイナリが Freescale のリファレンス ボードで正常に起動します。

編集: U-Boot にいくつかのトレースを追加しました。カーネルを呼び出す直前に、ポインター theKernel は 10800000 ではなく 10008000 です。これは、U-Boot が間違った場所にジャンプしていることを意味しますか?

4

3 に答える 3

7

Das U-Boot の移植に成功したようです。

それが誤った仮定であるという証拠があります。

カーネルを呼び出す直前のポインター theKernel は、10800000 ではなく 10008000 です。

どのバージョンの U-Boot を使用していますか?
U-Boot の 2012.10 バージョンと 2013.04 バージョンの両方で、変数theKernelは AVR32 や MIPS などのアーキテクチャのコードでのみ宣言および使用されます。
を使用する必要がある ARM コードはありませんtheKernel

u-boot-2012.10$ find . -print | xargs grep theKernel
./arch/avr32/lib/bootm.c:   void    (*theKernel)(int magic, void *tagtable);
./arch/avr32/lib/bootm.c:   theKernel = (void *)images->ep;
./arch/avr32/lib/bootm.c:          theKernel, params_start);
./arch/avr32/lib/bootm.c:   theKernel(ATAG_MAGIC, params_start);
./arch/microblaze/lib/bootm.c:  void    (*theKernel) (char *, ulong, ulong);
./arch/microblaze/lib/bootm.c:  theKernel = (void (*)(char *, ulong,    ulong))images->ep;
./arch/microblaze/lib/bootm.c:      (ulong) theKernel, rd_data_start, (ulong) of_flat_tree);
./arch/microblaze/lib/bootm.c:  theKernel (commandline, rd_data_start, (ulong) of_flat_tree);
./arch/mips/lib/bootm.c:    void (*theKernel) (int, char **, char **, int *);
./arch/mips/lib/bootm.c:    theKernel = (void (*)(int, char **, char **, int *))images->ep;
./arch/mips/lib/bootm.c:        (ulong) theKernel);
./arch/mips/lib/bootm.c:    theKernel(linux_argc, linux_argv, linux_env, 0);
./arch/mips/lib/bootm_qemu_mips.c:  void (*theKernel) (int, char **, char **, int *);
./arch/mips/lib/bootm_qemu_mips.c:  theKernel = (void (*)(int, char **, char **, int *))images->ep;
./arch/mips/lib/bootm_qemu_mips.c:      (ulong) theKernel);
./arch/mips/lib/bootm_qemu_mips.c:  theKernel(0, NULL, NULL, 0);
./arch/nds32/lib/bootm.c:   void    (*theKernel)(int zero, int arch, uint params);
./arch/nds32/lib/bootm.c:   theKernel = (void (*)(int, int, uint))images->ep;
./arch/nds32/lib/bootm.c:          (ulong)theKernel);
./arch/nds32/lib/bootm.c:   theKernel(0, machid, bd->bi_boot_params);
u-boot-2012.10$


ARM プロセッサで定義または割り当ててはならない変数をトレースする方法を説明してください。

U-Boot が「Starting kernel ...」を出力した後の次の出力は、「Uncompressing Linux...」である必要があります。Freescale arch の場合、このテキスト出力は、U-Boot によるカーネルへの(別名)
の適切な受け渡しに依存しています。これが U-Boot で適切に定義され ていることを確認する必要があります。machine type numberarch_id
machine type number

U-Boot の構成ファイルはどのようなものですか?

レジスタ操作コードを追加して、圧縮/head.S で GPIO を通知しようとしましたが、応答がありませんでした。

このコードが期待どおりに機能することを確認するために、このコードの健全性をチェックしましたか?
U-Boot コマンド ラインから GPIO 操作を試しましたか?

私の質問は、U-Boot が正しいエントリ ポイントを呼び出していることを確認するにはどうすればよいですか?

ARM arch の場合は、bootmコマンドで指定されたアドレスへのジャンプです。
uImage ロード アドレスとbootmは同じ 0x10800000 アドレスを指定するため、これで問題ないはずです (U-Boot が正しく構成され、ARM 用にビルドされていると仮定します)。

カーネルを呼び出す直前に、ポインター theKernel は 10800000 ではなく 10008000 です。これは、U-Boot が間違った場所にジャンプしていることを意味しますか?

はい。ソース コード (AVR32 または MIPS の場合) を確認すると、イメージ ヘッダー、特にエントリ ポイントの値から割り当てられて
いることがわかります。theKernelU-Boot はこの場所にジャンプします。
しかし、本当の問題は、ARM Cortex A9 がこのコードまたはこの変数を使用してはならないということです。

U-Boot が適切なアーチ用に構成されていないか、マシン タイプが正しく定義されていないようです。

訂正:

OP が指摘したように、U-Boot の古いバージョンはtheKernel、ARM アーチに対しても変数を使用していました。

U-Boot 出力の行:

   Loading Kernel Image ... OK  

U-Boot がカーネル イメージ (イメージ情報ヘッダーなし) をbootmアドレス 0x10800000 (およびヘッダー長のオフセット 0x40) からロード アドレス 0x10008000 に (正常に) コピーしたことを示します。このメモリ移動操作は、 common/cmd_bootm.cbootm_load_os()内のプロシージャによって実行されます。

したがって、報告した 0x10008000 の値はtheKernel.
U-Boot が間違った場所にジャンプしている兆候はありません。

既に述べたように、マシン タイプが正しく定義されていることを確認する必要があります。この値は__arch_decomp_setup()arch /arm/plat-mxc/include/mach/uncompress.hで 使用されるため、カーネルの起動前の解凍中にテキストを出力できます。

于 2013-08-22T23:10:07.250 に答える
4

vmlinux カーネル ファイルを起動していないように見えるので、エントリ ポイントについて心配する必要はありません。イメージの先頭にある解凍コードは、必要に応じてカーネルを再配置し、完了すると正しいエントリ ポイントにジャンプします。uBootが正しく実行しているように見える画像の先頭にジャンプするだけです。

カーネルのデバッグ、特に Earlyprintk と低レベルのデバッグ オプションをオンにして、もう一度起動してみます。少なくとも、どこが詰まっているかがわかります。

編集: 指摘したように、私の答えは、uBoot が最初から正しく動作している場合にのみ適用されます。この場合、そうでない可能性があります。おそらく、いくつかの LED をオンにしたり、いくつかのレジスタ値 (特に r0、r1、r2) をシリアルに出力したりするだけのダミーの「カーネル」を作成して起動することができます。次に、少なくとも原因として uBoot をチェックおよび/または除外できます。

于 2013-08-22T11:08:38.527 に答える