我有一个带有SPI闪存的设备我想在该闪存设备上使用UBIFS文件系统作为我的rootfs。我面临的问题是UBI模块在SPI模块初始化之前初始化。因此,当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)
答案 0 :(得分:37)
由内核初始化的模块的init例程(当它们是 静态链接到内核中)包含在指示的initcall()宏中 在启动序列中,它们应该运行。
请参阅include文件:include / linux / init.h以获取宏及其排序的列表。
指定的顺序是:
其中大多数都有一个“initcall_sync()阶段,用于等待完成
该阶段内的所有模块初始化例程。这些宏用于构建
每个阶段的函数指针表,按顺序调用
do_initcalls()
。
如果使用“module_init()”来包装初始化函数,那么 默认情况下,initcall()将调用置于初始化的“设备”阶段。 在该阶段内,项目按链接顺序排序。这意味着 表是在遇到函数时按顺序创建的 由链接器。
您可以通过更改初始阶段将初始化移动到早期阶段 initcall宏包装模块初始化函数,但要小心,因为 各个模块之间存在顺序依赖关系。另一种方法 更改初始化顺序(在一个阶段内)将调整链接 订购内核中的模块。
答案 1 :(得分:1)
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);
.......
答案 2 :(得分:0)
我可能错了,所以请检查这是否正确。
尝试编译所需的所有驱动程序作为模块(M),并按正确的顺序将模块加载到/ etc / modules中,这可以解决您的问题。
准确地说,因为你在挂载rootfs之前正在执行此操作,所以上述步骤应该在initram磁盘中完成。
(我有类似的情况,我需要以正确的顺序加载一些模块,以便能够解密fs)
希望这会有所帮助
CiaoCiao
塞尔吉奥