yaffs文件系统加载时出现Oops

来源:互联网 发布:python dict items 编辑:程序博客网 时间:2024/05/22 15:20

yaffs文件系统代码整合到kernel 2.6.32后编译出现如下warning:

fs/yaffs2/yaffs_vfs.c:1063:warning: initialization from incompatible pointer type

fs/yaffs2/yaffs_vfs.c:1192:warning: initialization from incompatible pointer type

fs/yaffs2/yaffs_vfs.c:1674:warning: initialization from incompatible pointer type

同时将其烧录进入mini2440开发板并启动开发板时出现如下Oops:

Unable tohandle kernel paging request at virtual address 72630012

pgd = c0004000

[72630012]*pgd=00000000

Internal error: Oops: 3 [#1]

last sysfs file:

Modules linked in:

CPU: 0    Not tainted (2.6.32.2 #18)

PC is at yaffs_getxattr+0x2c/0x84

LR is atget_vfs_caps_from_disk+0x50/0xec

pc :[<c0144bf8>]    lr :[<c0162620>]    psr: 60000013

sp : c3823ec8  ip : c0144bcc fp : c03de0ac

r10: c3823f80  r9 : 00000002 r8 : c340c880

r7 : 00000014  r6 : 7263000a r5 : c3823ee4  r4 : c3823f0c

r3 : 00000014  r2 : f0000010 r1 : c0387303  r0 : c340c880

Flags: nZCv  IRQs on FIQs on  Mode SVC_32  ISA ARM Segment kernel

Control:c000717f  Table: 30004000  DAC: 00000017

Process swapper(pid: 1, stack limit = 0xc3822270)

Stack: (0xc3823ec8to 0xc3824000)

3ec0:                   c3823f0c c340c880 c340e9c0c3804580 c340c880 c0162620

3ee0: 00001000c007c3d4 c39b6000 c007c424 00000000 c39b6000 c39a9d80 c3982800

3f00: 00000002c0162768 00000001 00000000 00000000 00000000 00000000 00000000

3f20: 00000000c3982800 c03de130 00000002 c3982800 00000000 c3823f80 c0091d4c

3f40: c398280000000000 c03de0a8 c0092360 c04c8082 00000000 c03de130 c0403840

3f60: c03de0a8c04c8082 c03de130 00000000 00000000 00000000 00000000 c002b9f8

3f80: 0000000000000000 00000000 00000000 00000000 00000000 00000000 00000000

3fa0: 0000000000000000 00000000 00000000 00000000 00000000 00000000 00000000

3fc0: 0000000000000000 00000002 c0403840 c00224e4 00000000 00000000 c0028588

3fe0: c0403840c0008438 00000000 00000000 00000000 c0029868 ffffefff fdffbfff

[<c0144bf8>](yaffs_getxattr+0x2c/0x84) from [<c0162620>](get_vfs_caps_from_disk+0x50/0xec)

[<c0162620>](get_vfs_caps_from_disk+0x50/0xec) from [<c0162768>](cap_bprm_set_creds+0xac/0x350)

[<c0162768>](cap_bprm_set_creds+0xac/0x350) from [<c0091d4c>](prepare_binprm+0xc4/0x108)

[<c0091d4c>](prepare_binprm+0xc4/0x108) from [<c0092360>] (do_execve+0x15c/0x2e4)

[<c0092360>](do_execve+0x15c/0x2e4) from [<c002b9f8>] (kernel_execve+0x34/0x84)

[<c002b9f8>](kernel_execve+0x34/0x84) from [<c0028588>] (init_post+0x98/0xf4)

[<c0028588>](init_post+0x98/0xf4) from [<c0008438>] (kernel_init+0xdc/0x10c)

[<c0008438>](kernel_init+0xdc/0x10c) from [<c0029868>] (kernel_thread_exit+0x0/0x8)

Code: 159f005811a01005 15962030 1b06843d (e5964008)

---[ end trace3cf0c84bc319fd44 ]---

Kernel panic - notsyncing: Attempted to kill init!

由log可以看出Oops出现的位置处于yaffs.o文件中的getxattr位置,错误的机器码是:e5964008

 

反汇编yaffs.o:

arm-linux-objdump-Dz -S  yaffs.o  > yaffs.dump

vim打开 yaffs.dump 搜索错误机器码(e5964008)所在位置:

此处该机器码出现于两个地方:

第一个地方:

int error = 0;

struct yaffs_dev*dev;

struct yaffs_obj*obj = yaffs_inode_to_obj(inode);

    838:        e5916128        ldr        r6,[r1, #296]        ; 0x128

yaffs_trace(YAFFS_TRACE_OS,

    83c:        e3120002        tst        r2,#2

    840:        159f0058        ldrne        r0,[pc, #88]        ; 8a0 <yaffs_getxattr+0x7c>

    844:        11a01005        movne        r1,r5

    848:        15962030        ldrne        r2,[r6, #48]        ; 0x30

    84c:        1bfffffe        blne        0<printk>

"yaffs_getxattr \"%s\" from object %d",

name,obj->obj_id);

 

if (error == 0) {

dev= obj->my_dev;

    850:        e5964008        ldr        r4,[r6, #8]

yaffs_gross_lock(dev);

    854:        e1a00004        mov        r0,r4

    858:        ebffff2a        bl        508<yaffs_gross_lock>

error= yaffs_get_xattrib(obj, name, buff, size);

    85c:        e1a01005        mov        r1,r5

    860:        e59d3018        ldr        r3,[sp, #24]

    864:        e1a02007        mov        r2,r7

    868:        e1a00006        mov        r0,r6

    86c:        ebfffffe        bl        5c0c<yaffs_get_xattrib>

    870:        e1a05000        mov        r5,r0

yaffs_gross_unlock(dev);

    874:        e1a00004        mov        r0,r4

    878:        ebffff5d        bl        5f4<yaffs_gross_unlock>

第二个地方:

struct inode *inode= dentry->d_inode;

int error = 0;

struct yaffs_dev*dev;

struct yaffs_obj*obj = yaffs_inode_to_obj(inode);

    7c0:        e5936128        ldr        r6,[r3, #296]        ; 0x128

 

yaffs_trace(YAFFS_TRACE_OS,

    7c4:        159f0050        ldrne        r0,[pc, #80]        ; 81c <yaffs_listxattr+0x78>

    7c8:        15961030        ldrne        r1,[r6, #48]        ; 0x30

    7cc:        1bfffffe        blne        0<printk>

"yaffs_listxattrof object %d", obj->obj_id);

 

if (error == 0) {

dev= obj->my_dev;

    7d0:        e5964008        ldr        r4,[r6, #8]

yaffs_gross_lock(dev);

    7d4:        e1a00004        mov        r0,r4

    7d8:        ebffff4a        bl        508<yaffs_gross_lock>

error= yaffs_list_xattrib(obj, buff, size);

    7dc:        e1a01005        mov        r1,r5

    7e0:        e1a02007        mov        r2,r7

    7e4:        e1a00006        mov        r0,r6

    7e8:        ebfffffe        bl        5bfc<yaffs_list_xattrib>

    7ec:        e1a05000        mov        r5,r0

yaffs_gross_unlock(dev);

    7f0:        e1a00004        mov        r0,r4

    7f4:        ebffff7e        bl        5f4<yaffs_gross_unlock>


结合机器码所在位置的汇编上下文可知错误出现在第一个地方,因为第一个地方有 <yaffs_getxattr+0x7c>标志,正好与Oops所提示出错地址(PC is at yaffs_getxattr+0x2c/0x84)相近,之后可通过上下文推测其对应的C代码位置,如此处可搜索log“yaffs_getxattr”所在位置:

grep "yaffs_getxattr" -nr ./yaffs/   :

./yaffs/yaffs_vfs.c:991:              "yaffs_getxattr\"%s\" from object %d",

由此可定位出C语言位置在yaffs_vfs.c的991行附近:

#ifdefYAFFS_NEW_XATTR

static ssize_tyaffs_getxattr(struct dentry * dentry, struct inode *inode,

constchar *name, void *buff, size_t size)

{

#else

static ssize_tyaffs_getxattr(struct dentry * dentry, const char *name,void *buff, size_tsize)

{

structinode *inode = dentry->d_inode;

#endif

interror = 0;

structyaffs_dev *dev;

structyaffs_obj *obj = yaffs_inode_to_obj(inode);

yaffs_trace(YAFFS_TRACE_OS,

"yaffs_getxattr \"%s\" from object %d",

name,obj->obj_id);

 

if(error == 0) {

dev= obj->my_dev;

yaffs_gross_lock(dev);

error= yaffs_get_xattrib(obj, name, buff, size);

yaffs_gross_unlock(dev);

 

}

yaffs_trace(YAFFS_TRACE_OS,"yaffs_getxattr done returning %d", error);

 

returnerror;

}

此处可分析C语言代码,发现有如下问题YAFFS_NEW_XATTR的定义如下:

#if(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))

#define YAFFS_NEW_XATTR 1

#else

#define YAFFS_NEW_GET_LINK 0

#endif

此处可知 YAFFS_NEW_GET_LINK是已经定义的因此如上C语言一定会编译

static ssize_tyaffs_getxattr(struct dentry * dentry, struct inode *inode,

constchar *name, void *buff, size_t size)

而#else永远不会被编译,同时查看2.6.32.2代码include/linux/fs.h

struct inode_operations{

….

ssize_t(*getxattr) (struct dentry *, const char *, void *, size_t);

……

}

该定义与

yaffs_getxattr(structdentry * dentry, struct inode *inode,

constchar *name, void *buff, size_t size)

无法匹配!!!!在结合编译时出现的warning:initialization from incompatible pointer type

可知出错正是此处

修正:将#ifdef YAFFS_NEW_XATTR

改为:#if  (YAFFS_NEW_XATTR > 0)

即可解决该bug !!!

原创粉丝点击