原创 为AM335x移植Linux内核主线代码(39)调试Ethernet之四

2015-2-13 20:48 1100 14 14 分类: MCU/ 嵌入式 文集: Linux Kernel的DTS

第九次执行inet_ioctl函数:

[   46.187323] ================================> inet_ioctl SSSS                
[   46.193367] ====> ioctl_num = 9 cmd = 0x8913                                 
[   46.198076] ====> delay 1s.                                                  
[   47.196022] ====> NO VALID SIOC*                                             
[   47.199408] ====> sk_prot->ioctl                                             
[   47.202786] =========================> inet_ioctl EEEEEEEEEEEEEE

在第八次的末尾和第九次的开始分别添加10S的延时,会发现,第八次执行完毕之后RJ45的指示灯正常闪烁,第九次开始执行之前就熄灭,说明在第八次和第九次执行ioctl之间,发生了一些事情。

到这里似乎陷入了困难,因为没有任何线索能够告诉我这些inet_ioctl函数是在哪里调用的,即使grep SIOCSIFFLAGS等等关键宏也毫无提示。

怎么办呢?

《Linux设备驱动程序》第四章的内容是“调试技术”,在这里找找线索。先尝试一下打开调试信息:
1. 使能CONFIG_DEBUG_KERNEL,它通常默认使能;
2. 使能CONFIG_DEBUG_INFO,它通常默认使能;
3. 使能CONFIG_DEBUG_DRIVER,它需要make menuconfig:
Device Drivers -> Generic Devices Options -> Driver Core verbose debug messages

好吧,貌似也没有什么有价值的线索!

http://www.skyfree.org/linux/kernel_network/ioctl.html
==================================================
原来inet_ioctl是被下面这个函数调用的(net/socket.c):
static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg);

http://www.linuxquestions.org/questions/linux-newbie-8/where-is-sys_ioctl-implemented-905941/
==================================================
然后sock_ioctl是被下面这个函数调用的(fs/ioctl.c):
int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned long arg);

然后do_vfs_ioctl又是被下面这个所调用(fs/ioctl.c):
SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg);
在include/linux/syscalls.h中有:

#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)
 
#define SYSCALL_DEFINEx(x, sname, ...)                          \
        SYSCALL_METADATA(sname, x, __VA_ARGS__)                 \
        __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)

为了搞清楚第八次和第九次inet_ioctl之间究竟发生了什么,需要跟踪代码,直到找到调用它们的函数;这里遇到的问题是,inet_ioctl的调用可不像是普通的被调用,而是牵涉到了SYSCALL的概念。因此需要将先弄清楚什么是SYSCALL_DEFINEx,再继续进行Ethernet的调试!

着急不?俺也着急!可如果坎摆在这里,就必须要跨过去。否则朝着对岸瞎戳也不是办法。
那究竟什么是SYSCALL呢?SYSCALL_DEFINEx又是怎样被使用的呢?
下一节就来了解它。

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
14
关闭 站长推荐上一条 /3 下一条