linux内核编程
文章平均质量分 84
百云在飘
这个作者很懒,什么都没留下…
展开
-
字符设备驱动程序之三
7. read和write方法read和write原型:ssize_t (*read)( struct file *filp, char __user *buff, size_t count, loff_t *offp);ssize_t (*write)( struct file *,filp char __user *,buff size_t count, loff_t *offp)原创 2009-05-10 19:57:00 · 784 阅读 · 0 评论 -
关于超时问题与线程调度的问题
1. 线程限制 在应用服务器中打流量,发现存在命令超时问题 分析:线程已经被唤醒,但是得不到调度。 操作系统是Linux-2.6.17,内核被设置为非抢占式内核,因此一旦一个内核线程得到调度,且该线程总是获得资源而没有阻塞,那么该线程将一直运行下去,其它线程得不到调度。 超时问题解决的核心是清除线程长期霸占CPU的情况。由于每个用户连接对应多个内核原创 2009-08-29 17:09:00 · 3373 阅读 · 0 评论 -
Linux内核中常见内存分配函数
1. 原理说明Linux内核中采用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系统中,用到了四级页表,如图2-1所示。四级页表分别为:l 页全局目录(Page Global Directory)l 页上级目录(Page Upper Directory)l 页中间原创 2009-12-13 10:20:00 · 10797 阅读 · 0 评论 -
通过proc文件系统让Linux内核空间和用户空间之间进行通信
1. 现象和问题描述1.需要在linux用户态下通过脚本直接跟内核交互,比如获取/设置内核中某些变量的值。2.需要在linux内核下启动运行时动态配置。2. 关键过程和根本原因分析/proc 文件系统是一个虚拟文件系统,通过它可以使用一种新的方法在 Linux内核空间和用户空间之间进行通信。在 /proc 文件系统中,我们可以将对虚拟文件的读写作为与内核中实体进行通信的一种手段,但原创 2010-05-04 20:50:00 · 1576 阅读 · 0 评论 -
什么是sys文件系统
1. 什么是sysfssysfs是Linux 内核中设计较新的一种虚拟的基于内存的文件系统,它的作用与 proc 有些类似,但除了与 proc 相同的具有查看和设定内核参数功能之外,还有为 Linux 统一设备模型作为管理之用。相比于 proc 文件系统,使用 sysfs 导出内核数据的方式更为统一,并且组织的方式更好,它的设计从 proc 中吸取了很多教训。 2. sysfs 与 /sy原创 2010-05-04 23:31:00 · 4551 阅读 · 0 评论 -
对内核模块添加sysfs属性
1. 添加 sysfs 支持如果你正在开发的设备驱动程序中需要与用户层的接口,一般可选的方法有:1.注册虚拟的字符设备文件,以这个虚拟设备上的 read/write/ioctl 等接口与用户交互;但 read/write 一般只能做一件事情, ioctl 可以根据 cmd 参数做多个功能,但其缺点是很明显的: ioctl 接口无法直接在 Shell 脚本中使用,为了使用 ioctl 的功能原创 2010-05-05 00:07:00 · 3657 阅读 · 0 评论 -
如何在加载模块时向模块传递参数值
1. 现象描述Linux系统中,动态加载的模块往往需要实现:1)在加载模块时,向模块传递一个参数值,且该参数值在模块运行过程中不能对其进行修改;2)在加载模块时,向模块传递一个参数值,且该参数值在模块运行过程中根据需求对其进行动态修改。2. 关键过程1、Linux系统2.6内核下,可以通过宏module_param(name, type, perm)将参数name声明为模块参数原创 2010-05-22 08:28:00 · 1678 阅读 · 0 评论 -
简单休眠之等待队列
使用等待队列 + 单链表 + 自旋锁 实现一个全局FIFO队列原创 2010-06-20 21:39:00 · 1449 阅读 · 0 评论 -
Linux内核读写文件
在用户态,读写文件可以通过read和write这两个系统调用来完成(C库函数实际上是对系统调用的封装)。 但是,在内核态没有这样的系统调用,我们又该如何读写文件呢?原创 2010-08-27 10:24:00 · 1731 阅读 · 0 评论 -
Linux slab 分配器剖析
良好的操作系统性能部分依赖于操作系统有效管理资源的能力。在过去,堆内存管理器是实际的规范,但是其性能会受到内存碎片和内存回收需求的影响。现在,Linux® 内核使用了源自于 Solaris 的一种方法,但是这种方法在嵌入式系统中已经使用了很长时间了,它是将内存作为对象按照大小进行分配。本文将探索 slab 分配器背后所采用的思想,并介绍这种方法提供的接口和用法。转载 2010-08-28 02:04:00 · 776 阅读 · 1 评论 -
内核比较: 2.6 内核中改进了内存管理
2.6 Linux 内核使用了许多技术来改进对大量内存的使用,使得 Linux 比以往任何时候都更适用于企业。本文列出了一些更重要的改变,包括反向映射(reverse mapping)、使用更大的内存页、页表条目存储在高端内存中,以及更稳定的内存管理器。转载 2010-08-28 00:51:00 · 528 阅读 · 0 评论 -
Linux环境进程间通信(五): 共享内存(下)(系统V)
在共享内存(上)中,主要围绕着系统调用mmap()进行讨论的,本部分将讨论系统V共享内存,并通过实验结果对比来阐述两者的异同。系统V共享内存指的是把所有共享数据放在共享内存区域(IPC shared memory region),任何想要访问该数据的进程都必须在本进程的地址空间新增一块内存区域,用来映射存放共享数据的物理内存页面。转载 2010-09-11 03:01:00 · 723 阅读 · 0 评论 -
Linux 同步方法剖析
在学习 Linux® 的过程中,您也许接触过并发(concurrency)、临界段(critical section)和锁定,但是如何在内核中使用这些概念呢?本文讨论了 2.6 版内核中可用的锁定机制,包括原子运算符(atomic operator)、自旋锁(spinlock)、读/写锁(reader/writer lock)和内核信号量(kernel semaphore)。 本文还探讨了每种机制最适合应用到哪些地方,以构建安全高效的内核代码。转载 2010-08-29 03:42:00 · 526 阅读 · 0 评论 -
read 系统调用剖析
大部分程序员可能会有这样的疑问:当在程序中调用库函数 read 时,这个请求是经过哪些处理最终到达磁盘的呢,数据又是怎么被拷贝到用户缓存区的呢?本文介绍了从 read 系统调用发出到结束处理的全过程。该过程包括两个部分:用户空间的处理、核心空间的处理。用户空间处理部分是系统调用从用户态切到核心态的过程。核心空间处理部分则是 read 系统调用在 linux 内核中处理的整个过程。转载 2010-09-15 13:53:00 · 691 阅读 · 0 评论 -
深入分析 Linux 内核链表
本文详细分析了 2.6.x 内核中链表结构的实现,并通过实例对每个链表操作接口进行了详尽的讲解。转载 2010-09-18 09:35:00 · 615 阅读 · 0 评论 -
Linux 内核的同步机制,第 1 部分
本系列文章分两部分,第一部分详细地介绍了 Linux 内核中的同步机制:原子操作、信号量、读写信号量和自旋锁的API,使用要求以及一些典型示例。第二部分将详细介绍在Linux内核中的另外一些同步机制,包括大内核锁、读写锁、大读者锁、RCU和顺序锁。转载 2010-09-23 01:54:00 · 581 阅读 · 0 评论 -
定时器使用和延迟执行
1. 定时器定时器有时也称为动态定时器或内核定时器,是管理内核时间的基础。定时器的使用很简单。你只需要执行一些初始化工作,设置一个超时时间,指定超时发生后执行的函数,然后激活定时器就可以了。注意,定时器并不是周期运行,它在超时后就自行销毁。 1.1. 使用定时器定时器由结构timer_list表示,在中:struct timer_list{ s原创 2009-06-09 21:19:00 · 5715 阅读 · 0 评论 -
下半部和推后执行的工作(续)
4. 工作队列工作队列(work queue)可以把工作推后,交由一个内核线程去执行,这个下半部总是会在进程上下文中执行。最重要的是工作队列允许重新调度甚至是睡眠。如果你需要一个可以重新调度的实体来执行你的下半部处理,你应该使用工作队列。如果推后执行的任务需要睡眠,那么就选择工作队列。 4.1. 工作队列的实现工作队列子系统是一个用于创建内核线程的接口,通过它创建的进程负责执行原创 2009-06-07 19:24:00 · 942 阅读 · 0 评论 -
下半部和推后执行的工作
1. 下半部下半部的任务就是执行与中断处理密切相关但中断处理程序本身不执行的工作。比如,如果上半部把数据从硬件拷贝到内存,那么当然应该在下半部中处理它们。如何决定什么任务在哪部分完成取决于驱动程序开发者自己的判断。注意,中断处理程序会异步执行,并且在最好的情况下它会锁定当前的中断线。这里有些建议:1) 如果一个任务队时间非常敏感,将其放在中断处理程序中执行2) 如果一个任务和硬件相关,原创 2009-06-07 18:56:00 · 1315 阅读 · 0 评论 -
构造和运行模块
1. HelloWorld 模块构造2.6.x内核的模块,必须在自己的系统中配置并构造好内核树。"helloworld"示例模块代码如下: #include #include MODULE_LICENSE("GPL");static int __init hello_init(void){ printk(KERN_ALERT "Hello, world/原创 2009-05-09 10:37:00 · 796 阅读 · 0 评论 -
字符设备驱动程序之一
1. scddp的设计scddp,即"Simple Character Device DriverProgram,简单的字符设备驱动程序"的缩写。scddp是一个操作内存区域的字符设备驱动程序,这片内存区域就相当于一个设备。这个设备是由一个全局且持久的内存区域组成。"全局"是指,如果设备被多次打开,则打开它的所有文件描述符可共享该设备所包含的数据。"持久"是指,如果设备关闭后再打开,则其中原创 2009-05-10 19:31:00 · 1118 阅读 · 0 评论 -
字符设备驱动程序之二
4. 字符设备的注册在内核调用设备的操作之前,必须分配并注册一个或多个struct cdev结构(在中定义)。分配和初始化该结构有两种方式。如果在模块运行时需要获取一个独立的cdev结构,则应该编写如下代码:struct cdev *my_cdev = cdev_alloc();my_cdev->ops = &my_fops;如果cdev结构需要嵌入到自己的设备特定结构中,就使原创 2009-05-10 19:44:00 · 706 阅读 · 0 评论 -
内核同步之自旋锁和信号量
3. 自旋锁Linux内核中最常见的锁是自旋锁。一个自旋锁就是一个互斥设备,它只能有两个值:"锁定"和"解锁"。如果锁可用,则"锁定"位被设置,而代码继续进入临界区;相反,如果锁被其他进程争用,则代码进入忙循环并重复检查这个锁,直到锁可用为止。这个循环就是自旋锁的"自旋"。自旋锁最多只能被一个可执行的线程持有。如果一个执行线程试图获得一个被争用的自旋锁,那么该线程就会一直进行忙循环-旋转-等待原创 2009-05-15 19:44:00 · 4910 阅读 · 3 评论 -
内核同步之名词解释和原子操作
1. 名词解释共享内存的应用程序必须要保护共享资源,防止共享资源被并发的访问。内核耶不例外。共享资源之所以要防止并发访问,是因为如果多个执行线程同时访问数据和操作数据,就有可能发生各线程之间相互覆盖共享数据的情况,造成被访问数据处于不一致状态。所谓临界区(critical region)就是访问和操作共享数据的代码段。如果两个执行线程有可能处于同一个临界区中,那么这就是程序包含了一个bug原创 2009-05-15 19:36:00 · 1903 阅读 · 0 评论 -
内核同步之Seq锁和屏障
5. 完成变量如果在内核中一个任务需要发出信号通知另一个任务发生了某个特定事件,利用完成变量(completion variable)是两个任务得以同步的简单方法。完成变量由结构completion表示,在中。静态初始化:DECLARE_COPLETION(my_comp);运行时动态初始化:int_completion(my_comp);在一个指定的完成变量上,需要等待的原创 2009-05-15 19:48:00 · 1510 阅读 · 0 评论 -
内存管理之一
1. 页内核把物理页作为内存管理的基本单位。内存管理单元(MMU)是把虚拟地址转换为物理地址的硬件。大多数32位体系结构支持4KB的页,而64位体系结构一般会支持8KB的页。内核用structpage结构表示系统中的每个物理页,在中定义。struct page{ page_flags_t flags; atomic_t原创 2009-05-21 22:57:00 · 1046 阅读 · 0 评论 -
内存管理之二
4. slab层为了便于数据结构的频繁分配和回收,会用到一个空闲链表。它相当于对象高速缓存以便快速存储频繁使用的对象类型。在内核中,空闲链表面临的主要问题是不能全局控制。为了弥补这一缺陷,Linux内核提供了slab层(slab分配器)。 4.1. slab层的设计slab层把不同的对象划为所谓高速缓存(cache)组,其中每个高速缓存都存放不同类型的对象。每种对象类型对应一个高速原创 2009-05-21 23:03:00 · 837 阅读 · 0 评论 -
页高速缓存和页回写
1. 页高速缓存页高速缓存(cache)是Linux内核实现的一种主要磁盘缓存。它主要用来减少对磁盘的I/O操作。具体的讲,就是通过把磁盘中的数据缓存到物理内存中,把对磁盘的访问变为对物理内存的访问。磁盘高速缓存的原因在于:一是访问磁盘的速度要远远低于访问内存的速度;第二,数据一旦被访问,就可能在短期内再次被访问到。页高速缓存是由RAM中的物理页组成的,缓存中每一页都对应着磁盘中的多个原创 2009-05-21 23:17:00 · 2129 阅读 · 0 评论 -
块IO层
1. 概述系统能够随机访问固定大小数据片的设备称为块设备,这些数据片称作块。另一种基本的设备类型是字符设备。字符设备按照字节流的方式被有序访问,像串口和键盘都属于字符设备。这两种类型的设备的根本区别在于它们是否可以被随机访问,换句话说,就是能否在访问设备时随意从一个位置跳到另一个位置。字符设备仅仅需要控制一个位置--当前位置;而块设备访问的位置必须在介质的不同区间前后移动,同时块设备对执行性能的要原创 2009-05-25 23:27:00 · 1375 阅读 · 0 评论 -
虚拟文件系统之二
4.3. 目录项对象 VFS把目录当作文件对待,所以在路径/bin/vim中,bin和vim都属于文件:bin是特殊的目录文件,而vim是一个普通文件,路径中的每个组成部分都由一个索引节点对象表示。 为了方便查找路径,VFS引入了目录项的概念。每个dentry代表路径中的一个特定部分。比如,/、bin、vim都是目录项对象。在路径中,包括普通文件在内,每一个部分都是目录原创 2009-05-25 23:42:00 · 778 阅读 · 0 评论 -
虚拟文件系统之一
1. 通用文件系统接口 虚拟文件系统(VFS)作为内核子系统,为用户空间程序提供了文件系统相关的接口。系统中所有文件系统不但依赖VFS共存,而且也依靠VFS系统协同工作。通过VFS,程序可以利用标准的UNIX文件系统对不同介质上的不同文件系统进行读写操作。 2. 文件系统抽象层 之所以可是使用这种通用接口对所有类型的文件系统进行操作,是因为内核在它的底层文件系统接口上建原创 2009-05-25 23:38:00 · 814 阅读 · 0 评论 -
时间管理
1. 内核中的时间概念时间管理在内核占有非常重要的地位。相对于事件驱动而言,内核中有大量函数都是基于时间驱动的。注意相对时间和绝对时间之间的区别。周期性产生的事件与推迟执行的事件之间的差别。周期性产生的事件都是由系统定时器驱动的。系统定时器是一种可编程硬件芯片,它以固定频率产生中断,也称定时器中断。而动态定时器是一种用来推迟执行程序的工具。系统定时器以某种频率自行触发时钟中断、该频原创 2009-06-09 21:13:00 · 1312 阅读 · 0 评论 -
中断和中断处理程序
1. 中断 Linux内核要对连接到计算机上的所有硬件设备进行管理,首先要能和它们互相通信。从所周知,处理器的速度跟外围硬件设备的速度往往不在一个数量级上。所以,需要一种机制,如果轮询(polling)是一种解决办法,可以让内核定期对设备的状态进行查询,然后做出相应的处理,但这让内核做了不少无用功。 更好的办法是由我们来提供一种机制,让硬件在需要的时候再向内核发出信原创 2009-06-07 12:32:00 · 7144 阅读 · 0 评论 -
进程地址空间
1. 进程地址空间其实内核除了管理本身的内存外,还必须管理进程的地址空间。Linux操作系统采用虚拟内存技术,因此系统中的所有进程之间以虚拟方式共享内存。进程地址空间由每个进程中的线性地址区组成,而且内核允许进程使用该空间中的地址。进程之间可以选择共享地址空间,我们称为这样的进程为线程。内存地址是一个给定的值,它要在地址空间范围之内的,这些可被访问的合法地址区间被称为内存区域,通过内核原创 2009-06-07 18:24:00 · 1698 阅读 · 0 评论 -
Linux 内核的同步机制,第 2 部分
这是本系列文章的第二部分,它详细地介绍了Linux内核中的同步机制:大内核锁、读写锁、大读者锁、RCU和顺序锁的API,使用要求以及一些典型示例。本系列文章的第一部分则详细地介绍了 Linux 内核中的其它一些同步机制,包括原子操作、信号量、读写信号量和自旋锁的API,使用要求以及一些典型示例。转载 2010-09-23 02:04:00 · 518 阅读 · 0 评论