![内核找不到initrd?](https://linux22.com/image/147596/%E5%86%85%E6%A0%B8%E6%89%BE%E4%B8%8D%E5%88%B0initrd%EF%BC%9F.png)
当尝试挂载 ext2 时,出现此错误:
Creating 4 MTD partitions on "MPC8313RDB Flash Map Info":
0x000000000000-0x000000100000 : "U-Boot"
0x000000100000-0x000000300000 : "Kernel"
0x000000300000-0x000000700000 : "JFFS2"
0x000000700000-0x000000800000 : "dtb"
List of all partitions:
1f00 1024 mtdblock0 (driver?)
1f01 2048 mtdblock1 (driver?)
1f02 4096 mtdblock2 (driver?)
1f03 1024 mtdblock3 (driver?)
No filesystem could mount root, tried: ext2
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)
由于某些原因,u-boot 无法将启动参数传递给内核,因此我通过修改 init/main.c 中的 boot_command_line 直接指定它们,这些是我的参数:
root=/dev/ram0 rw rootfstype=ext2 ramdisk_size=30000 ramdisk_blocksize=1024 console=ttyS0,115200
我认为(并且仍然认为)问题是内核没有足够的有关 initrd 的信息,所以我增大了 powerpc/boot/of.c 并手动设置
loader_info
if (a1 && a2 && a2 != 0xdeadbeef) {
//loader_info.initrd_addr = a1;
//loader_info.initrd_size = a2;
loader_info.initrd_addr= 0x07c15000;
loader_info.initrd_size= 0x00386815;
}
我选择这些值是因为这是 u-boot 报告的大小和位置
Loading Ramdisk to 07c15000, end 07f9b815 ... OK
如果我不指定 rootfstype 那么它默认为 yaffs2,这是输出:
yaffs: dev is 1048576 name is "ram0" rw
yaffs: passed flags ""
yaffs: dev is 1048576 name is "ram0" rw
yaffs: passed flags ""
yaffs: mtd is read only, setting superblock read only
------------[ cut here ]------------
WARNING: at mm/page_alloc.c:2544
Modules linked in:
CPU: 0 PID: 1 Comm: swapper Not tainted 3.16.62 #116
task: c782c000 ti: c781a000 task.ti: c781a000
NIP: c006dcc0 LR: c006d754 CTR: 00000000
REGS: c781b890 TRAP: 0700 Not tainted (3.16.62)
MSR: 00029032 <EE,ME,IR,DR,RI> CR: 22002244 XER: 00000000
GPR00: c006d754 c781b940 c782c000 00000000 00000001 00000000 c781b8a8 00000041
GPR08: c02a46ab 00000000 00000001 00000000 22002242 00000000 c00041a0 00000000
GPR16: 00000000 00000000 00000000 00000041 00024050 c02a45ec c02bbb40 c02bbb3c
GPR24: 00000000 00000014 00000000 00000000 c02a45e8 c02b10e0 00004050 00000001
NIP [c006dcc0] __alloc_pages_nodemask+0x660/0x86c
LR [c006d754] __alloc_pages_nodemask+0xf4/0x86c
Call Trace:
[c781b940] [c006d754] __alloc_pages_nodemask+0xf4/0x86c (unreliable)
[c781ba10] [c007f51c] kmalloc_order+0x18/0x4c
[c781ba20] [c01128bc] yaffs_tags_marshall_read+0x22c/0x264
[c781bae0] [c0110650] yaffs2_checkpt_find_block+0x90/0x1a8
[c781bb50] [c011125c] yaffs2_checkpt_rd+0x200/0x228
[c781bbe0] [c0114dcc] yaffs2_rd_checkpt_validity_marker+0x24/0xa4
[c781bc10] [c0115b68] yaffs2_checkpt_restore+0x68/0x714
[c781bc80] [c010fe90] yaffs_guts_initialise+0x46c/0x868
[c781bcb0] [c0108810] yaffs_internal_read_super.isra.16+0x420/0x83c
[c781bd50] [c0108c48] yaffs2_internal_read_super_mtd+0x1c/0x3c
[c781bd60] [c00a6224] mount_bdev+0x194/0x1c0
[c781bdb0] [c00a6c60] mount_fs+0x20/0xb8
[c781bdd0] [c00be984] vfs_kern_mount+0x54/0x120
[c781bdf0] [c00c1a30] do_mount+0x1f0/0xb60
[c781be50] [c00c2770] SyS_mount+0xac/0x120
[c781be90] [c0275e94] mount_block_root+0x130/0x2a0
[c781bee0] [c027635c] prepare_namespace+0x1b8/0x200
[c781bf00] [c0275b48] kernel_init_freeable+0x1a8/0x1bc
[c781bf30] [c00041b8] kernel_init+0x18/0x120
[c781bf40] [c000e310] ret_from_kernel_thread+0x5c/0x64
Instruction dump:
2f890000 40beff90 89210030 2f890000 419efe3c 4bffff80 73ca0200 4082fab4
3d00c02a 390846ab 89480001 694a0001 <0f0a0000> 2f8a0000 419efa98 39400001
---[ end trace fbbfd1e0d42ac49d ]---
VFS: Mounted root (yaffs2 filesystem) readonly on device 1:0.
devtmpfs: error mounting -2
Freeing unused kernel memory: 112K (c0275000 - c0291000)
这个问题的根源是什么?
答案1
由于某种原因,我的 U-boot 不让我的内核知道 initrd 正在加载到 ram 中的位置,因此我在 setup-common.c 中手动设置 initrd_start 和 initrd_end 。我将 ramdisk 加载的 ram 中的内存位置映射到内核的虚拟地址空间。我必须重新映射,因为 PAGE_OFFSET 大于 ramdisk 的地址。
void __init check_for_initrd(void)
{
#ifdef CONFIG_BLK_DEV_INITRD
initrd_start= (int)ioremap(0x07c15000 ,(0x07f9b815-0x07c15000) );
initrd_end= initrd_start + (0x07f9b815 - 0x07c15000);
printk("PAGE OFFSET: %lx\n", PAGE_OFFSET);
DBG(" -> check_for_initrd() initrd_start=0x%lx initrd_end=0x%lx\n",
initrd_start, initrd_end);