
linux内核设计与实现
文章平均质量分 83
鱼思故渊
这个作者很懒,什么都没留下…
展开
-
Linux进程间通信--mmap()共享内存(二)
内核怎样保证各个进程寻址到同一个共享内存区域的内存页面1、page cache及swap cache中页面的区分:一个被访问文件的物理页面都驻留在page cache或swap cache中,一个页面的所有信息由struct page来描述。struct page中有一个域为指针mapping ,它指向一个struct address_space类型结构。page cache或swap cac原创 2015-04-20 20:06:49 · 2991 阅读 · 0 评论 -
linux内存使用方法详细介绍
我是一名程序员,那么我在这里以一个程序员的角度来讲解Linux内存的使用。一提到内存管理,我们头脑中闪出的两个概念,就是虚拟内存,与物理内存。这两个概念主要来自于linux内核的支持。Linux在内存管理上份为两级,一级是线性区,类似于00c73000-00c88000,对应于虚拟内存,它实际上不占用实际物理内存;一级是具体的物理页面,它对应我们机器上的物理内存。这里要提到一个很重要的转载 2014-09-23 11:50:09 · 929 阅读 · 0 评论 -
几个系统调用分析 glibc中的malloc调用和共享内存原理
本文主要分析内存以及I/O相关的系统调用和库函数的实现原理,根据原理给出在使用过程中需要注意的问题和优化的侧重点,本文涉及到的系统调用包括readahead,pread/pwrite,read/write,mmap,readv/writev,sendfile,fsync/fdatasync/msync,shmget,malloc。 本文先简单介绍应用程序对内存的使用以及I/O系统对原创 2014-09-23 11:25:19 · 2287 阅读 · 0 评论 -
linux内核CFS进程调度策略
一、概述首先简单介绍一下基本的设计思路,CFS思路很简单,就是根据各个进程的权重分配运行时间(权重怎么来的后面再说)。进程的运行时间计算公式为:分配给进程的运行时间 = 调度周期 * 进程权重 / 所有进程权重之和 (公式1)调度周期很好理解,就是将所有处于TASK_RUNNING态进程都调度一遍的时间,差不多相当于O(1)调度算法中运行队列和过期队列切换一次的时间原创 2014-09-19 22:32:38 · 5482 阅读 · 1 评论 -
linux物理内存和虚拟内存的理解
第一层理解1. 每个进程都有自己独立的4G内存空间,各个进程的内存空间具有类似的结构2. 一个新进程建立的时候,将会建立起自己的内存空间,此进程的数据,代码等从磁盘拷贝到自己的进程空间,哪些数据在哪里,都由进程控制表中的task_struct记录,task_struct中记录中一条链表,记录中内存空间的分配情况,哪些地址有数据,哪些地址无数据原创 2014-09-19 10:59:18 · 1570 阅读 · 0 评论 -
linux系统调用fork()总结(二)
一,进程复制(或产生) 使用fork函数得到的子进程从父进程的继承了整个进程的地址空间,包括:进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端等。子进程与父进程的区别在于:1、父进程设置的锁,子进程不继承(因为如果是排它锁,被继承的话,矛盾了)2、各自的进程ID和父进程ID不同3、子进程的未决原创 2014-09-20 15:22:11 · 5797 阅读 · 0 评论 -
多进程和线程的区别 线程继承的部分
1、首先要明确进程和线程的含义: 进程(Process)是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位。与程序相比,程序只是一组指令的有序集合,它本身没有任何运行的含义,只是一个静态实体。进程是程序在某个数据集上的执行,是一个动态实体。它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而被撤消,反映了一个程序在一定的数据原创 2014-09-20 15:35:18 · 2869 阅读 · 0 评论 -
linux中fork()系统调用总结
由fork创建的新进程被称为子进程(child process)。该函数被调用一次,但返回两次。两次返回的区别是子进程的返回值是0,而父进程的返回值则是新进程(子进程)的进程 id。将子进程id返回给父进程的理由是:因为一个进程的子进程可以多于一个,没有一个函数使一个进程可以获得其所有子进程的进程id。对子进程来说,之所以fork返回0给它,是因为它随时可以调用getpid()来获取自己的pid;原创 2014-09-20 15:11:07 · 2067 阅读 · 0 评论 -
linux内核进程调度CFS 完全公平调度算法分析(一)
cfs调度器的运行时间是0(logN),而以前的调度器的运行时间是O(1),这是不是就是说cfs的效率比O(1)的更差呢?并不是那样,我们知道cfs调度器下的运行队列是基于红黑树组织的,找出下一个进程就是截下左下角的节点,固定时间完成,所谓的O(logN)指的是插入时间,可是红黑树的统计性能是不错的,没有多大概率真的用得了那么多时间,因为红节点和黑节点的特殊排列方式既保证了树的一定程度的平衡,又不转载 2014-09-19 22:21:22 · 1797 阅读 · 0 评论 -
linux内核CFS进程调度策略分析(二)
cfs调度器在2.6.23内核中被引入,起初的实现是多么的天真与纯朴,设计出来一个fair_key来代表队列的虚拟时钟,不管怎样总是实现了一个cfs的版本,到了2.6.25以后,cfs变得简单起来,没有了队列虚拟时钟的结构体,其概念直接融入了红黑树中的最左下角的调度实体的vruntime字段,其实就是让每个调度实体(没有组调度的情形下就是进程,以后就说进程了)的vruntime互相追赶,然后在某个转载 2014-09-19 22:25:20 · 1631 阅读 · 0 评论 -
brk()和sbrk()函数的使用
根据上一篇文章继续解释brk和sbrk的定义 在man手册中定义了这两个函数: 1 #include 2 int brk(void *addr);3 void *sbrk(intptr_t increment); 手册上说brk和sbrk会改变program break的位置,program break被定义为程序data segment的结束位置。感原创 2014-09-23 11:49:08 · 8476 阅读 · 0 评论 -
brk()和sbrk()使用方法解析
brk() , sbrk() 的声明如下:[cpp] view plaincopy#include int brk(void *addr); void *sbrk(intptr_t increment); 首先说明一点 sbrk()是函数库调用,brk()是系统调用这两个函数都用来改变 "program break" (程序间断点)的位置,这个位置可原创 2014-09-23 11:47:45 · 2123 阅读 · 0 评论 -
Linux进程的睡眠和唤醒(一个定时信号唤醒睡眠中的进程)
突然想到Nginx中时间更新这块处理,Nginx中为了减少调用系统调用gettimeofday这个函数(因为一旦调用了系统调用,就会使得进程从用户态切换到内核态,就会发生上下文切换,这个代价很大且不值得)而设置了系统时间更新的次数,内部时间更新有两种方式,一种就是在配置文件中设置更新的评论,另一种是没有设置更新频率,在后面这种情况下,可以使用epoll_wait()这个函数的最后一个参数来控制反复原创 2015-08-20 11:35:56 · 17923 阅读 · 0 评论 -
linux内存管理--linux内核高端内存
Linux内核地址映射模型x86 CPU采用了段页式地址映射模型。进程代码中的地址为逻辑地址,经过段页式地址映射后,才真正访问物理内存。段页式机制如下图。 Linux内核地址空间划分通常32位Linux内核地址空间划分0~3G为用户空间,3~4G为内核空间。注意这里是32位内核地址空间划分,64位内核地址空间划分是不同的。 Linux内核高端内存原创 2014-04-12 20:28:32 · 2849 阅读 · 0 评论 -
Linux进程间通信--mmap共享内存(一)
共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式。两个不同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量都可以。采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。对于像管道和消息原创 2015-04-20 20:03:19 · 6261 阅读 · 0 评论 -
Linux进程间通信--内存映射
一 内存映射概述 从原理上讲,Linux系统利用已有的存储管理机制可以很自然的实现进程间的共享存储。对于一段物理存储空间,只需通过进程的虚存管理机构就可以映射到各自的3G用户地址空间中。通过这种映射,在不同进程看来“私有”的数据事实上是同一段内存单元,它们被这些不同的进程所共享。 在Linux系统实际运行时,内存中原创 2015-04-20 20:22:19 · 3688 阅读 · 1 评论 -
Linux进程间通信--shmget()共享内存(一)
大多数共享内存的具体实现,都是把由不同进程之间共享的内存映射为同一段物理内存。 多个进程都把该物理内存区域映射到自己的虚拟地址空间,这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信。共享内存允许两个不相关的进程访问同一段物理内存, 由于数据不需要在不同的进程间复制,所以它是在两个正在运行的进程之间传递数据的一种非常有效的方式,一个进程向共享内存区域写入数据,共享该原创 2015-04-20 20:19:45 · 5692 阅读 · 0 评论 -
Linux进程间通信--shmget()共享内存(二)
共享内存区域是被多个进程共享的一部分物理内存。如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信。共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。这块共享虚拟内存的页面,出现在每一个共享该页面的进程的页表中。但是它不需要在所有进程的虚拟内存中都有相同原创 2015-04-20 20:18:04 · 2499 阅读 · 0 评论 -
进程分配内存的两种方式--brk() 和mmap()(不设计共享内存)
如何查看进程发生缺页中断的次数? 用ps -o majflt,minflt -C program命令查看。 majflt代表major fault,中文名叫大错误,minflt代表minor fault,中文名叫小错误。 这两个数值表示一个进程自启动以来所发生的缺页中断的次数。发成缺页中断后,执行了那些操作?原创 2014-09-23 11:31:56 · 14945 阅读 · 14 评论 -
linux 内存地址空间管理 mm_struct
Linux对于内存的管理涉及到非常多的方面,这篇文章首先从对进程虚拟地址空间的管理说起。(所依据的代码是2.6.32.60)无论是内核线程还是用户进程,对于内核来说,无非都是task_struct这个数据结构的一个实例而已,task_struct被称为进程描述符(process descriptor),因为它记录了这个进程所有的context。其中有一个被称为'内存描述符‘(memory de原创 2014-09-24 11:14:59 · 2501 阅读 · 1 评论 -
程序(进程)内存分布解析
在多任务操作系统中的每一个进程都运行在一个属于它自己的内存沙盘中。这个沙盘就是虚拟地址空间(virtual address space),在32位模式下它总是一个4GB的内存地址块。这些虚拟地址通过页表(page table)映射到物理内存,页表由操作系统维护并被处理器引用。每一个进程拥有一套属于它自己的页表,但是还有一个隐情。只要虚拟地址被使能,那么它就会作用于这台机器上运行的所有软件,转载 2014-09-23 15:05:23 · 1290 阅读 · 0 评论 -
linux中断--中断上下文&进程上下文
内核空间和用户空间是现代操作系统的两种工作模式,内核模块运行在内核空间,而用户态应用程序运行在用户空间。它们代表不同的级别,而对系统资源具有不同的访问权限。内核模块运行在最高级别(内核态),这个级下所有的操作都受系统信任,而应用程序运行在较低级别(用户态)。在这个级别,处理器控制着对硬件的直接访问以及对内存的非授权访问。内核态和用户态有自己的内存映射,即自己的地址空间。处理器总处于以下状态中的原创 2013-09-30 07:53:01 · 6401 阅读 · 0 评论 -
linux内存管理--进程在内存中的分布
一、进程与内存 所有进程(执行的程序)都必须占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等。不过进程对这些内存的管理方式因内存用途不一而不尽相同,有些内存是事先静态分配和统一回收的,而有些却是按需要动态分配和回收的。对任何一个普通进程来讲,它都会涉及到5种不同的数据段;代码段:代码段是用来存放可执行文件的操作指令,也就是说是它是可执行程原创 2013-09-26 10:51:43 · 8378 阅读 · 1 评论 -
linux中断--中断嵌套&中断请求丢失
关于中断嵌套:在linux内核里,如果驱动在申请注册中断的时候没有特别的指定,do_irq在做中断响应的时候,是开启中断的,如果在驱动的中断处理函数正在执行的过程中,出现同一设备的中断或者不同设备的中断,这时候新的中断会被立即处理,还是被pending,等当前中断处理完成后,再做处理。在2.4和2.6内核里,关于这一块是否有什么不同。一般申请中断的时候都允许开中断,即不使用SA_I原创 2014-04-14 20:06:04 · 10641 阅读 · 0 评论 -
linux内核分析--浅析中断处理机制解析
linux内核--中断和中断处理(一)linux内核--中断和中断处理(二)linux内核--中断处理程序linux内核--中断嵌套&ARM中断来源linux内核分析--中断中的下半部linux内核分析--中断和中断处理程序linux内核分析--中断的分类原创 2014-04-12 14:47:50 · 1655 阅读 · 0 评论 -
linux内存管理--内存管理机制综述
在理解linux内存管理之前需要知道80x86的分段和分页单元把逻辑地址转换为物理地址的有关内容。整个系统的性能取决于如何优先地管理动态内存。从两个角度介绍:连续物理内存处理、非连续内存区的处理。一、页框管理 Linux采用4KB页框大小作为标准的内存分配单元。内核把物理页作为内存管理的基本单位。内存管理单元(MMU,管理内存并把虚拟地址转换为物理地址的硬件)通常以页为单位进行处理。原创 2013-09-25 22:27:15 · 3922 阅读 · 0 评论 -
linux内存管理---物理地址、线性地址、虚拟地址、逻辑地址之间的转换
这几个地址之间的转换原创 2013-07-31 15:14:37 · 5212 阅读 · 4 评论 -
linux中断--LINUX中断机制与信号
在学习APUE时学习信号编程,很多地方不是理解,便查阅了网络上的相关资料,最常见的一句话就是“信号是中断机制的一种模拟”,既然提到了中断,那就首先了解了一下中断的具体分类以及实现,最后再找出中断和信号的区别。LINUX中断机制与信号中断和异常 l 中 断(也称硬件中断)定义:中断是由其他硬件设备依照CPU时钟周期信号随机产生的。分类: 可屏蔽中断非可原创 2013-09-22 21:49:13 · 5505 阅读 · 0 评论 -
linux中断--中断下半部机制的使用 & 中断编程
tasklet的实现tasklet(小任务)机制是中断处理下半部分最常用的一种方法,其使用也是非常简单的。正如在前文中你所知道的那样,一个使用tasklet的中断程序首先会通过执行中断处理程序来快速完成上半部分的工作,接着通过调用tasklet使得下半部分的工作得以完成。可以看到,下半部分被上半部分所调用,至于下半部分何时执行则属于内核的工作。对应到我们此刻所说的tasklet就是,在原创 2014-04-14 21:33:25 · 3572 阅读 · 0 评论 -
linux内核分析--中断中的下半部
1.软中断 实际上软中断使用的并不多,反而是后面的tasklet比较多,但tasklet是通过软中断实现的,软中断的代码位于/kernel/softirq.c中。软中断是在编译期间静态分配的,由softirq_action结构表示,它定义在linux/interrupt.h中:1234structsoftirq_action{原创 2014-04-12 14:06:51 · 2535 阅读 · 0 评论 -
linux中断--内核中断编程
Linux中断内核编程前言在前面分析了中断的基本原理后,就可以写一个内核中断程序来体验以下,也可以借此程序继续深入来了解内核中断的执行过程一.内核中断程序:我们还是来看一看成程序:在看程序之前,要熟悉如何进行模块编程,和了解module_pararm()的用法。如果不熟悉的话请大家看,module_param()的学习和Linux内核模块编程,在此不作解释。1.程序inte原创 2014-04-14 19:24:44 · 3952 阅读 · 1 评论 -
linux中断--中断原理分析
中断之原理篇前言:中断是计算机发展中一个重要的技术,它的出现很大程度上解放了CPU,提高了CPU的执行效率。在中断出现之前,CPU对IO采用的是轮询的方式进行服务,这使的CPU纠结在某一个IO上,一直在等待它的响应,如果它不响应,CPU就在原地一直的等下去。这样就导致了其他IO口也在等待CPU的服务,如果某个IO出现了important or emergency affairs,CPU原创 2014-04-14 18:48:28 · 4371 阅读 · 0 评论 -
linux内核分析--浅析内存管理机制
linux内存管理---虚拟地址、逻辑地址、线性地址、物理地址的区别(一)linux内存管理---物理地址、线性地址、虚拟地址。逻辑地址之间的转换(二)linux内存管理--linux内核高端内存linux内存管理--Linux中的物理和虚拟存储空间布局原创 2014-04-12 21:09:45 · 7647 阅读 · 0 评论 -
linux内核分析--中断处理流程
linux内核的中断处理, 里面由始至终都贯穿着"重要的事马上做, 不重要的事推后做"的异步处理思想. 于是整理一下~第一阶段--获取中断号每个CPU都有响应中断的能力, 每个CPU响应中断时都走相同的流程. 这个流程就是内核提供的中断服务程序.在进入中断服务程序时, CPU已经自动禁止了本CPU上的中断响应, 因为CPU不能假定中断服务程序是可重入的.中断处理程序的第一步原创 2014-04-12 15:04:19 · 4228 阅读 · 0 评论 -
linux内存管理--用户空间和内核空间
4G的进程地址空间被人为的分为两个部分--用户空间与内核空间。用户空间从0到3G(0xc0000000),内核空间占据3G到4G。用户进程通常情况下只能访问用户空间的虚拟地址,不能访问内核空间的虚拟地址。例外情况只有用户进程进行系统调用(代表用户进程在内核态执行)等时刻可以访问到内核空间。用户空间对应进程,所以每当进程切换,用户空间就会跟着变化;而内核空间是由内核负责映射,它并不会跟着进程变化,是固定的。内核空间地址有自己对应的页表,用户进程各自有不同的页表。每个进程的用户空间都是完全独立、互不相干的。原创 2013-09-26 12:06:18 · 12307 阅读 · 4 评论 -
内存管理--程序在内存中的分布
在多任务操作系统中的每一个进程都运行在一个属于它自己的内存沙盘中。这个沙盘就是虚拟地址空间(virtual address space)。1 32位虚拟内存布局在32位模式下虚拟地址空间总是一个4GB的内存地址块。这些虚拟地址通过页表(page table)映射到物理内存,页表由操作系统维护并被处理器引用。每一个进程拥有一套属于它自己的页表,但是还有一个隐情。只要虚拟地址被使用,那么它就会原创 2014-07-04 11:34:03 · 2752 阅读 · 1 评论 -
硬件内存的情况--内存就是RAM?
内存不全是RAM,让我们看看当今的Intel计算机是如何连接各个组件的吧。下图展示了主板上的主要组件:现代主板的示意图,北桥和南桥构成了芯片组。当你看图时,请牢记一个至关重要的事实:CPU一点也不知道它连接了什么东西。CPU仅仅通过一组针脚与外界交互,它并不关心外界到底有什么。可能是一个电脑主板,但也可能是烤面包机,网络路由器,植入脑内的设备,或CPU测试工作台。CPU主要通过3种方式转载 2014-07-04 11:42:40 · 2108 阅读 · 0 评论 -
内核中内存分配--关于高端内存
Linux把物理内存划分为了三个管理区, 分别为0-16MB的ZONE_DMA, 16-896MB的ZONE_NORMAL和高于896MB的ZONE_HIGHMEM也就是高端内存.至于为什么这么划分, ZONE_DMA好理解, 因为ISA总线只能对前16MB进行DMA寻址, 这块要分出来不能乱用. 而ZONE_NORMAL和ZONE_HIGHMEM为什么从896MB区分呢? 这还得从物理地址和原创 2014-07-04 10:49:00 · 1417 阅读 · 0 评论 -
linux内存管理---虚拟地址、逻辑地址、线性地址、物理地址的区别(一)
虚拟地址 、物理地址 、线性地址 、逻辑地址原创 2013-07-31 10:55:45 · 21313 阅读 · 2 评论 -
linux内核分析--为什么把中断分为上半部和下半步
中断服务例程一般都是在中断请求关闭的条件下执行的,以避免嵌套而使中断控制复杂化。但是,中断是一个随机事件,它随时会到来,如果关中断的时间太长,CPU就不能及时响应其他的中断请求,从而造成中断的丢失。因此,内核的目标就是尽可能快的处理完中断请求,尽其所能把更多的处理向后推迟。例如,假设一个数据块已经达到了网线,当中断控制器接受到这个中断请求信号时,Linux内核只是简单地标志数据到来了,然后让处理器原创 2013-10-18 21:33:02 · 7510 阅读 · 0 评论