版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Linux内核设计与实现 读书笔记(1)1-7第二章 Linux内核1内核开发特点1) 内核编译时不能访问C库;2) 浮点数很难使用;3) 内核只有一个定长堆栈;4) 注意同步和并发。第三章进程管理1 current宏:查找当前运行进程的进程描述符。2进程状态(5种)TASK_RUNNING : 1)正在运行;2)在运行队列中等待执行。TASK_INTERRUPTIBLE :进程正在睡眠,可以被信号唤醒。TASK_UNINTERRUPTIBLE :进程正在睡眠,不会收到信号被唤醒。TASK_ZOMBIE :僵死态,进程已经结束,父进程未使用wait4()。TASK_STOPPED3进程上下文进
2、程进入内核空间时,current宏依然有效,内核 代表进程执行”。4进程创建1) fork():拷贝当前进程创建一个子进程。2) exec():读取可执行文件并载入地址空间开始运行。3) 写时拷贝(copy-on-wrtie ):推迟数据拷贝,在需要写入数据时,数据才会被复制。4) vfork():不拷贝父进程的页表项,子进程作为父进程的一个线程在它的地址空间运行, 父进程被阻塞直至子进程退出,子进程不能向地址块空间写入数据。5线程Linux把所有的线程都当作进程来实现。6内核线程:独立运行在内核中的标准进程。内核线程没有独立的地址空间,只能在内核空间中运行,创建内核线程用kernel_thr
3、ead()。7进程终结1) 释放资源;2) 进入 TASK_ZOMBIE ;3) 等待 wait4()。第四章进程调度1多任务系统非抢占式多任务:主动让步抢占式多任务(preemptive):时间片2进程IO消耗型:常常阻塞处理器消耗型:执行代码3动态优先级调度方法允许调度程序根据需要加减优先级。两组优先级范围:1) nice值:-20至+19,默认值为0, nice值越大,优先级越低。2) 实时优先级:0至99,任何实时进程优先级都高于普通进程。4时间片默认时间片为20ms。进程时间片用完 一一进程到期一一所有进程都到期 一一重新计算时间片5可执行列队(run queue):每个处理器一个的
4、可执行进程链表,还包含每个处理器的调度 信息。cpu_rq(processor):返回给定处理器的可执行队列指针。this_rq():返回当前处理器的可执行队列。task_rq(task):返回给定任务所在的队列指针。this_rqock():锁住当前可执行列队。rq_unlock():释放给定列队上的锁。为了避免死锁,要锁住多个运行列队的代码,需要按同样的顺序获得这些锁。6优先级数组每个运行列队有两个优先级数组:一个活跃的,一个过期的。优先级数组包含一个优先级位图,共有140个优先级用了 5个32位长整形保存。活动数组:可执行队列上的进程还有时间片剩余。过期数组:可执行队列上的进程耗尽了时间
5、片。进程从活动数组移动至过期数组时重新计算时间片。重新计算时间片,以静态优先级为基础计算。助了判断Linux进程类型,Linux记录了进程用于休眠和执行的时间。若进程交互性非常强,时间片用完后,会被再次放入活动数组。7休眠休眠通过等待列队进程处理。等待歹U队:wait_queue_head_t静态创建等待列队:DECLARE_W AITQUEUE动态创建等待列队:ini t_waitqueue_head()加入等待列队:add_wait_queue()移出等待歹U队:remove_wait_queue()8负载平衡保证可执行列队之间的负载处于均衡状态(用于SMP )。两种调用方法:1 )当前可
6、执行列队为空;2)系统定时器200ms 一次。9上下文切换1) 将虚拟内存从上一个进程映射到新的进程中;2) 将上个进程处理器的状态切换到新的进程,保存、恢复栈信息和寄存器信息。10 schedule()被调用的时间1) 某个进程耗尽时间片时;2) 优先级高的进程进入可执行态时;3) 返回用户空间时;4) 中断返回时。11内核抢占只要没有持有锁,内核就可以进行抢占。preempt_count计数器记录内核锁的数量。内核抢占时机:1) 从中断返回内核空间时;2) 当内核代码再一次具有可抢占性的时候;3) 内核任务显示调用 shedule();4) 内核任务阻塞。12实时性内核实时调度策略:1)
7、SCHED_FIFO :简单,先进先出调度;2) SCHED_RR :时间片轮转调度,耗尽时间片后不再执行。 SCHED_NORMAL是普通、非实时的调度策略。核实时调度策略是基于静态优先级的:内核不为实时进程计算动态优先级,实时优先级范围:0-99。态非实时优先级范围:100-139 (对应nice值-20至+19)。第五章系统调用1应用程序通过软中断机制通知内核。2参数验证指针:1) 指针指向的内存区域属于用户空间;2) 指针指向的内存区域属于本进程地址空间;3) 如果读,内存标记为可读;如果写,内存标记为可写。3 copy_to_user()的三个参数:1) 进程空间的目的地址内存;2)
8、 内核空间源地址;3) 需要拷贝的数据长度(字节数)。copybit_from_user()禾口上面相反。第六章 中断和中断处理程序1上半部和下半部上半部:中断处理程序下半部:稍后完成的工作2注册中断int request_irq(irq, *ha ndle, irqflag, *dev name, *devid)irq 中断号。han dle 一个指针,指向中断处理程序。irqflag 标志位:SA_INTERRUPT 快速中断处理程序(禁止其他中断);SA_SHIRQ :可在多个中断处理程序间共享中断线。dev name 与中断相关的设备的ASCII文本表示法。dev_id用于共享中断线,
9、当中断需要退出时,dev_id提供唯一的标志信息。从共享中断线的中断处理程序中删除指定程序。3释放中断free_irq (un sig ned int irq, void *dev_id)4中断处理程序irqretur n_t in tr_ha ndle(i nt irq, void *dev_id, struct pt_regs *regs)regs: 一个指向结构体的指针,包含中断处理之前的处理器寄存器和状态,regs使用越来越少,应该忽略。返回值 irqreturn_t:1) IRQ_NONE :中断对应设备并不是注册函数期间指定的产生源;2) IRQ_HANDLE :正常返回值。重入问
10、题:Linux的中断处理程序无需考虑重入,当一个给定的中断处理程序正在执行,相 应的中断会被屏蔽。5中断上下文中断上下文不可以睡眠,不能从中断上下文中调用睡眠函数。中断栈:现在中断处理程序拥有自己的栈,每个处理器一个,大小为4KB。6中断控制local_irq_disable():禁止当前处理器上的本地中断;local_irq_enable():允许中断;local_irq_save(flag):禁止中断并保存系统状态;local_irq_restore(flag):恢复中断并恢复到原来的状态;disable_irq(unsigned int irq):禁止指定中断线;disable_irq_
11、nosync():不等待当前中断处理完毕就禁止指定中断;enable_irq(unsigned int irq):允许指定中断;synchronize_irq():等待一个特定的中断处理程序的退出。如果调用了两次 disable_irq(),需要对应调用两次 enable_irq()才可以恢复。第七章下半部和推后执行的工作1下半部1) 缩短中断执行时间;2) 下半部执行时允许响应所有的中断。2下半部的类型1) BH :早期实现,现在已经淘汰;2) 任务列队(task queue);3) 软中断(softirq ):静态定义的下半部接口,共32个,可在所有处理上同时执行。4) tasklet:基
12、于软终端的动态下半部实现,不同类型的tasklet可在不同处理器同时执行, 相同类型的tasklet不可以同时执行。5) 工作列队(work queue):取代任务列队,对推后执行的工作排队。6) 内核定时器:将操作推后到某个确定的时间段。3软中断1) 软中断最多有32个。2) 一个软中断不会抢占另外一个软中断,唯一可以抢占软中断的是中断处理程序。3) 软中断的执行时机:(1)从一个硬件中断代码返回时;(2)在ksoftirq内核线程中;(3) 显示检查和执行处理的软中断代码中,如网络子系统。4) 软中断保留给系统中对时间要求最严格和最重要的下半部使用:如网络和SCSI。4 tasklet1)
13、 tasklet通过软中断实现,本身也是软中断,有两种:HI_SOFTIRQ (优先级较高)和TASKLET_SOFTIRQ。2 )的状态有:0、TASKLET_STA TE_SCHED (已经被调度,正等待运行)和 TASKLET_STATE_RUN (正在运行,应用于多核系统)。3) tasklet的调度过程:(1) 检查tasklet的状态是否为 SCHED 返回;(2 )保存中断,禁止本地中断;(3) 将调度 tasklet 加入 tasklet_vec 或者 tasklet_hi_vec 表头;(4) 唤起 TASKLET_SOFTIRQ 或 HI_SOFTIRQ 中断do_soft
14、irq();(5) 恢复中断并恢复原状态。4) 使用 tasklet(1) 声明静态创建DECLARE_TASKLETDECLARE_TASKLET_DISABLED动态创建tasklet_ in it(t,tasklet_ha ndle,dev)(2) handlevoid tasklet_ha ndle( un sig ned long data)由于tasklet靠软中断实现,所以tasklet执行中不能睡眠 一一 不能使用信号量或阻塞函数。tasklet运行时运行中断,需要做好保护工作。(3) 调度tasklet_schedule(&m y_tasklet)加入调度列队tasklet_
15、disable() 禁止莫个tasklet,若正在执行则等待执行完毕再禁止tasklet_disable_nosync()立即禁止(不太安全)tasklet_enable()激活一个 tasklettasklet_kill()去掉列队的第一个tasklet(4) ksoftirq辅助软中断内核线程内核不会立即处理重新触发的软中断,当大量软中断出现时,内核会唤起一组线程来处理这些负载。(nice=19)5 工作队列( work queue)1) 工作队列可把工作推后,交由一个内核线程去执行。2) 工作队列在进程上下文执行,允许重新调度甚至是睡眠,但无法访问用户空间。3) 实现工作者线程event
16、s/n, n是处理器编号。worker_thread()函数:执行一个死循环并休眠,当有操作,线程被唤醒。4) 使用工作队列(1) 声明静态创建DECLARE_WORK( name, void(*fu nc)(void*), void *data)动态创建INIT_WORK(struct work_struct *work, void (*fu nc)(void*), void *data)(2 )处理函数void work_ha ndle(void *data)(3) 调度shedule_work(&work)马上调度shedule_delayed_work(&work,delay)延时调度
17、(4) 刷新flush_scheduled_work(void)等待队列中所有对象都被执行后才返回。can cel_delayed_work(struct work_struct *work)取消延时的工作。(5)创建新的工作列队可在默认的工作列队外创建新的进程:creat_work(c onst char *n ame)queue_work()类似 schedule_work(),针对自己的进程。queue_delayed_work()flush_workqueue()6下半部机制的选择下半部上下文顺序执行要求软中断中断没有tasklet中断同类型不可以同时执行工作队列进程没有(和进程上下文
18、一样被调度)1)易用性:工作列队 tasklet软中断2)速度:软中断tasklet工作队列3)开销:工作队列tasklet、软中断7下半部的锁机制1)tasklet(1)相同类型的tasklet不允许同时执行,无需同步。(2)不同类型的tasklet需使用锁机制。2)软中断所有共享数据结构都需要合适的锁。3)进程上下文和下半部共享中断,上下文访问共享数据前,需禁止下半部并获取锁的使用 权。4)中断上下文和下半部共享中断,需禁止中断并取得锁使用权。local_bh_disable()禁止本地处理器的软中断和tasklet处理,不用禁止工作列队。local_bh_e nable()Linux内核
19、设计与实现 读书笔记(2) 8-10第八章内核同步介绍1临界区和竞争条件临界区:访问和操作共享数据的代码段。竞争条件:两个执行线程处于同一个临界区中。2内核中造成并发的原因1)中断:任何时刻异步发生,打断当前执行的代码。2) 软中断和tasklet:任何时刻唤醒或调度软中断、tasklet。3)内核抢占(preempt)。4)睡眠及与用户空间的同步:唤醒调度程序,调度新进程执行。5)对称多处理器(SMP )。3需要加速的代码1)中断安全代码;2)SMP安全代码;3)抢占安全代码。给数据加锁而不是给代码加锁。4编程需注意的问题:1) 数据是否全局?除了当前线程,其他线程是否可以访问?2) 数据是
20、否在进程/中断上下文中共享?是否在两个不同中断中共享?3) 进程在访问数据时可否被抢占?被调度的新进程是否会访问同一数据?4) 当前进程是否会睡眠(阻塞)在某些资源上?共享数据处于何种状态?5) 怎样防止数据失控?若在另一处理器上调度?5预防死锁1) 加锁顺序是关键,使用嵌套锁必须以相同顺序获取锁;2) 防止发生饥饿;3) 不要重复请求同一个锁;4) 复杂的加锁方案也可能造成死锁一一简化设计;5) 建议以获取锁相反的顺序来释放锁。第九章内核同步方法1原子操作原子操作执行过程不被打断,原子操作接口分为整数操作接口和单独位操作接口。 2原子整数操作只有atomic类型可用于整数原子操作。atomi
21、c类型保证编译器不对相应的值进行优化。atomic类型可以屏蔽不同体系结构上实现原子类型的差异。atomic类型只能使用24位(现在已经没有这个限制)。定义:asm/atomic.hatomic_t v;atomic_t u = ATOMIC_INIT(0);操作:atomic_set(&v, 4)atomic_add(z, &v)atomic_sub(i nt i, atomic *v)atomic_i nc(&v)atomic_dec(&v)atomic_read(&v)转成整形atomic_dec_and_test(&v)给定原子变量减1,若为0则返回真。3原子位操作原子位操作对普通的内
22、存地址操作,没有atomic_t类型。定义:asm/bitops.h操作:set_bit(i nt nr, void *addr)clear_bit(i nt nr, void *addr)cha nge_bit(i nt nr, void *addr) 翻转test_and_set_bit()设置并返回原先的值test_a nd_clear_bit()test_a nd_cha nge()test_bit()返回第nr位非原子操作:_test_bit()4自旋锁自旋锁最多只能被一个可执行线程持有。若一个线程试图获得一个被征用的自旋锁,线程 会一直忙循环一一选择一一等待锁可用。缺点:由于自旋锁
23、在等待时自旋(浪费处理器时间),因此自旋锁不应长时间持有。优点:线程不用睡眠,不用进行上下文切换。数据结构:结构相关代码:asm/spi nl ock.h接口定义:linux/spinl ock.h声明:spi nlock_t mr_lock = SPIN_LOCK_UNLOCKED加锁:spin_lock(&mr_lock)解锁:spin_unl ock(&m r_lock)自旋锁特点:自旋锁最多被一个线程持有,为SMP提供了并发保护机制。单处理器编程时并不会加入自旋锁,仅当做检测内核抢占的开关。如果禁止内核抢占,则自旋锁无效。自旋锁可用于中断处理程序中(信号量不可用于自旋锁,会自旋),中断
24、中使用自旋锁首先应当关中断。自旋锁不可递归。自旋锁操作:spinock_irqsave(&mr_lock, flag)保存中断当前状态,关中断,获取锁spin_u nlock_irqstore(&mr_lock, flag)恢复中断到加锁前状态并释放锁sp inock_irq(&mr_lock)关中断,获取锁sp in _u nl ock_irq(&mr_lock) 关中断,释放锁因为很难搞清楚中断情况,推荐使用前者。其他操作:spin_lock_i nit()动态初始化知道 spi nlock_tspin_trylock()试图获取指定锁,若未获取则返回非0spin_is_locked()如
25、制定锁当前正在被获取,则返回非04读写自旋锁读写不同锁,多人和可并发持有读者锁,写锁只能被一个任务持有。用法:rwlock_t mr_rwlock = RW_LOCK_UNLOCKED; read_lock (&m r_rwlock) read_u nl ock (&mr_rwlock) write_lock(&mr_rwlock) write_ un lock(&mr_rwlock)(1) 不可将读锁 升级”为写锁,写锁会等待读锁。(2) 多个读者可以安全获得同一个读锁,也可递归获取读锁。 5信号量1) 信号量的特点(1) Linux中的信- 号量是- -种睡眠锁;(2) 信号量适用于锁会被
26、长期占有的情况;(3) 由于信号量会睡眠,所以只能用于进程上下文中,中断上下文不支持调度;(4) 可以在持有信号量时睡眠;(5 )不可以在持有信号量时使用自旋锁;(6) 信号量允许任意数目的锁持有者,自旋锁一个时刻只允许一个任务持有;(7 )在声明时课指定信号量拥有的持有者数量。2) 创建信号量定义: asm/semaphore.h静态声明:static DECLARE_SEMAPHORE_GENEIC( none , cou nt)互斥信号量声明:static DECLARE_MUTEX( name)动态创建:sema_i nit(sem, count)动态创建互斥对象:in it_MUTE
27、X(sem)(注意大小写)3) 使用信号量down()信号计数减1,若为0或大于0,则获取信号量,若为负数,则任务等待。 up()信号计数加1,若等待队列不为空,唤醒等待任务。downnterruptible(struct semaphore*)若信号量已被征用,则可进入中断睡眠状态。down_trylock()试图获取信号量,若已被征用,则立刻返回非零值。6读-写信号量(都是互斥信号量)定义:linu x/rwsem.h静态声明:static DECLARE_RWSEM( name)动态创建:in it_rwsem(struct rw_semaphore *sem)功能:dow n_ rea
28、d()up_read()dow n_write()up_write()dow ngrade_writer()动态将写锁转换为读锁7自旋锁与信号量中断上下文中只能使用自旋锁。任务睡眠时只能使用信号量。需求建议低开销加锁优先使用自旋锁短期锁定优先使用自旋锁长期加锁优先使用信号量中断上下文加锁使用自旋锁持有锁需要睡眠使用信号量8完成变量完成变量是同步两个任务的一种简单方法。定义:linu x/completio n.h静态创建:DECLARE_COMPLETION(mr_comp)动态创建:ini t_completi on()方法:wait_for_completio n(struct compl
29、etion *)等待指定的完成变量接受信号complete(struct completio n*) 发信号唤醒等待任务9禁止抢占内核代码使用自旋锁作为非抢占区域的标记。preempt_disable()增加抢占计数值,从而禁止内核抢占preempt_enable()减少抢占计数值,当减为 0时检查和执行被挂起的任务preempt_e nable_ no _resched()preempt_count()返回抢占计数get_cpu()put_cpu()10顺序和屏障屏障(barrier):确保城乡运行顺序的指令。rmb()阻止跨越屏障的转入动作发生重排序。read_barrier_depend
30、s()阻止跨越屏障的具有数据依赖关系的载入动作重排序。 wmb()阻止跨越屏障的载入和存储动作发生重排序。mb()阻止跨越屏障的载入和存储动作发生重排序。smp_rmb()在SMP上提供rmb()功能,在 UP上提供barrier。功能。 smp_read_barrier_depe nds()smp_wmb()smp_mb()barrirer()阻止编译器跨越屏障对载入或存储操作进行优化。第十章定时器和时间管理1时钟中断的工作1) 跟新系统运行时间;2) 跟新实际时间;3) 在SMP系统中均衡调度各处理器的运行列队;4) 检查当前进程是否耗尽时间片,若耗尽则进行重新调度;5) 运行超时的动态定
31、时器;6) 更新资源消耗和处理器时间的统计值。2节拍率HZARM 100( 10ms)i386 1000( 1ms)x86-64提高HZ的优点:1) 更高时钟中断解析度;2) 提高时间驱动事件的准确性(平均误差 5ms-0.5ms);3) 内核定时器能够以更高的频度和更高准确度执行;4) 依赖定时器的系统调用(如 poll和select)能以更高精度运行;5) 对资源消耗和系统运行时间的测量更准确;6) 提供进程抢占的准确度。缺点:1) 系统负担增加;2) 中断占用处理器的时间增加。3 jifiesjiffies全局变量用来记录系统自启动以来产生的节拍总数。定义:li nu x/jiffies
32、.hexter n un sig ned long volatile jiffies;extern u64 jiffies_64;jiffies 取 jifies_64 的低 32位jiffies溢出回绕:#defi ne time_after( unknown, known) (Io ng)(k nown)-(I on g)( unknown)0)#defi ne time_before (unknown, known) (Io ng)( unknown)-(I on g)(k nown)存有xtime中;(6 )计算平均负载。5实际时间(墙上时间)定义;kernel/timer.cstru
33、ct timespec xtime;struct timespec time_t tv_sec; / 秒,自 1970.7.1 开始的秒数long tv_n sec; /纳秒,自上一秒开始的纳秒数读写xtime需要用xtime_lock锁,是一个 seqlock锁。用户空间获取墙上时间的接口:gettimeofday()内核空间获取墙上时间的接口:sys_gettimeofday() -系统调用设置当前时间接口: settimeofday()6定时器(动态定时器)定义: li nu x/timer.hstruct timeist my_timer初始化:in it_timer(&m y_tim
34、er);my_timer.expires = jiffies + delay;my_timer.data = 0;my_timer.fu nctio n = my_fun ctio n;处理函数格式:void my_fun cti on(un sig ned long data)激活:add_timer(&m y_timer)修改定时时间:mod_timer(&m y_timer, jiffies+delay)停止定时器:del_timer(&m y_timer)del_timer_sync() mm指向当前进程的内存描述符。4) 内核线程:内核线程没有进程地址空间,也没有相关的内存描述符。新
35、内核线程直接使 用前一个进程的内存描述符。3内存区域vm_area_struct结构体:描述指定地址空间内存连续区间上的一个独立内存范围。VMA标志:标志内存区域所包含的页面的行为和信息。eg. C库在物理内存中仅占用一份空间(空间不可写),不需为每个进程保存一个C库。4内存区域接口find_vma():指定地址空间搜索第一个vm_end大于addr的内存区域。find_vma_prev():返回第一个小于 addr 的 VMA 。find_vma_intersection():返回第一个和指定地址区间相交的VMA 。mmap()do_mmap():将一个新的地址区间加入到进程地址空间中。un
36、 sig ned long do_mmap(struct file *file, un sgi ned long addr, un sig ned long len, un sig ned long prot, un sig ned long flag, un sig ned long offset)file :指定文件,NULL为匿名映射,否则为文件映射。offset:文件的偏移。len:长度。addr :可选参数,指定空闲区域的起始地址。 prot :指定内存区域中页面的访问权限(1)(2)(3)(4)PROT READPROT WRITEPROT EXEXPROT NONE对应 VM_R
37、EAD对应 VM_WRITE 对应 VM_EXEC 页不可访问flag :指定 VMA 标志(1)(2)(3)(4)(5)映射可以被共享MAP_SHAREDMAP_PRIV ATE映射不可以被共享MAP_FIXED 新区间必须开始于指定地址MAP_ANONYMOUS 映射是匿名的MAP GROWSDOWN VM GROWSDOWNaddr(6)MAP_DENYWRITE VM_DENYWRITE(7)MAP_EXECUTABLE VM_EXECUTABLE(8)MAP_LOCKED VM_LOCKED(9)MAP_NORESERVE 不需为映射保留空间(10) MAP_POPULATE 填充页
38、表(11) MAP_NONBLOCK 在10操作上不阻塞调用流程:mmap()-mmap2()-do_mmap()(内核系统调用)5页表项虚拟地址 物理地址:查询页表三级页表机制:PGD :级页表,全局目录PMD :二级页表PTE:最后一级页表mm-PGD-PMD-PTE- 物理地址TLB :缓冲虚拟地址到物理地址的信息。第十五章 页高速缓存和页回写1页高速缓存1) Linux内核的一种主要磁盘缓存,减少对磁盘的IO操作(将磁盘数据缓存至主存中);2) 页高速缓存缓存的是页面,所有的页IO操作都通过也高速缓存。2页回写脏数据:页高速缓存比后台存储数据新的数据。脏数据被写回:(1 )空闲内存低于
39、一个阈值,脏数据写回以释放内存。(2) 脏页在内存中驻留超过一个特定的阈值。pdflush内核线程:负责定时将脏数据刷入磁盘。pdflush线程可以有多个处理不同的设备列队。第十六章模块1构建模块将模块放在内核外:makefileobj-m := fish in g.ofishi ng-objs := fish in g-ma in.o fish in g-li ne.omake -C /kernel/source/locatio n SUBDIRS = $PWD modules2模块参数module_param (n ame, type, perm)name:用户可见的参数名type :参数
40、类型perm: sysfs文件系统下的文件权限3导出符号表导出的内核函数可被模块调用。EXPORT_SYMBOL()EXPORT_SYMBOL_GPL()第十七章 kobject与 sysfs1统一设备模型kobject:包含引用计数,父子关系和对象名称等基本对象道具,以统一方式提供这些功能。ktype :定义了一些 kobject相关默认特性,如析构、sysfs行为等。kset:(1) 嵌入的kobject作为kobject组的基类;(2) kset将相关的kobject集合在一起,相关的 kobject以独立目录与 sysfs中。 subsystem:包含kset的集合,是 sysfs的根目录映射。2 kobject使用方法初始化:kobject_i ni t(struct kobject *kobj)设置名称: kobject_set_ name(struct kobject *kobj, const char* fmt,.)增加引用计数:struct kobject* kobjec_get(struct kobject *kobj)减少
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度历史文化街区保护与开发合作协议4篇
- 二零二五年度领队与交通服务商合作协议范本4篇
- 2025年度个人股东股权转让协议范本详尽规定股权转让期限3篇
- 2025年度私立医院护士传染病防控聘用合同3篇
- 2025年度宠物活体销售渠道合作协议3篇
- 2025年度城市绿化工程监理与居间服务承包合同范本4篇
- 二零二五年度外墙涂料工程进度管理合同3篇
- 二零二五年度酒店客房用品租赁及售后服务协议3篇
- 二零二五版国际贸易实务实验报告与国际贸易政策分析合同3篇
- 2025版跨境贸易合同中因汇率变动情势变更的汇率风险规避协议4篇
- 2025年度土地经营权流转合同补充条款范本
- 南通市2025届高三第一次调研测试(一模)地理试卷(含答案 )
- 2025年上海市闵行区中考数学一模试卷
- 2025中国人民保险集团校园招聘高频重点提升(共500题)附带答案详解
- 0的认识和加、减法(说课稿)-2024-2025学年一年级上册数学人教版(2024)001
- 重症患者家属沟通管理制度
- 医院安全生产治本攻坚三年行动实施方案
- 法规解读丨2024新版《突发事件应对法》及其应用案例
- 工程项目合作备忘录范本
- 信息安全意识培训课件
- Python试题库(附参考答案)
评论
0/150
提交评论