快乐虾
http://blog.csdn.net/lights_joy/
lights@hb165.com
本文适用于
ADSP-BF561
uclinux-2008r1.5-rc3(smp patch)
Visual DSP++ 5.0(update 5)
欢迎转载,但请保留作者信息
讨论链接:http://www.bfin-tools.org/bbs/viewthread.php?tid=25&extra=
内核启动时有一个错误:
No usable address families found.
socket: Function not implemented
Unable to create socket
Unable to create socket
因为是网络相关,想当然地在sys_socket这个系统调用上中断下来,居然没有进入这个函数执行!进一步直接在system_call断下来,很明显已经指定了sys_socket这个系统调用的序号,但是跟踪进去居然跑到sys_ni_syscall函数执行了,摆明了是链接了一个错误的函数进来了。
查sys_socket,有这样的结果:
查找全部"sys_socket", 大小写匹配, 全字匹配, 子文件夹, 查找结果1, "整个解决方案", "*.*"
F:\embed\uClinux\uClinux-dist-2008R1.5-RC3\linux-2.6.x\include\linux\net.h(29):#define SYS_SOCKET 1 /* sys_socket(2) */
F:\embed\uClinux\uClinux-dist-2008R1.5-RC3\linux-2.6.x\include\linux\syscalls.h(421):asmlinkage long sys_socket(int, int, int);
F:\embed\uClinux\uClinux-dist-2008R1.5-RC3\linux-2.6.x\kernel\sys_ni.c(37):cond_syscall(sys_socket);
F:\embed\uClinux\uClinux-dist-2008R1.5-RC3\linux-2.6.x\net\socket.c(1199):asmlinkage long sys_socket(int family, int type, int protocol)
F:\embed\uClinux\uClinux-dist-2008R1.5-RC3\linux-2.6.x\net\socket.c(2025): err = sys_socket(a0, a1, a[2]);
可疑的地方在这里
cond_syscall(sys_socket);
查cond_syscall的定义:
/*
* "Conditional" syscalls
*
* What we want is __attribute__((weak,alias("sys_ni_syscall"))),
* but it doesn't work on all toolchains, so we just do it by hand
*/
#define cond_syscall(x) asm(".weak\t_" #x "\n\t.set\t_" #x ",_sys_ni_syscall");
这段代码展开就变成了下面的一段汇编代码:
.weak _sys_socket
.set _sys_socket,_sys_ni_syscall
先在VDSP文档中查一下.weak:
The .WEAK directive supports weak binding for a symbol. Use this directive where the symbol is defined (replacing the .GLOBAL directive to make a weak definition) and the .EXTERN directive (to make a weak reference).
symbol – the user-defined symbol
Although the linker generates an error if two objects define global symbols with identical names, it allows any number of instances of weak definitions of a name. All will resolve to the first, or to a single, global definition of a symbol.
One difference between .EXTERN and .WEAK references is that the linker does not extract objects from archives to satisfy weak references. Such references, left unresolved, have the value 0.
Note: The .WEAK (or .GLOBAL scope) directive is required to make symbols available for placement through RESOLVE commands in the .ldf file.
再查一下.set
The .SET directive is used to alias one symbol for another.
symbol1 becomes an alias to symbol2.
就这样,好好的sys_socket调用就变成了sys_ni_syscall。
把cond_syscall这几行语句注释掉,搞定。
1 参考资料
uclinux-2008R1.5-RC3(bf561)到VDSP5的移植(72):中断时SP的保存(2009-2-22)
uclinux-2008R1.5-RC3(bf561)到VDSP5的移植(73):.init.setup(2009-02-27)
uclinux-2008R1.5-RC3(bf561)到VDSP5的移植(74):initramfs(2009-02-27)
uclinux-2008R1.5-RC3(bf561)到VDSP5的移植(75):Milestone:内核成功启动(2009-02-27)
uclinux-2008R1.5-RC3(bf561)到VDSP5的移植(76):DM9000网卡驱动(2009-3-1)