职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 380|回复: 1

Linux内核网络协议栈2-socket从库函数到内核

[复制链接]
hxy 发表于 2011-8-27 10:19 | 显示全部楼层 |阅读模式
一、socket()......
推荐链接  见证又一......


  
一、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:
C代码  
movl $SYS_ify(socketcall), %eax /* System call number in %eax.  */  
  
/* Use ## so `socket' is a separate token that might be #define'd.  */  
movl $P(SOCKOP_,socket), %ebx   /* Subcode is first arg to syscall.  */  
lea 4(%esp), %ecx       /* Address of args is 2nd arg.  */  
  
        /* Do the system call trap.  */  
ENTER_KERNEL  

movl $SYS_ify(socketcall), %eax        /* System call number in %eax.  */

/* Use ## so `socket' is a separate token that might be #define'd.  */
movl $P(SOCKOP_,socket), %ebx        /* Subcode is first arg to syscall.  */
lea 4(%esp), %ecx                /* Address of args is 2nd arg.  */

        /* Do the system call trap.  */
ENTER_KERNEL这里,
SYS_ify宏定义为:glibc-2.3.6/sysdept/unix/sysv/linux/i386/Sysdept.h
C代码  
#define SYS_ify(syscall_name)   __NR_##syscall_name;  

#define SYS_ify(syscall_name)        __NR_##syscall_name;P宏定义为:glibc-2.3.6/sysdept/unix/sysv/linux/i386/socket.S
C代码  
#define P(a, b) P2(a, b)   
#define P2(a, b) a##b  

#define P(a, b) P2(a, b)
#define P2(a, b) a##b其中,##为连接符号;
C代码  
#define __NR_socketcall     102  

#define __NR_socketcall                102SOCKOP_socket:glibc-2.3.6/sysdept/unix/sysv/linux/Socketcall.h
C代码  
#define SOCKOP_socket       1  

#define SOCKOP_socket                1因此,中断号是102,子中断号是1;
4) int 0x80进入内核:glibc-2.3.6/sysdept/unix/sysv/linux/i386/Sysdept.h:
C代码  
# define ENTER_KERNEL int $0x80  

# define ENTER_KERNEL int $0x805) system_call中断入口:kernel/arch/x86/kernel/entry_32.S:
C代码  
syscall_call:   
    call *sys_call_table(,%eax,4)  

syscall_call:
        call *sys_call_table(,%eax,4)
6) 进入中断向量表:kernel/arch/x86/kernel/syscall_table_32.S中的102号中断:
C代码  
.long sys_socketcall  

.long sys_socketcall
7) 进入sys_socketcall()函数,根据子中断号以决定走哪个分支:kernel/net/Socket.c:
C代码  
switch (call) {   
    case SYS_SOCKET:   
        break;   
    case SYS_BIND:   
        …...  

switch (call) {
        case SYS_SOCKET:
                break;
        case SYS_BIND:
                …...
二、socket其他库函数(bind, accept...)
1、对于其他库函数,都是引用上面提到的glibc-2.3.6/sysdept/unix/sysv/linux/i386/socket.S来实现的,如
a) bind.S:
C代码  
#define socket  bind   
#define NARGS   3   
#define NO_WEAK_ALIAS   1   
#include <socket.S>   
weak_alias (bind, __bind)  

#define        socket        bind
#define        NARGS        3
#define NO_WEAK_ALIAS        1
#include <socket.S>
weak_alias (bind, __bind)b) accept.S:
C代码  
#define socket  accept   
#define __socket __libc_accept   
#define NARGS   3   
#define NEED_CANCELLATION   
#include <socket.S>   
libc_hidden_def (accept)  

#define        socket        accept
#define        __socket __libc_accept
#define        NARGS        3
#define NEED_CANCELLATION
#include <socket.S>
libc_hidden_def (accept)在各个库函数调用中,设置不同的参数,如socket(用于设置子中断号), NARGS(系统调用的参数个数)等,最终由
C代码  
movl $P(SOCKOP_,socket), %ebx   /* Subcode is first arg to syscall.  */  

movl $P(SOCKOP_,socket), %ebx        /* Subcode is first arg to syscall.  */来生成最终的子中断号,然后放到ebx寄存器中;
2、所有socket系统调用的子中断号参见glibc-2.3.6/sysdept/unix/sysv/linux/Socketcall.h:
C代码  
#define SOCKOP_socket       1   
#define SOCKOP_bind     2   
#define SOCKOP_connect      3   
#define SOCKOP_listen       4   
#define SOCKOP_accept       5   
#define SOCKOP_getsockname  6   
#define SOCKOP_getpeername  7   
#define SOCKOP_socketpair   8   
#define SOCKOP_send     9   
#define SOCKOP_recv     10   
#define SOCKOP_sendto       11   
#define SOCKOP_recvfrom     12   
#define SOCKOP_shutdown     13   
#define SOCKOP_setsockopt   14   
#define SOCKOP_getsockopt   15   
#define SOCKOP_sendmsg      16   
#define SOCKOP_recvmsg      17  

#define SOCKOP_socket                1
#define SOCKOP_bind                2
#define SOCKOP_connect                3
#define SOCKOP_listen                4
#define SOCKOP_accept                5
#define SOCKOP_getsockname        6
#define SOCKOP_getpeername        7
#define SOCKOP_socketpair        8
#define SOCKOP_send                9
#define SOCKOP_recv                10
#define SOCKOP_sendto                11
#define SOCKOP_recvfrom                12
#define SOCKOP_shutdown                13
#define SOCKOP_setsockopt        14
#define SOCKOP_getsockopt        15
#define SOCKOP_sendmsg                16
#define SOCKOP_recvmsg                17


愚人 发表于 2011-8-27 10:19 | 显示全部楼层
推荐链接

见证又一个准百万富翁的诞生!
20-30万急聘多名天才Java/MTA软件工程师
3G培训就业月薪平均7K+,不3K就业不花一分钱!

您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-4-29 15:03 , Processed in 0.121476 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表