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 !!!