linux系统用户态与内核态接口

简介
用户空间与内核空间的交互方式如下,下面逐一详细说明。

procfs

netlink

文件io读写

ioctl

debugfs

sysfs

procfs:在Linux系统中,procfs是一种伪文件系统,它提供了一种以文件的形式访问内核数据结构和系统信息的接口。用户空间可以通过读取和写入/proc目录下的文件来与内核进行交互。

netlink:Netlink是Linux内核中一种用于进程间通信的机制,它允许用户空间的进程与内核空间的进程进行双向通信。用户空间的进程可以通过创建和使用Netlink套接字的方式,与内核空间的进程进行交互。

文件IO读写:用户空间的进程可以通过标准的文件IO操作(如open、read、write等)与内核空间进行交互。这种方式往往用于与设备驱动程序进行通信,通过读写设备文件来访问设备。

ioctl:ioctl(Input/Output Control)是Linux中的一个系统调用,它可以用于在用户空间和内核空间之间进行特殊操作的交互。特定的指令可以通过ioctl传递给设备驱动程序,实现特定的功能。

debugfs:debugfs是Linux内核中的一个文件系统,用于调试目的。用户空间的进程可以通过读写debugfs文件系统中的文件来获取和修改内核的调试信息,从而与内核进行交互。

sysfs:sysfs是Linux内核中的一个文件系统,用于提供设备和驱动程序的信息。用户空间的进程可以通过读取sysfs文件系统中的文件来获取设备和驱动程序的相关信息,也可以通过写入sysfs文件系统中的文件来配置相关参数,与内核进行交互。

procfs

procfs是内核的进程文件系统,被挂载到 /proc目录下,通过内核访问进程信息。
我们可以创建proc文件和内核交互。

/proc/sys目录下存放了一些内核变量,文件和目录都是以ctl_table结构定义的。

ctl_table结构的注册、注销是通过kernel/sysctl.c中定义的register_sysctl_table和unregister_sysctl_table实现的。

procfs初始化首先看下fs/proc/ 文件夹里的Makefile。这里参考fs/proc/root.c。

void __init proc_root_init(void)
{
    struct vfsmount *mnt;
    int err;

    proc_init_inodecache();
    err = register_filesystem(&proc_fs_type);
    if (err)
        return;
    mnt = kern_mount_data(&proc_fs_type, &init_pid_ns);
    if (IS_ERR(mnt)) {
        unregister_filesystem(&proc_fs_type);
        return;
    }

    init_pid_ns.proc_mnt = mnt;
    proc_symlink("mounts", NULL, "self/mounts");

    proc_net_init();

#ifdef CONFIG_SYSVIPC
    proc_mkdir("sysvipc", NULL);
#endif
    proc_mkdir("fs", NULL);
    proc_mkdir("driver", NULL);
    proc_mkdir("fs/nfsd", NULL); /* somewhere for the nfsd filesystem to be mounted */
#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
    /* just give it a mountpoint */
    proc_mkdir("openprom", NULL);
#endif
    proc_tty_init();
#ifdef CONFIG_PROC_DEVICETREE
    proc_device_tree_init();
#endif
    proc_mkdir("bus", NULL);
    proc_sys_init();
}


proc目录下创建目录

fs/proc/generic.c

struct proc_dir_entry *proc_mkdir(const char *name,
        struct proc_dir_entry *parent)
{
    return proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent);
}

proc下创建文件

struct proc_dir_entry *entry = create_proc_entry("my_proc", 0, NULL);
    if(entry)
    {
        entry->read_proc = XXX_proc_read;
        entry->write_proc = XXX_proc_write;
    }
struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
                     struct proc_dir_entry *parent)
{
    struct proc_dir_entry *ent;
    nlink_t nlink;

    if (S_ISDIR(mode)) {
        if ((mode & S_IALLUGO) == 0)
            mode |= S_IRUGO | S_IXUGO;
        nlink = 2;
    } else {
        if ((mode & S_IFMT) == 0)
            mode |= S_IFREG;
        if ((mode & S_IALLUGO) == 0)
            mode |= S_IRUGO;
        nlink = 1;
    }

    ent = __proc_create(&parent, name, mode, nlink);
    if (ent) {
        if (proc_register(parent, ent) < 0) {
            kfree(ent);
            ent = NULL;
        }
    }
    return ent;
}


/proc/net/下文件procfs接口

extern struct proc_dir_entry *proc_net_fops_create
(struct net *net, const char *name, mode_t mode, const struct file_operations *fops);

extern void proc_net_remove(struct net *net, const char *name);

extern struct proc_dir_entry *proc_net_mkdir
(struct net *net, const char *name, struct proc_dir_entry *parent);

netlink

netlink_net_init

在文件系统中位网络命名空间创建一个proc入口。

static int __net_init netlink_net_init(struct net *net)
{
#ifdef CONFIG_PROC_FS
    if (!proc_net_fops_create(net, "netlink", 0, &netlink_seq_fops))
        return -ENOMEM;
#endif
    return 0;
}static const struct file_operations netlink_seq_fops = {
    .owner        = THIS_MODULE,
    .open        = netlink_seq_open,
    .read        = seq_read,
    .llseek        = seq_lseek,
    .release    = seq_release_net,
};
static const struct seq_operations netlink_seq_ops = {
    .start  = netlink_seq_start,
    .next   = netlink_seq_next,
    .stop   = netlink_seq_stop,
    .show   = netlink_seq_show,
};


static int netlink_seq_open(struct inode *inode, struct file *file)
{
    return seq_open_net(inode, file, &netlink_seq_ops,
                sizeof(struct nl_seq_iter));
}

文件io读写

内容待补充

ioctl

内容待补充

debugfs

内容待补充

sysfs

内容待补充

你可能感兴趣的:(linux内核,gnu,linux)