移植linux内核到s3c6410(根文件系统加载失败问题解决:Kernel panic - not syncing: VFS: Unable to mount root fs)

时间:2021-12-13 03:59:23
异常打印: 

List of all partitions:

No filesystem could mount root, tried:  ext2

Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)

Backtrace:

[<c003167c>] (dump_backtrace+0x0/0x114) from [<c02c0a64>] (dump_stack+0x18/0x1c)

 r6:00008000 r5:c03c8ca4 r4:c03c8ca4

[<c02c0a4c>] (dump_stack+0x0/0x1c) from [<c02c0acc>] (panic+0x64/0x180)

[<c02c0a68>] (panic+0x0/0x180) from [<c0009134>] (mount_block_root+0x260/0x2b0)

 r3:00000000 r2:00000020 r1:cf82df60 r0:c035b458

[<c0008ed4>] (mount_block_root+0x0/0x2b0) from [<c00091d8>] (mount_root+0x54/0x6c)

[<c0009184>] (mount_root+0x0/0x6c) from [<c0009360>] (prepare_namespace+0x170/0x1c4)

 r5:c00267ed r4:c03c8480

[<c00091f0>] (prepare_namespace+0x0/0x1c4) from [<c0008610>] (kernel_init+0x110/0x150)

 r5:c0025dac r4:c03c8420

[<c0008500>] (kernel_init+0x0/0x150) from [<c0049e90>] (do_exit+0x0/0x6d4)

 r5:c0008500 r4:00000000


定位步骤:

1、是否内核参数里的initrd的地址和大小不对?

      u-boot的处理:setup_initrd_tag,initrd_start/initrd_end是根据bootm参数的第二个地址然后解析头(image_header_t)而得来的,所以这个参数不应该有问题才对。

#ifdef CONFIG_INITRD_TAG
 if (initrd_start && initrd_end)
  setup_initrd_tag (bd, initrd_start, initrd_end);
#endif

内核的处理:

ATAG_INITRD

static int __init parse_tag_initrd(const struct tag *tag)
{
 printk(KERN_WARNING "ATAG_INITRD is deprecated; "
  "please update your bootloader.\n");
 phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
 phys_initrd_size = tag->u.initrd.size;
 return 0;
}

__tagtable(ATAG_INITRD, parse_tag_initrd);


 

bootargs: initrd = start,size

 

static int __init early_initrd(char *p)
{
 unsigned long start, size;
 char *endp;

 start = memparse(p, &endp);
 if (*endp == ',') {
  size = memparse(endp + 1, NULL);

  phys_initrd_start = start;
  phys_initrd_size = size;
 }
 return 0;
}
early_param("initrd", early_initrd);

 

优先级也是bootargs>ATAG_INITRD,但是我没有在bootargs里定义initrd参数,所以默认从文件里去读应该不会有什么问题的。

而且加了打印也确认这个start和size是OK的。

 

2、研究initrd启动流程

由于我使用的是cpio格式的initrd,所以内核处理流程为:

populate_rootfs-->unpack_to_rootfs解压到根文件系统。

reset_init-->kernel_init-->init_post执行用户初始化文件(ramdisk_execute_comman>execute_command>/sbin/init>/etc/init>/bin/init>/bin/sh),按上面顺序查找执行。

如果在根文件系统里找不到ramdisk_execute_command ,证明是老格式的initrd,不需要进入  prepare_namespace,直接进入init_post。

 if (!ramdisk_execute_command)
  ramdisk_execute_command = "/init";

 if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
  ramdisk_execute_command = NULL;
  prepare_namespace();
 }

 init_post();

ramdisk_execute_comman,execute_command怎么来的呢?

由下面的代码,可以确认ramdisk_execute_comman是bootargs里的rdinit=来得到。而execute_command 由init=来得到。

static int __init init_setup(char *str)
{
 unsigned int i;

 execute_command = str;
  for (i = 1; i < MAX_INIT_ARGS; i++)
  argv_init[i] = NULL;
 return 1;
}
__setup("init=", init_setup);

static int __init rdinit_setup(char *str)
{
 unsigned int i;

 ramdisk_execute_command = str;
 /* See "auto" comment in init_setup */
 for (i = 1; i < MAX_INIT_ARGS; i++)
  argv_init[i] = NULL;
 return 1;
}
__setup("rdinit=", rdinit_setup);

 

从打印看执行到了prepare_namespace,这说明是ramdisk_execute_comman找不到造成的。

检查bootargs参数:


root=/dev/ram rootfstype=ext2 init=/linuxrc console=ttySAC0,115200 mem=256M@0x50000000

确实传递不对,init=/linuxrc 是对应execute_command,rdinit=才是ramdisk_execute_comman。

修改后问题依旧,再看代码

sys_access((const char __user *) ramdisk_execute_command, 0) != 0

难道是ramdisk里没有linuxrc文件?确认ramdisk的rootfs目录下的文件,确实拷贝出错了,脚本有问题:

cp -a $BUSYBOXSOURCE/_install/ .

把文件目录拷贝到了根目录,而不是文件里的内容。

 

3、修改后出现了另外的问题:

Freeing init memory: 148K

ramdisk_execute_command=/linuxrc
linuxrc used greatest stack depth: 6072 bytes left
Kernel panic - not syncing: Attempted to kill init!
Backtrace:
[<c003169c>] (dump_backtrace+0x0/0x114) from [<c02c0a84>] (dump_stack+0x18/0x1c)
 r6:c03ae324 r5:c03c8ca4 r4:c03c8ca4
[<c02c0a6c>] (dump_stack+0x0/0x1c) from [<c02c0aec>] (panic+0x64/0x180)
[<c02c0a88>] (panic+0x0/0x180) from [<c0049f2c>] (do_exit+0x7c/0x6d4)
 r3:cf82ba80 r2:cf82bc94 r1:cf82bc60 r0:c0360377
[<c0049eb0>] (do_exit+0x0/0x6d4) from [<c004a608>] (do_group_exit+0x84/0xb8)
[<c004a584>] (do_group_exit+0x0/0xb8) from [<c0058c04>] (get_signal_to_deliver+0x348/0x384)
 r4:0830009f
[<c00588bc>] (get_signal_to_deliver+0x0/0x384) from [<c0030338>] (do_signal+0x70/0x600)
[<c00302c8>] (do_signal+0x0/0x600) from [<c00308e8>] (do_notify_resume+0x20/0x64)
[<c00308c8>] (do_notify_resume+0x0/0x64) from [<c002daf8>] (work_pending+0x24/0x28)
 r4:beea9bf0
OK

搜索了网上的资料后,使用arm-linux-gcc 4.0.0以上的编译器编译内核时需要加上这个配置:

Kernel Features  --->
            [*] Use the ARM EABI to compile the kernel                  
            [*]   Allow old ABI binaries to run with this kernel (EXPERIMENTA)

重新编译内核后,加载到单板上执行,初始化成功,bash shell #出来啦,高兴啊!!!


MINI6410 # bootm 0x50800000 0x51800000
## Booting image at 50800000 ...
   Image Name:   Linux-2.6.38
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    1925280 Bytes =  1.8 MB
   Load Address: 50008000
   Entry Point:  50008000
   Verifying Checksum ... OK
OK
## Loading Ramdisk Image at 51800000 ...
   Image Name:   ramdisk1.0
   Image Type:   ARM Linux RAMDisk Image (gzip compressed)
   Data Size:    1040671 Bytes = 1016.3 kB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
start_kernel ok

__log_buf=503b9724
setup arch


u.mem.start=50000000
u.mem.size=10000000

1
r_banks=00000001
start=50000000
u.mem.size=10000000
root=/dev/ram0 rdinit=/linuxrc console=ttySAC0,115200 mem=256M@0x50000000

2
r_banks=00000001
start=50000000
u.mem.size=10000000

3
r_banks=00000001
start=50000000
u.mem.size=10000000
1:
root=/dev/ram0 rdinit=/linuxrc console=ttySAC0,115200 mem=256M@0x50000000
IRQ init
Linux version 2.6.38 (root@localhost.localdomain) (gcc version 4.4.3 (ctng-1.6.1) ) #35 Sat Jul 30 18:27:28 CST 2011
CPU: ARMv6-compatible processor [410fb766] revision 6 (ARMv7), cr=00c5387f
CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
Machine: MINI6410
Memory policy: ECC disabled, Data cache writeback
CPU S3C6410 (id 0x36410101)
S3C24XX Clocks, Copyright 2004 Simtec Electronics
camera: no parent clock specified
S3C64XX: PLL settings, A=532000000, M=532000000, E=24000000
S3C64XX: HCLK2=266000000, HCLK=133000000, PCLK=66500000
mout_apll: source is fout_apll (1), rate is 532000000
mout_epll: source is epll (1), rate is 24000000
mout_mpll: source is mpll (1), rate is 532000000
mmc_bus: source is mout_epll (0), rate is 24000000
mmc_bus: source is mout_epll (0), rate is 24000000
mmc_bus: source is mout_epll (0), rate is 24000000
usb-bus-host: source is clk_48m (0), rate is 48000000
uclk1: source is dout_mpll (1), rate is 66500000
spi-bus: source is mout_epll (0), rate is 24000000
spi-bus: source is mout_epll (0), rate is 24000000
audio-bus: source is mout_epll (0), rate is 24000000
audio-bus: source is mout_epll (0), rate is 24000000
audio-bus: source is mout_epll (0), rate is 24000000
irda-bus: source is mout_epll (0), rate is 24000000
camera: no parent clock specified
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 65024
Kernel command line: root=/dev/ram0 rdinit=/linuxrc console=ttySAC0,115200 mem=256M@0x50000000
PID hash table entries: 1024 (order: 0, 4096 bytes)
Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
Memory: 256MB = 256MB total
Memory: 254576k/254576k available, 7568k reserved, 0K highmem
Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
    DMA     : 0xff600000 - 0xffe00000   (   8 MB)
    vmalloc : 0xd0800000 - 0xf6000000   ( 600 MB)
    lowmem  : 0xc0000000 - 0xd0000000   ( 256 MB)
    pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
    modules : 0xbf000000 - 0xbfe00000   (  14 MB)
      .init : 0xc0008000 - 0xc002b000   ( 140 kB)
      .text : 0xc002b000 - 0xc03902e8   (3477 kB)
      .data : 0xc0392000 - 0xc03b8560   ( 154 kB)
NR_IRQS:246
VIC @f6000000: id 0x00041192, vendor 0x41
VIC @f6010000: id 0x00041192, vendor 0x41
Console: colour dummy device 80x30
console [ttySAC0] enabled
Calibrating delay loop... 530.84 BogoMIPS (lpj=2654208)
pid_max: default: 32768 minimum: 301
Security Framework initialized
SELinux:  Initializing.
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
hw perfevents: enabled with v6 PMU driver, 3 counters available
NET: Registered protocol family 16
MINI6410: Option string mini6410=0
MINI6410: selected LCD display is 480x272
hw-breakpoint: found 6 breakpoint and 1 watchpoint registers.
hw-breakpoint: maximum watchpoint size is 4 bytes.
S3C6410: Initialising architecture
bio: create slab <bio-0> at 0
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
NetLabel: Initializing
NetLabel:  domain hash size = 128
NetLabel:  protocols = UNLABELED CIPSOv4
NetLabel:  unlabeled traffic allowed by default
NET: Registered protocol family 2
IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
TCP established hash table entries: 8192 (order: 4, 65536 bytes)
TCP bind hash table entries: 8192 (order: 3, 32768 bytes)
TCP: Hash tables configured (established 8192 bind 8192)
TCP reno registered
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1

initrd_start=0xc1800040,err =ox0
Trying to unpack rootfs image as initramfs...
Freeing initrd memory: 1016K
audit: initializing netlink socket (disabled)
type=2000 audit(0.650:1): initialized
VFS: Disk quotas dquot_6.5.2
Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
msgmni has been set to 499
cryptomgr_test used greatest stack depth: 7212 bytes left
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
s3c6400-uart.0: ttySAC0 at MMIO 0x7f005000 (irq = 16) is a S3C6400/10
s3c6400-uart.1: ttySAC1 at MMIO 0x7f005400 (irq = 20) is a S3C6400/10
s3c6400-uart.2: ttySAC2 at MMIO 0x7f005800 (irq = 24) is a S3C6400/10
s3c6400-uart.3: ttySAC3 at MMIO 0x7f005c00 (irq = 28) is a S3C6400/10
brd: module loaded
Uniform Multi-Platform E-IDE driver
ide-gd driver 1.18
mousedev: PS/2 mouse device common for all mice
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
TCP bic registered
Initializing XFRM netlink socket
NET: Registered protocol family 17
Registering the dns_resolver key type
registered taskstats version 1
Initalizing network drop monitor service
Freeing init memory: 140K

ramdisk_execute_command=/linuxrc
mount used greatest stack depth: 6344 bytes left
rcS used greatest stack depth: 6240 bytes left

Processing /etc/profile... Done

/ #
/ #
/ #