Chinaunix首页 | 论坛 | 博客
  • 博客访问: 138994
  • 博文数量: 36
  • 博客积分: 1180
  • 博客等级: 少尉
  • 技术积分: 260
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-30 10:21
文章分类

全部博文(36)

文章存档

2012年(1)

2011年(21)

2010年(14)

分类: BSD

2011-05-24 17:30:00

BSD-4.4 网络初始化概述

在系统初始化期间,分别为每个网络设备分配一个独立的ifnet结构。每个ifnet结构有一个列表,它包含这个设备的一个或多个协议地址结构ifaddr

3-5说明了一个接口和它的地址之间的关系。

结构i f n e t比较大,我们分五个部分来说明:

实现信息 硬件信息 接口统计 函数指针 输出队列

// 接口的通用信息结构ifnet

struct ifnet {

     char * if_name;                    /* name, e.g. ``en'' or ``lo'' */

     struct ifnet * if_next;         /* all struct ifnets are chained */

     struct ifaddr * if_addrlist; /* linked list of addresses per if */

     // 实现信息

    struct if_data {

        // 硬件信息

        // 接口统计

    };

    // 函数指针

    struct ifqueue {

        // 输出队列

     };

};

 

// 协议地址结构ifaddr

struct ifaddr {

       struct     sockaddr *ifa_addr;   /* address of interface */

       struct     sockaddr *ifa_dstaddr;      /* other end of p-to-p link */

#define   ifa_broadaddr       ifa_dstaddr    /* broadcast address interface */

       struct     sockaddr *ifa_netmask;     /* used to determine subnet */

       struct     ifnet *ifa_ifp;              /* back-pointer to interface */

       struct     ifaddr *ifa_next;   /* next address for interface */

       void (*ifa_rtrequest)(); /* check or clean routes (+ or -)'d */

       u_short   ifa_flags;        /* mostly rt_flags for cloning */

       short       ifa_refcnt;             /* extra to malloc for link info */

       int    ifa_metric;            /* cost of going out this interface */

#ifdef notdef

       struct     rtentry *ifa_rt;     /* XXXX for ROUTETOIF ????? */

#endif

};

 

==============================================================

网络初始化函数init_main.c中的main开始:

cpu_startup查找并初始化所有连接到系统的硬件设备,包括任何网络接口。

在内核初始化硬件设备后,它调用包含在pdevinit数组(./usr.bin/config中配置, 在内核配置期间构造这个数组)中的每个pdev_attach函数。

struct pdevinit pdevinit[] = {

   { slattach, 1 },

   { loopattach, 1 },

   { 0, 0 }

};

一旦一个设备被识别,一个设备专用的初始化函数就被调用。一般来说如:

1)一个AMD7990LANCE以太网接口:leattach函数被调用

2)一个串行线IP(SLIP)接口:slattach 函数被调用

3)一个环回接口:loopattach函数被调用

每个设备驱动函数(leattach/slattach/loopattach)为一个网络接口

1. 2. 构造专用的struct le_softc , struct le_softc中构造以太网共用的struct arpcom ,

struct le_softc {

    struct arpcom sc_ac; /* common Ethernet structures */

#define    sc_if  sc_ac.ac_if   /* network-visible interface */

#define    sc_addr    sc_ac.ac_enaddr   /* hardware Ethernet address */

    struct lereg0 *sc_r0;    /* DIO registers */

    struct lereg1 *sc_r1;    /* LANCE registers */

    struct lereg2 *sc_r2;    /* dual-port RAM */

    ……

}

 

struct arpcom {

    struct   ifnet ac_if;     /* network-visible interface */

    u_char ac_enaddr[6];     /* ethernet hardware address */

    struct in_addr ac_ipaddr;  /* copy of ip address- XXX */

    struct ether_multi *ac_multiaddrs; /* list of ether multicast addrs */

    int ac_multicnt;      /* length of ac_multiaddrs list */

};

3.设备复制硬件地址到 arpcom 结构中的sc_addr( sc_ac.ac_enaddr )

4. 初始化 ifnet 结构

构造完后,

bpfattach登记有BPF的接口,在图31-8中说明。

函数if_attach把初始化了的ifnet结构插入到接口的链表中(3.11)

在函数 if_attach

{

    1.配置全局数组: ifnet_addrs

struct ifaddr ** ifnet_addrs;

第一次调用if_attach时,数组ifnet_addrs不存在,因此要分配16(16=8<<1)项的空间。当数组满时,一个两倍大的新数组被分配,并且老数组中的项被复制到新的数组中。

2. 创建链路层名称并计算链路层地址的长度

3. 链路层地址 sockaddr_dl{}

4. 链路层掩码 sockaddr_dl{}

    5. 函数ether_ifattach执行对所有以太网设备通用的ifnet结构的初始化。

}

接口结构被初始化并链接到一起后,main(3-23)调用ifinit,如图3-42所示。

ifinitdomaininit完成网络接口和协议的初始化,并且scheduler开始内

核进程调度。

ifinitdomaininit在第7章讨论。

阅读(1905) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~