linux内核基础层的学习(1)

一:内核基础层数据结构

1:双向链表list

a):链表的定义

struct list_head{
 struct list_head *next,*pre;
 }

b):container对象和list_entry

#define container_of(ptr,type,member){  \
    const typeof(((type *)0->member) *_mptr = (ptr);     (type*)((char*)_mptr-offset(type,member));})
#define list_entry(ptr,type,member) \
    container_of(ptr,type,member)

对双向链表的详细介绍请参考我的博客:

linux内核list.h的学习

2:hash链表

a):定义

struct hlist_head{
    struct hlist_head *first;
}

b):hash链表库

与list相同

请参考下面文章的后面部分就是hash链表的内容:

linux内核list.h的学习

3:红黑树

a):实质上是自平衡二叉树

b):定义在rbtree.c文件中(静待博客更新,对rbtree的介绍)

c):应用场景

主要用在内存管理,IO调度算法等实现了红黑树

4:radix输–基树

a):定义在/lib/radix_tree.c中

b):radix树是一种空间换时间的数据结构,通过空间的冗余减少了时间上的消耗

(静待博客更新,对radix_tree的介绍)

c):page cache的管理使用了radix tree

二:内核基础层的同步机制

1:自旋锁

a):作用

(1):如果数据未锁,那么就获取锁并运行,如果数据已锁,那么就一定旋转(其实是反复执行一条指令)

(2):单处理器环境(非抢占式内核)下,自旋锁其实不起作用

(3):单处理器,抢占式内核环境下,自旋锁起的作用就是禁止抢占

b):自旋锁的调用

(1):spin_lock

(2):spin_unlock

2:内核信号量

a):定义在文件semaphore.h文件里

b):semaphore和mutex

(1):sema_init:计数可以为多

(2):init_mutex:计数为1的信号量

c):信号量的操作

(1):up:释放信号量

(2):down:获取信号量,如果不能获取,则进入睡眠状态

(3):down_trylock:获取信号量,如果不能获取则立即返回,进程不进入睡眠状态

注意:

自旋锁和信号量的区别

1:自旋锁可以用在中断处理函数和tasklet等不可睡眠的场景,而信号量不行

2:可睡眠的场景既可以使用信号量,也可以使用自旋锁,自旋锁通常用在轻量级场景

3:同步机制–原子变量

a):原子变量提供了一种原子的数据结构,对这种数据结构的读写不可被细分和打断

b):原子变量提供的调用

(1):atomic_add:加一个整数到原子变量

(2):automic_sub:从原子变量减去一个整数

(3):automic_set:设置原子变量的数值

(4):automic_read:读取原子变量的数值

4:同步机制–completion

a):completion提供了一种等待完成的机制

b):提供的调用

(1):wait_for_completion:等待操作完成

(2):complete:完成的信号

5:其他内核同步机制

a):CPU变量 DEFINE_PER_CPU

b):RCU锁

c):顺序锁

时间: 2024-10-08 18:12:09

linux内核基础层的学习(1)的相关文章

Linux内核分析第一次学习报告

Linux内核分析第一次学习报告 学生 黎静 学习内容 1.存储程序计算机工作模型 冯诺依曼体系结构:核心思想为存储程序计算机. CPU抽象为for循环,总是执行下一条指令,内存保存指令和数据,CPU来解释和执行这些指令. API:应用程序编程接口(程序员与计算机的接口界面) ABI:二进制接口,指令编码(程序员与CPU的接口界面) 2.X86汇编 1.寄存器 (1)通用寄存器 (2)段寄存器: (3)标志寄存器 2.计算机的汇编指令 (1)movl指令: 寄存器寻址,寄存器模式,以%开头的寄存

linux内核启动过程学习总结

下面是学习linux内核启动过程的记录 平台是:powerpc mpc8548 + linux2.6.23 内核 通用寄存器的作用r0 :在函数开始时使用r1 :存放堆栈指针,相当于ia32架构中的esp寄存器r2 :存放当前进程的描述符的地址r3 :存放第一个参数和返回地址r4-r10 :存放函数的参数r11 :用在指针的调用和当前一些语言的环境指针r12 :用于存放异常处理r13 :保留做为系统线程IDr14-r31 :作为本地变量,具有非易失性 Linux启动过程描述 第一步:使用Boot

Linux内核源码学习之 数据结构

本篇记录在学习Linux内核源码过程中对一些知道但不熟悉不会用的数据结构进行记录. union 是在学习进程复制函数do_fork中遇到的: <sched.h> union thread_union { struct thread_info thread_info; unsigned long stack[THREAD_SIZE/sizeof(long)]; }; struct  thread_info和stack被声明为union 共享空间 "联合"是一种特殊的类,也是一

《Linux内核分析》学习总结与学习心得

一.目录列表 第一周:计算机是如何工作的? http://www.cnblogs.com/dvew/p/5224866.html 第二周:操作系统是如何工作的? http://www.cnblogs.com/dvew/p/5245866.html 第三周:构造一个简单的Linux系统MenOS http://www.cnblogs.com/dvew/p/5270915.html 第四.五周:系统调用的三层皮 http://www.cnblogs.com/dvew/p/5285685.html h

Linux内核“问题门” - 学习问题、经验集锦

陈宪章说:"学贵有疑,小疑则小进,大疑则大进.疑者,觉悟之机也,一番觉悟一番长进." 培根说:"多问的人将多得." 还在学校的时候导师在激情讲演之后对着会议室里形态各异但均静默不语的我们痛心疾首的说:"会提问题很重要啊,同志们!不会提问题怎么有资格做研究!" 这样铿锵有力的训诫今日想起仍觉深受刺激,于是就要不可避免得要做出一些反应来.不过一是因为咱这年代还没有非主流的说法,二是因为也没有冯仰妍同学的性别优势,不可能受到刺激就整出个门来.咱能够做到

Linux内核(16) - 高效学习Linux内核

世界悲结束了,章鱼哥也退役了,连非诚勿扰中的拜金女也突然的少了很多.这本<Linux内核修炼之道>在卓越.当当.china-pub上也已经开卖了,虽然是严肃文学,但为了保证流畅性,大部分文字我还都是斟词灼句,反复的念几遍才写上去的,尽量考虑到写上去的每段话能够让读者产生什么疑惑,然后也都会紧接着尽量的去进行解释清楚,中间的很多概念也有反复纠结过怎么解释能够更容易的理解,力求即使对于初学者也可以有很少阻碍的一气读完.同时我也把书中一部分自己的感悟抽出来整理了精华版,share出来.当然水平有限,

Linux内核(17) - 高效学习Linux驱动开发

这本<Linux内核修炼之道>已经开卖(网上的链接为: 卓越.当当.china-pub ),虽然是严肃文学,但为了保证流畅性,大部分文字我还都是斟词灼句,反复的念几遍才写上去的,尽量考虑到写上去的每段话能够让读者产生什么疑惑,然后也都会紧接着尽量的去进行解释清楚,中间的很多概念也有反复纠结过怎么解释能够更容易的理解,力求即使对于初学者也可以有很少阻碍的一气读完.同时我也把书中一部分自己的感悟抽出来整理了精华版,share出来.当然水平有限,错漏之处有发现而修订时遗漏的,也有尚没有发现的.这本书

linux内核I2C子系统学习(三)

写设备驱动: 四部曲: 构建i2c_driver 注册i2c_driver 构建i2c_client ( 第一种方法:注册字符设备驱动.第二种方法:通过板文件的i2c_board_info填充,然后注册) 注销i2c_driver 具体如下: ●    构建i2c_driver static struct i2c_driver pca953x_driver = {                 .driver = {                                     .n

Linux内核源码学习之 内核页表打印

本学期Linux内核实验最后是打印内核页表,线性地址----物理地址 我看到这个实验题目的时候想到的就是这个init函数(因为这部分当时就是我讲的^_^),这个函数是初始化linux内核页表的,也就是将32位系统中3G以上的896M线性地址映射到物理地址的0-896M,在其调用者paging_init函数中还处理了其他的情况,比如固定映射之类的.那属于高端内存映射那一块的内容,目前我们先看一下如何将内核页表3G~3G+896M的线性地址对应的物理地址打印出来. 一下的源码是linux2.6.11