- 博客(51)
- 收藏
- 关注
原创 触摸屏驱动
多点电容触摸芯片的接口,一般都为 I2C 接口,因此驱动主框架肯定是 I2C。当设备树中触摸 IC的设备节点和驱动匹配以后 。进入probe入口函数。在此函数中初始化触摸 IC,中断和 input 子系统等linux 里面一般都是通过中断来上报触摸点坐标信息,因此需要用到中断框架。在中断服务程序中上报读取到的坐标信息,根据所使用的多点电容触摸设备类型选择使用 Type A 还是 Type B 时序触摸屏的坐标信息、屏幕按下和抬起信息都属于 linux 的 input 子系统,因此向 linux
2023-10-04 20:33:17
740
原创 进程管理--CFS调度器(2)
主要以CFS调度器为例,介绍一下进程调度的一般流程。首先是调度的时机,基本调度器会根据TIF_NEED_RESHED标记判断是否需要进行调度,所以这个标记的设置就是调度的开始。满足抢占的条件就是,唤醒的进程的虚拟时间首先要比正在运行进程的虚拟时间小,并且差值还要大于一定的值才行(这个值是sysctl_sched_wakeup_granularity,称作唤醒抢占粒度)。
2023-09-26 11:45:05
158
原创 进程管理--CFS调度器(1)
CFS(Completely Fair Scheduler,完全公平调度器)用于Linux系统中普通进程的调度。它给cfs_rq(cfs的run queue)中的每一个进程设置一个虚拟时钟,vruntime。如果一个进程得以执行,随着时间的增长(一个个tick的到来),其vruntime将不断增大。没有得到执行的进程vruntime不变。调度器总是选择vruntime跑得最慢的那个进程来执行。这就是所谓的“完全公平”。
2023-09-26 11:39:51
188
原创 进程管理--进程调度基本概念
所有的就绪进程都会被放入某个CPU的rq上去,具体放到哪个rq上,这个在调度均衡里面讲。内核一共定义了五个调度类,属于不同调度类的进程会被放入不同的子队列,所以rq中包含三个子运行队列cfs_rq、rt_rq、dl_rq。因为有两个调度类idle、stop,每个CPU只能有一个进程,所以没必要弄个队列,直接关联它们的进程就可以了。内核中处理优先级如上所示,范围是0-139,数值越低,优先级越高,其中nice映射到100-139,RT优先级逆向映射到0-99。内核中定义了上面这几个宏,代表不同的调度策略。
2023-09-26 11:36:40
147
原创 进程管理--上下文切换
上下文切换:当一个任务切换到另一个任务时,它需要保存当前任务的所有状态,即保存当前任务的上下文,以便在再次执行该任务时,能恢复之前的状态,继续执行。上下文:描述了任务的执行状态。包括任务执行过程中堆栈中的内容和寄存器值,获取的资源信息,自身状态等。
2023-09-26 11:31:04
128
原创 进程管理--进程创建
进程拷贝或创建的一个整体调用流程:首先通过系统调用陷入内核,然后kernel_clone完成创建。其中描述符和资源的拷贝,pid的分配等都在copy_process中完成,完成创建后需要通过wake_up_new_task加入调度。可以使用fork或vfork创建进程,使用clone系统调用创建线程。在内部都是用kernel_clone实现。区别只是传入的args不同(用来控制新进程或线程与父进程或线程共享什么资源)。进程在某一时刻只可能有一种状态。
2023-09-26 11:22:58
97
原创 同步 -- 互斥锁
等待队列的第一个对象出列,表示下一个将要获得锁的任务。把下一个任务的task_struct地址写入到mutex lock的owner变量中(相当于下一个任务获得了互斥锁),唤醒下一个任务继续执行。__mutex_unlock_fast(快解锁):比较lock->owner和curr是否一致,一致则直接把0写到lock->owner中,表示解锁。互斥锁初始化比较简单,就是把owner,wait_lock,wait_list这几个成员初始化一下。解锁:mutex_unlock。加锁:mutex_lock。
2023-09-19 09:53:46
100
原创 同步 -- 信号量
获取成功,则sem->count -1。获取失败,将进程加入等待队列,开始休眠,直到已获得信号量的进程释放信号量时,会唤醒等待队列的进程。进程睡眠时,状态是TASK_UNINTERRUPTIBLE,表示睡眠过程不接受信号打断,释放信号量:如果等待队列为空,说明没有任务在等待,则直接将count++。如果不为空,唤醒队列头部的任务,并出队。
2023-09-19 09:49:57
69
原创 同步 -- 自旋锁
自旋锁的初始化:就是做个spinlock->raw_spinlock->arch_spinlock_t的转换,然后把arch_spinlock_t的val初始化为0
2023-09-19 09:44:18
76
原创 中断子系统 -- 中断通用框架
不管哪种形式,最终都可以通过linux irq号来找到对应的中断描述符;图的左侧灰色部分,主要在中断控制器驱动中进行初始化设置,包括各个结构中函数指针的指向等,其中struct irq_chip用于对中断控制器的硬件操作,struct irq_domain与中断控制器对应,完成的工作是硬件中断号到Linux irq的映射;在设备申请注册中断的过程中进行设置,比如struct irqaction中handler的设置,这个用于指向我们设备驱动程序中的中断处理函数;irqaction以链表的形式组织,Irq
2023-09-14 14:37:42
229
原创 中断子系统 --- 硬件相关层
这部分与具体的CPU架构相关,不同的架构有不同的执行方式。以ARMv8为例,具体见下面的Arch-specific中断处理流程源码分析
2023-09-14 14:27:39
91
原创 中断子系统--硬件层(GICv3)
硬件层:最下层为硬件连接层,对应的是具体的外设与SoC的物理连接,中断信号是从外设到中断控制器,由中断控制器统一管理,再路由到处理器上;硬件相关层:这个层包括两部分代码,一部分是架构相关的,比如ARM64处理器处理中断相关,另一部分是中断控制器的驱动代码;通用层:这部分也可以认为是框架层,是硬件无关层,这部分代码在所有硬件平台上是通用的;用户层:这部分也就是中断的使用者了,主要是各类设备驱动,通过中断相关接口来进行申请和注册,最终在外设触发中断时,进行相应的回调处理;
2023-08-08 20:31:58
669
原创 ARMv8内存模型
内核空间和用户空间有单独的转换表,这意味着它们的映射可以分开保存。EL0/EL1 使用左边的地址空间,EL2/EL3使用右边的。两者 的空间范围如图所示,是可伸缩的。任何超出配置范围的地址在被访问时都会生成异常作为转换错误
2023-07-16 17:27:06
2307
原创 ARMv8 异常模型
例如,EL1 的操作系统内核可能会禁用 EL0 的浮点指令,以节省应用程序之间上下文切换的时间。ARM v8有4个异常级别,每一个异常级别对应一个 VBAR(Vector Base Address Register) 寄存器,用来指向异常向量表的基地址,同时每一个异常向量表会分为4组,每一组包含4 种异常,导致无效指令的原因有很多,包括未定义的指令、当前异常级别不允许的指令或已被禁用的指令。复杂的系统可能有许多具有不同优先级的中断源,包括嵌套中断处理的能力,其中较高优先级的中断可以中断较低优先级的中断。
2023-07-16 17:23:24
1652
原创 ARMv8指令集架构
load的值0x1F的最高位是空的。此处被编译为LDR(literal)指令(将label的链接地址编码进imm19),加载到x0寄存器中的是label的链接地址。基址寄存器是一个X寄存器,它包含被访问数据的完整的或绝对的虚拟地址,如下图所示,LDR指令把X1寄存器中的值作为内存地址,读出其中的数值到W0寄存器中。说明3:标号(label)本质上是一个数值,即符号地址(链接地址),相当于PC+编码偏移值=label(目标地址)(具体在编码中可体现),并且默认情况下,标号只在定义它的源文件中可见。
2023-07-16 17:19:06
1175
原创 ARMv8寄存器
该架构提供了 31 个通用寄存器。每个寄存器都可以用作 64 位 X 寄存器 (X0…X30),或用作 32 位 W 寄存器 (W0…W30)。这是查看同一寄存器的两种不同方式。比如这张寄存器图,W0是X0的低32位,W1是X1的低32位:图 1.寄存器图对于数据处理指令,选择X或W决定操作的大小。使用X寄存器将导致 64 位计算,使用 W 寄存器将导致 32 位计算。此示例执行 32 位整数加法:ADD W0, W1, W2此示例执行 64 位整数加法:ADD X0, X1, X2。
2023-07-16 17:09:44
1404
原创 二:用户空间内存分配
malloc 通过 brk() 方式申请的内存,free 释放内存的时候,并不会把内存归还给操作系统,而是缓存在 malloc 的内存池中,待下次使用;malloc 通过 mmap() 方式申请的内存,free 释放内存的时候,会把内存归还给操作系统,内存得到真正的释放
2023-04-18 11:15:44
916
原创 一:内存碎片
内部碎片:是指已经分配出去的内存空间,却不能被充分利用的内存空间。也就是说分配出去的内存空间大于请求的内存空间,而导致有些内存自己用不到,其他的进程也无法使用。
2023-04-18 09:53:19
146
原创 ARM体系之异常中断
在ARM体系结构中,同步异常是指在指令执行期间产生的异常,通常是由于执行的指令出现了一些错误或者条件不满足而导致的。同步异常可以被捕获并且在指令执行结束之前进行处理,处理完成后再恢复指令执行。
2023-03-26 16:10:32
344
原创 GPT系列解读--GPT1
GPT-1采用了Transformer架构,并使用了大规模的无监督预训练方法,能够生成连贯的自然语言文本。具体来说,GPT-1使用了一个基于Transformer解码器的自回归语言模型(auto-regressive language model),通过最大化文本序列的概率,预测下一个单词。其中,GPT-1在单个英文句子的语言模型任务上表现最好,达到了0.99的困惑度(perplexity),超过了之前的SOTA模型。GPT-1的成功为基于预训练的自然语言处理模型的发展提供了新的思路和方法。
2023-03-21 17:23:34
3010
1
原创 排序-堆排序
③在7被交换下来后,下面还有子节点,所以需要继续与子节点对比,左孩子11比7大,所以11与7交换位置,交换位置后7下面为有序区,不参与对比,所以本轮结束,无序区再次形成一个最大堆。每一个三角关系都是一个堆,上面是父节点,下面两个分叉是子节点。一般用数组来表示堆,下标为 i 的结点的父结点下标为(i-1)/2;首先将堆顶元素100交换至最底部7的位置,7升至堆顶,100所在的底部位置即为有序区,有序区不参与之后的任何对比。②在7升至顶部之后,对顶部重新做最大堆调整,左孩子33代替7的位置。
2023-03-19 12:40:56
64
原创 排序-快速排序
快速排序算法的实现基于分治思想,它将一个大的数组分成两个小的数组进行排序,再将这两个小的数组合并起来,得到排序后的结果。具体来说,快速排序算法的实现步骤如下:
2023-03-19 12:32:53
151
原创 linux字符设备驱动框架详解
以主设备号为 cdev_map 编号,使用哈希函数 f(major)=major%255 来计算组数下标 (使用哈希函数是为了链表节点尽量平均分布在各个数组元素中,提高查询效率);每个主设备号可包含一系列不同次设备号的字符设备节点。主设备号冲突, 则以次设备号为比较值来排序链表节点。
2023-03-10 12:02:44
589
原创 MIT 6.S081操作系统 之 文件系统详解
磁盘读写的最小单位是扇区,扇区的大小只有 512B 大小,很明显,如果每次读写都以这么小为单位,那这读写的效率会非常低。所以,文件系统把多个扇区组成了一个逻辑块,每次读写的最小单位就是逻辑块(数据块),Linux 中的逻辑块大小为 4KB,也就是一次性读写 8 个扇区,这将大大提高了磁盘的读写的效率。
2023-03-10 11:57:29
306
原创 MIT 6.S081操作系统之 多进程和多线程
每一个CPU核在一个时间只会做一件事情,每个CPU核在一个时间只会运行一个线程,它要么是运行用户进程的线程,要么是运行内核线程,要么是运行这个CPU核对应的调度器线程。类似的每一个线程要么是只运行在一个CPU核上,要么它的状态被保存在context中。线程永远不会运行在多个CPU核上,线程要么运行在一个CPU核上,要么就没有运行。1.从一个用户进程切换到另一个用户进程,都需要从第一个用户进程接入到内核中,保存用户进程的状态并运行第一个用户进程的内核线程。RUNNING,线程当前正在某个CPU上运行。
2023-03-10 11:55:28
66
原创 TMUX常用命令
获取当前会话信息:tmux display-message -p ‘#S’获取当前窗口信息:tmux display-message -p ‘#W’获取当前窗格信息:tmux display-message -p ‘#P’
2023-03-10 11:51:10
335
原创 SPI 通信协议 最详细解读!!!
SPI(Serial Peripheral Interface,串行外围接口)是一种高速、全双工、同步的通信总线,主要应用在、FLASH、实时时钟、AD转换器上,以及数字信号处理器和数字信号解码器之间。
2023-03-04 16:29:02
3052
原创 通信协议之IIC 最详细解读!!
i2c的数据字节定义为8-bits长度,对每次传送的总字节数量没有限制,但对每一次传输必须伴有一个应答(ACK)信号, 其时钟由主设备提供,而真正的应答信号由从设备发出,在时钟为高时,通过拉低并保持SDA的值来实现。I2C规定将发起通信的设备称为主设备,主设备发起一次通信后,其它设备均为从设备。传输时,SCL为高电平的时候SDA表示的数据有效,即此时的SDA为高电平时表示数据“1”,为低电平时表示数据“0”。当SCL为低电平时,SDA的数据无效,一般在这个时候SDA进行电平切换,为下一次表示数据做好准备。
2023-03-04 16:21:03
3361
原创 Page fault(异常)
假设现在是子进程在执行store指令,那么我们会分配一个新的物理内存page,然后将page fault相关的物理内存page拷贝到新分配的物理内存page中,并将新分配的物理内存page映射到子进程。这里使用自旋锁是考虑到这种情况:进程P1和P2共用内存M,M引用计数为2,此时CPU1要执行fork产生P1的子进程,CPU2要终止P2,那么假设两个CPU同时读取引用计数为2,执行完成后CPU1中保存的引用计数为3,CPU2保存的计数为1,那么后赋值的语句会覆盖掉先赋值的语句,从而产生错误。
2023-03-03 18:43:32
1865
原创 Lab3 Page tables相关知识和实验
为什么需要虚拟地址?隔离性。将用户程序之间,用户程序和内核之间进行内存隔离。防止一个程序错误的操作了另一个程序的内存。通过PTE的flags位,可为系统提供更多的功能。
2023-03-03 18:39:56
134
原创 Lab4 Trap(内核状态切换)
内核完成它的工作之后,代码执行会返回到用户空间,继续执行ecall之后的指令,也就是ret,最终返回到原c程序中。首先,我们需要保存32个用户寄存器。在函数中,可以通过查看a0寄存器,这是第一个参数,a1是第二个参数,a2是第三个参数等,获得在用户空间调用write时传入的参数。程序计数器也需要在某个地方保存,它几乎跟一个用户寄存器的地位是一样的,我们需要能够在用户程序运行中断的位置继续执行用户程序。我们需要保存32个用户寄存器的内容,这样当我们想要恢复用户代码执行时,我们才能恢复这些寄存器的内容。
2023-03-03 18:39:51
158
原创 MIT 6.S081 Lab1系统调用
exec将当前进程的内存和寄存器替换为一个新的程序(/init),当kernel执行完毕exec指定的程序后,回到/init进程。函数实现逻辑为:首先需要获取系统调用的参数,也就是从用户态传入的参数mask,然后设置当前进程的syscall_trace为该参数(需要在进程结构体中添加该项),同时为了能够保证真正地trace指定的系统调用,那么就不仅仅在该进程,同时也需要相关所有的子进程也传递该参数,就需要在fork.c函数中增加一行赋值语句。添加一个系统调用,返回空闲的内存、以及已创建的进程数量。
2023-03-03 18:35:58
153
原创 MIT 6.S081/828 环境搭建/GDB调试+VScode
按照官方文档下载相关软件。最新xv6源码使用此架构qemu-system-riscv64。直接make qemu即可成功我们来看传给QEMU的几个参数:-kernel:这里传递的是内核文件(kernel目录下的kernel文件),这是将在QEMU中运行的程序文件。-m:这里传递的是RISC-V虚拟机将会使用的内存数量-smp:这里传递的是虚拟机可以使用的CPU核数-drive:传递的是虚拟机使用的磁盘驱动,这里传入的是fs.img文件其他架构:执行make qemu会报错找不到qemu。
2023-03-03 18:33:42
1388
原创 Python/Pytorch常用函数大汇总(持续更新中)
nargs - 应该读取的命令行参数个数,可以是具体的数字,或者是?在上面的代码中,我们先导入了argparse这个包,然后包中的ArgumentParser类生成一个parser对象(好多博客中把这个叫做参数解析器),其中的description描述这个参数解析器是干什么的,当我们在命令行显示帮助信息的时候会看到description描述的信息。而对于tensor的计算操作,默认是要进行计算图的构建的,在这种情况下,可以使用 with torch.no_grad():,强制之后的内容不进行计算图构建。
2023-02-04 17:25:09
930
原创 Linux内核--内核同步下(并发控制)
Linux中的信号量是一种睡眠锁。如果有一个任务试图获得一个不可用(已经被占用)的信号量时,信号量会将其推进一个等待队列,然后让其睡眠。这时处理器能重获自由,从而去执行其他代码。当持有的信号量可用(被释放)后,处于等待队列中的那个任务将被唤醒,并获得该信号量。
2023-02-04 17:19:15
60
原创 论文阅读笔记--SiameseFC
B为batch_size,gt代表ground truth,对于每个通道值都一样,靠近中心位置全部置1,代表是正样本。以bbox的中心为中心,构建一个面积为127*127的区域,其中包括bbox周围环境信息,如果超出图片范围则通过像素平均值进行填充。以上一帧bbox的中心为中心,构建一个面积为255*255的区域,如果超出范围则通过平均值进行pad。预测时,第一帧bbox已知的,且预测是顺序预测,因此,预测过程中,预测帧前一帧的bbox是已知的。的时候,这时候会有最大的相似度,这为网络输出的。
2023-02-04 17:16:29
164
原创 论文阅读笔记--Siamese RPN++
如图,模板图像和检测图像的feature map,在回归分支和分类分支中,都首先分别经过一个卷积神经层(由conv层和bn层构成),得到一样的空间分辨率和channel维度。该卷积神经层不同于SiamRPN中的卷积神经层,其不对feature map进行channel升维,只是对两组feature map都进行了finetune,使其维度对称。在经过卷积神经层之后,模板图像和检测图像的feature map进行depthwise的相关操作,即是逐个channel的两者的分量之间进行相关操作,输出和chann
2023-02-04 17:13:43
284
1
原创 论文阅读笔记--Swintrack
(考虑到transformer是序列到序列模型,transformer自然可以接受多模态数据作为输入)这里是直接将两分支的特征做concate,然后输入encode,可以节省计算量,减少参数。g和h分别是q和k的起始索引,例如,1表示来自模板图像的token,2表示来自搜索图像的token。对于标准的Transformer模块,要求输入的是token(向量)序列,即二维矩阵[num_token, token_dim],即对图片做分割,详细可参考VIT,Swintransformer。是一个可学习的参数。
2023-02-04 17:10:06
441
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人