SPIフラッシュストレージを備えたデバイスがあります。そのフラッシュデバイスのUBIFSファイルシステムをrootfsとして使用したいと考えています。私が直面している問題は、SPIモジュールが初期化される前にUBIモジュールが初期化されることです。このため、UBIが読み込まれると、(カーネルコマンドラインを介して)私が指定したUBIデバイスに接続できないため、rootfsはありません。以下のコンソール出力はこれを示しています。
_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)
_
カーネルによって初期化されたモジュールの初期化ルーチン(カーネルに静的にリンクされている場合)は、起動シーケンスで実行する必要があることを示すinitcall()マクロにラップされます。
マクロとその順序のリストについては、インクルードファイルinclude/linux/init.hを参照してください。
そこで指定された順序は次のとおりです。
これらのほとんどには、 "initcall_sync()フェーズがあります。これは、そのフェーズ内のすべてのモジュール初期化ルーチンの完了を待機するために使用されます。マクロは、各フェーズの関数ポインタのテーブルを構築するために使用され、do_initcalls()
。
「module_init()」を使用して初期化関数をラップする場合、デフォルトでは、initcall()は初期化の「デバイス」フェーズに呼び出しを置きます。そのフェーズでは、アイテムはリンク順で並べられます。つまり、テーブルは、リンカによって検出された関数の順序によって作成されます。
どのinitcallマクロがモジュールの初期化関数をラップするかを変更することで、初期化を前のフェーズに移動できる場合がありますが、さまざまなモジュール間に順序の依存関係があるので注意してください。 (フェーズ内で)初期化順序を変更する別の方法は、カーネル内のモジュールのリンク順序を調整することです。
@ティムバードはすでにそれに答えました-モジュールの順序を変更する方法を示したい:-
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);
.......
間違いかもしれませんので、間違いないか確認してください。
必要なすべてのドライバーをモジュール(M)としてコンパイルし、ロードするモジュールを/ etc/modulesに正しい順序で配置すると、問題が解決する可能性があります。正確に言うと、これはbeforeを実行しているため、rootfsがマウントされているため、上記の手順はinitramディスクで実行する必要があります。 (私は同様のシナリオがあり、fsを復号化できるように、いくつかのモジュールを正しい順序でロードする必要があります)
お役に立てれば
バイバイ
セルジオ