Linux内核设计与实现
文章平均质量分 65
BruceZhang
计算机专业的一个小学生
展开
-
Linux内核探讨-- 第七章
本文是个人分析《Linux内核设计与实现》而写的总结,欢迎转载,请注明出处: http://blog.csdn.net/dlutbrucezhang/article/details/13004095 第七章--进程地址空间 内原创 2013-10-30 10:26:01 · 2253 阅读 · 0 评论 -
Linux2.6--虚拟文件系统
虚拟文件系统(有时也称作虚拟文件交换,更常见的是简称做VFS)作为内核子系统,为用户空间程序提供了文件和文件系统相关的接口.系统中的所有文件系统不但依赖VFS共存,而且也依赖VFS系统协同工作.通过虚拟文件系统,程序可以利用标准的UNIX系统调用对不同的文件系统,甚至不同的介质上的文件系统进行读写操作,如下如图所示: 这幅图的含义是: VFS执行的动作:使用CP(1)命令从ex原创 2013-08-14 10:10:33 · 2183 阅读 · 0 评论 -
Linux2.6内核 -- 编码风格(3)
9.typedef 内核开发者们强烈反对使用 typedef 语句。他们的理由是: 1> typedef 掩盖了数据的真实类型 2> 由于数据类型隐藏起来了,所以很容易因此而犯错误,比如以传值的方式向栈中推入结构 4> 使用 typedef 往往是因为想要偷懒,例如,可能会定义一个这样的形式: typedef unsigned char uchar 无论如何,尽量少原创 2013-08-25 13:48:05 · 2503 阅读 · 0 评论 -
Linux2.6中的Slab层
还记得一个进程创建的时候是什么给它分配的“进程描述符”吗?没错,是slab分配器,那么,这个slab分配器是个什么东西呢? 分配和释放数据结构是所有内核中最普遍的操作之一。为了便于结构的频繁分配和回收,编程人员常常会用到空闲链表。空闲链表中包含可供使用的,已经分配好的数据结构块。当代码需要一个新的数据结构实例时,就可以从空闲链表中抓取一个,而不需要再去执行一些分配内存的代码,这样不仅高效原创 2013-08-12 16:23:14 · 2201 阅读 · 0 评论 -
Linux2.6内核 -- 结构的初始化
Linux 内核中用到了大量的结构体,在编码规范中也给出了结构体初始化的规则,这篇文章中有对其的解释:http://blog.csdn.net/dlutbrucezhang/article/details/10296897,不过,这篇文章中并没有给出实例分析,下面我写了一段测试程序:#include#includestruct test { int test_value1; float原创 2013-08-25 15:06:39 · 2235 阅读 · 0 评论 -
Linux2.6内核 -- 编码风格(2)
5.每行代码的长度 源代码中要尽可能的保证每行代码长度不超过80个字符,因为这样做可以使代码最适合在标准的 80 * 24 的终端上显示。事实上,并不存在一个广泛接受的标准--如果代码行超过 80 个字符应该折到下一行。 有些开发者会在圆括号内分行,对齐排列函数参数,它看起来就好像下面这样:static void get_new_parrot(const char *name,原创 2013-08-25 10:34:54 · 2354 阅读 · 0 评论 -
Linux2.6内核 -- 编码风格(1)
像所有其他大型软件一样,Linux 制定了一套编码风格,对代码的格式,风格和布局做出了规定。下面我就对 2.6 内核中的代码约定进行介绍。 1.缩进 缩进风格是用制表位(Tab)每次缩进 8 个字符长度。这里指的并不是利用 8 个空格进行缩进。这里的规定很明确,每次缩进通过制表位进行,每个制表位 8 个字符长度。(这里是不是有点奇怪,我们在编程时是不是用 4 个字符缩进就行了?原创 2013-08-25 10:10:57 · 2482 阅读 · 0 评论 -
mmap详解
共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式, 因为进程可以直接读写内存,而不需要任何数据的拷贝。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次数据: 一次从输入文件到共享内存区,另一次从共享内存区到输出文件。实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建立共享内存区域。而是保持共享区域,直到转载 2013-08-24 17:37:49 · 2756 阅读 · 1 评论 -
直接内存访问(DMA)
1. 什么是DMA直接内存访问是一种硬件机制,它允许外围设备和主内存之间直接传输它们的I/O数据,而不需要系统处理器的参与。使用这种机制可以大大提高与设备通信的吞吐量。 2. DMA数据传输有两种方式引发数据传输:第一种情况:软件对数据的请求1. 当进程调用read,驱动程序函数分配一个DMA缓冲区,并让硬件将数据传输到这个缓冲区中。进程处于睡眠状态。2. 硬件将数据写入到DMA缓冲区中,当写入完转载 2013-08-12 14:48:22 · 2289 阅读 · 0 评论 -
内存管理单元--MMU
现代操作系统普遍采用虚拟内存管理(Virtual Memory Management)机制,这需要处理器中的MMU(Memory Management Unit,内存管理单元)提供支持,本节简要介绍MMU的作用。首先引入两个概念,虚拟地址和物理地址。如果处理器没有MMU,或者有MMU但没有启用,CPU执行单元发出的内存地址将直接传到芯片引脚上,被内存芯片(以下称为物理内存,以便与虚拟内存区分)接收转载 2013-08-12 15:19:54 · 2852 阅读 · 1 评论 -
Linux2.6内核--对块IO层操作的讨论
当一个块被调入内存时(也就是说,在读入后或等待写出时),它要存储在缓冲区中。每个缓冲区与一个块对应,它相当于是磁盘块在内存中的表示。块包含一个或多个扇区,但大小不能超过一页,所以一页可以容纳一个或多个内存块。由于内核在处理数据时需要一些相关的控制信息(比如块属于哪个设备,块对应于哪个缓冲区),所以,每一个缓冲区都有一个对应的描述符。该描述符用 buffer_head 结构体表示,称作缓冲区头,在文原创 2013-08-23 15:44:33 · 2473 阅读 · 0 评论 -
对 jiffies 溢出、回绕及 time_after 宏的理解
原文如下:关于jiffies变量: 全局变量jiffies用来记录自启动以来产生的节拍的总数。系统启动时会将该变量初始化为0,此后,每当时钟中断产生时就会增加该变量的值。jiffies和另外一个变量息息相关:HZ。HZ是每秒系统产生的时钟中断次数,所以jiffies每秒增加的值也就是HZ;在x86体系结构中,内核版本在2.4以前的值为100,在2.6内核中被定义为1000。 jiffie转载 2013-08-12 11:11:20 · 5554 阅读 · 1 评论 -
Linux2.6内核--VFS层中和进程相关的数据结构
系统中的每一个进程都有自己的一组打开的文件,像根文件系统,当前工作目录,安装点等。有三个数据结构将 VFS 层和系统的进程紧密的联系在一起,它们分别是:file_struct,fs_struct 和 namespace 结构体。 file_struct 结构体定义在文件 中。该结构体由进程描述符中的 files 目录项指向。所有的单个进程相关的信息(如打开的文件和文件描述符)都包含在其原创 2013-08-23 14:01:48 · 2583 阅读 · 0 评论 -
Linux2.6--Linus电梯
内核为了处理来自IO层的请求,需要进行相应的优化,因为当请求很多时,且请求的块又都几种在一块,那么如果按照顺序处理这些请求无疑是很大的时间开销,所以,我们需要寻求方法来处理这种情况(当然,不只是这一种情况),这篇文章介绍的就是Linux中经典的IO调度程序--Linus电梯,这个是以Linux的发明者Linus自己的名字命名的。在2.4版的内核中,Linus电梯是默认的IO调度程序。虽然在后来的2原创 2013-08-14 13:31:46 · 2323 阅读 · 0 评论 -
Linux内核线程
内核线程是直接由内核本身启动的进程。内核线程实际上是将内核函数委托给独立的进程,与系统中其他进程“并行”执行(实际上,也并行于内核自身的执行),内核线程经常被称为内核“守护进程”。它们主要用于执行下列任务:l 周期性地将修改的内存页与页来源块设备同步。l 如果内存页很少使用,则写入交换区。l 管理延时动作l 实现文件系统的事务日志。 内核线程主要有两种类型:1. 线程启动后一直等待,直至内转载 2013-08-14 15:15:56 · 1682 阅读 · 0 评论 -
Linux内核探讨-- 第七章
本文是个人分析《Linux内核设计与实现》而写的总结,欢迎转载,请注明出处: http://blog.csdn.net/dlutbrucezhang/article/details/12868723 第七章--内存管理 Lin原创 2013-10-20 19:30:45 · 1746 阅读 · 1 评论 -
Linux内核探讨-- 第六章
本文是个人分析《Linux内核设计与实现》而写的总结,欢迎转载,请注明出处: http://blog.csdn.net/dlutbrucezhang/article/details/12347097 第六章--内核同步 关于同原创 2013-10-19 10:54:19 · 1852 阅读 · 0 评论 -
Linux内核探讨-- 第六章
本文是个人分析《Linux内核设计与实现》而写的总结,欢迎转载,请注明出处: http://blog.csdn.net/dlutbrucezhang/article/details/12347097 第六章--虚拟文件系统原创 2013-10-24 20:15:56 · 1642 阅读 · 0 评论 -
Linux内核探讨-- 第五章
本文是个人分析《Linux内核设计与实现》而写的总结,欢迎转载,请注明出处: http://blog.csdn.net/dlutbrucezhang/article/details/12280435 第五章--下半部和退后执原创 2013-10-06 20:03:03 · 1755 阅读 · 0 评论 -
Linux内核探讨-- 第四章
本文是个人分析《Linux内核设计与实现》而写的总结,欢迎转载,请注明出处: http://blog.csdn.net/dlutbrucezhang/article/details/12207851 第四章--中断和中断处理原创 2013-10-04 15:56:13 · 2063 阅读 · 0 评论 -
Linux内核探讨-- 第二章
本文是个人分析《Linux内核设计与实现》而写的总结,欢迎转载,请注明出处: http://blog.csdn.net/dlutbrucezhang/article/details/12185125 第二章 --进程调度原创 2013-09-30 10:58:14 · 2346 阅读 · 0 评论 -
Linux内核探讨-- 第三章
本文是个人分析《Linux内核设计与实现》而写的总结,欢迎转载,请注明出处: http://blog.csdn.net/dlutbrucezhang/article/details/12207851 第三章 --系统调用 系统原创 2013-10-01 09:27:42 · 1995 阅读 · 0 评论 -
神奇的大内核锁
Big Kernel Lock(BKL)(大内核锁),是linux内核中使用到的一种锁,它跟普通的锁原理上的一样的:lock_kernel();/* 临界区 */unlock_kernel();但是它又有一些非常诡异的地方。从表面上看:1、BKL是一个全局的锁(注意,是“一个”而不是“一种”),它保护所有使用它来同步的临界区。一旦一个进程获得BKL,进入被它保护的临界区,不但该临界区被上锁,所有被转载 2013-09-04 10:55:46 · 2589 阅读 · 0 评论 -
线程在Linux中的实现
早在以前,我们就知道,CPU调度的基本单位是线程,而进程是拥有资源的基本单位,进程是用进程描述符表示的,那么线程是怎么实现和表示的呢? 线程机制是现代编程技术中常用的一种抽象概念.该机制提供了在同一程序内共享内存地址空间运行的一组线程.这些线程还可以共享打开的文件和其他的资源(都是指进程的)。线程机制支持并发程序设计技术,在多处理器系统上,它也能保证真正得并行处理。 下面,首先看原创 2013-08-18 15:55:23 · 3694 阅读 · 1 评论 -
读《Linux内核设计与实现》我想到了这些书
从题目中可以看到,这篇文章是以我读《Linux内核设计与实现》而想到的其他我读过的书,所以,这篇文章的主要支撑点是《Linux内核》。 开始读这本书已经是很久以前的事了,不过,由于时间和精力原因,没有认真的分析和深入研究这本书所涉及的诸多内容,现在想来,仍旧很是遗憾,直到最近,再次把这本书拿过来阅读,才勉强可以说是对书中的知识点有了一定的了解,我说的这种了解,远达不到精通的地步,可能略懂原创 2013-08-19 08:59:49 · 15463 阅读 · 37 评论 -
linux下字节对齐
一,内存地址对齐的概念 计算机内存中排列、访问数据的一种方式,包含基本数据对齐和结构体数据对齐。 32位系统中,数据总线宽度为32,每次能够读取4字节数据。地址总线为32,最大寻址空间为4GB。但是由于最低位A[0]~A[1]是不用于寻址的,因此只能访问4的倍数的地址空间,但是寻址空间还是2^30*字长=4GB。 因此内存中除了结构体中成员变量之外的基本类型的开始的手地址最低两位都是0。转载 2013-08-15 16:11:19 · 3920 阅读 · 0 评论 -
Linux/Unix--设备类型
在Linux以及所有的Unix系统中,设备被分为以下三种类型: 块设备 字符设备 网络设备 块设备通常写为 blkdev ,它是可以寻址的,寻址以块为单位,块大小随设备的不同而不同;块设备通常支持重定位操作,也就是对数据的随机访问。块设备的例子有硬盘,蓝光光碟,还有如Flash这样的存储设备。块设备是通过称为“块设备节点”的特殊文件来访问的,并且通常被挂载原创 2013-08-15 13:22:34 · 3326 阅读 · 0 评论 -
Linux内存映射--mmap函数
Linux提供了内存映射函数mmap, 它把文件内容映射到一段内存上(准确说是虚拟内存上), 通过对这段内存的读取和修改, 实现对文件的读取和修改, 先来看一下mmap的函数声明:头文件:原型: void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offsize);返回值: 成功则返回映射区起始地址, 失转载 2013-08-14 17:12:07 · 3819 阅读 · 0 评论 -
Linux2.6内核--内存管理(1)--分页机制
在内核里分配内存可不像在其他地方分配内存那么容易。造成这种局面的因素很多。从根本上讲,是因为内核本身不能像用户空间那样奢侈的使用内存。内核与用户空间不同,它不具备这种能力,它不支持简单便捷的内存分配方式。比如,内核一般不能睡眠。此外,处理内存分配错误对于内核来说也绝非是一件简单的事。正式由于这些限制,再加上内存分配机制不能太复杂,所以在内核中获取内存要比在用户空间复杂的多。 首先,我们讨原创 2013-08-22 14:51:39 · 2509 阅读 · 0 评论 -
Linux2.6内核--内存管理(2)--区
由于硬件的限制,内核不能对所有的页一视同仁。有些页位于内存中的特定物理地址上,所以,不能将其用于一些特别的任务。(关于内存分页机制可以查看:http://blog.csdn.net/dlutbrucezhang/article/details/10181535)由于存在这种限制,所以内核会把页划分为不同的区。内核使用区对具有相似特性的页进行分组。Linux必须处理如下两种由于硬件存在缺陷而引起的内原创 2013-08-22 15:21:38 · 2326 阅读 · 1 评论 -
linux内存屏障浅析
内存屏障主要解决了两个问题:单处理器下的乱序问题和多处理器下的内存同步问题。为什么会乱序现在的CPU一般采用流水线来执行指令。一个指令的执行被分成:取指、译码、访存、执行、写回、等若干个阶段。然后,多条指令可以同时存在于流水线中,同时被执行。指令流水线并不是串行的,并不会因为一个耗时很长的指令在“执行”阶段呆很长时间,而导致后续的指令都卡在“执行”之前的阶段上。相反,流水线是并行的,多个指令可以同转载 2013-08-22 09:34:39 · 2002 阅读 · 0 评论 -
Linux上程序调试的基石(1)--ptrace
引子: 1.在Linux系统中,进程状态除了我们所熟知的TASK_RUNNING,TASK_INTERRUPTIBLE,TASK_STOPPED等,还有一个TASK_TRACED。这表明这个进程处于什么状态? 2.strace可以方便的帮助我们记录进程所执行的系统调用,它是如何跟踪到进程执行的? 3.gdb是我们调试程序的利器,可以设置断点,单步跟踪程序。它的实现原理又是什么? 所有这一切的背后都转载 2013-08-06 15:20:34 · 2262 阅读 · 0 评论 -
Linux系统调用中的参数验证
我们都知道,用户程序可以通过库函数来通知内核执行系统调用,由于是在内核空间中执行,所以,每一个步骤都需要非常小心,因为错误的操作随时可以导致系统崩溃。 系统调用必须仔细检查它们所有的参数是否合法有效。举例来说,与文件IO相关的系统调用必须检查文件描述符是否有效。与进程相关的函数必须检查提供的PID是否有效。必须检查每个参数,保证它们不但合法有效,而且正确。进程不应该让内核去访问那些无权访原创 2013-08-19 13:01:04 · 2376 阅读 · 0 评论 -
Linux2.6--进程抢占和上下文切换
上下文切换,也就是从一个可执行进程切换到另一个可执行进程,由定义在kernel/sched.c中的context_switch()函数负责处理。每当一个新的进程被选出来准备投入运行的时候,schedule()就会调用该函数。它完成了两相基本工作: 1.调用声明在中的switch_mm(),该函数负责把虚拟内存从上一个进程映射切换到新的进程中去,其实就是切换到另一个进程的地址空间中,请看下原创 2013-08-19 10:07:59 · 3042 阅读 · 1 评论 -
Linux内核2.6的进程调度
Linux是多任务抢占操作系统,多任务就是指多个进程间通过分时切换来并发执行。非抢占的系统是对每个进程而言,除非时间片用完或主动放弃否则不会被剥夺CPU,主动放弃包括调用一些调度的系统调用(比如sched_yield)或者调用IO等阻塞操作。抢占式系统表示即使当前进程没有用完时间片,也没有主动放弃CPU,如果调度系统发现有更高动态优先级的进程,则强制剥夺当前进程的CPU,选择更高动态优先级的进程执转载 2013-08-06 22:08:45 · 1953 阅读 · 0 评论 -
Linux上程序调试的基石(2)--GDB
3. GDB的实现 GDB是GNU发布的一个强大的程序调试工具,用以调试C/C++程序。可以使程序员在程序运行的时候观察程序在内存/寄存器中的使用情况。它的实现也是基于ptrace系统调用来完成的。 其原理是利用ptrace系统调用,在被调试程序和gdb之间建立跟踪关系。然后所有发送给被调试程序的信号(除SIGKILL)都会被gdb截 获,gdb根据截获的信号,查看被调试程序相应的内存地址,并控制转载 2013-08-06 15:22:56 · 2063 阅读 · 0 评论 -
Linux内核基础
Linux系统运行的应用程序通过系统调用来与内核通信。应用程序通常调用库函数(比如C库函数)再有库函数通过系统调用界面,让内核带其完成各种不同的任务。下面这张图显示的就是应用程序,内核和硬件之间的关系: 在任何时间点上我们都可以将每个处理器的活动概括为以下三者之一:1.运行于用户空间,执行用户进程2.运行于内核空间,处于进程上下文,代表某个特定的进程执行3.运行于内核空间,处于中断上下文原创 2013-08-05 20:42:07 · 1909 阅读 · 0 评论 -
Linux中printk()实例
新建hello.c#include #include int init_module(void) { printk(KERN_INFO "Welcome.....\n"); return 0; } void cleanup_module(void) { printk(KERN_INFO "Bye....\n"); } 然后在同一目录下转载 2013-08-05 21:47:51 · 1720 阅读 · 0 评论 -
Linux中的中断处理
与Linux设备驱动中中断处理相关的首先是申请与释放IRQ的API request_irq()和free_irq(),request_irq()的原型为:int request_irq(unsigned int irq,void (*handler)(int irq, void *dev_id, struct pt_regs *regs),unsigned long irq原创 2013-03-22 14:19:50 · 5795 阅读 · 4 评论 -
Linux系统调用
1 系统调用意义linux内核中设置了一组用于实现系统功能的子程序,称为系统调用。系统调用和普通库函数调用非常相似,只是系统调用由操作系统核心提供,运行于核心态,而普通的函数调用由函数库或用户自己提供,运行于用户态。 一般的,进程是不能访问内核的。它不能访问内核所占内存空间也不能调用内核函数。CPU硬件决定了这些(这就是为什么它被称作"保护模式")。为了和用户空原创 2013-03-22 14:19:11 · 2166 阅读 · 0 评论