自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(335)
  • 问答 (2)
  • 收藏
  • 关注

原创 算法---链表

要反转链表的第一个节点是head,head的前面一个节点是pre,如果head是首节点,则pre等于NULL,要反转链表的最后一个节点的后一个节点是p。比如说我们要反转的是2,5,4,3,则head节点是2,pre是7,p是6;如果反转的是9,7,2,则head是9,pre是NULL,p是3.下面函数返回值是反转链表后的首节点,head是要反转链表的首节点,p是要反转链表的最后一个节点的后一个节点。在这里,我们约定数据元素类型是。反转全部元素,反转全部元素最后一个节点的下一个节点是NULL。......

2022-07-20 15:45:34 970 1

原创 Linux设备驱动开发--- DMA

文章目录1 设置DMA映射缓存一致性和DMADMA映射一致映射流式DMA映射2 完成的概念3 DMA引擎API分配DMA从通道设置从设备和控制器指定参数DMA是计算机系统的一项功能,它允许设备在没有CPU的干预的情况下访问系统主存储器RAM,使CPU完成其他任务。DMA控制器是负责DMA管理的外设,在现代处理器和微控制器中都能发现它。DMA功能用于执行内存读写和写入操作而不占用CPU周期。当需要传输数据块时,处理器向DMA控制器提供源地址和目标地址以及总字节数。然后,DMA控制器会自动将数据从源传输到目

2022-05-24 18:22:28 3873 1

原创 用户虚拟地址转化成物理地址,物理地址转换成内核虚拟地址,内核虚拟地址转换成物理地址,虚拟地址和对应页的关系

文章目录1. 用户虚拟地址转换成物理地址2. 内核虚拟地址转换成物理地址3. 物理地址转换成内核虚拟地址4 虚拟地址和对应页1. 用户虚拟地址转换成物理地址2. 内核虚拟地址转换成物理地址3. 物理地址转换成内核虚拟地址4 虚拟地址和对应页...

2022-05-23 22:01:45 1723

原创 Linux设备驱动开发---设备树的概念

文章目录1 内核设备与驱动匹配函数在这篇文章中:https://blog.csdn.net/qq_41683305/article/details/124508716,我们介绍了平台设备驱动的基本概念,包括平台设备、平台驱动以及怎么匹配的,接下来我们来介绍匹配的具体细节以及设备的概念。1 内核设备与驱动匹配函数...

2022-05-21 10:26:41 2653 1

原创 延迟和定时器管理

文章目录1 内核中时间概念2 标准定时器jiffies和HZ定时器API标准定时器案例3 高精度定时器(HRT)高精度定时器案例4 内核中延迟和睡眠原子上下文非原子上下文1 内核中时间概念时间概念对计算机来说有些模糊,事实上内核必须在硬件的帮助下才能计算和管理时间。硬件为内核提供了一个系统定时器用于计算流失的时间。系统定时器以某种频率自发触发时钟中断,该频率可以通过编程预定,称为节拍率(系统定时器的频率)。因为节拍率对内核来说是可知的,所以内核知道连续两次时钟中断的间隔时间,这个间隔时间就是节拍。内核

2022-05-14 22:17:14 325

转载 Linux系统编程---守护进程

1 守护进程的概述Daemon(守护进程)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务。Linux系统的大多数服务器就是通过守护进程实现的。常见的守护进程包括系统日志进程syslogd、 web服务器httpd、邮件服务器sendmail和数据库服务器mysqld等。守护进程一般在系统启动时开始运行,除非强行终止,否则直到系统关机都保持运行。守护进程经常以超级用户(root

2022-05-11 16:19:03 714

原创 排序算法---快速排序、堆排序、冒泡排序

排序算法1 快速排序1 快速排序文章原地址:https://blog.csdn.net/morewindows/article/details/6684558快速排序的平均时间复杂度是0(NlogN),它采用了一种分治的策略,通常称其为分治法。该方法的基本思想是:先从数列中取出一个数作为基准数。分区:将大于这个数放到它的右边,小于等于它的数全放在它的左边再对左右区间重复第二步,直到各区间只要一个数虽然快速排序称为分治法,但分治法这三个字显然无法很好概括快速排序的全部步骤,因此我对快速排序做了

2022-05-09 22:24:31 972

原创 Linux内存地址管理

在操作系统中,虚拟地址到物理地址转换是由MMU完成的,MMU转换的都是虚拟地址,所以访问数据,必须是虚拟地址,不能是物理地址,否则访问不了数据。进程访问的都是进程内虚拟地址,内核访问的都是内核虚拟地址,进程用不了内核虚拟地址,同样内核用不了进程内虚拟地址。...

2022-05-09 19:47:58 1117

转载 进程上下文和中断上下文

文章目录进程的preempt_count变量thread_infopreempt_counthardirq相关softirq相关上下文进程的preempt_count变量thread_info在内核中,上下文的设置和判断接口可以参考 include/linux/preempt.h 文件,整个机制的实现都依赖于一个变量:preempt_count,这个变量被定义在进程struct task_struct的 thread_info域中 ,也就是线程描述符中,线程描述符被放在内核栈的底部,在内核中可以通过

2022-05-07 10:28:00 586

转载 内存重映射

#include <sys/mman.h> void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); int munmap(void *addr, size_t length);用户空间的mmap()会通过系统调用调用内核的do_mmap()函数。do_mmap()函数会:首先创建一个新的VMA并初始.......

2022-05-05 11:24:54 1513

原创 进程虚拟地址管理

文章目录1 地址分布实际使用中的内存区域1 地址分布现在采用虚拟内存的操作系统通常都使用平坦地址空间,平坦地址空间是指地址空间范围是一个独立的连续空间(比如,地址从0扩展到429496729位地址空间),对于32位的操作系统而言,每个进程的虚拟地址空间都是0x00000000~0xC0000000,合计3G大小。进程的3G虚拟地址空间只有映射为物理地址空间,才能够被使用,那么进程是如何管理和分配它的3G虚拟地址空间呢?这就用到了分治思想,进程虚拟地址空间按照不同的访问属性和功能划分为不同的内存区

2022-05-05 10:16:19 337

原创 slab下kmalloc内核函数实现

文章目录kmalloc的整体实现获取高速缓存高速缓存获取index总结https://blog.csdn.net/qq_41683305/article/details/124554490,在这篇文章中,我们介绍了伙伴算法、slab机制和常见的内存管理函数,接下来,我们看看kmalloc内核函数的具体实现。kmalloc() 分配连续的物理地址,用于小内存分配。get_free_page() 分配连续的物理地址,用于整页分配。在slab机制下(还有slob、slub),kmalloc() 函数是基于 s

2022-05-04 14:11:51 775

原创 C语言uthash的用法

官网解释:https://troydhanson.github.io/uthash/userguide.html在使用之前,我们必须包含uthash.h的头文件,你需要将该头文件加入到你的项目中#include "uthash.h"1 定义一个哈希表我们直到,在哈希表中,最重要的就是键和值,在 utash 中,哈希表由结构体组成。 每个结构体代表一个键值关联。 一个或多个结构体里的域构成键, 该结构指针就是值。我们定义一个my_struct 结构体,用id的值作为键值,my_struct 的实例

2022-05-03 21:44:00 2322 1

原创 伙伴算法、slab机制、内存管理函数

文章目录

2022-05-03 18:17:51 1769

原创 linux设备驱动开发---平台设备驱动程序

有些物理总线已为人熟知:USB、I2S、I2C、UART、SPI、PIC、SATA等。这种总线是名为控制器的硬件设备。由于它们是SoC的一部分,因此无法删除,不可发现,也称为平台设备。从SoC的角度来看,这些设备(总线)内部通过专用总线连接,而且大部分时间是专用的,专门针对制造商。从内核的角度来看,这些是根设备,未连接到任何设备,也就是未连接到任何总线上。这就是伪平台总线的用途,伪平台总线也称为平台总线,是内核虚拟总线,该总线实际不存在,用于连接不在内核所知物理总线上的设备和驱动程序。在下面的讨论中,平台

2022-05-03 11:04:49 1139

原创 C语言多维数组

如果某个数组的维数超过1,它就被称为多维数组,例如,下面这个声明:int matrix[6][10]创建了一个包含60个元素的矩阵。但是,它是6行每行10个元素,还是10行每行6个元素?为了回答这个问题...

2022-04-28 20:21:21 1940

转载 Linux系统编程---I/O多路复用

文章目录1 什么是IO多路复用2 解决什么问题说在前面I/O模型阻塞I/O非阻塞I/OIO多路复用信号驱动IO异步IO3 目前有哪些IO多路复用的方案解决方案总览常见软件的IO多路复用方案4 具体怎么用selectpollepolllevel-triggered and edge-triggered状态变化通知(edge-triggered)模式下的epoll5 不同IO多路复用方案优缺点poll vs selectepoll vs poll&select1 什么是IO多路复用一句话解释:单线程

2022-04-28 18:24:27 1066

原创 linux系统编程---线程总结

线程总结1 线程的实现2 线程的属性3 线程的同步4 线程池https://zhuanlan.zhihu.com/p/3425737051 线程的实现2 线程的属性3 线程的同步https://www.zhihu.com/search?type=content&q=linux%E7%BA%BF%E7%A8%8B4 线程池https://www.zhihu.com/search?type=content&q=linux%E7%BA%BF%E7%A8%8B%E6%B1%A0..

2022-04-28 15:19:02 523

原创 同步---自旋锁

1 自旋锁的基本概念自旋锁最多只能被一个可执行线程持有,如果一个执行线程试图获得一个已经被使用的自旋锁,那么该线程就会一直进行自旋,等待锁重新可用。在任何时刻,自旋锁都可以防止多余一个的执行线程同时进入临界区。Linux内核实现的自旋锁是不可递归的,如果你请求一个你已经持有的自旋锁,那么你将会自旋,等待释放这个锁,由于自旋,释放这个锁的操作不会被执行,所以会一直处于自旋忙等待中,于是就被锁死了。自旋锁可以在中断处理程序中使用。在中断处理程序中使用自旋锁时,一定要在获取锁之前,首先禁止本地中断(当前处理

2022-04-28 14:34:40 1850

转载 算法---KMP算法

字符串1 KMP算法状态机概述构建状态转移1 KMP算法原文链接:https://zhuanlan.zhihu.com/p/83334559先约定,本文用pat表示模式串,长度为M,txt表示文本串,长度为N,KMP算法是在txt中查找子串pat,如果找到,返回这个子串的起始索引,否则返回-1.用一张图演示一下KMP算法:KMP算法永不回退txt中的索引i,不走回头路。而是借助一个数组dp,dp数组中存储的信息把pat移到正确的位置继续匹配。KMP的难点在于计算dp数组,计算这个dp数组,之和

2022-04-26 19:50:11 227

原创 同步---信号量

信号量1 信号量2 驱动程序和测试程序3 内核的具体实现1 信号量Linux中的信号量是一种睡眠锁。如果有一个任务试图获得一个已经被占用的信号量时,信号量会将其放到一个等待队列,然后让其睡眠,这时处理器去执行其他代码。当持有信号量的进程将信号量释放后,处于等待队列中的那个任务将被唤醒,并获得该信号量。信号量定义在文件include/linux/semaphore.h中/* Please don't access any members of this structure directly */st

2022-04-26 14:30:17 2025

原创 Linux设备驱动开发---字符设备驱动程序

字符设备驱动程序1 主设备和次设备的概念设备号的注册和释放静态方法动态方法区别2 设备文件操作struct file_operations与struct file、struct inode关系3 分配和注册字符设备class_createcdev_adddevice_create4 字符设备驱动程序字符设备通过字符(一个接一个的字符)以流方式向用户程序传递数据,就像串行端口那样。字符设备驱动通过/dev目录下的特殊文件公开设备的属性和功能,通过这个文件可以在设备和用户应用程序之间交换数据,也可以通过它来控

2022-04-26 09:12:45 3085

原创 linux内核文件描述符fd、文件索引节点inode、文件对象file关系

文件描述符fd、文件索引节点inode、文件对象file关系1 VFS对象1.1 超级块对象1.2 索引节点对象1.3 文件对象1.4 进程描述符1.5 files_struct2 如何根据文件描述符fd找到文件?1 VFS对象在说fd、inode和file关系之前,我们先了解VFS的几个概念。分别是进程描述符、超级块对象、索引节点和文件对象。1.1 超级块对象超级块对象代表一个已安装的文件系统,由super_block结构体表示,定义在文件linux/fs中。1.2 索引节点对象索引节点对象代

2022-04-23 15:01:27 3332 3

原创 编写最简单的字符设备驱动

编写最简单的字符设备驱动1 编写驱动代码2 编写makefile3 编译和加载驱动4 编写应用程序测试驱动1 编写驱动代码驱动代码chardev.c如下:#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/cdev.h>#include <linux/fs.h>#include <linux/wait.h>#include <linux/

2022-04-22 10:31:29 6346

原创 算法---栈和队列

栈和队列1 栈栈的顺序存储栈的链式存储2 队列队列的顺序存储队列的链式存储1 栈参考文章:https://zhuanlan.zhihu.com/p/346164833https://zhuanlan.zhihu.com/p/120965372#:~:text=%E6%A0%88%E6%98%AF%E4%B8%80%E7%A7%8D%20%E5%90%8E%E8%BF%9B%E5%85%88%E5%87%BA%EF%BC%88LIFO%EF%BC%89,%E7%9A%84%E6%95%B0%E6%8D

2022-04-21 21:49:45 560

原创 linux系统编程---进程总结

进程控制总结1 进程创建的三种方式2 进程终止3 进程等待4 进程替换1 进程创建的三种方式https://zhuanlan.zhihu.com/p/498427466?utm_source=wechat_session&utm_medium=social&utm_oi=977698418977746944&utm_campaign=shareopn2 进程终止https://zhuanlan.zhihu.com/p/435709371https://zhuanlan.zh

2022-04-21 17:22:08 1144

转载 算法---递归

递归结题三部曲何为递归?程序反复调用自身即是递归。我自己在刚开始解决递归问题的时候,总是会去纠结这一层函数做了什么,它调用自身后的下一层函数又做了什么…然后就会觉得实现一个递归解法十分复杂,根本就无从下手。相信很多初学者和我一样,这是一个思维误区,一定要走出来。既然递归是一个反复调用自身的过程,这就说明它每一级的功能都是一样的,因此我们只需要关注一级递归的解决过程即可。从图中可以看出,递归是先递后归,自下往上处理。如上图所示,我们需要关心的主要是以下三点:整个递归的终止条件。一级递归需要做

2022-04-18 21:48:29 80

原创 Linux内核设计与实现---kobject sysfs

kobject sysfs1 kobject2 ktype3 kset4 subsystem5 别混淆了这些结构体6 管理和操作kobject7 引用计数8 sysfssysfs中添加和删除kobject向sysfs添加文件9 内核事件层1 kobject2 ktype3 kset4 subsystem5 别混淆了这些结构体6 管理和操作kobject7 引用计数8 sysfssysfs中添加和删除kobject向sysfs添加文件9 内核事件层...

2022-04-18 15:51:57 1150

原创 Linux内核设计与实现---模块

模块1 构建模块放在内核源代码树中放在内核代码外2 安装模块3 产生模块依赖性4 载入模块5 管理配置选项6 模块参数7 导出符号表Linux内核是模块化组成的,它允许内核在运行时动态地向其中插入或从中删除代码。与开发的内核核心子系统不同,模块开发更接近编写新的应用程序,因为至少要在模块文件中具有入口点和出口点。下面是hello_world内核模块#include <linux/init.h>#include <linux/module.h>#include <

2022-04-17 09:49:54 1125

原创 Linux内核设计与实现---页高速缓存和页回写

页高速缓存和页回写1 页高速缓存2 基树3 缓冲区高速缓存4 pdflush后台例程膝上型电脑模式bdflush和kupdated避免拥塞的方法:使用多线程1 页高速缓存2 基树3 缓冲区高速缓存4 pdflush后台例程膝上型电脑模式bdflush和kupdated避免拥塞的方法:使用多线程...

2022-04-15 22:02:50 384

原创 Linux内核设计与实现---进程地址空间

进程地址空间1 内存描述符分配内存描述符销毁内存描述符mm_struct与内核线程2 内存区域VMA标志VMA操作内存区域的树形结构和内存区域的链表结构实际使用中的内存区域3 操作内存区域find_vma()find_vma_prev()find_vma_intersection()4 mmap()和do_mmap():创建地址空间5 munmap()和do_munmap():删除地址空间6 页表1 内存描述符分配内存描述符销毁内存描述符mm_struct与内核线程2 内存区域VMA标志VMA

2022-04-14 10:55:10 903

原创 算法---数

数1 最大公约数2 最小公约数3 进制转换4 阶乘统计阶乘尾部0的个数1 最大公约数欧几里得算法:两个整数的最大公约数等于其中较小的那个数和两数相除余数的最大公约数。gcd(a,b)=gcd(b,a%b); /* a>b*/具体代码实现如下:int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b);}2 最小公约数设a,b的最小公约数为lcm(a,b)。有定理:lcm(a,b)*gcd(a,b)=a*b);具体

2022-04-13 21:48:38 332

原创 Linux内核设计与实现---块I/O层

块I/O层1 解刨一个块设备2 缓冲区和缓冲区头3 bio结构体4 请求队列5 I/O调度程序I/O调度程序的工作Linux电梯最终期限I/O调度程序预测I/O调度程序完全公正的排队I/O调度程序空操作的I/O调度程序I/O调度程序的选择小结1 解刨一个块设备2 缓冲区和缓冲区头3 bio结构体4 请求队列5 I/O调度程序I/O调度程序的工作Linux电梯最终期限I/O调度程序预测I/O调度程序完全公正的排队I/O调度程序空操作的I/O调度程序I/O调度程序的选择小结...

2022-04-12 11:22:42 1327

原创 Linux内核设计与实现---虚拟文件系统

虚拟文件系统1 通用文件系统2 文件系统抽象层3 Unix文件系统4 VFS对象及其数据结构5 超级快对象6 索引节点对象7 目录项对象目录项状态目录项缓存目录项操作8 文件对象9 和文件系统相关的数据结构10 和进程相关的数据结构Linux中的文件系统1 通用文件系统2 文件系统抽象层3 Unix文件系统4 VFS对象及其数据结构5 超级快对象6 索引节点对象7 目录项对象目录项状态目录项缓存目录项操作8 文件对象9 和文件系统相关的数据结构10 和进程相关的数据结构Lin

2022-04-11 10:52:36 1691

原创 Linux内核设计与实现---内存管理

内存管理1 页2 区3 获得页获得填充为0的页释放页4 kmalloc()gfp_mask标志kfree()5 vmalloc()6 slab层7 slab分配器的接口8 在栈上的静态分配9 高端内核的映射永久映射临时映射10 每个CPU的分配11 新的每个CPU的接口编译时的每个CPU数据运行时每个CPU数据12 使用每个CPU数据的原因13 分配函数的选择1 页2 区3 获得页获得填充为0的页释放页4 kmalloc()gfp_mask标志kfree()5 vmalloc()6 sl

2022-04-08 11:09:31 461

原创 搜索---广度优先遍历、深度优先遍历、回溯法

广度优先搜索(BFS)广度优先搜索是按层来处理顶点的,距离开始点最近的那些顶点首先被访问,而最远的那些顶点则最后被访问。BFS的代码使用了一个队列。搜索的步骤:首先选择一个顶点作为起始顶点,将起始顶点放入队列中从队列首部选出一个顶点,将与之相邻并且没有被访问的结点依次加入到队列的队尾,然后访问这些与之相邻并且没有被访问过的结点,将队列队首的结点删去。按照步骤2处理队列中下一个结点,直到找到要找的结点或者队列中没有结点结束。void BFS(){ 定义队列; 定义备忘录,用于记

2022-04-05 21:27:11 2227

原创 UNIX环境高级编程---进程间通信总结

进程间通信1 管道匿名管道命名管道2 消息队列3 信号量4 共享内存5 信号6 套接字总结Linux下的进程通信机制叫做IPC(InterProcess Communication),在Linux下有6大通信的方法,分别是:Socket、管道、信号、信号量、消息队列、共享内存。每个进程的用户地址空间都是独立的,一般而言是不能互相访问的,但内核空间是每个进程都共享的,所以进程之间要通信必须通过内核。1 管道匿名管道匿名管道是在内核中申请一块固定大小的缓冲区,程序拥有写入和读取的权利。匿名管道是半双

2022-04-01 16:25:00 1169

原创 Linux内核设计与实现---内核同步方法

内核同步方法1 原子操作原子整数操作原子位操作2 自旋锁其他针对自旋锁的操作自旋锁和下半部3 读-写自旋锁4 信号量创建和初始化信号量使用信号量5 读-写信号量6 自旋锁和信号量7 完成变量8 BKL9 禁止抢占10 顺序和屏障1 原子操作原子整数操作原子位操作2 自旋锁其他针对自旋锁的操作自旋锁和下半部3 读-写自旋锁4 信号量创建和初始化信号量使用信号量5 读-写信号量6 自旋锁和信号量7 完成变量8 BKL9 禁止抢占10 顺序和屏障...

2022-04-01 15:37:24 1946

转载 基于Hash表的排序--C语言

我们知道,C语言里面是没有hash表的,但是我们可以用一个结构体表示,对结构体排序,我们可以用qsort排序。下面我们用一个LeedCode上面的一道题目讲解。347. 前 K 个高频元素这个题目是让我们求解前k个高频元素,求解思路如下:我们构建一个Hash表,Hash表用一个结构体表示,该结构体存放元素值和元素的个数,我们先把数组里面的值存放到Hash表里面,然后我们对该Hash表按照元素个数进行进行排序,这样就可以找到前k个高频元素了。1 定义Hash表#define Hash_SIZE 20

2022-03-28 21:51:13 691

原创 Mac VSCode配置C语言环境(可以调试)

Mac VSCode配置C语言环境c_cpp_properties.jsontasks.jsonlaunch.json新建一个文件夹,用vscode,然后再新建一个test.c文件。#include <stdio.h>int main(void){ int a=1,b=1; int c=a+b; printf("%d\n",c); return 0;}这篇文章说怎么配置c_cpp_properties.json、tasks.json、launch.

2022-03-26 20:34:14 11544 6

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除