摘要: 概述 本文主要介绍SYN Flood攻击的原理,以及防火墙设备的防御手段; TCP三次握手 TCP建立连接过程需要经过三次握手,在三次握手成功之后,建立连接,进而进行数据传输;假设有客户端和服务器,客户端向服务器发起连接请求: (1) 客户端向服务器发送SYN报文; (2) 服务器收到SYN之后向客 阅读全文
posted @ 2019-10-29 22:27 AlexAlex 阅读(1054) 评论(0) 推荐(0)
摘要: DOS攻击 DOS攻击是Denial of Service的简称,即拒绝服务攻击;其主要通过洪水攻击的方式,耗尽目标机器的资源或者网络带宽,造成服务服务中断或者停止;DOS攻击攻击源为单一电脑; DDOS攻击 DDOS攻击是Distributed Denial of Service的缩写,即分布式拒 阅读全文
posted @ 2019-10-29 22:25 AlexAlex 阅读(684) 评论(0) 推荐(0)
摘要: 0. 权重 进程的优先级与内核的nice值对应,nice值降低对应权重增加; 内核根据进程类型和静态优先级计算权重值; 内核不仅维护进程自身的权重,还维护调度队列的权重,当进程被加入到调度队列时,也要该进程的权重增加到队列权重中; 1. 完全公平调度延时周期 内核可以通过参数sysctl_sched 阅读全文
posted @ 2019-10-29 22:22 AlexAlex 阅读(473) 评论(0) 推荐(0)
摘要: 内中调度器分为周期性调度器和主调度器,他们是调度工作的主体,而更为详细的调度根据策略的不同交给不同的调度类,比如交给公平调度类; 周期性调度器: 周期调度器按照一定的频率周期性的运行,除了进行调度相关的数据统计之外,还会激活具体进程调度类的周期性调度方法; 在完全公平调度类的周期性调度方法中,首先更 阅读全文
posted @ 2019-10-29 22:21 AlexAlex 阅读(649) 评论(0) 推荐(0)
摘要: 总览 进程调度的总览图如下,当进程被标记为运行状态时,会加入到就绪队列中;队列中的调度实体(进程)维护自己的虚拟时间,该虚拟时间与就绪队列虚拟时间的差值作为红黑树的键值,将调度实体存入红黑树中,其中左下节点为键值最小的节点,最急需被调度,越向右节点的优先级越低; 调度子系统总图如下,进程调度激活有两 阅读全文
posted @ 2019-10-29 22:06 AlexAlex 阅读(417) 评论(0) 推荐(0)
摘要: 在单处理器系统上,在给定时刻只有一个程序可以运行,在多处理器系统上,可以真正并行运行的进程数据,取决于物理CPU的数目; 进程优先级 在比较粗糙的划分中,进程分为实时进程和非实时进程; 1. 硬实时进程具有严格的时间限制,某些任务必须在指定的时间内完成; 2. 软实时进程是硬实时进程的一种弱化形式, 阅读全文
posted @ 2019-10-29 21:59 AlexAlex 阅读(484) 评论(0) 推荐(0)
摘要: 负载均衡(Load Balance,简称LB)是一种服务器或网络设备的集群技术。负载均衡将特定的业务(网络服务、网络流量等)分担给多个服务器或网络设备,从而提高了业务处理能力,保证了业务的高可用性。负载均衡基本概念有:实服务、实服务组、虚服务、调度算法、持续性等,其常用应用场景主要是服务器负载均衡, 阅读全文
posted @ 2019-10-29 21:56 AlexAlex 阅读(581) 评论(0) 推荐(0)
摘要: 中断和锁 1. 硬中断和软中断(包括tasklet和timer)共享数据,硬中断中使用spin_lock/spin_unlock,软中断中使用spin_lock_irq/spin_unlock_irq或者spin_lock_irqsave/spin_unlock_irqrestore; 硬中断可以打 阅读全文
posted @ 2019-10-29 21:52 AlexAlex 阅读(2613) 评论(0) 推荐(0)
摘要: 工作队列可以把工作推后,交给一个内核线程去执行–这个下半部分总是会在进程上下文中执行;通过工作队列执行的代码占尽进程上下文的优势;最重要的是工作队列允许重新调度甚至睡眠; 在工作队列和软中断/tasklet中做出选择很容易;如果推后执行的任务需要睡眠,那么就选择工作队列;如果推后执行的任务不需要睡眠 阅读全文
posted @ 2019-10-29 21:50 AlexAlex 阅读(1297) 评论(0) 推荐(0)
摘要: 多数情况下,为了控制一个寻常的硬件设备,tasklet机制都是实现自己下半部的最佳选择;tasklet可以动态创建,使用方便,执行起来还算快; 声明tasklet tasklet既可以静态的创建,也可以动态的创建;如果准备静态的创建一个tasklet,可以使用下面的两个宏之一: 1 #define 阅读全文
posted @ 2019-10-29 21:44 AlexAlex 阅读(624) 评论(0) 推荐(0)
摘要: 软中断保留给系统中对时间要求严格以及最重要的下半部使用;目前,只有两个子系统(网络和SCSI)直接使用软中断;此外,内核定时器和tasklet都是建立在软中断上的;在使用软中断之前,要先确定为什么不能使用tasklet,tasklet可以动态生成,并且对加锁的要求不高,使用起来也很方便,性能也不错; 阅读全文
posted @ 2019-10-29 21:42 AlexAlex 阅读(832) 评论(0) 推荐(0)
摘要: 中断处理程序的局限 1. 中断处理程序以异步的方式执行,并且它有可能会打断其他重要代码的执行,因此,为了避免被打段的代码停止时间过长,中断处理程序应该执行的越快越好; 2. 如果当前有一个中断处理程序在执行,在最好的情况下(没有设置IRQF_DISABLED),与该中断同级别的其他中断就会被屏蔽,在 阅读全文
posted @ 2019-10-29 21:40 AlexAlex 阅读(533) 评论(0) 推荐(0)
摘要: 注册中断处理程序 中断处理程序是管理硬件驱动程序的组成部分;如果设备使用中断,那么相应的驱动程序就注册一个中断处理程序; 驱动程序通过request_irq()函数注册,并且激活给定的中断线,以处理中断;request_irq()函数可能会睡眠,因此,不能再中断上下文或者其他不行允许阻塞的代码中调用 阅读全文
posted @ 2019-10-29 21:37 AlexAlex 阅读(1502) 评论(0) 推荐(0)
摘要: 中断 中断使得硬件可以发出通知给处理器,本质上是一种特殊的电信号,由硬件设备发向处理器,处理器接收到中断后,会马上向操作系统反应此信号的到来,然后就由操作系统负责处理这些新来的数据;硬件设备生成中断并不考虑与处理器的始终同步,中断可能随时产生,内核随时都有可能被中断打断; 不同设备的中断不同,而每个 阅读全文
posted @ 2019-10-29 21:33 AlexAlex 阅读(830) 评论(0) 推荐(0)
摘要: 数组形式 支持SMP的现代操作系统使用每个cpu上的数据,对于给定的处理器其数据是唯一的;一般来说,每个cpu的数据存放在一个数组中,数组总的每一项对应着系统上的一个存在的处理器;按当前处理器号确定这个数组的当前元素;使用方式如下: 1 unsigned long my_percpu[NR_CPUS 阅读全文
posted @ 2019-10-29 21:32 AlexAlex 阅读(2229) 评论(0) 推荐(0)
摘要: vmalloc()函数的工作方式类似于kmalloc(),只不过在前者分配的内存虚拟地址是连续的,而物理地址则无须连续;这也是用户空间分配函数的工作方式:由malloc()返回的页在进程的虚拟地址空间是连续的,但是,这并不保证它们在物理RAM中也是连续的;kmalloc()函数确保页在物理地址上是连 阅读全文
posted @ 2019-10-29 19:43 AlexAlex 阅读(536) 评论(0) 推荐(0)
摘要: get_free_page 如果模块需要分配大块的内存,使用面向页的分配会有很多优点; 分配页面可使用下面的函数: 1 unsigned long get_zeroed_page(gfp_t gfp_mask) 返回指向新页面的指针并将页面清零; 1 unsigned long __get_free 阅读全文
posted @ 2019-10-29 19:41 AlexAlex 阅读(3470) 评论(0) 推荐(0)
摘要: 内核中有些地方的内存分配是不允许失败的,为了确保这种情况下的成功分配,内核开发者建立了一种称为内存池的抽象;内存池其实就是某种形式的后备高速缓存,它试图始终保存空闲的内存,以便在紧急状态下使用; mempool会分配一些内存块,空闲且不会真的得到使用;因此,使用mempool很容易浪费大量内存;几乎 阅读全文
posted @ 2019-10-29 19:35 AlexAlex 阅读(685) 评论(0) 推荐(0)
摘要: 设备驱动程序常常会反复的分配很多相同大小的内存块;内核实现了后备高速缓存来对此进行支持,以反复的使用这些相同的内存块; 创建 Linux内核的高速缓存管理有时被称为“slab分配器”;因此,相关函数和类型在<linux/slab.h>中声明;slab分配器实现的告诉缓存具有kmem_cache类型; 阅读全文
posted @ 2019-10-29 19:32 AlexAlex 阅读(543) 评论(0) 推荐(0)
摘要: 原型 kmalloc的原型如下: 1 void *kmalloc(size_t size, gfp_t flags) 第一个参数是要分配的块的大小,第二个参数是分片标志; flags标志 最常用的标志是GFP_KERNEL,表示内存分配(最终总是调用get_free_page来实现实际的分配,这就是 阅读全文
posted @ 2019-10-29 19:17 AlexAlex 阅读(1202) 评论(0) 推荐(0)
摘要: 综述 如果需要在将来的某个时间点调度执行某个动作,同时在该时间点到达之前不会阻塞当前进程,则可以使用内核定时器; 内核定时器是一个数据结构,它告诉内核在用户定义的时间点使用用户定义的参数来执行一个用户定义的函数; 被调度运行的函数几乎肯定不会再注册这些函数的进程正在执行时运行,相反,这些函数会异步的 阅读全文
posted @ 2019-10-29 19:15 AlexAlex 阅读(680) 评论(0) 推荐(0)
摘要: 长延迟 有些驱动程序需要延迟比较长的时间,即长于一个时钟滴答; 忙等待 如果想把执行延迟若干个时钟滴答,或者对延迟的精度要求不高,最简单的实现方法就是一个监视jiffies计数器的循环;这种忙等待的实现方法通常具有下面形式,其中j1是延迟终止的jiffies值: 1 while (time_befo 阅读全文
posted @ 2019-10-29 19:14 AlexAlex 阅读(1779) 评论(0) 推荐(0)
摘要: 墙上时间 内核一般通过jiffies来获取当前时间,该数值表示的是最近一次系统启动到当前的时间间隔,它和设备驱动程序无关,因为它的声明期只限于系统的运行期;但是驱动程序可以用jiffies来计算不同事件之间的间隔;通常,利用jiffies值来测量时间间隔已经足够了,如果要测量更短的时间差,只能使用处 阅读全文
posted @ 2019-10-29 19:09 AlexAlex 阅读(3254) 评论(0) 推荐(0)
摘要: 概述 内核通过定时器中断来跟踪事件流; 时钟中断由系统定时硬件以及周期性的间隔产生,这个间隔由内核根据HZ的值设定,HZ是一个细节结构有关的常数;作为一般性规则,即使知道对应平台上的确切HZ值,也不应该在编程时依赖该HZ值; 如果想改变系统时钟中断发生的频率,可以通过修改HZ值来进行,但是,如果修改 阅读全文
posted @ 2019-10-29 19:06 AlexAlex 阅读(718) 评论(0) 推荐(0)
摘要: 尽管大多数时候阻塞型和非阻塞型操作的组合以及select方法可以有效的查询设备,但是某些时候用这种技术处理就效率不搞了; 例如:一个进程在低优先级执行长的循环计算,但又需要尽可能快的处理输入数据,如果该进程正在响应来自数据收集外设新观测的数据,则应该在新数据可用时理解知晓并处理;我们可以使用poll 阅读全文
posted @ 2019-10-29 19:01 AlexAlex 阅读(609) 评论(0) 推荐(0)
摘要: 使用非阻塞IO的应用程序经常使用select,poll,epoll系统调用;它们的功能本质上是一样的:都允许进程决定是否可以对一个或者多个打开的文件做非阻塞的读取或者写入;这些电泳也会阻塞进程,直到给定的文件描述符中的任何一个可读取或者写入;因此,它们常常用于那些需要使用多个输入或者输出流而又不会阻 阅读全文
posted @ 2019-10-29 18:59 AlexAlex 阅读(1148) 评论(0) 推荐(0)
摘要: 休眠简介 当一个进程被置入休眠时,它会被标记为一种特殊状态,并从调度器的运行队列中移走;直到某些情况下修改了这个状态,进程才会在任意cpu上调度,即运行该进程;休眠中的进程会被搁置在一边,等待将来的某个时间发生; 为了将进程以一种安全方式进入休眠,需要牢记下面的规则: 第一条规则,永远不要在原子上下 阅读全文
posted @ 2019-10-29 18:57 AlexAlex 阅读(1526) 评论(0) 推荐(0)
摘要: ioctl 除了读取和写入设备之外,大部分驱动程序还需要另外一种能力,即通过设备驱动程序执行各种类型的硬件控制,通常这种需求使用ioctl方法支持,该方法实现了同名的系统调用; 在用户空间,ioctl系统调用的原型如下: 1 int ioctl(int d, int request, ...); 原 阅读全文
posted @ 2019-10-29 18:52 AlexAlex 阅读(2271) 评论(0) 推荐(0)
摘要: 读取-复制-更新(read-copy-update,RCU)是一种高级的互斥机制,在正确的条件下,可以获得高的性能; RCU对它保护的数据结构做了一些限定,它针对经常发生读而很少发生写的情况做了优化,被保护的资源应该通过指针访问,而对这些资源的引用必须仅由原子代码拥有,在RCU保护的代码范围内不能进 阅读全文
posted @ 2019-10-29 18:48 AlexAlex 阅读(523) 评论(0) 推荐(0)
摘要: 当要保护的资源很小,很简单,会频繁的被访问而且写入访问很少的且必须快速时(即读不允许让写饥饿),就可以使用顺序锁(seqlock);从本质上讲,顺序锁会允许读取者对资源的自由访问,但需要读取者检查是否和写入者发生冲突,当这种冲突发生时,就需要重试对资源的访问; 顺序锁通常不能用于保护包含指针的数据结 阅读全文
posted @ 2019-10-29 18:46 AlexAlex 阅读(388) 评论(0) 推荐(0)
摘要: 原子整数操作 当共享资源是一个简单的整数值时,可以使用内核提供的一种原子的整数类型,称为atomic_t,定义在<linux/types.h>中,操作定义在<linux/atomic.h>中; 原子位操作 内核提供了一组针对原子位进行操作的函数,它们与体系结构相关,定义在文件<asm/bitops. 阅读全文
posted @ 2019-10-29 18:38 AlexAlex 阅读(459) 评论(0) 推荐(0)
摘要: 概念 自旋锁可以再不能休眠的代码中使用,比如中断处理例程;在正确使用的情况下,自旋锁通常可以提供比信号量更高的性能; 一个自旋锁是一个互斥设备,它只能由两个值,锁定和解锁;通常实现为某个整数值中的单个位;希望获得特定锁的代码测试相关位,如果锁可用,则锁定位被设置,而嗲吗继续进入临界区;相反,如果锁被 阅读全文
posted @ 2019-10-29 18:36 AlexAlex 阅读(989) 评论(0) 推荐(0)
摘要: 内核编程中常见的一种模式是,在当前线程之外初始化某个活动,然后等待该活动的结束;这个活动可能是,创建一个新的内核线程或者新的用户空间进程、对一个已有进程的某个请求,或者某种类型的硬件动作等; 内核提供了完成量(completion)来完成上述需求;完成量是一个轻量级的机制,它允许一个线程告诉另一个线 阅读全文
posted @ 2019-10-29 16:55 AlexAlex 阅读(1577) 评论(0) 推荐(0)
摘要: 概念 一个信号量本质是一个整数值,它和一堆函数联合使用,这一对函数通常称为P和V;希望进入临界区的进程将在相关信号量上调用P;如果信号量的值大于零,则该值会减少1,进程可以继续执行;相反,如果信号量的值为0或者更小,则进程必须等待知道其他人释放该信号量;对信号量的解锁通过调用V完成;该函数增加信号量 阅读全文
posted @ 2019-10-29 16:49 AlexAlex 阅读(686) 评论(0) 推荐(0)
摘要: 竞态产生 Linux系统找那个存在大量的并发联系,因此会导致可能的竞态; 1. 正在运行的用户空间进程可以以多种组合方式访问我们的代码; 2. SMP系统甚至可以再不同的处理器上同时执行我们的代码; 3. 内核代码是可抢占的,因此,我们的驱动程序代码可能在任何时候丢失对处理器的独占,而拥有处理器的进 阅读全文
posted @ 2019-10-29 16:46 AlexAlex 阅读(328) 评论(0) 推荐(0)
摘要: read和write原型 read和write方法完成的任务是相似的,亦即,拷贝数据到应用程序空间,或者反过来从应用程序空间拷贝数据;因此,它们的原型很相似,如下: 1 ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); 阅读全文
posted @ 2019-10-29 16:45 AlexAlex 阅读(2745) 评论(0) 推荐(0)
摘要: open方法 open方法提供给驱动程序以初始化的能力,在大部分驱动程序汇总,open应该完成以下工作: 1. 检查特定设备的错误,如设备为准备就绪或者硬件问题; 2. 如果设备是首次打开,则对其进行初始化; 3. 如有必要,更新f_op指针; 4. 分配并填写置于filp->private_dat 阅读全文
posted @ 2019-10-29 16:43 AlexAlex 阅读(3464) 评论(0) 推荐(0)
摘要: 内核内部使用struct cdev结构来标识字符设备,在内核调用设备的操作之前,必须分配并注册一个或者多个上述结构,为此,我们的代码需要包含<linux/cdev.h>,其中定义了这个结构以及相关的辅助函数; 分配和初始化 分配和初始化上述结构的方式分为两种: 1. 如果打算在运行的时候获取一个独立 阅读全文
posted @ 2019-10-29 16:41 AlexAlex 阅读(731) 评论(0) 推荐(0)
摘要: 文件对象 文件对象是进程已经打开文件描述符的内存中的表示,单个文件可能有多个表示打开文件描述符的file结构; 1 struct file { 2 union { 3 struct llist_node fu_llist; /* 文件对象链表 */ 4 struct rcu_head fu_rcuh 阅读全文
posted @ 2019-10-29 16:39 AlexAlex 阅读(471) 评论(0) 推荐(0)
摘要: 主设备号和次设备号 对字符设备的访问是通过文件系统内的设备名称进行的,这些名称被称为特殊文件、设备文件、或者简单称之为文件系统树的节点,它们通常位于/dev目录。字符设备驱动程序的设备文件可以通过ls -l命令输出的第一列中的c字符来识别,块设备也出现在/dev下,但它们由字符b来标识; 通过执行l 阅读全文
posted @ 2019-10-29 16:36 AlexAlex 阅读(2693) 评论(0) 推荐(0)
摘要: 模块支持参数的方法 内核允许驱动程序指定参数,这些参数可在运行insmod或者modprobe命令装载模块时赋值,modprobe还可以从它的配置文件(/etc/modporb.conf)中读取参数值; insmod加载模块时指定参数的方式如下: 1 insmod hellop howmany=10 阅读全文
posted @ 2019-10-29 16:33 AlexAlex 阅读(864) 评论(0) 推荐(0)
摘要: insmod使用公共内核符号表来解析模块中未定义的符号。功能内核符号表中包含了所有全局内核项(函数和变量)的地址,这是实现模块化驱动程序所必须的。当模块装载到内核后,它所导出的任何符号都会变成内核符号表的一部分。通常情况下,模块只需要实现自己的功能,无需导出任何符号,但是如果其他模块想要使用该模块的 阅读全文
posted @ 2019-10-29 16:31 AlexAlex 阅读(1107) 评论(0) 推荐(0)