
Linux内核学习笔记
文章平均质量分 76
记录对Linux2.6.32分析学习的笔记,以源码注释加流程分析的方式呈现。主要涉及内存管理、进程管理、进程调度、文件系统等部分。
bullbat
爱好程序设计,对待问题喜欢追根溯源。
展开
-
Linux内存管理之页面回收
请求调页机制,只要用户态进程继续执行,他们就能获得页框,然而,请求调页没有办法强制进程释放不再使用的页框。因此,迟早所有空闲内存将被分配给进程和高速缓存,Linux内核的页面回收算法(PFRA)采取从用户进程和内核高速缓存“窃取”页框的办法不从伙伴系统的空闲块列表。 实际上,在用完所有空闲内存之前,就必须执行页框回收算法。否则,内核很可能陷入一种内存请求的僵局中,并导致系统崩溃。也原创 2012-03-02 09:12:04 · 13762 阅读 · 3 评论 -
Linux缓存机制之块缓存
作者:bullbat 在Linux内核中,并非总使用基于页的方法来承担缓存的任务。内核的早期版本只包含了块缓存,来加速文件操作和提高系统性能。这是来自于其他具有相同结构的类UNIX操作系统的遗产。来自于底层块设备的块缓存在内存的缓冲区中,可以加速读写操作。 与内存页相比,块不仅比较小(大多数情况下),而且长度可变的,依赖于使用的块设备(或文件系统)。随着日渐倾向于使用原创 2012-02-29 15:19:11 · 8432 阅读 · 1 评论 -
Linux缓存机制之页缓存
作者:bullbat Linux运用一个功能广泛的缓冲和缓存框架来提高系统的速度。缓冲和缓存利用一部分系统物理内存,确保最重要、最常使用的块设备数据在操作时可直接从主内存获取,而无需从低速设备读取。物理内存还用于存储从快设备读取的数据,使得随后对该数据的访问可直接在物理内存进行,而无需从外部设备再次取用。考虑系统中多种因素然后延迟写回在总体上改进了系统的性能。前面分析的部分原创 2012-02-27 09:13:10 · 9750 阅读 · 0 评论 -
Linux设备驱动编程模型之设备篇
设备驱动程序模型建立在几个基本数据结构上,这些结构描述了总线、设备、设备驱动、属性以及他们之间的关系。我们首先认识一下这些数据结构。 一、数据结构设备表述符struct device { struct device *parent;/*指向父设备的指针*/ /*该字段用于管理device和其他device结构,一起device 与其他结构之间的关系*/ stru原创 2012-02-25 16:37:59 · 3248 阅读 · 0 评论 -
Linux设备驱动编程模型之上层容器篇
2.6内核增加了一个引人注目的新特性——统一设备模型(device model)。设备模型提供了一个独立的机制专门来表示设备,并描述其在系统中的拓扑结构,从而使得系统具有以下优点:l 代码重复最小化。l 提供诸如引用计数这样的统一机制。l 可以列举系统中所有的设备,观察它们的状态,并且查看它们连接的总线。l 可以将系统中的全部原创 2012-02-14 20:30:44 · 3236 阅读 · 3 评论 -
Linux虚拟文件系统之文件读取(sys_read())
在文件成功打开之后,进程将使用内核提供的read和write系统调用,来读取或修改文件的数据。内核中文件读写操作的系统调用实现基本都一样,下面我们看看文件的读取。/*sys_read()*/SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count){ struct file *file; ssiz原创 2012-02-13 17:13:20 · 4482 阅读 · 1 评论 -
Linux虚拟文件系统之文件打开(sys_open())
在文件读写之前,我们必须先打开文件。从应用程序的角度来看,这是通过标准库的open函数完成的,该函数返回一个文件描述符。内核中是由系统调用sys_open()函数完成。/*sys_open*/SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, int, mode){ long ret; /*检查是否应原创 2012-02-13 15:43:28 · 9593 阅读 · 0 评论 -
Linux虚拟文件系统之文件系统卸载(sys_umount())
Linux中卸载文件系统由umount系统调用实现,入口函数为sys_umount()。较于文件系统的安装较为简单,下面是具体的实现。/*sys_umont系统调用*/SYSCALL_DEFINE2(umount, char __user *, name, int, flags){ struct path path; int retval; /*找到装载点的vfsmount原创 2012-02-13 10:35:41 · 3913 阅读 · 0 评论 -
Linux虚拟文件系统之文件系统安装(sys_mount())
对于前面的根目录文件系统的安装中涉及到了mount系统调用的调用,这里我们考虑一个文件系统将被安装在一个已经安装文件系统之上的情形,即调用mount系统调用实现。mount系统调用被用来安装一个普通文件系统,他的服务例程为sys_mount()。 /*sys_mount系统调用*//*dev_name为待安装设备的路径名;dir_name为安装点的路径名;type是表示文件系统类型的字原创 2012-02-10 19:09:36 · 4628 阅读 · 0 评论 -
Linux虚拟文件系统(安装根文件系统)
安装根文件系统式系统初始化的关键部分。Linux内核允许根文件系统放在很多不同的地方,比如硬盘分区、软盘、通过NFS共享的远程文件系统以及保存在ramdisk中。内核要在变量ROOT_DEV中寻找包含根文件系统的磁盘主设备号。当编译内核时,或者像最初的启动装入程序传递一个合适的“root”选项时,根文件系统可以被指定为/dev目录下的一个设备文件。安装根文件系统分为两个阶段:1,内核安装特原创 2012-02-10 11:36:09 · 4051 阅读 · 0 评论 -
Linux虚拟文件系统(内核初始化<二>)
这部分主要对linux虚拟文件系统内核初始化部分做些补充。关于shrinker,inode和dentry cache初始化阶段都需要注册自己的shrinker,用于缩减cache。两个操作原理类似。shrinker数据结构介绍/* * A callback you can register to apply pressure to ageable caches. * * 'shr原创 2012-02-09 16:54:10 · 6498 阅读 · 2 评论 -
Linux虚拟文件系统(内核初始化<一>)
Linux虚拟文件系统在内核初始化的start_kernel()函数中主要调用两个函数来实现。asmlinkage void __init start_kernel(void){ …… vfs_caches_init_early(); …… vfs_caches_init(totalram_pages); ……}一、早期初始化虚拟文件系统的早期初始化有函数vfs原创 2012-02-09 15:09:57 · 4948 阅读 · 2 评论 -
Linux虚拟文件系统(节点路径搜索)
前面对linux虚拟文件系统的架构以及设计到的数据结构有了一个整体的认识,这里看看linux内核怎么根据给定的文件路径名在内存中找到和建立代表着目标文件或目录的dentry结构和inode结构。文件路径的搜索是文件系统中最基本也是最重要的一部分之一,后面我们会看到,文件的打开、关闭等等操作都将涉及到文件路径的搜索。下面我们看看linux内核中时怎么实现的。一、搜索中所用数据结构/*这个数据原创 2012-02-08 15:49:31 · 5915 阅读 · 2 评论 -
Linux虚拟文件系统(概述)
Linux虚拟文件系统是一个内核软件层,用来处理与UNIX标准文件系统相关的所有系统调用。其健壮性表现在能为各种文件系统提供一个通用的接口。Linux虚拟文件系统支持的文件系统可以划分为三种主要的类型:磁盘文件系统这些文件系统管理在本地磁盘分区中可用的磁盘空间或者其他可以起到磁盘作用的设备(比如说一个USB闪存)。网络文件系统这些文件系统允许访问属于其他网络计算机的文件系统所包原创 2012-02-08 09:58:54 · 8930 阅读 · 3 评论 -
Linux内存管理之slab机制(概述)
通过前面所有代码的分析和总结,已经把各个部分熟悉了一遍,在此对Linux内核中slab机制做最后的总结。伙伴系统算法采用页作为基本内存区,这适合于大块内存的请求。对于小内存区的申请,比如说几十或几百个字节,我们用slab机制。Slab分配器把对象分组放进高速缓存。每个高速缓存都是同类型对象的一种“储备”。包含高速缓存的主内存区被划分为多个slab,每个slab由一个活多个连续的页组成,这些原创 2012-01-11 21:01:49 · 31162 阅读 · 0 评论 -
Linux内存管理之slab机制(销毁cache)
cache的销毁很简单,依次检查和释放本地CPU cache、共享cache、三链以及cache本身。从cache的创建我们看到,创建的cache主要是从cache_cache中获得的,因为cache_cache中对象的大小就是cache结构体的大小,所以这里只是释放到cache_cache就OK了。static void __kmem_cache_destroy(struct kmem_ca原创 2012-01-11 10:41:08 · 3505 阅读 · 0 评论 -
Linux内存管理之slab机制(创建cache)
Linux内核中创建cache节点由函数kmem_cache_create()实现。该函数的执行流程:1,从全局cache_cache中获得cache结构,因为全局cache_cache初始化对象的大小就是kmem_cache结构的大小,所以返回的指针正好可以转换为cache结构;调用 kmem_cache_zalloc(&cache_cache, gfp);2,获得slab中碎片大小原创 2012-01-11 10:27:49 · 6392 阅读 · 0 评论 -
Linux内存管理之slab机制(销毁slab)
总结完了slab创建、对象分配、对象释放,在这里再看看slab的销毁。销毁slab很简单,由函数slab_destroy()实现。/** * slab_destroy - destroy and release all objects in a slab * @cachep: cache pointer being destroyed * @slabp: slab pointer bei原创 2012-01-10 20:55:07 · 3113 阅读 · 0 评论 -
Linux内存管理之slab机制(释放对象)
Linux内核中将对象释放到slab中上层所用函数为kfree()或kmem_cache_free()。两个函数都会调用__cache_free()函数。代码执行流程:1,当本地CPU cache中空闲对象数小于规定上限时,只需将对象放入本地CPU cache中;2,当local cache中对象过多(大于等于规定上限),需要释放一批对象到slab三链中。由函数cache_flusha原创 2012-01-10 17:23:15 · 4348 阅读 · 1 评论 -
Linux内存管理之slab机制(分配对象)
Linux内核从slab中分配内存空间上层函数由kmalloc()或kmem_cache_alloc()函数实现。kmalloc()->__kmalloc()->__do_kmalloc()/** * __do_kmalloc - allocate memory * @size: how many bytes of memory are required. * @flags: the原创 2012-01-10 15:23:23 · 3749 阅读 · 1 评论 -
Linux内存管理之slab机制(创建slab)
Linux内核中创建slab主要由函数cache_grow()实现,从slab的创建中我们可以完整地看到slab与对象、页面的组织方式。/* * Grow (by 1) the number of slabs within a cache. This is called by * kmem_cache_alloc() when there are no active objs left原创 2012-01-10 10:45:44 · 3742 阅读 · 0 评论 -
Linux内存管理之slab机制(初始化)
一、内核启动早期初始化start_kernel()->mm_init()->kmem_cache_init()执行流程:1,初始化静态initkmem_list3三链;2,初始化cache_cache的nodelists字段为1中的三链;3,根据内存情况初始化每个slab占用的页面数变量slab_break_gfp_order;4,将cache_cache加入cache_c原创 2012-01-09 20:57:57 · 4881 阅读 · 1 评论 -
Linux内存管理之伙伴系统(内存释放)
Linux内核伙伴系统中页面释放,主函数为free_pages()一、上层操作/*用虚拟地址进行释放*/void free_pages(unsigned long addr, unsigned int order){ if (addr != 0) { VM_BUG_ON(!virt_addr_valid((void *)addr)); __free_pages(virt_to原创 2012-01-09 10:06:49 · 4069 阅读 · 0 评论 -
linux内存管理之伙伴系统(内存分配)
一、Linux伙伴系统分配器伙伴系统分配器大体上分为两类。__get_free_pages()类函数返回分配的第一个页面的线性地址;alloc_pages()类函数返回页面描述符地址。不管以哪种函数进行分配,最终会调用alloc_pages()进行分配页面。为清楚了解其分配制度,先给个伙伴系统数据的存储框图也就是每个order对应一个free_area结构,free_area以不同原创 2012-01-08 21:11:37 · 10754 阅读 · 0 评论 -
linux内存管理之伙伴系统(建立)
内核使用伙伴系统来解决内存分配引起的外部碎片问题。一、数据结构描述结构zone中的free_area数组描述伙伴系统该数组为free_area结构struct zone {…… struct free_area free_area[MAX_ORDER];……};struct free_area {/*链表类型为5类,对于分类为新加入的*/ struct list_h原创 2012-01-07 22:01:53 · 3551 阅读 · 0 评论 -
linux高端内存管理之非连续内存区(分配和释放)
前面总结了非连续内存区域的内核描述,接着看看他的分配和释放。一、非连续内存区的分配不管是vmalloc()还是vmalloc_32()等系列的分配函数最后都会调用__vmalloc_node()函数实现,直接看这个函数的实现。 * __vmalloc_node - allocate virtually contiguous memory * @size: allocation原创 2012-01-06 15:16:06 · 4350 阅读 · 0 评论 -
linux高端内存管理之非连续内存区(描述)
总结了高端内存区的固定内核映射区、临时内核映射与永久内核映射。但是对于高端内存中各个区间的布置我们任然不是很清楚,首先我们从整体上看看内核对高端内存的划分情况。如果内存足够大(比如用户:内核线性空间=3:1,内核就只能访问线性空间的第4GB内容,如果物理内存超过1GB则视为足够大),内核线性空间无法同时映射所有内存。这就需要将内核线性空间分出一段不直接映射物理内存,而是作为窗口分时映射使用原创 2012-01-06 14:43:26 · 4400 阅读 · 0 评论 -
linux内核高端内存管理之固定内存区与映射
前面总结了高端内存中永久内核映射和临时内核映射。linux高端内存中的临时内存区为固定内存区的一部分,下面是Linux内存布局图对于固定内存在linux内核中有下面描述enum fixed_addresses {#ifdef CONFIG_X86_32 FIX_HOLE, FIX_VDSO,#else VSYSCALL_LAST_PAGE, VSYSCALL_FIR原创 2012-01-05 19:31:38 · 4401 阅读 · 0 评论 -
linux高端内存管理之临时内核映射
临时内核映射区属于高端内存中的固定内核映射区中的一部分。当必须创建一个映射而当前的上下文又不能睡眠时,内核提供了临时映射(也就是所谓的原子映射)。有一组保留的映射,他们可以存放新创建的临时映射。内核可以原子地把高端内存中的一个页映射到某个保留的映射中。因此,临时映射可以用在不能睡眠的地方,比如中断处理程序中,因为获取映射时绝不会阻塞。每个CPU都有他自己的窗口集合,他们用enum km_t原创 2012-01-05 15:14:44 · 3606 阅读 · 0 评论 -
linux高端内存管理之永久内核映射
与直接映射的物理内存末端、高端内存的始端所对应的线性地址存放在high_memory变量中,在x86体系结构上,高于896MB的所有物理内存的范围大都是高端内存,它并不会永久地或自动地映射到内核地址空间,尽管x86处理器能够寻址物理RAM的范围达到4GB(启用PAE可以寻址到64GB)。一旦这些页被分配,就必须in射到内核的逻辑地址空间上。在x86上,高端内存中的页被映射到3GB-4GB。内核原创 2012-01-05 14:59:45 · 4385 阅读 · 0 评论 -
linux启动内存分配器
linux启动内存分配器是在伙伴系统、slab机制实现之前,为满足内核中内存的分配而建立的。本身的机制比较简单,使用位图来进行标志分配和释放。一、数据结构介绍1,保留区间因为在建立启动内存分配器的时候,会涉及保留内存。也就是说,之前保留给页表、分配器本身(用于映射的位图)、io等得内存在分配器建立后,当用它来分配内存空间时,保留出来的那些部分就不能再分配了。linux中对保留内存空间的原创 2012-01-04 20:23:29 · 3129 阅读 · 0 评论 -
linux页表机制管理初始化
linux页表机制的建立分为两个阶段,第一个阶段在启动初始化时,调用汇编代码实现临时的分页;第二阶段在内核初始化时建立完整的完整的页表机制。对于物理地址扩展(PAE)分页机制中,intel通过在她得处理器上把管脚数从32增加到36已经满足了这些需求,寻址能力可以达到64GB。不过,只有引入一种新的分页机制把32位线性地址转换为36位物理地址才能使用所增加的物理地址。linux为对多种体系的支持,选原创 2012-01-04 15:25:05 · 6275 阅读 · 1 评论 -
linux内存管理之活动内存区
Linux内存活动区域其实就是全局变量e820中的内存块做了相关的检查和对其处理后的区域。在管理区初始化等地方有用到。数据结构struct node_active_region { unsigned long start_pfn; unsigned long end_pfn; int nid;};初始化活动内存的初始化工作在setup_arch()->initmem原创 2012-01-01 21:01:16 · 3552 阅读 · 3 评论 -
linux物理内存管理区初始化
Linux物理内存管理区在start_kernel函数中进行初始化,此时启动分配器已经建立,所以可以从bootmem中分配需要的内存。一、全局变量初始化max_pfn:最大物理页面帧号start_kernel()->setup_arch()->e820_end_of_ram_pfn()找出最大可用内存页面帧号。void __init setup_arch(char **cmdlin原创 2012-01-01 20:50:57 · 6200 阅读 · 1 评论 -
linux物理内存探测
linux在被bootloader加载到内存后, cpu最初执行的linux内核代码是/header.S文件中的start_of_setup函数,这个函数在做了一些准备工作后会跳转到boot目下文件main.c的main函数执行,在这个main函数中我们可以第一次看到与内存管理相关的代码,这段代码调用detect_memeory()函数检测系统物理内存在header.S中执行下面汇编代码:原创 2011-12-31 15:38:14 · 4365 阅读 · 0 评论 -
linux物理内存描述
linux使用于广泛的体系结构,因此需要用一种与体系结构无关的方式来描述内存。linux用VM描述和管理内存。在VM中兽药的普遍概念就是非一致内存访问。对于大型机器而言,内存会分成许多簇,依据簇与处理器“距离”的不同,访问不同的簇会有不同的代价。每个簇都被认为是一个节点(pg_data_t),每个节点被分成很多的成为管理区(zone)的块,用于表示内存中的某个范围。除了ZONE_DMA,ZON原创 2011-12-31 10:36:00 · 5696 阅读 · 2 评论 -
linux内存管理概述
linux内存管理建立在基本的分页机制基础上,在linux内核中RAM的某些部分将会永久的分配给内核,并用来存放内核代码以及静态内核数据结构。RAM的其余部分称为动态内存,这不仅是进程所需的宝贵资源,也是内核本身所需的宝贵资源。实际上,整个系统的性能取决于如何有效地管理动态内存。因此,现在所有多任务操作系统都在经历优化对动态内存的使用,也就是说,尽可能做到当要时分配,不需要时释放。内存管理是o原创 2011-12-30 20:58:07 · 4365 阅读 · 2 评论 -
linux内核分析之软定时器笔记
定时器是一种软件功能,即允许在将来的某个时刻,函数在给定的时间间隔用完时被调用。超时表示与定时器相关的时间间隔已经用完的那个时刻。linux上考虑两种类型的定时器,即动态定时和间隔定时器。第一种类型由内核使用,而间隔定时器由进程在用户态创建。动态定时器动态定时的主要数据结构是一个叫做tvec_bases的per cpu变量,他包含NR_CPUS个元素,系统中每个CPU都有一个。每个元素原创 2011-12-28 20:42:02 · 2127 阅读 · 0 评论 -
linux内核分析之进程地址空间
本文主要介绍linux内核中进程地址空间的数据结构描述,包括mm_struct/vm_area_struct。进程线性地址区间的分配流程,并对相应的源代码做了注释。 内核中的函数以相当直接了当的方式获得动态内存。当给用户态进程分配内存时,情况完全不同了。进程对动态内存的请求被认为是不紧迫的,一般来说,内核总是尽量推迟给用户态进程分配内存。由于用户进程时不可信任的,因此,内核必须能随时准备捕获用原创 2011-12-27 15:36:32 · 3315 阅读 · 0 评论 -
linux内核分析之缺页中断
linux缺页异常程序必须能够区分由编程引起的异常以及由引用属于进程地址空间但还尚未分配物理页框的页所引起的异常。在x86-ia32体系上由do_page_fault函数处理,每个版本有所差异,现分析的版本为2.6.32 /* regs:该结构包含当异常发生时的微处理器寄存器的值 3位的error_code,当异常发生时由控制单元压入栈中 -如果第0位被清0,则异常由访问一个不存在原创 2011-12-28 11:39:54 · 8744 阅读 · 0 评论