免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4279 | 回复: 1
打印 上一主题 下一主题

Linux内核网络协议栈2-socket从库函数到内核 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-06-24 17:33 |只看该作者 |倒序浏览
本帖最后由 zhuyoong 于 2011-06-24 17:35 编辑

一、socket()库函数到系统调用,再到内核
1、Linux运行的C库是glibc;
2、socket()调用如下:
1) socket()->__socket():glibc-2.3.6/sysdept/generic/socket.c (weak_alias(name1, name2))
2) __socket():glibc-2.3.6/sysdept/unix/sysv/linux/i386/socket.S
3) ENTER_KERNEL:
  1.   
  2. movl $SYS_ify(socketcall), %eax /* System call number in %eax.  */  
  3.   
  4. /* Use ## so `socket' is a separate token that might be #define'd.  */  
  5. movl $P(SOCKOP_,socket), %ebx   /* Subcode is first arg to syscall.  */  
  6. lea 4(%esp), %ecx       /* Address of args is 2nd arg.  */  
  7.   
  8.         /* Do the system call trap.  */  
  9. ENTER_KERNEL  
复制代码
这里,
SYS_ify宏定义为:glibc-2.3.6/sysdept/unix/sysv/linux/i386/Sysdept.h
  1.   
  2. #define SYS_ify(syscall_name)   __NR_##syscall_name;  
复制代码
P宏定义为:glibc-2.3.6/sysdept/unix/sysv/linux/i386/socket.S
  1.    
  2. #define P(a, b) P2(a, b)  
  3. #define P2(a, b) a##b  
复制代码
其中,##为连接符号;
  1.    
  2. #define __NR_socketcall     102  
  3. SOCKOP_socket:glibc-2.3.6/sysdept/unix/sysv/linux/Socketcall.h

  4. #define SOCKOP_socket       1  
复制代码
因此,中断号是102,子中断号是1;
4) int 0x80进入内核:glibc-2.3.6/sysdept/unix/sysv/linux/i386/Sysdept.h:
  1.   
  2. # define ENTER_KERNEL int $0x80  
复制代码
5) system_call中断入口:kernel/arch/x86/kernel/entry_32.S:
  1.    
  2. syscall_call:  
  3.     call *sys_call_table(,%eax,4)  
复制代码
6) 进入中断向量表:kernel/arch/x86/kernel/syscall_table_32.S中的102号中断:
  1.    
  2. .long sys_socketcall  
复制代码
7) 进入sys_socketcall()函数,根据子中断号以决定走哪个分支:kernel/net/Socket.c:
  1.    
  2. switch (call) {  
  3.     case SYS_SOCKET:  
  4.         break;  
  5.     case SYS_BIND:  
  6.         …...  
复制代码
二、socket其他库函数(bind, accept...)
1、对于其他库函数,都是引用上面提到的glibc-2.3.6/sysdept/unix/sysv/linux/i386/socket.S来实现的,如
a) bind.S:
  1.   
  2. #define socket  bind  
  3. #define NARGS   3  
  4. #define NO_WEAK_ALIAS   1  
  5. #include <socket.S>  
  6. weak_alias (bind, __bind)  
复制代码
b) accept.S:
  1.    
  2. #define socket  accept  
  3. #define __socket __libc_accept  
  4. #define NARGS   3  
  5. #define NEED_CANCELLATION  
  6. #include <socket.S>  
  7. libc_hidden_def (accept)  
复制代码
在各个库函数调用中,设置不同的参数,如socket(用于设置子中断号), NARGS(系统调用的参数个数)等,最终由

C代码  
movl $P(SOCKOP_,socket), %ebx   /* Subcode is first arg to syscall.  */  

来生成最终的子中断号,然后放到ebx寄存器中;
2、所有socket系统调用的子中断号参见glibc-2.3.6/sysdept/unix/sysv/linux/Socketcall.h:
  1.    
  2. #define SOCKOP_socket       1  
  3. #define SOCKOP_bind     2  
  4. #define SOCKOP_connect      3  
  5. #define SOCKOP_listen       4  
  6. #define SOCKOP_accept       5  
  7. #define SOCKOP_getsockname  6  
  8. #define SOCKOP_getpeername  7  
  9. #define SOCKOP_socketpair   8  
  10. #define SOCKOP_send     9  
  11. #define SOCKOP_recv     10  
  12. #define SOCKOP_sendto       11  
  13. #define SOCKOP_recvfrom     12  
  14. #define SOCKOP_shutdown     13  
  15. #define SOCKOP_setsockopt   14  
  16. #define SOCKOP_getsockopt   15  
  17. #define SOCKOP_sendmsg      16  
  18. #define SOCKOP_recvmsg      17  
复制代码
系列文章,请参考我在iteye的blog:http://diecui1202.iteye.com

评分

参与人数 1可用积分 +6 收起 理由
Godbach + 6 感谢分享

查看全部评分

论坛徽章:
0
2 [报告]
发表于 2012-02-18 10:28 |只看该作者
非常感谢,流程很清楚。
最近正在看网络子系统,看到这个真是念头通畅了,呵呵。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP