精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>电脑技术>>● FreeBSD>>FreeBSD 核心探讨 (cool!)>>FreeBSD核心探讨.10.驱动程序篇

主题:FreeBSD核心探讨.10.驱动程序篇
发信人: liangvy()
整理人: hahalee(1999-06-29 12:02:55), 站内信件
[ Lenn<[email protected]>版权所有,不得书面出版 ]

2。4进程通信
    (socket和network interface)

        网络协议和路由选择的过程中,为选择合适的网络接口,一般进程没必要对
网络接口进行明确指示。所以,网络卡就不和文件系统的名字对应,而是在核心内部
的struct ifnet(@net/if.h)进行对应。用命令ifconfig和netstat -i就可以看到各个
网卡的struct ifnet的参数。
        unix中,进程通信和网络介入的通信的场合,使用network interface。进行
通信的进程,根据socket()的系统调用,把socket作为通信手段。这个时候,需要指
定协议族,通信类型,具体的协议等。综合起来,有如下的参数:

int socket( int domain,         //protocal family
            int type,           //通信形式
            int protocal        //具体的协议
          )

根据protocal family可以推算出可以通信的范围,同时,可以控制通信类型和具体的
协议。通信类型有如下的四个种类。

.SOCK_STREAM
        基于连接的传输,具有可靠性,可以保证通信的发送接收顺序的双向通信路。
    但不限制数据的传输顺序的紧急数据发送情况也有可能。发送数据和接受数据的
    的间隔不一定。比如一次发送10个byte,可能一次接受完毕,但发送100个byte,
    可能一次接受完毕,也可能分两次接收。

.SOCK_DREAM
        可靠性比较低。不是基于连接传输。每次的发送数据长度是有限制的。

.SOCK_SEQPACKET
        基于连接的传输,具有可靠性,可以保证通信的发送接收顺序的双向通信路。
    和.SOCK_STREAM不同的地方是,发送数据和接受数据的间隔一定,每次的发送长度
    也是限制的。

.SOCK_RAW
        核心内部的network protocal和interface的控制中使用。

        通信类型受制于具体的协议。freebsd协议族有如下的一些:
---------------------------------------------------------------------------
协议族                  通信类型                定义模块
PF_ROUTE                SOCK_RAW                net/rtsock.c
PF_APPLETALK            SOCK_DGRAM              netatalk/at_proto.c
PF_INET                 SOCK_DGRAM              netinet/in_proto.c
                        SOCK_STREAM
                        SOCK_RAW
PF_IPX                  SOCK_DRAM               netipx/ipx_proto.c
                        SOCK_STREAM
                        SOCK_SEQACKET
                        SOCK_RAW
PF_KEY                  SOCK_RAW                netkey/key.c
PF_NS                   SOCK_DGRAM              netns/ns_proto.c
                        SOCK_STREAM
                        SOCK_SEQACKET
                        SOCK_RAW
PF_LOCAL                SOCK_STREAM             kern/uipc_proto.c
                        SOCK_DGRAM
--------------------------------------------------------------------------

这些协议族由各个struct domain里定义。在这里面,当前的协议族里可能利用的通信
类型可以在struct protosw里找到。protocal family的登记可以把宏DOMAIN_SET()设
定的信息通过函数domaininit()(@kern/uipc_domain.c)读到kernel的初始化中。

        由系统调用socket()取得的socket,在进程里可以象文件柄一样的进行操作。
适当的设置后,可以使用read()/write()调用。由open()取得的文件柄对应read()/
write()/ioctl()/select()/close()处理可以使用vn_read()/vn_write()/vn_ioctl()
/vn_select()/vn_close()进行相应替换,对socket的处理则是soo_read()/soo_write
()/soo)ioctl()/soo_select()/soo_close()(@kern/sys_socket.c)进行取代。对应于
socket的struct protosw的子过程则在任何地方都可以进行处理。还有可以用send()
/sendto()/sendmsg()进行发送,recv()/resvfrom()/recvmsg()进行接收。

        socket是绑定在通信路上的,所以,如果不规定通信对象的端子,就不能进行
实际的通信操作。也就是说,必须指定对象和自己的socket的地址。这个和protocal 
family不大一样,它由struct sockaddr_XXX指定。但是对socket指定地址的系统调用
对每个socket family并没有统一性,系统调用层次的地址在struct sockaddr(@sys/
socket.h)里面包含。这样,就可以区别它的成员sa_family里各个
struct sockaddr_XXX 了。
        s = socket(PF_INET,SOCK_DGRAM,0)取得的socket由band()进行address的设
定后,
        sendto(s,msg,mlen,sockaddr_to,tolen)
        里的 message msg向sockaddr_to的地址送去,kernel内则顺序进行如下的操
作处理。

        1.系统调用sendto()的处理过程sendto()(@kern/uipc_syscalls.c)就是,得
    到参数后在调用sendit()(@kern/uipc_syscalls.c).
        2.sendit()先从参数得到发送的地址,再调用sosend()
    (@kern/uipc_socket.c).
        3.sosend()从struct uio取得发送数据,然后向struct mbuf变换。建立socket
    时候所指定address family/protocal的处理过程把
    so_proto->pr_usrreqs->pru_send调出来。在这里调用了udp_userreq()(@netinet/
    udp_usrreq.c)。
        4.udp_usrreq()是PRU_SEND处理,它调用了udp_output()。
        5.udp_output是UDP包的分组变换,它调用ip_output()(@netinet/ip_output)。
        6.ip_output()的功能是从发送ip地址开始,选择network interface的子过程。
    如果是ethernet,则调用ether_output()(@net/if_ethersubr.c)。还有IP firewall
    的处理也在这里进行。
        7.ether_output()则由发送ip地址取得ethernet的地址。进行ethernet打包,
    调用在network interface里设定的子过程if_start。再对network card进行io。

(下章开始介绍如何编写驱动程序)
Lenn <[email protected]>

--

Lenn 
Tel:    0755-3913403(H)
E-mail: [email protected]
Oicq: Lenn 28663

※ 来源:.网易 BBS bbs.netease.com.[FROM: www2.dt.sanyo.co.jp]

[关闭][返回]