Linux内核研究
文章平均质量分 74
山庄来客
这个作者很懒,什么都没留下…
展开
-
Android Sync Framework
Fence提出的原因如下:在复杂的DMA管线如图形管线(多媒体,摄像头,GPU以及显示设备),一个buffer的消费者需要知道生产者什么时候完成生产(即创建一个Buffer,并像里面放置消费者所需要的数据)。同样地,生产者也需要知道消费者什么时候使完它创建的Buffer,以便它可以重新使用这个Buffer。一个Buffer可能被多个不同的消费者使用不同的时间。另外,一个消费者可能需要互原创 2015-03-22 21:51:50 · 7078 阅读 · 1 评论 -
The evolution of driver page remapping
Two weeks ago, this page looked at the newVM_UNPAGED flag, introduced in 2.6.15-rc2 to mark virtual memory areas (VMAs) which are not made up of "normal" pages. These areas are usually created by devi转载 2012-06-26 17:05:53 · 567 阅读 · 0 评论 -
Linux kernel design patterns - part 2
Last week we discussed the value of enunciating kernel design patterns and looked at the design patterns surrounding reference counts. This week we will look at a very different aspect of coding and转载 2012-06-27 21:52:00 · 1101 阅读 · 0 评论 -
The Android ION memory allocator(有删节)
ION is a generalized memory manager that Google introduced in the Android 4.0 ICS (Ice Cream Sandwich) release to address the issue of fragmented memory management interfaces across different Android转载 2013-01-04 15:12:52 · 1479 阅读 · 0 评论 -
struct vm_area_struct内核数据结构
Linux内核中,关于虚存管理的最基本的管理单元应该是struct vm_area_struct了,它描述的是一段连续的、具有相同访问属性的虚存空间,该虚存空间的大小为物理内存页面的整数倍。 下面是struct vm_area_struct结构体的定义:/** This struct defines a memory VMM memory area. There is o转载 2012-06-02 17:23:15 · 1161 阅读 · 0 评论 -
Linux kernel design patterns - part 3
In this final article we will be looking at just one design pattern. Westarted with the fine details of reference counting,zoomed out to look at whole data structures, and now move to the even large转载 2012-06-27 21:53:35 · 834 阅读 · 0 评论 -
Linux kernel design patterns - part 1
One of the topics of ongoing interest in the kernel community is that of maintaining quality. It is trivially obvious that we need to maintain and even improve quality. It is less obvious how best to转载 2012-06-28 13:41:11 · 908 阅读 · 0 评论 -
udev与devfs文件系统
devfs(设备文件系统)是由Linux2.4内核引入的,它的出现主要使得设备驱动程序能够自主管理自己的设备文件。具体来说,devfs具有如下优点: 可以通过程序在设备初始化时在/dev目录下创建设备文件,卸载设备时将它删除。 设备驱动程序可以指定设备名、所有者和权限位,用户空间程序仍可以修改所有者和权限位。 不再需要为设备驱动程序分配主设备号以及处理次设备号,原创 2012-08-23 23:01:11 · 3094 阅读 · 0 评论 -
Miscellaneous Character Drivers
Sometimes people need to write “small” device drivers, to support custom hacks—either hardware or software ones. To this end, as well as to host some real drivers, the Linux kernel exports an interf原创 2012-08-23 23:02:31 · 689 阅读 · 0 评论 -
Linux-2.6设备模型与sysfs文件系统
kobject对象: 它是设备模型的基本结构,对应于sysfs文件系统中的一个目录,它是一个结构体,不过在Linux中引入了面向对象的思想,从某些角度,也可以看成是一个类。kobject对象通常被嵌入到其他的结构中,从面向对象的观点看,kobject可以看成是基类,而其他类都是派生的产物。 一个kobject的例子/* * Sample原创 2012-08-23 22:58:04 · 1540 阅读 · 0 评论 -
iotcl函数
Linux系统建议以如图方式定义ioctl()的命令码。设备类型(type)序列号(nr)方向数据尺寸(size)8bit8bit2bit13/14bit命令码的设备类型字段为一个“幻数”,可以是0~0xff之间的值,命令码的序列号也是8位宽,命令码的方向字段原创 2012-08-23 23:03:57 · 1802 阅读 · 0 评论 -
字符设备驱动程序框架
1, 设备号的内部表示形式 类型:dev_t 32=12(主设备号) + 20(次设备号)相关宏: MAJOR(dev_t dev) MINOR(dev_t dev) MKDEV(int major, int minor);2. 分配和释放设备号 相关函数: //静态分配设备号原创 2012-08-08 23:31:15 · 758 阅读 · 0 评论 -
可延迟函数、内核微线程以及工作队列
本文研究多个用于在内核环境当中延迟处理的方法(特别是在 Linux 内核版本 2.6.27.14 当中)。 尽管这些方法针对 Linux 内核,但方法背后的理念, 对于系统架构研究具有更广泛的意义。例如, 可以将这些理念应用到传统的嵌入式系统当中,取代原有的调度程序来进行任务调度 。在开始研究用于内核中的可延迟函数之前, 让我们先了解一下相关问题的背景情况。 操作系统会因为一个硬件事件而产生中转载 2010-07-30 11:21:00 · 887 阅读 · 0 评论 -
proc文件系统编程
proc文件系统是一种虚拟的文件系统,它只存在于内存当中,一般用来在内核中输出一些信息到用户层,通常可以利用其来打印内核程序中的一些调试信息,具体的操作如下代码。 #include #include #include #include MODULE_LICENSE("Dual BSD/GPL");MODULE_AUTHOR("fuyajun1983cn@yahoo.com.cn原创 2011-10-14 20:55:32 · 1945 阅读 · 0 评论 -
linux内核中操作文件的方法--使用get_fs()和set_fs(KERNEL_DS)
#include linux/kernel.h>#include linux/module.h>#include linux/init.h>#include linux/fs.h>#include linux/string.h>#include linux/mm.h>#include linux/syscalls.h>#include asm/unistd.h>#i转载 2013-03-19 13:52:19 · 13496 阅读 · 0 评论 -
内核变量——Jiffies
全局变量jiffies表示自系统启动以来系统产生的嘀嗒数。当启动时,内核初始化该变量为0。每次时钟中断就会增1,所以系统运行时候可以计算为:jiffies/HZ秒。 jiffies变量定义如下:extern unsigned long volatile jiffies;将jiffies转换为秒:(jiffies / HZ)。将秒换算为jiffies:(seconds*HZ)原创 2012-06-26 23:09:48 · 967 阅读 · 0 评论 -
ldd3随书源码移植
最近,因工作需要,重新温习了一遍LDD3这本经典的内核编程方面的指南,当然不免玩了一下随书的源码。在GitHub找了一份已经移植到2.6.37的版本上,不过,由于现在内核使用的版本已经进入了3.x时代,放到内核3.13的版本上编译一下,发现接口还是改变了不少,于是,在学习期间,顺便对例子的代码进行了修改,使其能够在3.13内核版本上进行编译, 目前修改工作已经完成,欢迎有同样需求的同学稳步如下地址下原创 2016-01-24 16:23:27 · 1059 阅读 · 0 评论 -
等待队列——休眠与唤醒
<!--@page {margin:0.79in}p {margin-bottom:0.08in}-->内核中的休眠是通过等待队列来处理的。等待队列是一个由正在等待某个事件发生的进程组成的一个简单链表。在内核用wait_queue_head_t来表示。<!--@page {margin:0.79in}p {margin-bottom:0.原创 2012-03-29 20:58:29 · 2286 阅读 · 0 评论 -
I/O端口和I/O内存
I/O端口和I/O内存每个外设都是通过读写它的寄存器来控制的。通常,通过内存地址空间或I/O地址空间进行访问。在硬件层面上,I/O区域与内存区域(DRAM)在概念上没有区别,它们都是通过在地址总线和控制总线上触发电信号来进行读写操作。根据处理器的不同,有些处理如X86拥有独立的外设地址空间,以区别普通的内存地址空间。针对I/O端口,会提供特殊的CPU访问指令。而有些处理器则使用统一的地址空间。原创 2014-02-21 18:35:56 · 1024 阅读 · 0 评论 -
Direct I/O
通常情况下,大多数I/O操作在内核层次上都会进行数据缓冲,以提高性能。然后,有些情况下,直接对用户空间的缓冲区进行I/O读写操作可能更能提高性能和数据传输速率,特别针对大数据传递的情形,这样将省去了将数据从内核空间复制到用户空间的操作,从而节省了传输时间。当然,在使用Direct I/O之间,也有必要了解下它的一些开销,毕竟,天下没有免费的午餐。首先,启用Direct I/O,意味着将失去原创 2014-01-20 18:31:49 · 2885 阅读 · 0 评论 -
大块数据申请及DMA
在内核中有时需要申请一段大内存,方法之一是可以采取如下方法:示例: 如何将1M的物理内存作为私人使用(假设物理内存大小为256M):1. 在内核启动时,通过mem=255M参数,让内核只能使用255M的空间。2. 然后通过如下调用来使用这个1M的私人空间: dmabuf= ioremap (0xFF00000 /* 255M */, 0x100000 /* 1M */)原创 2014-01-20 18:41:49 · 9388 阅读 · 0 评论 -
内核中的几种内存分配器
<!--@page {margin:0.79in}p {margin-bottom:0.08in}-->内存管理是内核是最复杂同时也是最重要的一部分,其中就涉及到了多种内存分配器,如果内核初始化阶段使用的bootmem分配器,分配大块内存的伙伴系统,以及其分配较小块内存的slab、slub和slob分配器。1.bootmem分配器bootmem分原创 2011-10-30 17:05:58 · 2962 阅读 · 0 评论 -
[内存管理] linux kernel内存映射实例分析
作者:JHJ(jianghuijun211@gmail.com)日期:2012/08/24欢迎转载,请注明出处 引子现在android智能手机市场异常火热,硬件升级非常迅猛,arm cortex A9 + 1GB DDR似乎已经跟不上主流配置了。虽说硬件是王道,可我们还是不禁还怀疑这么强大的硬件配置得到充分利用了吗?因此以后我都会正对ARM平台分析kernel的转载 2013-07-03 15:37:35 · 1593 阅读 · 0 评论 -
利用CMake编译内核模块
最近在做LDD书上的一些例子, 为了统一管理代码的编译,使内核模块的编译跟应用程序的编译过程一致,决定使用CMake来做工程的编译,编译脚本如下:cmake_minimum_required(VERSION 2.8)project(ldd)set(KERNEL_DIR /usr/src/linux-headers-3.2.0-48-generic-pae)function(compi原创 2013-07-09 23:19:45 · 8495 阅读 · 0 评论 -
内核中断下半部机制
<!--@page {margin:0.79in}p {margin-bottom:0.08in}-->下半部的主要任务就是执行中断相关的,不在中断处理器中执行的工作。如何将中断任务分为上下两部分分别执行呢,如下提供一些参考:如果工作对时间敏感,那么在中断处理器中执行。如果工作与硬件相关,在中断处理器中执行。如果工作需要确保另一个原创 2012-04-06 23:53:26 · 14482 阅读 · 0 评论 -
内核数据结构之队列
<!--@page {margin:0.79in}p {margin-bottom:0.08in}-->在操作系统内核中,一个常见的编程模式就是生产者和消费者。实现这种模式的最容易的方式就是队列。生产者将数据插入队列,消费者将数据移出队列。消费者以数据进队的顺序消费数据。内核中通用队列的实现称为kfifo,其实现文件位于kernel/kfifo.c中。本部分原创 2012-03-30 23:53:16 · 3942 阅读 · 0 评论 -
Linux内核模块
Linux内核的整体结构非常庞大,其包含的组件也非常多,我们需要包含所需的部分功能组件。有两种方法:一种是将所需的功能组件编译进内核。二是,将所需的功能组件编译成独立于内核的模块,需要时动态加载进内核。通常采用第二种方式,它的好处是:n 模块本身不被编译入内核映像,从而控制了内核的大小。n 模块一旦被加载,它就和内核中的其他部分完全一样。一个简单的内核模块的例子:原创 2012-08-08 23:19:14 · 1021 阅读 · 0 评论 -
进程管理
<!--@page {margin:0.79in}p {margin-bottom:0.08in}-->进程创建使用系统调用fork()或vfork(),在内核中,这些函数是通过clone()系统调用完成的。进程通过系统调用exit()退出。父进程通过系统调用wait4()系统调用来查询一个停止的子进程的状态。基于wait4()系统调用的C函数有wait(),w原创 2012-03-02 20:25:08 · 152 阅读 · 0 评论 -
内核同步机制——完成量
<!--@page {margin:0.79in}p {margin-bottom:0.08in}-->内核中的许多部分初始化某些活动为单独的执行线程,然后等待这些线程完成。完成接口是一种有效并简单的方式来实现这样的代码模式。<!--@page {margin:0.79in}p {margin-bottom:0.08in}-->原创 2012-03-02 20:18:27 · 884 阅读 · 0 评论 -
内核同步机制——互斥量
<!--@page {margin:0.79in}p {margin-bottom:0.08in}--><!--@page {margin:0.79in}p {margin-bottom:0.08in}-->互斥量数组结构:structmutex.静态定义:DEFINE_MUTEX(name);动态初始化:mute原创 2012-03-02 20:14:53 · 605 阅读 · 0 评论 -
内核同步机制——信号量
<!--@page {margin:0.79in}p {margin-bottom:0.08in}-->1.通用版信号量用于对一个或多个资源进行互斥访问。基本操作如下:void sema_init(struct semaphore *sem, int val);//信号量初始化函数静态初始化:DECLARE_MUTEX(name);//初始化为1原创 2012-02-11 15:51:47 · 709 阅读 · 0 评论 -
在i386平台Linux 2.6 上实现一个系统调用
<!--@page {margin:0.79in}p {margin-bottom:0.08in}--> 1. 引言本文档解释了怎样在Linux2.6中实现一个新的系统调用。一个系统调用被应用程序用来向操作系统请求服务。<!--@page {margin:0.79in}p {margin-bottom:0.08in}-->翻译 2012-02-11 15:42:12 · 953 阅读 · 0 评论 -
内核同步机制——自旋锁
由于关键代码区可以跨越了多个函数或数据结构,需要有更通用的同步方法:锁。内核中最常见的一种锁就是自旋锁。相同的锁可用于多处。自旋锁可用在不可睡眠的场景,如中断处理函数。自旋锁是一种互斥设备,只有两个值:“锁定”和“非锁定”。它通常实现为一个整数值的某个比特位。想获取某个锁的代码首先测试相关的位,如果锁可得,则该位的“锁定”位被置位,代码继续执行,反之,代码将进入一个紧凑的循环,不停地检测锁原创 2012-02-10 21:00:36 · 1247 阅读 · 0 评论 -
内核同步机制——原子操作
内核为原子操作提供了两组接口。一组操作整数,一个组操作比特位。1.整数原子操作数据类型为:typedefstruct {volatileint counter;}atomic_t;为了保持内核在各个平台兼容,以前规定atomic_t的值不能超过24位(都是SPARC惹的祸),不过现在该规定已经不需要了。相关操作如下:voidatomic_set(原创 2011-11-01 23:31:48 · 877 阅读 · 0 评论 -
内核中的通知链
通知链(Notifier Chains):通知链用于向请求通知的代码区发送状态变化消息。有几个内核中预定义的通知器:l Die Notification: 当一个内核函数触发了一个由“opps”引起的陷阱或错误时。l Net device notificati原创 2011-10-14 20:52:32 · 1559 阅读 · 0 评论 -
条件编译在内核中的使用(技巧1)
当需要根据编译时配置,以不同方式执行某一任务时,一种可能的方法是,使用两个不同的函数,每次调用时,根据某些预处理器条件来的选择正确的一个:void do_somehting(){…#ifdef CONFIG_WORK_HARDdo_work_fast();原创 2011-10-14 20:51:01 · 957 阅读 · 0 评论 -
内核数据结构之链表
<!--@page {margin:0.79in}p {margin-bottom:0.08in}-->内核中的许多数据结构都是通过链表来的维护的,Linux内核提供了链表的通用处理操作,供内核中其他数据结构使用。只需将链表结构嵌入到目标数据结原创 2011-08-28 16:47:08 · 605 阅读 · 0 评论 -
内核线程
内核线程可以用户两种方法实现:1. 古老的方法创建内核线程:ret = kernel_thread(mykthread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD); 内核线程方法的实现static DECLARE_WAIT_QUEUE_HEAD(myevent_waitqueue);rwlock_t原创 2011-06-29 21:23:00 · 688 阅读 · 0 评论 -
系统调用
<!--@page {margin:0.79in}p {margin-bottom:0.08in}-->用户程序请求内核程序为其服务主要通过以下几种方式:中断系统调用信号其中,系统调用是一种常见方式,它在用户进程与硬件之间提供了一个层,该层主要提供以下三个目的:它为用户空间提供了一个抽象的硬件接口它确保了系原创 2012-03-24 17:46:35 · 694 阅读 · 0 评论 -
内核热插拔管理
<!--@page {margin:0.79in}p {margin-bottom:0.08in}-->在可插拔的总线如USB(和CardbusPCI)中,终端用户在主机运行时将设备插入到总线上。在大部分情况下,用户期望设备立即可用。这意味着系统必须作许多事情,包括:找到一个可以处理设备的驱动。它可能包括装载一个内核模块,较新的驱动可以用模块初始化工原创 2012-03-24 17:42:52 · 923 阅读 · 0 评论