1. socket_init()建立vfsmount文件系统
static struct vfsmount *sock_mnt __read_mostly;
static int __init sock_init(void)
{
skb_init(); //为socket buffer创建高速缓存
init_inodecache(); //为struct sock_alloc创建高速缓存
//创建已安装文件系统
register_filesystem(&sock_fs_type);
sock_mnt = kern_mount(&sock_fs_type);
}
static struct file_system_type sock_fs_type = {
.name = "sockfs",
.mount = sockfs_mount,
.kill_sb = kill_anon_super,
};
static struct file_system_type *file_systems;
int register_filesystem(struct file_system_type * fs)
{
struct file_system_type ** p;
/*将sock_fs_type注册到全局的file_systems中*/
p = find_filesystem(fs->name, strlen(fs->name));
if(p)
return error;
else
*p = fs;
}
函数kern_mount()将调用vfs_kern_mount()创建vfsmount
struct vfsmount *
vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
{
struct vfsmount *mnt;
struct dentry *root;
mnt = alloc_vfsmnt(name); //从高速缓存中获取vsfmount结构
root = mount_fs(type, flags, name, data);
//建立vfsmount与dentry的对应关系
mnt->mnt_root = root;
mnt->mnt_sb = root->d_sb;
mnt->mnt_mountpoint = mnt->mnt_root;
mnt->mnt_parent = mnt;
return mnt;
}
创建dentry对象
struct dentry *
mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
{
struct dentry *root;
struct super_block *sb;
root = type->mount(type, flags, name, data); //调用sock_fs_type中的sockfs_mount()
sb = root->d_sb;
return root;
}
sockfs_mount()将调用mount_pseudo()
static const struct super_operations sockfs_ops = {
.alloc_inode = sock_alloc_inode,
.destroy_inode = sock_destroy_inode,
.statfs = simple_statfs,
};
static const struct dentry_operations sockfs_dentry_operations = {
.d_dname = sockfs_dname,
};
struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name,
const struct super_operations *ops,
const struct dentry_operations *dops, unsigned long magic)
{
struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
//创建super block并注册到全局super_blocks中
struct dentry *dentry;
struct inode *root;
root = new_inode(s); //创建inode对象
dentry = d_alloc(NULL, &d_name); //创建dentry对象
//将创建的3个对象建立联系
……
return dentry;
}
初始化完成后:sock_mnt->vfsmount->dentry->inode->superblock
2. inet_init()网络网络层初始化
static int __init inet_init(void)
{
proto_register(/*tcp, udp, raw*/); //将inet socket结构proto注册到proto_list中
sock_register(&inet_family_ops); //将协议族net_proto_family注册到net_families中
inet_add_protocol(/*tcp, udp, icmp*/);
//将协议处理接口结构net_protocol注册到inet_protos中
//建立inetsw链表与inetsw_array数组的对应关系
for (r = &inetsw[0]; r < &inetsw[SOCK_MAX]; ++r)
INIT_LIST_HEAD(r);
for (q = inetsw_array; q < &inetsw_array[INETSW_ARRAY_LEN]; ++q)
inet_register_protosw(q);
……
}
Socket基本结构:
3. socket()
SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
{
struct socket *sock;
/*调用sock_alloc创建struct socket_alloc,其中包含struct socket和struct inode;
调用sock->create()-------->inet_create()创建struct sock
*/
retval = sock_create(family, type, protocol, &sock);
//创建文件描述符struct file,将file指针放入fd数组中
retval = sock_map_fd(sock,flags&(O_CLOEXEC|O_NONBLOCK));
return retval;
}
结构如图:
struct socket_alloc
|-------------|
| socket |------>sock
|-------------|
|----dentry->| inode |------------>
Struct file->path-| |-------------| Super_block
|----fsmount->dentry->inode------>
用户进程通过文件描述符就可以找到INET socket。BSD socket层从已注册的INET proto_ops结构中调用INET层socket支持例程来执行工作。例如,一个ipv4的BSD socket建立请求,将用到下层的INET socket的建立函数。为了不把BSD socket与tcpip的特定信息搞混,INET socket层使用它自己的数据结构struct sock,它与BSD socket结构相连。Sock结构的协议操作指针也在初始化时建立,它依赖于被请求的协议。如果请求时TCP,那么sock结构的协议操作指针将指向TCP连接所必须的TCP协议操作集。
4. net_dev_ini ()网络设备抽象层初始化
static int __init net_dev_init(void)
{
//Initialise the packet receive queues.
for (i = 0; i < NR_CPUS; i++) {
struct softnet_data *queue; queue = &per_cpu(softnet_data, i);
skb_queue_head_init(&queue->input_pkt_queue);
queue->throttle = 0;
queue->cng_level = 0;
queue->avg_blog = 10; /* arbitrary non-zero */
queue->completion_queue = NULL;
INIT_LIST_HEAD(&queue->poll_list);
set_bit(__LINK_STATE_START, &queue->backlog_dev.state);
queue->backlog_dev.weight = weight_p;
queue->backlog_dev.poll = process_backlog;
atomic_set(&queue->backlog_dev.refcnt, 1);
}
open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL);
open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL);
}
为每个CPU创建一个struct softnet_data的队列,表示要交给此CPU处理的数据包。并注册网络相关的软中断。
网络设备抽象层通过struct net_device调用指定的device driver与设备通信。
5. device driver initialize
用insmod加载驱动模块时,内核会默认执行模块中的module_init()函数
static int __init xxx_init_module (void)
{
return pci_register_driver(&xxx_pci_driver);
}
module_init(xxx_init_module);
pci_register_driver()注册设备驱动程序(struct pci_driver)
int __pci_register_driver(struct pci_driver *drv, struct module *owner,
const char *mod_name)
{
/*将strcut pci_driver加到总线链表中,并执行.probe()初始化设备驱动 */
driver_register(&drv->driver);
/* 为驱动创建sysfs文件 */
pci_create_newid_file(drv);
pci_create_removeid_file(drv);
}
strcut pci_driver->probe()调用驱动初始化函数初始化struct net_device
static int __devinit xxx_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct net_device *dev = NULL;
xxx_init_board (pdev, &dev);
/* 设备抽象层提供驱动操作函数 */
dev->open = xxx_open;
dev->hard_start_xmit =xxx_start_xmit;
dev->poll = xxx_poll;
dev->stop = xxx_close;
dev->do_ioctl = netdev_ioctl;
}