Linux设备模型(上)之底层模型

低速信号设计之 ESPI 篇 ESPI 是 Intel 推出的增强型串行外设接口,基于 SPI 发展而来,新增 Reset# 和 Alert# 信号,采用点对点主从通信模型,最高速率达 33MHz,支持半双工与 DMA 传输。 其物理接口含 10 条线路,通信协议分物理层、数据链路层等四层。布局布线需关注信号完整性、电源完整性,还得考虑与 SPI 的兼容性。 ESPI 广泛应用于计算机系统(连接 BIOS、电源管理器等)和工业控制领域,具有引脚少、功耗低等优势,但设计复杂且存在兼容性挑战。 阅读详情
 

以《LDD3》的说法:Linux设备模型这部分内容可以认为是高级教材,对于多数程序作者来说是不必要的。但是我个人认为:对于一个嵌入式Linux的底层程序员来说,这部分内容是很重要的。以我学习的ARM9为例,有很多总线(如SPI、IIC、IIS等等)在Linux下已经被编写成了子系统,无需自己写驱动;而这些总线又不像PCI、USB等在《LDD3》上有教程,有时还要自己研究它的子系统构架,甚至要自己添加一个新的总线类型。

对于这方面的学习,以下内容部分出自《LDD3》,部分出自国嵌,部分出自多位大牛博客。

---------------------------------------------------------------------------------------------------------------------------------

Linux设备模型的目的是:为内核建立起一个统一的设备模型,从而有一个对系统结构的一般性抽象描述。

2.6 设备模型提供了这个抽象. 现在它用在内核来支持不同的任务, 包括

电源管理和系统关机:这些需要对系统结构的理解,设备模型使OS能以正确顺序遍历系统硬件。

与用户空间的通讯 : sysfs 虚拟文件系统的实现被紧密地捆绑进设备模型, 并且暴露它所代表的结构. 关于系统到用户空间的信息提供和改变操作参数的旋纽正越来越多地通过 sysfs 和 通过设备模型来完成.

可热插拔设备:计算机硬件正更多地动态变化; 外设可因用户的一时念头而进出. 在内核中使用的来处理和(特别的)与用户空间关于设备插入和拔出的通讯, 是由设备模型来管理

设备类别:系统的许多部分需要知道什么类型的设备可用. 设备模型包括一个机制来分配设备给类别, 它在一个更高的功能性的级别描述了这些设备, 并且允许它们从用户空间被发现.

对象生命期:设备模型的实现需要创建一系列机制来处理对象的生命周期、对象间的关系和对象在用户空间的表示。  

----------------------------------------------------------------------------------------------------------------------

一、sysfs初探

sysfs is a ram-based filesystem initially based on ramfs. It provides

sysfs 是一个最初基于ramfs的位于内存的文件系统。它提供

a means to export kernel data structures, their attributes, and the

一些方法以导出内核的数据结构、他们的属性和

linkages between them to userspace.

他们与用户空间的连接。

sysfs is tied inherently to the kobject infrastructure. Please read

sysfs 始终与kobject的底层结构紧密相关。请阅读

Documentation/kobject.txt for more information concerning the kobject

Documentation/kobject.txt 文档以获得更多关于 kobject 接口的信息。

interface.


可以先把documentation/filesystems/sysfs.txt读一遍。文档这种东西,真正读起来就嫌少了。

Sysfs文件系统是一个类似于proc文件系统的特殊文件系统,用于将系统中的设备组织成层次结构,并向用户模式程序提供详细的内核数据结构信息。


去/sys看一看,
localhost:/sys#ls /sys/
block/ bus/ class/ devices/ firmware/ kernel/ module/ power/
Block目录:包含所有的块设备
Devices目录:包含系统所有的设备,并根据设备挂接的总线类型组织成层次结构
Bus目录:包含系统中所有的总线类型
Drivers目录:包括内核中所有已注册的设备驱动程序
Class目录:系统中的设备类型(如网卡设备,声卡设备等) 

sys下面的目录和文件反映了整台机器的系统状况。比如bus,
localhost:/sys/bus#ls
i2c/ ide/ pci/ pci express/ platform/ pnp/ scsi/ serio/ usb/
里面就包含了系统用到的一系列总线,比如pci, ide, scsi, usb等等。比如你可以在usb文件夹中发现你使用的U盘,USB鼠标的信息。

我们要讨论一个文件系统,首先要知道这个文件系统的信息来源在哪里。所谓信息来源是指文件组织存放的地点。比如,我们挂载一个分区,

mount -t vfat /dev/hda2 /mnt/C

我们就知道挂载在/mnt/C下的是一个vfat类型的文件系统,它的信息来源是在第一块硬盘的第2个分区。

但是,你可能根本没有去关心过sysfs的挂载过程,她是这样被挂载的。

mount -t sysfs sysfs /sys

ms看不出她的信息来源在哪。sysfs是一个特殊文件系统,并没有一个实际存放文件的介质。断电后就玩完了。简而言之,sysfs的信息来源是kobject层次结构,读一个sysfs文件,就是动态的从kobject结构提取信息,生成文件。

所以,首先,我要先讲一讲sysfs文件系统的信息来源 -- kobject层次结构。kobject层次结构就是linux的设备模型。

 

二、Kobject、Kset 和 Subsystem

1)Kobject

Kobject实现基本的面向对象管理机制,是构成LInux2.6设备模型的核心结构。

它与sysfs文件系统紧密相连,在内核中注册每个kobject对象对应sysfs文件系统中的一个目录。

kobject是一种数据结构,定义在 <linux/kobject.h>

  1. struct kobject {  
  2.     const char    * k_name;/*指向设备名称的指针 */  
  3.     char            name[KOBJ_NAME_LEN];/*kobject 的名字数组,设备名称*/  
  4.     struct kref        kref;/*kobject 的引用计数*/  
  5.     struct list_head    entry;/*kobject 之间的双向链表,与所属的kset形成环形链表*/  
  6.     struct kobject        * parent;/*在sysfs分层结构中定位对象,指向上一级kset中的struct kobject kobj*/  
  7.     struct kset        * kset;/*指向所属的kset*/  
  8.     struct kobj_type    * ktype;/*负责对该kobject类型进行跟踪的struct kobj_type的指针*/  
  9.     struct dentry        * dentry;/*sysfs文件系统中与该对象对应的文件节点路径指针*/  
  10.     wait_queue_head_t    poll;/*等待队列头*/  
  11. };  

kobject 是组成设备模型的基本结构,初始它只被作为一个简单的引用计数, 但随时间的推移,其任务越来越多。现在kobject 所处理的任务和支持代码包括:

对象的引用计数 :跟踪对象生命周期的一种方法是使用引用计数。当没有内核代码持有该对象的引用时, 该对象将结束自己的有效生命期并可被删除。

sysfs 表述:在 sysfs 中出现的每个对象都对应一个 kobject, 它和内核交互来创建它的可见表述。

数据结构关联:整体来看, 设备模型是一个极端复杂的数据结构,通过其间的大量链接而构成一个多层次的体系结构。kobject 实现了该结构并将其聚合在一起。

热插拔事件处理 :kobject 子系统将产生的热插拔事件通知用户空间。

一个kobject对自身并不感兴趣,它存在的意义在于把高级对象连接到设备模型上。因此内核代码很少(甚至不知道)创建一个单独的 kobject;而kobject 被用来控制对大型域(domain)相关对象的访问,所以kobject 被嵌入到其他结构中。kobject 可被看作一个最顶层的基类,其他类都它的派生产物。 kobject 实现了一系列方法,对自身并没有特殊作用,而对其他对象却非常有效。

 对于给定的kobject指针,可使用container_of宏得到包含它的结构体的指针。

kobject 初始化

kobject的初始化较为复杂,但是必须的步骤如下:

(1)将整个kobject清零,通常使用memset函数。

(2)调用kobject_init()函数,设置结构内部一些成员。所做的一件事情是设置kobject的引用计数为1。

void kobject_init(struct kobject *kobj);

struct kobject{
    const char    * k_name;/*kobject 的名字数组(sysfs 入口使用的名字)指针;如果名字数组大小小于KOBJ_NAME_LEN,它指向本数组的name,否则指向另外分配的一个名字数组空间 */
    char            name[KOBJ_NAME_LEN];/*kobject 的名字数组,若名字数组大小不小于KOBJ_NAME_LEN,只储存前KOBJ_NAME_LEN个字符*/
    struct kref        kref;/*kobject 的引用计数*/
    struct list_head    entry;/*kobject 之间的双向链表,与所属的kset形成环形链表*/
    struct kobject        * parent;/*在sysfs分层结构中定位对象,指向上一级kset中的struct kobject kobj*/
    struct kset        * kset;/*指向所属的kset*/
    struct kobj_type    * ktype;/*负责对该kobject类型进行跟踪的struct kobj_type的指针*/
    struct dentry        * dentry;/*sysfs文件系统中与该对象对应的文件节点路径指针*/
    wait_queue_head_t    poll;/*等待队列头*/
};

(3)设置kobject的名字

int kobject_set_name(struct kobject *kobj, const char *format, ...);

(4)直接或间接设置其它成员:ktype、kset和parent。 (重要)

对引用计数的操作

kobject 的一个重要函数是为包含它的结构设置引用计数。只要对这个对象的引用计数存在, 这个对象( 和支持它的代码) 必须继续存在。底层控制 kobject 的引用计数的函数有:

  1. struct kobject *kobject_get(struct kobject *kobj);/*若成功,递增 kobject 的引用计数并返回一个指向 kobject 的指针,否则返回 NULL。必须始终测试返回值以免产生竞态*/  
  2. void kobject_put(struct kobject *kobj);/*递减引用计数并在可能的情况下释放这个对象*/  
  3.    

release 函数kobject 类型

一个重要事情是当一个 kobject 的引用计数到 0 时会发生什么?引用计数不由创建 kobject 的代码直接控制,当 kobject 的最后引用计数消失时,必须异步通知,而后kobject中ktype所指向的kobj_type结构体包含的release函数当kobject引用计数为0时会被调用,释放kobject占用的资源。通常原型如下:

 

  1. void my_object_release(struct kobject *kobj)  
  2. {  
  3.   
  4.  struct my_object *mine = container_of(kobj, struct my_object, kobj);   
  5.   
  6. /* Perform any additional cleanup on this object, then... */  
  7.  kfree(mine);  
  8. }  

每个 kobject 必须有一个release函数, 并且这个 kobject 必须在release函数被调用前保持不变( 稳定状态 ) 。 这样,每一个 kobject 需要有一个关联的 kobj_type 结构,指向这个结构的指针能在 2 个不同的地方找到:(1)kobject 结构自身包含一个成员(ktype)指向kobj_type (kobj_type 结构里包含kobject对象的一些属性);

  1. struct kobj_type {  
  2.     void (*release)(struct kobject *kobj);  
  3.     const struct sysfs_ops *sysfs_ops;  
  4.     struct attribute **default_attrs;  
  5.     const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);  
  6.     const void *(*namespace)(struct kobject *kobj);  
  7. };  

kobje_type的attribute成员:

  1. struct attribute{  
  2.       char*name;//属性文件名   
  3.        structmodule *owner;  
  4.       mode_tmode;  
  5. }  

struct attribute(属性):对应于kobject的目录下一个文件,name就是文件名。

  1. struct sysfs_ops  
  2. {  
  3. ssize_t (*show)(structkobejct *,  struct attribute *,  char  *name);  
  4. ssize_t (*store)(structkobejct *,  struct attribute *,  char  *name);  
  5. }  

show:当用户读属性文件时,该函数被调用,该函数将属性值存入buffer中返回给用户态;

store:当用户写属性文件时,该函数被调用,用于存储用户存入的属性值。show相当于read,store相当于write。

(2)如果这个 kobject 是一个 kset 的成员, kset 会提供kobj_type 指针。

  1. struct kset {  
  2.     struct kobj_type    * ktype; /*指向该kset对象类型的指针*/  
  3.     struct list_head    list;/*用于连接该kset中所有kobject以形成环形链表的链表头*/  
  4.     spinlock_t        list_lock;/*用于避免竞态的自旋锁*/  
  5.     struct kobject        kobj; /*嵌入的kobject*/  
  6.     struct kset_uevent_ops    * uevent_ops;   
  7.   
  8. /*原有的struct kset_hotplug_ops * hotplug_ops;已经不存在,被kset_uevent_ops 结构体替换,在热插拔操作中会介绍*/  
  9. };  

 kobject注册函数,该函数只是kobjec_init和kobject_add_varg的简单组合。

  1. extern int __must_check kobject_init_and_add(struct kobject *kobj,struct kobj_type *ktype,struct kobject *parent,const char *fmt, ...);   

kobject 删除

  1. void kobject_del(struct kobject *kobj);   

 Kobject测试程序:

  1. #include <linux/device.h>   
  2. #include <linux/module.h>   
  3. #include <linux/kernel.h>   
  4. #include <linux/init.h>   
  5. #include <linux/string.h>   
  6. #include <linux/sysfs.h>   
  7. #include <linux/stat.h>   
  8.    
  9. MODULE_AUTHOR("David Xie");  
  10. MODULE_LICENSE("Dual BSD/GPL");  
  11.    
  12. void obj_test_release(struct kobject *kobject);  
  13. ssize_t kobj_test_show(struct kobject *kobject, struct attribute *attr,char *buf);  
  14. ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr,const char *buf, size_t count);  
  15.    
  16. struct attribute test_attr = {  
  17.         .name = "kobj_config",  
  18.         .mode = S_IRWXUGO,  
  19. };  
  20.    
  21. static struct attribute *def_attrs[] = {  
  22.         &test_attr,  
  23.         NULL,  
  24. };  
  25.    
  26.    
  27. struct sysfs_ops obj_test_sysops =  
  28. {  
  29.         .show = kobj_test_show,  
  30.         .store = kobj_test_store,  
  31. };  
  32.    
  33. struct kobj_type ktype =   
  34. {  
  35.         .release = obj_test_release,  
  36.         .sysfs_ops=&obj_test_sysops,  
  37.         .default_attrs=def_attrs,  
  38. };  
  39.    
  40. void obj_test_release(struct kobject *kobject)  
  41. {  
  42.         printk("eric_test: release .\n");  
  43. }  
  44.    
  45. ssize_t kobj_test_show(struct kobject *kobject, struct attribute *attr,char *buf)  
  46. {  
  47.         printk("have show.\n");  
  48.         printk("attrname:%s.\n", attr->name);  
  49.         sprintf(buf,"%s\n",attr->name);  
  50.         return strlen(attr->name)+2;  
  51. }  
  52.    
  53. ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr,const char *buf, size_t count)  
  54. {  
  55.         printk("havestore\n");  
  56.         printk("write: %s\n",buf);  
  57.         return count;  
  58. }  
  59.    
  60. struct kobject kobj;  
  61. static int kobj_test_init()  
  62. {  
  63.         printk("kboject test init.\n");  
  64.         kobject_init_and_add(&kobj,&ktype,NULL,"kobject_test");  
  65.         return 0;  
  66. }  
  67.    
  68. static int kobj_test_exit()  
  69. {  
  70.         printk("kobject test exit.\n");  
  71.         kobject_del(&kobj);  
  72.         return 0;  
  73. }  
  74.    
  75. module_init(kobj_test_init);  
  76. module_exit(kobj_test_exit);   


程序分析:

----》kobj_test_init(),----》kobject_init_and_add(&kobj,&ktype,NULL,"kobject_test");----》为NULL,创建在sysfs/

----》struct kobject kobj;没赋值,正常使用

----》struct kobj_type ktype,记录kobject一些属性和操作

----》def_attrs----》指针数组,一个指针代表创建一个文件。test_attr----》文件名字kobj_config,读写权限S_IRWXUGO

 ----》obj_test_sysops----》.读时调用 kobj_test_show函数,写时调用kobj_test_store函数

 ----》obj_test_release

测试效果:

1)在sys下创建一个子目录kobject_test

2)在kobject_test创建一个文件kobj_config

3)当读kobj_config时,打印信息

4)当写kobj_config时,打印信息

----------------------------------------------------------------------------------------------------------------------

2)Kset

kset是具有相同类型的kobject的集合,在sysfs中体现成一个目录,在内核中用kset数据结构表示。

一个 kset 的主要功能是容纳; 它可被当作顶层的给 kobjects 的容器类. 实际上, 每个 kset 在内部容纳它自己的 kobject, 并且它可以, 在许多情况下, 如同一个 kobject 相同的方式被对待. 值得注意的是 ksets 一直在 sysfs 中出现; 一旦一个 kset 已被建立并且加入到系统, 会有一个 sysfs 目录给它. kobjects 没有必要在 sysfs 中出现, 但是每个是 kset 成员的 kobject 都出现在那里.

通俗的讲,kobject建立一级的子目录,里面只能包含文件;kset可以为kobject建立多级的层次性的父目录。

  1. struct kset {  
  2. struct subsystem * subsys; 所在的subsystem的指针  
  3. struct kobj type * ktype; 指向该kset对象类型描述符的指针  
  4. struct list head list; 用于连接该kset中所有kobject的链表头  
  5. struct kobject kobj; 嵌入的kobject  
  6. struct  kset_uevent_ops * uevent_ops; 指向热插拔操作表的指针  
  7. };  

kset操作:

  1. void kset_init(struct kset *kset);  
  2. int kset_add(struct kset *kset);  
  3. int kset_register(struct kset *kset);  
  4. void kset_unregister(struct kset *kset);  

热插拔事件:在linux系统中,当系统配置发生变化时,如添加kset到系统或移动kobject,一个通知会从内核空间发送到用户空间,这就是热插拔事件。热插拔事件会导致用户空间中的处理程序(如udev,mdev)被调用,这些处理程序会通过加载驱动程序,创建设备节点等来响应热插拔事件。比如,当数码相机通过USB线缆插入到系统时。热插拔事件会导致对/sbin/hotplug程序的调用,该程序通过加载驱动程序,创建设备节点,挂装分区,或者其他正确的动作来响应。

对热插拔事件的实际控制是由struct kset_uevent_ops结构中的函数完成的。

  1.        struct kset_uevnt_ops{  
  2.         int (*filter)(struct kset *kset,struct  kobject *kobj);  
  3.          const char *(*name)(struct kset *kset, struct kobject *kobj );  
  4.          int (*uevent)(struct kset *kset,struct  kobject *kobj,struct kobj_uevent *env);  
  5. }  

当kset下的kset或者kobject发生变化时,上面三个函数被调用。
功能:

filter决定是否产生事件,如果返回0,将不产生事件。

name向用户空间传递一个合适的字符串

uevent通过环境变量传递任何热插拔脚本需要的信息,他会在(udev或mdev)调用之前,提供添加环境变量的机会。

kset测试程序:

  1. #include <linux/device.h>   
  2. #include <linux/module.h>   
  3. #include <linux/kernel.h>   
  4. #include <linux/init.h>   
  5. #include <linux/string.h>   
  6. #include <linux/sysfs.h>   
  7. #include <linux/stat.h>   
  8. #include <linux/kobject.h>   
  9.    
  10. MODULE_AUTHOR("David Xie");  
  11. MODULE_LICENSE("Dual BSD/GPL");  
  12.    
  13. struct kset kset_p;  
  14. struct kset kset_c;  
  15.   
  16. int kset_filter(struct kset *kset, struct kobject *kobj)  
  17. {  
  18.         printk("Filter: kobj %s.\n",kobj->name);  
  19.         return 1;  
  20. }  
  21.    
  22. const char *kset_name(struct kset *kset, struct kobject *kobj)  
  23. {  
  24.         static char buf[20];  
  25.         printk("Name: kobj %s.\n",kobj->name);  
  26.         sprintf(buf,"%s","kset_name");  
  27.         return buf;  
  28. }  
  29.    
  30. int kset_uevent(struct kset *kset, struct kobject *kobj,struct kobj_uevent_env *env)  
  31. {  
  32.         int i = 0;  
  33.         printk("uevent: kobj %s.\n",kobj->name);  
  34.   
  35.         while( i < env->envp_idx){  
  36.                 printk("%s.\n",env->envp[i]);  
  37.                 i++;  
  38.         }  
  39.   
  40.         return 0;  
  41. }  
  42.   
  43. struct kset_uevent_ops uevent_ops =   
  44. {  
  45.         .filter = kset_filter,  
  46.         .name   = kset_name,  
  47.         .uevent = kset_uevent,  
  48. };  
  49.    
  50. int kset_test_init()  
  51. {  
  52.         printk("kset test init.\n");  
  53.         kobject_set_name(&kset_p.kobj,"kset_p");  
  54.         kset_p.uevent_ops = &uevent_ops;  
  55.         kset_register(&kset_p);  
  56.    
  57.         kobject_set_name(&kset_c.kobj,"kset_c");  
  58.         kset_c.kobj.kset = &kset_p;  
  59.         kset_register(&kset_c);  
  60.         return 0;  
  61. }  
  62.    
  63. int kset_test_exit()  
  64. {  
  65.         printk("kset test exit.\n");  
  66.         kset_unregister(&kset_p);  
  67.         kset_unregister(&kset_c);  
  68.         return 0;  
  69. }  
  70.    
  71. module_init(kset_test_init);  
  72. module_exit(kset_test_exit);  

程序分析:

---》kset_test_init初始化kset---》kobject_set_name(&kset_p.kobj,"kset_p");---》创建一个struct kset kset_p,目录名字是kset_p

---》注册kset_register(&kset_p);----》添加一个目录kset_p

---》kobject_set_name(&kset_c.kobj,"kset_c");---》创建一个struct kset kset_c,目录名字是kset_c

---》kset_c.kobj.kset = &kset_p;  kset_c的父目录是kset_p,也就是讲kset_p下有一个目录kset_c

---》注册kset_register(&kset_c);----》添加一个目录kset_c

---》当在kset_p下增加一个kset_c目录,发生热插拔事件,调用uevent_ops ---》kset_filter被调用,返回0,不传递事件,返回1,传递

---》kset_name打印名字

---》kset_uevent打印信息

测试效果:

1)sys下有kset_p/kset_c

2)打印热插拔信息

如果将kset_c.kobj.kset = &kset_p;这行注释掉,也就是不产生热插拔事件,它就不打印kset_uevent的信息

原因在于当kset下的kset或者kobject发生变化时,在kset_p下增加一个kset_c目录,就会调用kset_uevnt_ops下的三个函数

【AI Guide】AI面试攻略只用看这一篇就够了!力争做全网最全的AI面试攻略——大模型(五)Adapter 微调 Adapter 微调(Adapter Fine-tuning)是一种高效的参数高效微调(PEFT)方法。相较于全参数微调(Full Fine-tuning),Adapter 在预训练模型的特定层插入轻量级的可训练模块,而冻结原始模型参数,从而减少计算和存储开销。是缩放因子,控制 Adapter 输出的影响程度。设 Transformer 层的隐藏状态为。为 Adapter 层的可训练参数,为非线性激活函数,如 ReLU。为冻结的预训练模型参数, 阅读详情

相关推荐

Streamlit安装避坑指南:从零到一键启动你的第一个数据可视化应用

本文提供了一份详尽的Streamlit安装避坑指南,帮助用户从零开始快速启动第一个数据可视化应用。文章深入剖析了安装过程中常见的网络超时、依赖冲突、环境变量缺失等核心问题,并给出了使用虚拟环境、配置国内镜像源、利用.whl文件离线安装等多种经过验证的解决方案,确保安装过程顺畅无阻。

weixin_29065015的博客 615

linux kset subsystem 3.10内核,Linux驱动设备模型

Linux设备模型的目的是:为内核建立起一个统一的设备模型,从而有一个对系统结构的一般性抽象描述。现在内核使用设备模型支持多种不同的任务:(1)电源管理和系统关机 :这些需要对系统结构的理解,设备模型使OS能以正确顺序遍历系统硬件。(2)与用户空间的通讯 :sysfs 虚拟文件系统的实现与设备模型的紧密相关, 并向外界展示它所表述的结构。向用户空间提供系统信息、改变操作参数的接口正越来越多地通过 ...

weixin_34379309的博客 269

Uniapp-APP后台保活插件(安卓后台保活)

Uniapp-APP后台保活插件(安卓后台保活)亲测有效!

weixin_57844432的博客 1万+

linux kset subsystem 3.10内核,sysfs源码笔记

sysfs就是linux中/sys/下的所有内容,官方文档中sysfs的定义如下:sysfs 是一个最初基于 ramfs 且位于内存的文件系统。它提供导出内核数据结构及其属性,以及它们之间的关联到用户空间的方法。只要内核配置中定义了 CONFIG_SYSFS ,sysfs 总是被编译进内核。你可通过以下命令挂载它:mount -t sysfs sysfs /sys本文的代码是基于centos7,l...

weixin_30495795的博客 236

小米手机Magisk解锁与Root完整指南:从Bootloader到模块管理

Android系统Root权限获取是设备深度定制的核心技术之一,其核心原理在于通过修改系统启动流程获取超级用户权限。Systemless Root技术通过动态挂载修改,在不触碰系统分区的前提下实现功能注入,既保证了系统完整性,又能绕过完整性检测。这一技术为设备带来了极高的可定制性,用户可以通过模块化方式增强系统功能、修改UI界面或启用隐藏特性。在小米手机生态中,由于官方提供了完整的Bootloader解锁通道,结合Magisk的无系统修改Root方案,使得安全可控的深度定制成为可能。本文聚焦于Bootloa

weixin_29164185的博客 334

uniapp 开发微信小程序请求问题 , 真机调试正常,开发工具正常,但是使用扫码预览接口都是不通的,发布到体验版也是请求失败

uniapp开发小程序体验版接口请求失败(真机可以)

weixin_60408555的博客 3954

linux内核之kobject与kset

kobject数据结构 struct kobject { const char *name;//对象的文本名称,可利用sysfs导出到用户空间. struct list_head entry;//标准的链表元素,可将多个kobject放到一个链表中. struct kobject *parent;//父对象指针,可建立kobject的层次关系. struct kset *kset;//将对象与其他对象放置到一个集合时,需要kset struct kobj_type *ktype;//属性,名

qq_39048131的博客 533

STM32F407+OV2640的DCMI+DMA双缓冲JPEG图像采集系统

在嵌入式视觉系统中,数字摄像头接口(DCMI)是MCU连接CMOS图像传感器的关键硬件通道,其与DMA协同实现零CPU干预的高速数据流采集;而JPEG作为一种基于DCT变换与量化压缩的有损图像格式,依赖传感器端硬件编码引擎才能满足实时性要求。理解DCMI三重同步时序(PCLK/HSYNC/VSYNC)与DMA双缓冲机制的流水线协作原理,是突破带宽瓶颈、避免FIFO溢出和帧丢失的技术基础。该架构广泛应用于智能硬件、工业检测与边缘AI前端等需低功耗、高可靠图像捕获的场景,本文以OV2640与STM32F407为

weixin_42103128的博客 157

linux驱动模型之kobject kset

分析kobject,及相关的ktype和kset。

风雨无阻 1084

纳米尺度仿真软件:GROMACS_(3).分子动力学模拟原理

分子动力学(MD)模拟是一种强大的计算方法,通过数值积分牛顿运动方程,追踪粒子在时间上的位置和速度变化,提供关于体系动力学行为的详细信息。选择合适的力场、设置初始条件、应用边界条件、控制温度和压力、选择合适的时间步长、计算能量和力,是 MD 模拟的关键步骤。通过这些步骤,可以对各种化学、生物和材料体系进行模拟和分析,揭示其结构、动力学和热力学性质。高级应用如反应路径模拟和蛋白质折叠研究,进一步扩展了 MD 模拟的应用范围。

kkchenjj的博客 1100

永恒之蓝漏洞复现(ms17-010)

Metasploit Framework(MSF)是一款开源安全漏洞检测工具,附带数千个已知的软件漏洞,并保持持续更新。Metasploit可以用来信息收集、漏洞探测、漏洞利用等渗透测试的全流程,被安全社区冠以“可以黑掉整个宇宙”之名。刚开始的Metasploit是采用Perl语言编写的,但是再后来的新版中,改成了用Ruby语言编写的了。在kali中,自带了Metasploit工具。

渗透之路,攻防之间皆学问 2万+

Linux设备驱动工程师之路——设备模型(上)底层模型

Linux设备驱动工程师之路——设备模型(上)底层模型 K-Style 转载请注明来自于衡阳师范学院08电2  Y-Kee http://blog.youkuaiyun.com/ayangke,QQ:843308498   一、重要知识点            1.Sysfs文件系统        Sysfs文件系统是一种类似于proc文件系统的特殊文件系统,它存在于内存当中,当系统启动时由内核

屌丝终有逆袭日。 2172

基于深度学习的大豆病害检测识别系统:YOLOv10 + UI界面 + 数据集

YOLOv10是一种高效的目标检测算法,能够在保持高精度的同时,提供较快的检测速度。YOLOv10使用了改进的卷积神经网络架构,并在多个计算机视觉任务中表现出色。在本项目中,我们将使用YOLOv10进行大豆病害的检测和分类。本系统利用YOLOv10算法,实现了大豆病害的实时检测和分类。通过结合深度学习和图像处理技术,可以帮助农业领域的专业人员更加高效地识别和诊断大豆病害,提高农作物的生产力与质量。

YOLO 700

linux设备模型 底层

以《LDD3》的说法:Linux设备模型这部分内容可以认为是高级教材,对于多数程序作者来说是不必要的。但是我个人认为:对于一个嵌入式Linux的底层程序员来说,这部分内容是很重要的。以我学习的ARM9为例,有很多总线(如SPI、IIC、IIS等等)在Linux下已经被编写成了子系统,无需自己写驱动;而这些总线又不像PCI、USB等在《LDD3》上有教程,有时还要自己研究它的子系统构架,甚至要自己添

u012590688的专栏 407

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Linux设备模型,底层原理简介-[Kobject、Kset 和 Subsystem]

Linux设备模型,底层原理简介 2008-11-28 22:52:42    作者:佚名  来源:互联网 Linux设备模型,底层原理简介 Linux设备模型的目的是:为内核建立起一个统一的设备模型,从而有一个对系统结构的一般性抽象描述。 现在内核使用设备模型支持多种不同的任务: 电源管理和系统关机 :这些需要对系统结构的理解,设备模型使OS能以正确顺序遍历系统硬件。 与

yhgdev的专栏 806

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

linux设备驱动程序架构的研究,Linux设备驱动程序学习(12)-Linux设备模型(底层原理简介)...

Linux设备驱动程序学习(12)-Linux设备模型(底层原理简介)以《LDD3》的说法:Linux设备模型这部分内容可以认为是高级教材,对于多数程序作者来说是不必要的。但是我个人认为:对于一个嵌入式Linux的底层程序员来说,这部分内容是很重要的。以我学习的ARM9为例,有很多总线(如SPI、IIC、IIS等等)在Linux下已经被编写成了子系统,无需自己写驱动;而这些总线又不像PCI、USB...

weixin_35089715的博客 136

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Linux设备模型(底层原理简介)

Linux设备模型(底层原理简介) 以《LDD3》的说法:Linux设备模型这部分内容可以认为是高级教材,对于多数程序作者来说是不必要的。但是我个人认为:对于一个嵌入式Linux的底层程序员来说,这部分内容是很重要的。以我学习的ARM9为例,有很多总线(如SPI、IIC、IIS等等)在Linux下已经被编写成了子系统,无需自己写驱动;而这些总线又不像PCI、USB等在《LDD3》上有教程,有时还要自己研究它的子系统构架,甚至要自己添加一个新的总线类型。 对于这方面的学习,我推荐几个网页,这些也是我这部分

myspor的专栏 687

·Linux设备驱动程序学习(12)-Linux设备模型(底层原理)

以《LDD3》的说法:Linux设备模型这部分内容可以认为是高级教材,对于多数程序作者来说是不必要的。但是我个人认为:对于一个嵌入式Linux的底层程序员来说,这部分内容是很重要的。以我学习的ARM9为例,有很多总线(如SPI、IIC、IIS等等)在Linux下已经被编写成了子系统,无需自己写驱动;而这些总线又不像PCI、USB等在《LDD3》上有教程,有时还要自己研究它的子系统构架,甚至要自己添

jeffade的专栏 530

linux设备模型的由来,Linux设备模型(底层原理简介)

externint__must_check kobject_init_and_add(structkobject*kobj,structkobj_type*ktype,structkobject*parent,constchar*fmt,...);这样的函数,所以请根据你使用的内核版本自己研究了.kset 在一个标准的内核链表中保存了它的子节点,在大部分情况下, 被包含的 k...

weixin_32288959的博客 180

Linux 设备模型(上)之底层模型

以《LDD3》的说法:Linux设备模型这部分内容可以认为是高级教材,对于多数程序作者来说是不必要的。但是我个人认为:对于一个嵌入式Linux的底层程序员来说,这部分内容是很重要的。以我学习的ARM9为例,有很多总线(如SPI、IIC、IIS等等)在Linux下已经被编写成了子系统,无需自己写驱动;而这些总线又不像PCI、USB等在《LDD3》上有教程,有时还要自己研究它的子系统构架,甚至要自己添

ZP1015 2153

Linux设备模型的底层原理

Linux设备模型的目的是:为内核建立起一个统一的设备模型,从而有一个对系统结构的一般性抽象描述。 现在内核使用设备模型支持多种不同的任务: 电源管理和系统关机 :这些需要对系统结构的理解,设备模型使OS能以正确顺序遍历系统硬件。 与用户空间的通讯 :sysfs 虚拟文件系统的实现与设备模型的紧密相关, 并向外界展示它所表述的结构。向用户空间提供系统信息、改变操作参数的接口正越来越多地通过

心核智慧科技 360度人脸识别开放算法 新零售系统定制 753
上一篇: 关于platform_driver 是如何匹配 platform_device的和如何调用到platform_driver中的probe函数的研究
下一篇: Linux文件系统学习(一)之相关概念
ADC0809608
博客等级 码龄17年 44粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值