linux内核源码学习
天堂1223
这个作者很懒,什么都没留下…
展开
-
linux内核list.h的学习
这个是学习linux内核的第一篇文章,所有的学习内容都在list.h的注释里面,直接上代码。#ifndef _LINUX_LIST_H#define _LINUX_LIST_H#ifdef __KERNEL__#include #include #include #include /* * Simple doubly linked l原创 2015-04-01 15:23:01 · 2385 阅读 · 0 评论 -
进程调度(四)
紧接上一篇!!(二)抢占和进程上下文上下文切换,就是从一个可执行进程切换到另一个可执行进程,由定义在kernel/sched.c中的context_switch()函数处理,该函数主要完成两项基本工作:1:调用声明在asm/mmu_context.h中的switch_mm(),该函数负责把虚拟内存从上一个进程映射切换到新进程中。2:调用声明在asm/system.h文件中的switch_to(原创 2015-06-23 11:13:22 · 942 阅读 · 0 评论 -
中断与中断处理(二)
**书接上回**(六):中断上下文当执行一个中断处理程序的时候,内核处于中断上下文中.中断上下文由于没有后备进程,所以不可以睡眠,同时中断上下文具有严格的时间限制,因为他打断了其他代码.中断处理程序栈的设置是一个配置选项.原来的时候,中断处理程序共享所中断进程的内核栈,大小是两页的大小,即在32位系统上是8KB,在64位系统上是16KB.现在每一个中断处理程序都有自己的一个中断栈,大小是原来的一半,原创 2015-07-13 09:22:50 · 2040 阅读 · 0 评论 -
中断和中断处理(一)
(一):中断中断本质上是一种特殊的电信号,由硬件设备发向处理器。处理器在接收到中断后,会马上向操作系统反映此信号的到来,然后就u由操作系统来处理这些新到来的数据。不同的设备对应的中断不同,而每个中断都通过一个唯一的数字标志。这些中断值被称为中断请求线(IRQ)。中断是随时随地发生的,也就是说中断并不考虑与处理器的时钟同步。异常:异常的产生必须与处理器时钟同步,异常也被成为同步中断。在处理器执行到由于原创 2015-07-13 07:45:34 · 3327 阅读 · 2 评论 -
从内核出发
(一):内核源码的获取 1:通过网站 https://www.kernel.org/ 可以获得最新版本的内核源码,现在最新版的内核源码版本为如果想要获取之前版本的内核源码,点击进入 https://www.kernel.org/pub/ 进入分支。在《linux内核的设计与实现》的这本书中,我们使用的是 内核版本 2.6.18.2:从git中获取linux内核源码 在t原创 2015-06-15 15:55:02 · 933 阅读 · 0 评论 -
进程管理(二)
进程描述符中包含的数据能完整地描述一个正在执行的程序:他打开的文件,进程的地址空间,挂起的信号,进程的状态等。1:分配进程描述符linux通过使用slab分配器分配task_struct结构,这样能够达到对象复用和缓存着色的目的。现在只需在栈底或栈顶创建一个新的结构struct thread_info结构即可。首先我们先看一下thread_info的结构:struct thread_info {原创 2015-06-16 01:10:59 · 805 阅读 · 0 评论 -
进程管理(一)
(一):进程的概念线程,是在进程中活动的对象。每个线程都拥有一个独立的程序计数器,进程栈和一组进程寄存器。内核调度的是线程而不是进程。在Linux中,进程和线程的区别比较微妙,一会我们通过源码来查看其两个的区别。进程提供两种虚拟机制,虚拟处理器和虚拟内存。其中在线程之间可以共享虚拟内存,但是每个线程都拥有各自的虚拟处理器。在linux中,创建一个进程的函数是fork(),该系统调用通过复制一个现有原创 2015-06-16 01:00:12 · 898 阅读 · 0 评论 -
下半部和推后执行的工作--tasklet
(一):tasklettasklet是利用软中断实现的一种下半部机制,他和进程没有任何关系,他在本质上和软中断是相似的,行为表现也很相近.但是他的接口很简单,锁保护也要求较低.1:tasklet的实现tasklet有两类软中断代表:HI_SOFTIRQ和TASKLET_SOFTIRQ.这两者之间唯一的实际区别在于,HI_SOFTIRQ类型的软中断先于TASKLET_SOFTIRQ类型的软中断执行.1原创 2015-09-02 10:42:46 · 811 阅读 · 0 评论 -
内核同步介绍
(一):临界区和竞争条件所谓临界区(也称为临界段)就是访问和操作共享数据的代码段.多个执行线程并发访问同一个资源通常是不安全的,为了避免在临界区中并发访问,编程者必须保证这些代码原子的执行--也就是说,操作在执行结束前不能被打断,就如同整个临界区是一个不可分割的指令一样.如果两个执行线程有可能处于同一个临界区中同时执行,那么这就是程序包含的一个bug.如果这种情况确实发生了,我们就成他是竞争条件,这原创 2015-09-09 17:19:08 · 609 阅读 · 0 评论 -
下半部和下半部执行的工作--工作队列
工作队列(work queue)是另外一种将工作推后执行的形式.他和其他形式都不相同.工作队列可以把工作推后,交由一个内核线程去执行,这个下半部分总是会在进程上下文中去执行.这样,通过工作队列执行的代码能占尽进程上下文的所有优势.最重要的是工作队列能允许重新调度甚至是休眠.通常,在工作队列和软中断/tasklet中做出选择非常容易.如果推后执行的任务需要睡眠,那么就选择工作队列,如果不需要睡眠,就选原创 2015-09-06 23:35:48 · 1438 阅读 · 0 评论 -
下半部和推后执行的工作
(一):下半部下半部的任务就是执行与中断处理密切相关但中断处理程序本身不执行的工作.那么有一些提示可以借鉴哪些工作放在上半部中执行,哪些工作放在下半部执行.1:如果一个任务对时间非常敏感,将其放在中断处理程序中进行2:如果一个任务与硬件相关,将其放在中断处理程序中进行3:如果一个任务保证不被其他中断打断,将其放在中断处理程序中进行4:其他所有任务,考虑放在下半部执行1:为什么要用下半部我们希原创 2015-08-21 14:27:00 · 1123 阅读 · 0 评论 -
Linux内核源码(asm/bitops/atomic.h)学习
在之前的一篇博客中,着重讲解了在Linux内核中同步方法--对于整型的原子操作,除此之外,内核同步方法中还有对位的原子操作.下面我们来列举一下原子位操作的列表: 原子位操作 描述 void set_bit(int nr, volatile unsigned long *addr) 原子的设置addr所指对象的第nr位 void clear_bit(int nr, volatile原创 2015-10-12 17:12:49 · 1480 阅读 · 0 评论 -
Linux内核源码(asm/atomic.h)学习
由于现在正在看Linux下的内核同步方法,其中第一个提到的就是原子变量,其中会有原子操作.其中原子变量被定义在linux/types.h头文件中,在这一篇博客中,主要学习原子操作,这些原子操作的函数被定义在asm/atomic.h文件中,其中包括,初始化,原子读,原子更改等操作,下面我们来看一下内核源码,其中,有我的一些注释,这个是比较简单的,因为,该原子变量的操作是由体系结构的指令操作的.只因为他原创 2015-10-12 14:03:06 · 4581 阅读 · 0 评论 -
系统调用(二)
(五):系统调用的实现1:实现系统调用实现一个系统调用就是考虑他的用途,每一个系统调用都有一个确定的用途,在Linux中不提倡采用多用途的系统调用(一个系统调用通过传递不同的参数值来选择完成不同的工作)。2:参数验证系统调用必须仔细检查他们所有的参数是否合法有效。最重要的一项检查就是检查用户提供的指针是否有效。 在接收一个用户空间的指针之前,内核必须保证:1:指针指向的内存区域属于用户空间,进程原创 2015-06-23 20:35:29 · 974 阅读 · 0 评论 -
进程调度(三)
(一)睡眠和唤醒休眠(被阻塞)的进程处于一个特殊的不可执行状态。无论什么原因,导致进程进入休眠状态,内核的操作都是相同的:进程把自己标志成休眠状态,从可执行红黑树中移出,放入等待队列,然后调用schedule()选择和执行一个其他进程。唤醒的过程正好相反,进程把自己标志成可运行状态,然后再从等待队列中移到可执行红黑树中。1:等待队列 休眠通过等待队列进程处理,等待队列是由等待某些事件的发生的进程组原创 2015-06-23 11:08:10 · 818 阅读 · 0 评论 -
types.h头文件学习
types.h头文件纵观,就可以看出是对一些数据类型的重命名或者是定义,以及对DMA通用地址的定义以及其64为的特性。下面是types.h头文件的源代码,主要的学习内容都在注释当中。#ifndef _I386_TYPES_H#define _I386_TYPES_H#ifndef __ASSEMBLY__/** * 纵观这个头文件,发现该头文件主要是用来给 * 定义类型以及给类型重新命名的原创 2015-04-18 22:39:39 · 3920 阅读 · 1 评论 -
内核compiler.h的学习
直接上代码就可以了,所以的学习都在注释当中呢!#ifndef __LINUX_COMPILER_H#define __LINUX_COMPILER_H#ifndef __ASSEMBLY__//如果宏定义了__CHECKER__//详细学习一个Sparse#ifdef __CHECKER__/** * 这个使用来修饰一个变量的,这个变量必须是非解除参考的,no * dereference原创 2015-04-09 17:12:02 · 1181 阅读 · 0 评论 -
内核memory barrier学习
本文例子均在 Linux(g++)下验证通过,CPU 为 X86-64 处理器架构。所有罗列的 Linux 内核代码也均在(或只在)X86-64 下有效。本文首先通过范例(以及内核代码)来解释 Memory barrier,然后介绍一个利用 Memory barrier 实现的无锁环形缓冲区。Memory barrier 简介程序在运行时内存实际的访问顺序和程序代码编写的访问顺序不一定一致,这就是内转载 2015-04-09 16:07:32 · 1116 阅读 · 0 评论 -
stddef.h头文件学习
stddef.h头文件看意思就是标准定义,定义有一些变量和宏。其中定义了NULL和offsetof()宏,NULL指向0或者是无效指针,offsetof获取一个元素在结构中的偏移量。下面看看具体的代码注释和笔记。#ifndef _LINUX_STDDEF_H#define _LINUX_STDDEF_H#include <linux/compiler.h>/* * #undef 预定义取消指令原创 2015-04-09 17:48:50 · 3283 阅读 · 1 评论 -
内核bug.h以及GCC内联汇编的学习
所有的学习的内容都在注释当中,我的学习过程是,看到这个代码段之后,将其中需要的只是去大体的学习一遍。争取能够做到理解整体的部分。 下面展示出我的学习的代码:#ifndef _I386_BUG_H#define _I386_BUG_H/* * Tell the user there is some problem. * 告诉用户出现了一些问题 * The offending file an原创 2015-04-17 14:02:08 · 1315 阅读 · 0 评论 -
GCC内联汇编
GCC,linux的GNU C编译器使用AT&T/UNIX汇编语法。 (一):AT&T汇编和intel汇编的不同 1:前缀 在intel语法中,寄存器和立即数都没有前缀,而在AT&T中,寄存器使用前缀“%”,而立即数前面使用前缀“$”; 在intel语法中,十六进制和二进制立即数后面缀以”h”和“b”,但在AT&T语法中,在前面缀以”0x”, 2:操作数的方向不同 AT&T和intel汇原创 2015-04-17 21:53:47 · 3232 阅读 · 0 评论 -
byteorder.h学习
在typeorder.h头文件中,主要定义了下面几个函数,__u32 ___arch__swab32(__u32 val),___arch__swab64(__u64 val);这两个函数的含义基本上是将32位寄存器中的字节次序变反,将64位寄存器中的字节次序变反。 举个列子,有一个以16进制表示的32位变量,a=0x12345678;其中由于其是十六进制的,所以12占一个字节,34占一个字节,5原创 2015-04-18 22:38:19 · 1688 阅读 · 0 评论 -
进程管理(四)
接着上一文,我们看一下do_fork()函数:long do_fork(unsigned long clone_flags, unsigned long stack_start, struct pt_regs *regs, unsigned long stack_size, int __user *parent_tidp原创 2015-06-16 20:55:44 · 1102 阅读 · 0 评论 -
进程管理(三)
(一):进程创建linux不同于其他操作系统,linux在进程的创建的时候,将进程的创建和执行程序分成了两个函数,fork()和exec()。进程在创建的过程中,首先通过fork()函数拷贝一份当前进程来创建一个子进程。子进程和父进程的区别仅仅在于PID,PPID(父进程的进程号,子进程将其设置为被拷贝进程的进程号)和某些资源以及统计量(被挂起的信号等)。exec()函数负责执行负责执行可执行文件并原创 2015-06-16 20:49:21 · 863 阅读 · 0 评论 -
进程调度(二)
紧接上一文!!!!3:进程选择在CFS调度里面,当需要选择下一个进程的时候,将会选择最小的vruntime的进程。这个其实就是CFS调度的算法的核心。CFS使用红黑树来组织可运行进程队列,并利用其迅速找到最小的vruntime值的进程。在Linux中,红黑树是一个子平衡的二叉搜索树。下面我们就来看一下如何挑选下一个vruntime最小的进程。1):挑选下一个任务根据红黑树的原理,假设vruntim原创 2015-06-18 21:28:09 · 890 阅读 · 0 评论 -
进程调度(一)
调度程序负责决定将哪个进程投入运行,何时运行,以及运行多长时间。进程调度程序可看作在可运行态进程之间分配有限的处理器时间资源的内核子系统。(一):多任务多任务操作系统就是能并发的交互执行多个进程的操作系统,多任务系统可以分为两类:非抢占式多任务和抢占式多任务。Linux提供了抢占式多任务,在这个模式下,由调度程序来决定什么时候停止一个进程的运行,以便其他进程能够得到执行机会,这个强制挂起的动作就叫做原创 2015-06-18 21:24:27 · 1082 阅读 · 0 评论 -
系统调用(一)
(一):与内核通信系统调用在用户空间和硬件设备之间添加了一个中间层。该层主要有三个作用:1:他为用户空间提供了一种硬件的抽象接口2:系统调用保证了系统的稳定和安全。3:每个进程都运行在虚拟系统中,而在用户空间和系统的其余部分提供这样一层公共接口,也是出于这种考虑。在Linux中,系统调用是用户空间访问内核的唯一手段。(二):API,POSIX,C库一般情况下,应用程序通过在用户空间实现的原创 2015-06-23 20:31:14 · 1182 阅读 · 0 评论 -
Linux内核同步方法(一)
LInux内核提供了一组相当完备的同步方法.(一):原子操作原子操作是其他同步方法的基石.原子操作可以保证指令以原子的方式执行--执行过程不被打断.原子原本是指不可分割的微粒,所以,原子操作也就是不能够被分割的指令.两个原子操作绝对不可能并发的访问同一个变量.内核提供了两组原子操作接口--一组针对整数的操作,另一组针对单独的位进行操作.在Linux支持的所有体系结构上都实现了这两组接口.大多数体系结原创 2015-10-13 17:13:49 · 1208 阅读 · 0 评论