2012-04-28 13 views
20

私はSPIフラッシュ記憶装置を持っています私はrootfsとしてそのフラッシュ装置にUBIFSファイルシステムを使用したいと思います。私が直面している問題は、SPIモジュールが初期化される前にUBIモジュールが初期化されることです。このため、UBIがロードされるとき、UBIデバイスに(カーネルコマンドラインを介して)それを伝えることができないので、rootfsはありません。以下のコンソール出力はこれを示しています。Linuxはモジュールのinit呼び出しの順序をどのように決定しますか?

init/main.cには、単に関数ポインタのリストを呼び出すdo_initcalls()関数があることがわかりました。これらの関数ポインタは、カーネルに組み込まれているモジュールのすべてのmodule_init()関数を指しています。これらの関数ポインタは、カーネルバイナリの特別なセクションに置かれるため、この順序はコンパイル時に選択されます。しかし、私はまだその秩序がどのように決定されたかを考え出していない。

[ 0.482500] UBI error: ubi_init: UBI error: cannot initialize UBI, error -19 
    [ 0.492500] atmel_spi atmel_spi.0: Using dma0chan0 (tx) and dma0chan1 (rx) for DMA transfers 
    [ 0.500000] atmel_spi atmel_spi.0: Atmel SPI Controller at 0xf0000000 (irq 13) 
    [ 0.507500] m25p80 spi0.1: mx25l25635e (32768 Kbytes) 
    [ 0.512500] Creating 7 MTD partitions on "jedec_flash": 
    [ 0.520000] 0x000000000000-0x000000020000 : "loader" 
    [ 0.527500] 0x000000020000-0x000000060000 : "u-boot" 
    [ 0.537500] 0x000000060000-0x000000080000 : "u-boot-env" 
    [ 0.547500] 0x000000080000-0x000000280000 : "kernel0" 
    [ 0.557500] 0x000000280000-0x000000480000 : "kernel1" 
    [ 0.567500] 0x000000480000-0x000001240000 : "fs" 
    [ 0.575000] 0x000001240000-0x000002000000 : "play" 
    [ 0.590000] AT91SAM9 Watchdog enabled (heartbeat=15 sec, nowayout=0) 
    [ 0.607500] TCP cubic registered 
    [ 0.615000] VFS: Cannot open root device "ubi0:root0" or unknown-block(0,0) 
    [ 0.622500] Please append a correct "root=" boot option; here are the available partitions: 
    [ 0.630000] 1f00    128 mtdblock0 (driver?) 
    [ 0.635000] 1f01    256 mtdblock1 (driver?) 
    [ 0.640000] 1f02    128 mtdblock2 (driver?) 
    [ 0.645000] 1f03   2048 mtdblock3 (driver?) 
    [ 0.650000] 1f04   2048 mtdblock4 (driver?) 
    [ 0.655000] 1f05   14080 mtdblock5 (driver?) 
    [ 0.660000] 1f06   14080 mtdblock6 (driver?) 
    [ 0.665000] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) 
+0

にもかかわらず、これができない場合がありますので、私は、[そう]への移行のためにフラグが立てられてきましたソースコードを変更する必要がありますが、少なくともKbuildのトリッキーが必要です。また、[so]は専門家がいる場所です。私はあなたが特定の注文に頼らなければならないと思うし、何かをマウントするように言われるまでUBIドライバーはどんなデバイスにもアクセスしようとすべきではないと思う。 – Gilles

+0

[LINUX:静的にリンクされたモジュールの読み込みの順序](http://stackoverflow.com/questions/5669647/linux-order-of-statically-linked-module-loading)は、あなたがモジュールを確実にする必要があることを示唆しています必要な初期化順序でmakefileの(ツリーの)ツリーに現れます。 –

+0

'EPROBE_DEFER'を使って問題を解決する別の方法があるかもしれません。私はそれを調べるでしょう。 –

答えて

0

私は間違っている可能性がありますので、正しいかどうか確認してください。
必要なすべてのドライバをモジュール(M)としてコンパイルして、/ etc/modulesにロードするモジュールを正しい順序で配置してください。これが問題を解決する可能性があります。 の前に rootfsがマウントされているので正確に言うと、上記の手順はinitramディスクで行われます。 (私は同様のシナリオを持っていると私はFSを解読できるようにするには、正しい順序でいくつかのモジュールをロードする必要があります)

希望この役立ちます
CiaoCiao
は セルジオ

+1

モジュールをルートファイルシステムに置くので、別々のモジュールとしてコンパイルすることはできません。私が話しているこれらのモジュールは、ルートファイルシステムをマウントするためのモジュールです。 –

+0

@ ShawnJ.Goff:私は重要な詳細について言及することを忘れていると気づいたので、投稿を編集しました。 initramfsの部分。 :) – sergico

+0

initramfsはオプションではありません。私のビルドのサイズは許容できないほど大きくなります。 –

32

モジュールの初期化ルーチン(カーネルに静的にリンクされている場合は) がカーネルによって初期化され、起動シーケンスで実行されるべきときに を示すinitcall()マクロにラップされます。

マクロのリストとその順序については、インクルードファイル:include/linux/init.hを参照してください。

  • early_initcall
  • pure_initcall
  • core_initcall
  • postcore_initcall
  • arch_initcall subsys_initcall
  • fs_initcall
  • 順序が指定され10

  • rootfs_initcall
  • device_initcall
  • late_initcall

これらのほとんどは、その相内 の完了のためのすべてのモジュールの初期化ルーチンを待つために使用される「initcall_sync()相を有します。これらのマクロは、 の各フェーズの関数ポインタテーブルを構築するために使用されます。これらのポインタは、順番に do_initcalls()で呼び出されます。

"module_init()"を使用して初期化関数をラップすると、デフォルトで initcall()は呼び出しを初期化の「デバイス」フェーズに入れます。 このフェーズでは、アイテムはリンク順に並べられます。これは、 のテーブルが、リンカによって の機能の順番で作成されたことを意味します。

initcallマクロがモジュール初期化関数をラップするものを変更することで初期化を前の段階に移すことができるかもしれませんが、 にはさまざまなモジュール間で順序の依存関係があるため注意してください。 (フェーズ内で)初期化順序を変更するもう1つの方法は、カーネル内のモジュールのリンク の順序を調整することです。

0

@Tim鳥はすでにそれに答えた - 私は、モジュールの順序を変更する方法を示したいと思います: -

pure_initcall(fn)   --> Loaded first 
core_initcall(fn)   
core_initcall_sync(fn)  
postcore_initcall(fn)  
postcore_initcall_sync(fn) 
arch_initcall(fn)   
arch_initcall_sync(fn)  
subsys_initcall(fn)  
subsys_initcall_sync(fn) 
fs_initcall(fn)   
fs_initcall_sync(fn)  
rootfs_initcall(fn)  
device_initcall(fn)  
device_initcall_sync(fn) 
late_initcall(fn)   
late_initcall_sync(fn) --> Loaded last 

Usage - Replace fn by the module init function pointer, example for i2c core driver: 
....... 
postcore_initcall(i2c_init); // To delay i2c core loading use subsys_initcall(i2c_init)     
module_exit(i2c_exit); 
....... 
関連する問題