linux 内核设备管理模型sysfs(入门篇)
sysfs是linux 内核从2.6中开始引入的设备管理模型,该模型通过一个虚拟的文件系统sysfs 将整个硬件的层级模型显现和组织起来,并将其采用矩阵式管理方式,还是支持热插拔等功能,该设备模型自从2.6内核引入至今 到5.0以上版本都没有经过大改,说明了该模型兼容性较好,能够不断适应新的硬件发展。
sysfs文件系统将每个设备抽象成文件,并将其组织形式如下:
一个usb 的鼠标设备mouse 1, 其设备类型class为输入设备,同时usb总线 buses类型中有归属与usb-hid, 在deivces一个驱动设备中其属于usb2 中的port 1端口设备dev1:1-0,采用类似一个矩阵式管理形式。
sysfs文件系统,将所有的设备都在sys目录内进行组织:
sys目录解释如下:
- block:包含所有的块设备。
- bus:包含所有的总线类型。
- class: 包含所有的设备类型。
- dev::包括所有的块设备和字符设备,该目录下维护一个按照字符设备和块设备的主次号码(major:minor)链接到真是设备(/sys/devices)的符号链接文件。
- devices:包括系统中所有的设备并根据设备挂接的总线类型组织层次结构。
- firmware:含对固件对象(firmware object)和属性进行操作和观察的接口。
- fs:该目录使用来描述系统中所有的文件系统,包括文件系统本身和按照文件系统分类存放的已挂载点。
- hypervisor:该目录是与虚拟化Xen相关的装置。
- module: 该目录下有系统中所有的模块信息,不论这些模块是以内联(inlined)方式编译到内核映像文件中还是编译为外模块(.ko文件),都可能出现在/sys/module中。即module目录下包含了所有的被载入kernel的模块。
- power:该目录是系统中的电源选项,对正在使用的power子系统的描述。这个目录下有几个属性文件可以用于控制整个机器的电源状态,如可以向其中写入控制命令让机器关机/重启等等。
kobject
内核sysfs文件系统使用kobject将上述图片中的各个对象链接起来,并组成一个分层的结构体系,内核为sysfs文件目录内的每个目录都创建一个kobject结构,kobject是sysfs文件系统的最基本的管理单元,相当于面向对象中的最顶层基类,其他类型都相当与是对kobject的派生类。
在linux 5.4.56 内核版本中,kobject结构如下
struct kobject {const char *name;struct list_head entry;struct kobject *parent;struct kset *kset;struct kobj_type *ktype;struct kernfs_node *sd; /* sysfs directory entry */struct kref kref;
#ifdef CONFIG_DEBUG_KOBJECT_RELEASEstruct delayed_work release;
#endifunsigned int state_initialized:1;unsigned int state_in_sysfs:1;unsigned int state_add_uevent_sent:1;unsigned int state_remove_uevent_sent:1;unsigned int uevent_suppress:1;
};
先对比较简单
- name:为该koject 的name,相当于sysfs内的目录名称。
- entry:为一个链接结构,用于将其他kobject结构链接起来
- parent: 指向该kobject的父kobject,即相当于该kobejct的父目录。
- kset::相同类型的kobject集合,指向该kobject归属于哪个kset(详细后面描述)
- ktype: 指向该对象类型,里面包含了对该对象的一些操作以及默认属性。
- sd: syfs目录节点,所有的kobject都以kernfs_node节点挂载到syfs 管理文件中,在内核中所有节点的根root节点为struct kernfs_node *sysfs_root_kn(位于mount.c文件中),sysfs会遍历sysfs_root_kn内的所有节点。
- kref: kobject计数,当该计数为0时,该kobject将会释放。
- 其他状态:其他为描述该kobject类型。
kobject 主要实现及接口实现主要位于lib/kobject.c文件。
在内核模块中对外提供的API主要如下:
API名称 | 作用及描述 |
void kobject_init(struct kobject *kobj, struct kobj_type *ktype) | 非GPL接口, kobject初始化函数,需要提供kobj_type |
int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype, struct kobject *parent, const char *fmt, ...) | 初始化kobject,并将其加入到sysfs文件系统中 |
struct kobject *kobject_create_and_add(const char *name, struct kobject *parent) | 创建一个kobject 并将其加入到指向的parent中,如果parent为NULL,则指向的时sys根目录,如block等 |
int kobject_rename(struct kobject *kobj, const char *new_name) | 重新修改kobj name |
int kobject_move(struct kobject *kobj, struct kobject *new_parent) | 将该kobject从parent中移除掉 |
int kobject_set_name(struct kobject *kobj, const char *fmt, ...) | 非GPL接口,设置kobject name |
int kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...) | 非GPL接口,添加kobject接口到parent中 |
void kobject_del(struct kobject *kobj) | 非GPL接口,删除该kobject |
struct kobject *kobject_get(struct kobject *kobj) | 非GPL接口, 获取kobject,会增加kobject中的 kref计数 |
int kset_register(struct kset *k) | 初始化并注册kobject |
void kobject_put(struct kobject *kobj) | 减少kobject中的计数,一般kobject释放 并 不直接释放而是通过该接口通过减少计数,直到为0时进行释放 |
void kset_unregister(struct kset *k) | 去注册kobject |
用例一:kobject使用
下面为一个最基本简单 用例,使用上述API,编写一个内核模块,实现在sys的根目录内创建一个test目录,与block、dev等目录平行:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kobject.h>
MODULE_LICENSE("GPL v2");static struct kobject * testKobj = NULL;
static int __init sysfs_test_init(void)
{testKobj = kobject_create_and_add("test", NULL);if (!testKobj){printk(KERN_INFO "create test kbject failed\n");return 1;}return 0;
}static void __exit sysfs_test_exit(void)
{kobject_put(testKobj);
}module_init(sysfs_test_init);
module_exit(sysfs_test_exit);
MODULE_AUTHOR("hzk");
MODULE_DESCRIPTION("A simple moudule for sysft test");
MODULE_VERSION("V1.0");
,makefile如下
obj-m :=test_sysfs.o
KERNEL :=/usr/src/linux-headers-5.4.0-56-generic
#KERNEL :=/usr/src/kernels/3.10.0-957.el7.x86_64
PWD :=$(shell pwd)
modules:make -C $(KERNEL) M=$(PWD) modules
clean:rm -f *.o *.ko
~
运行结果如下在sys根目录下生成test目录
kobj_type
通过上述简单用例主要为kobject的基本使用规则,在kobject中还有一个重要的数据结构为kobj_type结构,主要提供koj类型,主要数据结构如下:
struct kobj_type {void (*release)(struct kobject *kobj);const struct sysfs_ops *sysfs_ops;struct attribute **default_attrs; /* use default_groups instead */const struct attribute_group **default_groups;const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);const void *(*namespace)(struct kobject *kobj);void (*get_ownership)(struct kobject *kobj, kuid_t *uid, kgid_t *gid);
};
下面将依次说明上述kobj_type中的主要数据结构
- release: 在linux内核驱动代码中,由于创建者在创建完成kobject之后,供用户程序进行使用,但是通常在内核驱动生命周期中,其实并无法预知该kobject何时被释放,故在设计kobject数据结构时,采用引用计数方法来记录,当引用计数为0时可以释放该kobject,而通常在内核驱动程序中经常会在kobjct基础上外挂一些数据,所以当该kobject释放时需要同时释放该驱动的一些数据,故需要提供release 回调给驱动程序用于释放一些数据。
- default_attrs: 一般在每个sysfs目录内都会存在一些该目录的属性,使应用程序可以与内核进行交互。
- syfs_ops:为内核提供的与数据交互的一些接口一般包含show和restore两个功能。
在linux内核内部提供一个默认的kobj_type,故如果一个驱动没有特殊要求,可以不设置,使用默认dynamic_kobj_ktype
static void dynamic_kobj_release(struct kobject *kobj)
{pr_debug("kobject: (%p): %s\n", kobj, __func__);kfree(kobj);
}static struct kobj_type dynamic_kobj_ktype = {.release = dynamic_kobj_release,.sysfs_ops = &kobj_sysfs_ops,
};
kobj_sysfs_ops 实现如下:
/* default kobject attribute operations */
static ssize_t kobj_attr_show(struct kobject *kobj, struct attribute *attr,char *buf)
{struct kobj_attribute *kattr;ssize_t ret = -EIO;kattr = container_of(attr, struct kobj_attribute, attr);if (kattr->show)ret = kattr->show(kobj, kattr, buf);return ret;
}static ssize_t kobj_attr_store(struct kobject *kobj, struct attribute *attr,const char *buf, size_t count)
{struct kobj_attribute *kattr;ssize_t ret = -EIO;kattr = container_of(attr, struct kobj_attribute, attr);if (kattr->store)ret = kattr->store(kobj, kattr, buf, count);return ret;
}const struct sysfs_ops kobj_sysfs_ops = {.show = kobj_attr_show,.store = kobj_attr_store,
};
用例二:kobj_type
在上述用例一基础上,提供进行简单修改,提供kobj_type的release功能:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/slab.h>
MODULE_LICENSE("GPL v2");static struct kobject * testKobj = NULL;static void test_sysfs_release(struct kobject * kobj)
{printk(KERN_INFO "test sysfs release\n");kfree(kobj);
}static struct kobj_type test_type = {//.sysfs_ops = &test_sysfs_ops,.release = test_sysfs_release,// .default_groups = test_sys_groups,
};
static int __init sysfs_test_init(void)
{int ret = 0;testKobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);if (!testKobj){printk(KERN_INFO "kzalloc kobject failed\n");\return 1;}ret = kobject_init_and_add(testKobj, &test_type, NULL, "test");if (ret){printk(KERN_INFO "int and add kbject failed\n");return 1;}return 0;
}static void __exit sysfs_test_exit(void)
{kobject_put(testKobj);
}module_init(sysfs_test_init);
module_exit(sysfs_test_exit);
MODULE_AUTHOR("hzk");
MODULE_DESCRIPTION("A simple moudule for sysft test");
MODULE_VERSION("V1.0");
将kobject改为动态申请,这样当引用计数为0时, 需要收到释放动态申请的kobject,需要在kobj_type 中设置该驱动模块的release函数,该用例也是内核源码中释放kobject实现的一个原理。
attribute
attribute属性为该sys目录内的一些属性值,一般用于驱动程序与用户交互的数据等,attribute结构如下:
struct attribute {const char *name;umode_t mode;
#ifdef CONFIG_DEBUG_LOCK_ALLOCbool ignore_lockdep:1;struct lock_class_key *key;struct lock_class_key skey;
#endif
};
- name:为该属性名称
- mode:为该属性读写权限,按照通常的rwx以及root 用户 group进行组合。
其用法一般需要结合sysfs_ops,用户对该属性的读写操作
struct sysfs_ops {ssize_t (*show)(struct kobject *, struct attribute *, char *);ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
};
用例三:默认attribute
attribute主要有两种方法,第一种方式是在创建kobject时通过在struct kobj_type 结构中指定默认attribue方式。
在用例二的基础上进一步进行改进,对test目录内提供两个属性,属性名称分别为name和para
include <linux/init.h>
#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
MODULE_LICENSE("GPL v2");static struct kobject * testKsetKobj = NULL;static ssize_t test_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
{struct kobj_attribute * obj_attr = NULL;obj_attr = container_of(attr,struct kobj_attribute, attr);if (!obj_attr->show){return 0;}return obj_attr->show(kobj, obj_attr, buf);
}static ssize_t test_attr_store(struct kobject *kobj, struct attribute * attr, const char *buf, size_t len)
{struct kobj_attribute * obj_attr = NULL;obj_attr = container_of(attr,struct kobj_attribute, attr);if (!obj_attr->store){return 0;}return obj_attr->store(kobj, obj_attr, buf, len);
}static const struct sysfs_ops test_sysfs_ops ={.show = test_attr_show,.store = test_attr_store,
};
static void test_kset_release(struct kobject *kobj)
{printk(KERN_INFO "test kset relsase\n");kfree(kobj);
}
static ssize_t sysfs_test_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{return sprintf(buf,"hello world\n");
}static ssize_t sysfs_test_store(struct kobject *kobj, struct kobj_attribute * attr, const char * buf, size_t count)
{printk(KERN_INFO "sys test module recv: %s\n", buf);return count;
}
static struct kobj_attribute testName =__ATTR(name, 0664,sysfs_test_show,sysfs_test_store);static struct kobj_attribute testPara =__ATTR(para, 0664,sysfs_test_show,sysfs_test_store);static struct attribute *test_sys_attrs[] = {&testName.attr,&testPara.attr,NULL,
};ATTRIBUTE_GROUPS(test_sys);static struct kobj_type test_ktype = {.sysfs_ops = &test_sysfs_ops,.release = test_kset_release,.default_groups = test_sys_groups,
};
static int __init kset_test_init(void)
{testKsetKobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);if(!testKsetKobj){printk(KERN_INFO "create and add kset kobject failed\n");return 1;}if (kobject_init_and_add(testKsetKobj, &test_ktype, NULL,"test")){kfree(testKsetKobj);return 1;}return 0;
}
static void __exit kset_test_exit(void)
{kobject_put(testKsetKobj);
}module_init(kset_test_init);
module_exit(kset_test_exit);
MODULE_AUTHOR("hzk");
MODULE_DESCRIPTION("A simple moudule for sysft test");
MODULE_VERSION("V1.0");
执行结果如下:
用例四:非默认attribute
除了上述用例三在创建kobject时借助kobj_type 中的default_attrs来创建默认属性,sysfs还提供了专用接口用于创建一个非默认attribute 接口如下:
int sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp)
attribute_group定义如下:
struct attribute_group {const char *name;umode_t (*is_visible)(struct kobject *,struct attribute *, int);umode_t (*is_bin_visible)(struct kobject *,struct bin_attribute *, int);struct attribute **attrs;struct bin_attribute **bin_attrs;
};
通过在attrs中指定要创建的attribute。
include <linux/init.h>
#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
MODULE_LICENSE("GPL v2");static struct kobject * testKobj = NULL;
static struct kobject * testkobj_hello = NULL;static ssize_t sysfs_test_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{return sprintf(buf,"hello world\n");
}static ssize_t sysfs_test_store(struct kobject *kobj, struct kobj_attribute * attr, const char * buf, size_t count)
{printk(KERN_INFO "sys test module recv: %s\n", buf);return count;
}
static struct kobj_attribute testName =__ATTR(name, 0664,sysfs_test_show,sysfs_test_store);static struct kobj_attribute testPara =__ATTR(para, 0664,sysfs_test_show,sysfs_test_store);
static struct attribute *testAttr[] = {&testName.attr,&testPara.attr,NULL,
};
static struct attribute_group testGroup = {.attrs = testAttr,
};
static int __init sysfs_test_init(void)
{testKobj = kobject_create_and_add("test", NULL);if (!testKobj){printk(KERN_INFO "create test kbject failed\n");return 1;}testkobj_hello = kobject_create_and_add("hello", testKobj);if (!testkobj_hello){printk(KERN_INFO "create test hello kbject failed\n");return 1;}sysfs_create_group(testkobj_hello, &testGroup);return 0;
}static void __exit sysfs_test_exit(void)
{sysfs_remove_group(testkobj_hello,&testGroup);kobject_put(testkobj_hello);kobject_put(testKobj);
}module_init(sysfs_test_init);
module_exit(sysfs_test_exit);
MODULE_AUTHOR("hzk");
MODULE_DESCRIPTION("A simple moudule for sysft test");
MODULE_VERSION("V1.0");
运行结果如下:
内嵌kobject和attribute
一般kobject和attribute很少单独使用,单独使用一般都没有太多意义,内核和驱动工程师很少单独创建一个kobject和 单独使用attribute,内核中在上述的基础上提供了更高一层级的使用方法,而kobject和attribute作为内嵌到其中,相当于C++面向对象中的派生类,例如字符设备cdev结构:
struct cdev {struct kobject kobj;struct module *owner;const struct file_operations *ops;struct list_head list;dev_t dev;unsigned int count;
} __randomize_layout;
kobject是sysfs的管理基本单位,很多时候在编写release,show或者其他函数中需要根据传入的kobject参数获取到cdev整个结构的地址,就需要使用到内核中的container_of结构,例如在上述cdev结构需要根据提供的kobj,获取到cdev结构,使用方法如下:
struct cdev * device = container_of(kp, struct cdev, kobj);
attribute使用方法类似,内核中提供了各种各样的基于attribute的扩展属性,例如在kobject模块中就存在一个默认的kobj_attribute属性,定义如下:
struct kobj_attribute {struct attribute attr;ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,char *buf);ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,const char *buf, size_t count);
};
其使用方法同样如下
struct kobj_attribute * kattr = container_of(attr, struct kobj_attribute, attr);
这样类似的嵌入结构在内核的数据结构中非常常见。
kset
kset为相同类型的kobject集合,为kobject更高一级的组织形式,其数据结构主要如下:
struct kset {struct list_head list;spinlock_t list_lock;struct kobject kobj;const struct kset_uevent_ops *uevent_ops;
} __randomize_layout;
- list::用于链接kset中所有kobject的链表 头部
- list_lock:为list锁
- kobj:为内嵌的kobject,其kset本身也可以认为是一个kobject.
- uevent_ops为:事件操作集合
内核主要提供kset相关API如下:
API | 作用及说明 |
struct kset *kset_create_and_add(const char *name, const struct kset_uevent_ops *uevent_ops, struct kobject *parent_kobj) | 生成并添加一个kset |
struct kobject *kset_find_obj(struct kset *kset, const char *name) | 从kset中查找该名为name的kobject |
int kset_register(struct kset *k) | 注册一个kset |
void kset_unregister(struct kset *k) | 去注册kset |
kset使用方法需要按照一定的套路来实现:
1:首先创建一个kset
2: 创建一个kobject,并将该kobject指向该kset
3:将kobject添加到sysfs,此时不需要指定parent,可以根据设置的kset 自动按照所属的kset层级进行添加
include <linux/init.h>
#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
MODULE_LICENSE("GPL v2");static struct kobject * testKobj = NULL;
static struct kset * testKset = NULL;
static struct kobject * testKsetKobj = NULL;
static struct kobject * testKsetKobj2 = NULL;static ssize_t test_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
{struct kobj_attribute * obj_attr = NULL;obj_attr = container_of(attr,struct kobj_attribute, attr);if (!obj_attr->show){return 0;}return obj_attr->show(kobj, obj_attr, buf);
}static ssize_t test_attr_store(struct kobject *kobj, struct attribute * attr, const char *buf, size_t len)
{struct kobj_attribute * obj_attr = NULL;obj_attr = container_of(attr,struct kobj_attribute, attr);if (!obj_attr->store){return 0;}return obj_attr->store(kobj, obj_attr, buf, len);
}static const struct sysfs_ops test_sysfs_ops ={.show = test_attr_show,.store = test_attr_store,
};
static void test_kset_release(struct kobject *kobj)
{printk(KERN_INFO "test kset relsase\n");
}static ssize_t sysfs_test_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{return sprintf(buf,"hello world\n");
}static ssize_t sysfs_test_store(struct kobject *kobj, struct kobj_attribute * attr, const char * buf, size_t count)
{printk(KERN_INFO "sys test module recv: %s\n", buf);return count;
}
static struct kobj_attribute testName =__ATTR(name, 0664,sysfs_test_show,sysfs_test_store);static struct kobj_attribute testPara =__ATTR(para, 0664,sysfs_test_show,sysfs_test_store);static struct attribute *test_sys_attrs[] = {&testName.attr,&testPara.attr,NULL,
};
ATTRIBUTE_GROUPS(test_sys);static struct kobj_type test_ktype = {.sysfs_ops = &test_sysfs_ops,.release = test_kset_release,.default_groups = test_sys_groups,
};
static int __init kset_test_init(void)
{testKobj = kobject_create_and_add("test", NULL);if (!testKobj){printk(KERN_INFO "create test kbject failed\n");return 1;}testKset = kset_create_and_add("kset_test", NULL, testKobj);if (!testKset){printk(KERN_INFO "create and add kset failed\n");kobject_put(testKobj);return 1;}testKsetKobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);if(!testKsetKobj){printk(KERN_INFO "create and add kset kobject failed\n");kset_unregister(testKset);kobject_put(testKobj);return 1;}testKsetKobj2 = kzalloc(sizeof(struct kobject), GFP_KERNEL);if(!testKsetKobj2){printk(KERN_INFO "create and add kset kobject2 failed\n");kset_unregister(testKset);kobject_put(testKobj);return 1;}testKsetKobj->kset=testKset;if (kobject_init_and_add(testKsetKobj, &test_ktype, NULL,"test_para")){kset_unregister(testKset);kobject_put(testKsetKobj);kobject_put(testKobj);return 1;}testKsetKobj2->kset=testKset;if (kobject_init_and_add(testKsetKobj2, &test_ktype, NULL,"test_para_2")){kset_unregister(testKset);kobject_put(testKsetKobj);kobject_put(testKsetKobj2);kobject_put(testKobj);return 1;}return 0;
}
static void __exit kset_test_exit(void)
{kset_unregister(testKset);kobject_put(testKsetKobj);kobject_put(testKsetKobj2);kobject_put(testKobj);
}module_init(kset_test_init);
module_exit(kset_test_exit);
MODULE_AUTHOR("hzk");
MODULE_DESCRIPTION("A simple moudule for sysft test");
MODULE_VERSION("V1.0");
创建一个kset 名称为kset_test,该kset下面有两个kobject 分别为test_para和test_para_2, 该每个下面都有两个相同名称的属性name和para,
kset 与 kobj_type
kset侧重于对相同类型的kobject的集合,而kobject_type关心的是kobject 对象的类型,两者用途不同。
kset内的所有kobject具有相同的属性,所以kset经常被用户相同设备类型驱动但是有多个设备场景,每个设备的sys目录下都具有相同的属性。
subsystem
在早期得sysfs的系统设计中,kset之上还有更高一个层级的设计为subsystem系统抽象,该结构为一系列的kset集合,为更高一层的抽象,其实本质上subsystem为相同类型的kobject的集合和kse的概念有点相重合,在后来版本中将该结构进删除,删除补丁为:
driver core patches for 2.6.23
该部分在现代内核代码中已经灰飞烟灭,故不再描述该功能 。
linux 内核设备管理模型sysfs(入门篇)相关推荐
- linux 内核设备管理模型sysfs(进阶篇)
<linux 内核设备管理模型sysfs(入门篇)>讲述了内核设备管理模型sysfs的基础管理单元kobject和kset,但是在实际过程中很少有驱动工程师有机会直接操作上述结构,linu ...
- linux 内核模型,The Linux Kernel Device Model - Overview -- Linux 内核设备模型概述
--------------------------------------------------------------------------------------------------- ...
- Scala进阶之路-并发编程模型Akka入门篇
Scala进阶之路-并发编程模型Akka入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Akka Actor介绍 1>.Akka介绍 写并发程序很难.程序员不得不处 ...
- 【Linux内核系列】百分百干货篇丨不要错过,5个方面分析内核架构,让你对内核不再陌生
5个方面分析内核架构,让你对内核不再陌生 1. 内存管理 mm_struct 2. 进程管理 task_struct 3. 网络协议栈 sk_buff 4. 文件系统 super_block 5. 设 ...
- 和菜鸟一起学linux内核源码之启动篇
又是一个周末,日子过得比较散,虽然期间也有不断地看书学习,总觉得有点小盲目.想想毕业也快要1年了,从事嵌入式linux的研发工作也1年多了.这1年多的从实习到正式工作到现在的自己,进步有,也很大,但是 ...
- linux 内核驱动模型,linux设备驱动模型架构分析 一
linux设备驱动模型架构分析 一 发布时间:2018-07-04 15:14, 浏览次数:584 , 标签: linux 概述 LDD3中说:"Linux内核需要一个对系统结构的一般性描述 ...
- linux内核基本模型,Linux设备模型(1)_基本概念
Linux设备模型(1)_基本概念 作者:wowo 发布于:2014-2-27 17:01 分类:统一设备模型 1. 前言 在"Linux内核的整体架构"中,蜗蜗有提到,由于Lin ...
- 学习linux内核-- 内存,看一篇就够了(多图)
内存模块 1 linux内存总体布局:内存分成用户态和内核态 4G进程地址空间解析 内核地址空间 进程地址空间 2 地址转换和页表 2.1 地址转换 虚拟内存是指程序使用的逻辑地址.每个进程4G.所有 ...
- Linux学习 第一期 Ubuntu入门篇
第1讲 开发电脑的选择 一.开发电脑要求 1.1.CPU要求 4核8线程,2核编译代码性能?编译大工程的时候很耗费CPU,编译QT大概要很久. 核心越多越好,主频越高越好. 1.2.内存要求 最少16 ...
最新文章
- APUE和UNP怎么学?
- SpringBoot ElasticSearch 全文搜索
- 怎么找回失踪的NTLDR文件
- 【PAT乙级】1030 完美数列 (25 分)
- PHP的require与include
- Vue.JS项目输入框中使用v-model导致number类型值自动转换成string问题的解决方案
- Qt简介以及如何配置Qt使用VS2010进行开发
- Atom飞行手册翻译: 4.1 配置API
- 局域网只看到少数电脑_利用局域网高速传输大文件的两种方法
- 广西(柳州)创建国家级车联网先导区建设方案
- 机器学习数学基础十:相关分析
- 把基础打牢了,将来就可以触类旁通,行行都可以写出精彩
- 笔记本重装系统后office没了
- 华硕灵耀pro16参数 华硕灵耀pro16怎么样
- 单线双向模块_UART学习
- 转载 RINEX 中观测值的类型
- 读《Spring 实战(第四版)》第三章 高级装配
- Ansys workbench 17.2 学习笔记
- python 股票_十分钟学会用Python交易股票
- CSS标准颜色值查找 16进制10进制颜色值表 颜色中英文名称 在线颜色配色对比效