linux内核
liujun01203
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
分配DMA缓冲区
使用DMA缓冲区的主要问题是:当大于一页时,它们必须占据连续的物理页,这是因为设备使用ISA或者PCI系统总线传输数据,而这两种方式使用的都是物理地址。虽然既可以在系统启动时,也可以在运行时分配DMA缓冲区,但是模块只能在运行时刻分配它们的缓冲区。驱动程序作者必须谨慎地为DMA操作分配正确的内存类型,因为并不是所有内存区间都适合DMA操作。在实际操作中,一些设备和一些系统中高端内存不能用于DMA,这是因为外围设备不能使用高端原创 2010-07-26 09:00:00 · 985 阅读 · 1 评论 -
调度程序的负载平衡
<br /> Linux的调度程序为对称多处理系统的每个处理器准备了单独的可执行队列和锁。也就是说,每个处理器拥有一个自己的进程链表,而它只对属于自己的这些进程进行调度操作。出去效率的考虑,整个调度系统从每个处理器来看都是独立的。那么,针对对称多处理系统,调度程序有没有提供什么加强型的策略来提升整体的调度呢?如果可执行队列间出现负载不均衡的情况时,比如一个处理器的队列上有五个进程,而另外一个处理器的队列上只有一个进程。该怎么办呢?这些问题由负载平衡程序解决,它负责保证可执行队列之间的负载处于均衡状原创 2010-08-30 14:29:00 · 523 阅读 · 0 评论 -
上下文切换
<br /><br />上下文切换,也就是从一个可执行进程切换到另一个可执行进程,由定义在kernel/sched.c中的context_switch()函数负载处理。每当一个新的进程被选出来准备投入运行的时候,schedule()就会调用该函数。它完成了两项基本的工作:<br />调用定义在include/asm/mmu_context.h中的switch_mm(),该函数负责把虚拟内存从上个进程切换到新进程中。<br />调用定义在include/asm/system.h中的switch_t原创 2010-08-30 16:06:00 · 479 阅读 · 0 评论 -
与处理器绑定有关的系统调用
<br /><br /> Linux调度程序提供强制的处理器绑定机制。也就是说,虽然它尽力通过一种软的或者说自然的亲和性试图使进程尽量在同一个处理器上运行。但它也允许用户强制指定“这个进程无论如何必须在这些处理器上运行。”这种强制的亲和性保存在进程task_struct的cpu_allowed这个位掩码标志中。该掩码标志的每一位对应一个系统可用的处理器。 默认情况下,所有的位都被设置,进程可以在系统中所有可用的处理器上执行。用户可以通过sched_setaffinity()设置一个不同的一个或几原创 2010-08-30 14:30:00 · 447 阅读 · 0 评论 -
内核抢占VS用户抢占
<br />用户抢占<br />内核即将返回用户空间的时候,如果need_resched被设置,会导致schedule()被调用,此时就会发生用户抢占。在内核返回用户空间的时候,它知道自己是安全的,因为既然它可以继续去执行当前进程,那么它当然可以再去选择一个新的进程去执行。所以内核无论是从中断处理程序还是在系统调用后返回,都会检查need_resched标志。如果它被设置了,那么,内核就会选择一个其他(更合适的)进程投入运行。从中断处理程序或系统调用返回的代码都是跟体系结构相关的,在entry.S文件中原创 2010-08-30 15:22:00 · 1652 阅读 · 0 评论 -
共享的中断处理程序
<br />共享的中断处理程序和非共享的中断处理程序差异主要有以下三处:<br />1)request_irq()参数的flags必须设置为SA_SHIRQ标志;<br />2)对每个注册的中断处理程序来说,dev_id参数必须唯一。指向任一设备结构的指针就可以满足这一要求;通常会选择设备结构,因为它是唯一的,而且中断处理程序可能会用到它。不能给共享的处理程序传递NULL值。<br />3)中断处理程序必须能够区分它的设备是否真的产生了中断。这既需要硬件的支持,也需要处理程序中有相关的处理逻辑。原创 2010-09-02 17:04:00 · 441 阅读 · 0 评论 -
中断控制
<br /> Linux内核提供了一组接口用于操作机器上的中断状态。这些接口为我们提供了能够禁止当前处理器中的中断系统,或屏蔽掉整个机器中的一条中断线的能力,这些例程都是与体系结构相关的,可以在<asm/system.h>和<asm/irq.h>中找到。<br /> 一般来说,控制中断系统的原因归根结底是需要提供同步。通过禁止中断,可以确保某个中断处理程序不会抢占当前的代码。此外,禁止中断还可以禁止内核抢占。然而,不管是禁止中断还是禁止内核抢占,都没有提供任何保护机制来防止来自其他原创 2010-09-03 08:38:00 · 372 阅读 · 0 评论 -
I/O调度程序
<br /><br />如果简单地以内核产生请求的次序直接将请求发向块设备的话,性能肯定让人难以接受。磁盘寻址是整个计算机中最慢的操作之一,每一次寻址---定位硬盘磁头到特定块上的某个位置---需要花费不少时间。所以尽量缩短寻址时间无疑是提高系统性能的关键。<br />为了优化寻址操作,内核既不会简单的按请求接收次序,也不会立即将其提交给磁盘。相反,它会在提交前,先执行名为合并和排序的预操作,这中预操作可以极大地提高系统的整体性能。在内核中负责提交I/O请求的子系统被称为I/O调度程序。<br />原创 2010-08-31 19:59:00 · 1126 阅读 · 0 评论 -
几个重要的Linux操作系统 内核文件介绍
在网络中,不少服务器采用的是Linux系统。为了进一步提高服务器的性能,可能需要根据特定的硬件及需求重新编译Linux内核。编译Linux内核,需要根据规定的步骤进行,编译内核过程中涉及到几个重要的文件。比如对于RedHat Linux,在/boot目录下有一些与Linux内核有关的文件,进入/boot执行:ls –l。编译过RedHat Linux内核的人对其中的System.map 、vmlinuz、initrd-2.4.7-10.img印象可能比较深刻,因为编译内核过程中涉及到这些文件的建立等操作原创 2010-09-21 13:51:00 · 475 阅读 · 0 评论 -
__attribute__ 属性之constructor/destructor
<br />#include<stdio.h><br /><br />void __attribute__( (constructor) ) display()<br />{<br /> printf("hello world!/n");<br />}<br /><br /><br />void __attribute__((destructor)) print()<br />{<br /> printf("exit /n");<br />}<br /><br />原创 2010-10-13 11:13:00 · 677 阅读 · 0 评论 -
page_address()函数分析--如何通过page取得虚拟地址
<br />由于X86平台上面,内存是划分为低端内存和高端内存的,所以在两个区域内的page查找对应的虚拟地址是不一样的。<br /><br />一. x86上关于page_address()函数的定义<br /><br />在include/linux/mm.h里面,有对page_address()函数的三种宏定义,主要依赖于不同的平台:<br /><br />首先来看看几个宏的定义:<br />CONFIG_HIGHMEM:原创 2010-10-11 10:28:00 · 2403 阅读 · 0 评论 -
软连接VS硬链接
<br />首先要弄清楚,在Linux系统中,内核为每一个新创建的文件分配一个Inode(索引结点),每个文件都有一个惟一的inode号。文件属性保存在索引结点里,在访问文件时,索引结点被复制到内存在,从而实现文件的快速访问。 <br />链接是一种在共享文件和访问它的用户的若干目录项之间建立联系的一种方法。Linux中包括两种链接:硬链接(Hard Link)和软链接(Soft Link),软链接又称为符号链接(Symbolic link)。 <br />一、硬链接<br />硬链接说白了是一个指针,指向原创 2010-08-26 11:43:00 · 391 阅读 · 0 评论 -
并发控制经验之谈
多年使用锁的经验说明,我们很难驾轻就熟地使用锁。并发的管理本来就非常棘手,而许多使用方法都可能导致错误。本文将总结一些并发控制中容易导致错误的东西。不明确的规则: 恰当的锁定模式需要清晰和明确的规则。当我们创建一个可被并行访问的对象时,应该同时定义用来控制访问的锁。锁定模式必须在一开始就安排好,否则其后的改进将会非常困难。先期的时间投入通常会在调试阶段获得收益。在编写代码时肯定会遇到几个函数,它们均需要访问某个受特定锁保护的结构。这时。我们必须小心:如果某个获得锁的函数要调用其它同样试图获取这个锁的函数。我原创 2010-08-11 11:43:00 · 278 阅读 · 0 评论 -
并发的来源
<br />在现代Linux系统中存在大量的并发来源。比如正在运行的多个用户空间进程可能以一种令人惊讶的组合方式访问我们的代码。SMP系统甚至可在不同的处理器上同时执行我们的代码。内核代码是可抢占的;因此,我们的内核代码可能在任何时候(非原子上下文)丢失对处理器的独占,而拥有处理器的进程可能正在调用我们的内核代码。设备中断是异步事件,也会导致代码的并发执行。内核还提供了许多可延迟代码执行的机制,比如workqueue、tasklet以及timer等,这些机制使得代码可在任何时刻执行,而不管当前进程在做什么。原创 2010-08-11 08:53:00 · 232 阅读 · 0 评论 -
获取大的缓冲区
<br />内核在获取大的、连续内存缓冲区时易于失败。这是因为系统内存会随着时间的流逝而碎片化,这将导致无法获得真正的大内存区域。因为,不需要大的缓冲区也可以有其他途径来完成自己的工作,因此内和开发者并没有大缓冲区分配工作作为高优先级的任务来计划。在试图获得大内存区之前,我们应该仔细考虑其他的实现途径。到目前为止,执行大的I/O操作的最好方式是通过离散/聚集操作。原创 2010-07-26 10:24:00 · 172 阅读 · 0 评论 -
在引导时获得专用缓冲区
<br />如果的确需要连续的大块内存作为缓冲区,就最好在系统引导期间通过请求内存来分配。这也是获得大量连续内存页面的唯一方法,他绕过了__get_free_pages函数在缓冲区大小上的最大尺寸和固定粒度的双重限制。 模块不能在引导时分配内存,而只有直接连接到内核的设备驱动程序才能在引导时分配内存。<br />内和被引导时,它可以访问系统所有的物理内存,然后调用各个子系统的初始化函数进行初始化,它允许初始化代码分配私有的缓冲区,同时减少了留给常规系统操作的RAM数量。原创 2010-07-26 12:36:00 · 245 阅读 · 0 评论 -
长度为0的数组——C语言的非标准用法之一
在标准C和C++中,长度为0的数组是被禁止使用的。不过在GNU C中,存在一个非常奇怪的用法,那就是长度为0的数组,比如Array[0];很多人可能觉得不可思议,长度为0的数组是没有什么意义的,不过在这儿,它表示的完全是另外的一层意思,这个特性是不可移植的,所以,如果你致力于编写可移植,或者是稍稍需要跨平台的代码,这些Trick最好还是收起来的好。 在GNU的指南中,它是如此写道: struct line { int length;原创 2010-07-27 09:23:00 · 757 阅读 · 0 评论 -
内存分配
<br />kmalloc:它和malloc相似,除非被阻塞,否则这个函数勊运行得很快,而且不对所获取的空间清零,也就是说,分配给它的区域仍然保持着原有的数据。它分配的区域在物理内存中也是连续的。<br />void *kmalloc(size_t size, int flags) : 第一个参数是要分配的快的大小,第二个参数是分配标志,分配标志可以控制kmalloc的行为。<br /> <br />关于size参数: Linux处理内存分配的方法是,创建一系列的内存对象池,每个池中的内存块大小是固定一致的原创 2010-07-27 10:46:00 · 251 阅读 · 0 评论 -
在引导时获得专用缓冲区
<br />如果的确需要连续的大块内存作为缓冲区,就最好在系统引导期间通过请求内存来分配。这也是获得大量连续内存页面的唯一方法,他绕过了__get_free_pages函数在缓冲区大小上的最大尺寸和固定粒度的双重限制。 模块不能在引导时分配内存,而只有直接连接到内核的设备驱动程序才能在引导时分配内存。<br />内和被引导时,它可以访问系统所有的物理内存,然后调用各个子系统的初始化函数进行初始化,它允许初始化代码分配私有的缓冲区,同时减少了留给常规系统操作的RAM数量。原创 2010-07-26 10:41:00 · 282 阅读 · 0 评论 -
通用DMA层
<br /> DMA操作最终会分配缓冲区, 并将总线地址传递给设备。一个可移植的驱动程序要求对所有体系架构都能安全而正确地执行DMA操作,编写这样一个驱动程序的难度超出了一般人的想象。不同的系统对处理缓存一致性上有不同的方法;如果不能正确处理该问题,驱动程序会引起内存冲突 。一些系统拥有复杂的总线硬件,使得DMA任务或变得简单,或变得困难。并且不是所有的系统都能对全部的内存执行DMA。幸运的是,内和提供了一个与总线——体系架构无关的DMA层,它会隐藏大多数问题。强烈建议编写驱动程序时,为DM原创 2010-07-26 12:46:00 · 285 阅读 · 0 评论 -
md中线程线程创建模型
<br />md中创建线程的过程如下:<br />首先准备一个结构体 mdk_thread_s:<br /> <br />typedef struct mdk_thread_s { void (*run) (mddev_t *mddev); mddev_t *mddev; wait_queue_head_t wqueue; unsigned long flags; struct task_struct *tsk; unsigned long timeou原创 2010-07-27 14:48:00 · 339 阅读 · 0 评论 -
SMP(Symmetrical Multi-Processing)
<br /> 对称多处理"(Symmetrical Multi-Processing)又叫SMP,是指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构。它是相对非对称多处理技术而言的、应用十分广泛的并行技术。在这种架构中,一台电脑不再由单个CPU组成,而同时由多个处理器运行操作系统的单一复本,并共享内存和一台计算机的其他资源。虽然同时使用多个CPU,但是从管理的角度来看,它们的表现就像一台单机一样。系统将任务队列对称地分布于多个CPU之上,从而极大地提高了原创 2010-07-27 13:56:00 · 644 阅读 · 0 评论 -
后备高速缓存
<br />设备驱动程序常常会反复地分配很多同一大小的内存块。既然内核已经维护了一组拥有同一大小内存块的内存池,那么为什么不为这些反复使用的块增加某些特殊的内存池呢?实际上,内核的确实现了这种形式的内存池,通常称为后备高速缓存。设备驱动程序通常不会涉及这种使用后备高速缓存的内存行为,但也有例外,linux2.6中的USB和SCSI驱动程序就使用了这种高速缓存。<br />Linux内核的高速缓存管理有时称为“slab分配器”。slab分配器实现的高速缓存具有kmem_cache_t类型,可通过调用kmem_原创 2010-07-28 09:34:00 · 994 阅读 · 0 评论 -
热插拔
<br /><br />热插拔事件的产生<br />一个热插拔事件是从内核空间发送到用户空间的通知,它表明系统配置出现了变化。无论kobject被创建还是被删除,都会产生这种事件。比如当数码相机通过USB线插入到系统时,用户切换控制台终端时,或者当给磁盘分区时,都会产生这类事件。热插拔事件会导致对/sbin/hotplug程序的调用,该程序通过加载驱动程序,创建设备节点,挂载分区,或者其他动作来响应事件。<br />我们要讨论最后一个重要的kobject函数用来产生这些事件。当我们把kobject传递给ko原创 2010-08-02 17:20:00 · 365 阅读 · 0 评论 -
Linux内存管理之高端内存映射
<br />一:引子<br />我们在前面分析过,在linux内存管理中,内核使用3G—>4G的地址空间,总共1G的大小。而且有一部份用来做非连续空间的物理映射(vmalloc).除掉这部份空间之外,只留下896M大小供内核映射到物理地址。通常,我们把物理地址超过896M的区域称为高端内存。内核怎样去管理高端内存呢?今天就来分析这个问题。<br />内核有三种方式管理高端内存。第一种是非连续映射。这我们在前面的vmalloc中已经分析过了,在vmalloc原创 2010-10-11 10:29:00 · 548 阅读 · 0 评论
分享