- 博客(306)
- 资源 (14)
- 收藏
- 关注

原创 分享我的疯狂Linux内核知识
<br />距离2011年的6月不到半个小时了,从2009年的6月,我开始接触Linux以来,从安装第一个Linux到配置Linux网卡,从熟悉各种命令到使用标准glibc库进行编程,从学习PC汇编基础知识到能读懂Linux内核源代码,风风雨雨走过了整整两年。<br /> <br />两年前的我,还是个不知名小公司的PHP初级程序员;如今已是国内某著名公司的下一代云存储产品核心开发团队的一员。伴我走过的,是700多个csdn夜晚。每当我每看懂一个ULK章节,我就疯狂地把这个章节的内容记录到优快云博客中,因
2011-05-31 23:51:00
12190
12
原创 内核态基本套接字编程
1 建立监听和连接服务 服务端建立tco监听的代码如下:struct sockaddr_in locaddr;struct socket *sock;struct socket *newsock;int rc;int backlog = 0;int shutd
2013-08-04 20:42:00
5541
转载 一个简单的内核线程
一个简单的linux内核线程的例子,根据精通linux设备驱动上的代码整合而成。#include #include #include #include MODULE_LICENSE("GPL");static DECLARE_WAIT_QUEUE_HEAD(myevent_waitqueue); //声明了一个等待队列头,我们可以将要睡眠的进程放入本列表static struc
2013-07-25 16:52:29
3694
原创 64位x86体系Linux内核进程切换
首先简单提一下这个宏和函数的被调用关系: schedule() --> context_switch() --> switch_to --> __switch_to() 这里面,schedule是唯一调用switch_to的函数,涉及到一些调度算法,这里不讨论。当schedule()需要暂停A进程的执行而继续B进程的执行时,就发生了进程之间的切换。进程切换主要有两大步:1、
2013-01-27 21:30:04
6156
转载 调用函数时 寄存器到底发生了那些变化
一直存在比较模糊的概念,因此用一个例子强化记忆。Linux x86 gcc3.2.3 AT&T格式的汇编代码如下: void fun() { int a = 'A'; } void main() { int b; fun(); return; } 开始调试 [sanool@sanool ex2]$ gd
2013-01-27 21:14:41
3645
原创 树及树的算法(5) —— B树(上)
1970年,鲁道夫·贝尔(R.Bayer)的先于红黑树提出了B树。这种适用于外查找的树,是一种平衡的多叉树,又称B-树。 B树与红黑树最大的不同在于,B树的结点可以有许多子女,从几个到几千个。那为什么又说B树与红黑树很相似呢?因为与红黑树一样,一棵含n个结点的B树的高度也为O(log2n),但可能比一棵红黑树的高度小许多,应为它的分支因子比较大。所以,B树可以在O(log2n)时间内,实现
2012-07-30 00:45:55
4791
原创 树及树的算法(4) —— 红黑树
红黑树是在1972年由德国科学家鲁道夫·贝尔发明的,他称之为“对称二叉B树”,它现代的名字是在 Leo J. Guibas和 Robert Sedgewick 于1978年写的一篇论文中获得的。红黑树的实现是很复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的:它可以在O(log n)时间内做查找,插入和删除,这里的n是树中元素的数目。图:鲁道夫·贝尔 红黑树和
2012-05-31 23:17:41
6200
原创 树及树的算法(3) —— 平衡二叉树
在计算机科学中,平衡二叉树(AVL树)是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下都是O(log n)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。AVL树得名于它的发明者是前苏联数学家G.M. Adelson-Velsky和E.M. Landis,他们在1962年的论文《An al
2012-05-31 23:10:56
2872
原创 树及树的算法(2) —— 二叉查找树
二叉查找树(Binary Search Tree,简称BST),或者是一棵空树,或者是具有下列性质的二叉树:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。二叉排序树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉排序树的存储结构。中序遍历二叉排序树可得到一个关键字的
2012-05-31 23:06:27
2705
原创 树及树的算法(1) —— 二叉树
从现在开始,我们研究算法理论中最重要的树的实现问题,其中包括抽象树、N叉树及二叉树,这里重点研究二叉树。树状图是一种数据结构,它是由n(n>=1)个有限结点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:每个结点有零个或多个子结点;每一个子结点只有一个父结点;没有前驱的结点为根结点;除了根结点外,每个子结点可以分为m个不相交
2012-05-31 22:55:09
3066
原创 基本数据结构(5) —— 有序表
1 有序线性表有序线性表是最基本的可搜索容器,其提供除了可搜索容器的操作,还有自己的一些基本操作。那么什么是可搜索容器呢,可搜索容器定义如下:class SearchableContainer : public virtual Container{public: virtual bool IsMember (Object const&) const = 0; virtual
2012-04-29 23:27:50
4032
原创 基本数据结构(4) —— 队列
队列,又称为伫列(英文queue),与栈想反,是先进先出(FIFO, First-In-First-Out)的线性表。在具体应用中通常用链表或者数组来实现。队列只允许在后端(称为rear)进行插入操作,在前端(称为front)进行删除操作。 队列的操作方式和栈类似,唯一的区别在于队列只允许新数据在后端进行添加。 队列的架构设计如下:抽象队列的实现如下:class Que
2012-04-29 22:57:27
2773
原创 基本数据结构(3) —— 栈
1 栈栈(stack),在计算机科学中,是一种特殊的串行形式的数据结构,它的特殊之处在于只能允许在链结串行或阵列的一端(称为栈顶,top)进行加入(push)和输出(pop)的运算。栈可以用一维动态数组或链表的形式来完成。 由于堆栈数据结构只允许在一端进行操作,因而按照后进先出(LIFO, Last In First Out)的原理运作。堆栈数据结构使用两种基本操作:推入(push)和
2012-04-29 21:51:07
2760
原创 基本数据结构(2) —— 链表
链表开发于1955-56,由当时所属于兰德公司(英语:RAND Corporation)的艾伦纽维尔(Allen Newell),克里夫肖(Cliff Shaw)和赫伯特西蒙(Herbert Simon)在他们编写的信息处理语言(IPL)中做为原始数据类型所编写。IPL被作者们用来开发几种早期的人工智能程序,包括逻辑推理机,通用问题解算器和一个计算机象棋程序。 链表的形态主要有单链表、
2012-04-29 21:37:54
2754
原创 基本数据结构(1) —— 动态数组
我们设计动态数组的目的在于,利用C++模板技术,消除C++语言中对数组的种种限制,如数组无法成为函数的参数或返回值(除非是指针),数组无法直接赋值等等。1 一维动态数组 一维动态数组将一个普通数组封装成data: 来看具体实现: template class Array{protected: T* data; unsigned int base;
2012-04-29 21:32:11
3449
原创 路径名查找
当进程要使用一个文件时,如open()、mkdir()、rename()或stat()等,就要首先进行路径名查找,即是将人类易于识别的字符串形式路径名,转换为一个文件在内核中的内部表示,也就是目录项、vfsmount和inode等。 执行这一任务的标准过程就是分析路径名并把它拆分成一个文件名序列。除了最后一个项以外,所有的文件名都必定是目录。如果路径名的第一个字符是“/”,例如:/usr/
2012-04-15 21:28:47
3235
转载 linux 32位平台,文件大小受限于2G的解决方法
公司的asterisk系统已经发生了两次crash,检查日志,都是在日志文件写满到2G后自动执行转储时,日志还在写继续写入而导致的。google以后,发现了下面这边文章,赞!解决了文件大小限于2G的问题,转帖到自己的空间保留。突破Linux上面ftell函数2GB的文件大小限制http://www.demix.cn/h?z=28507在 32 位元的 Linux 上面写超过 2
2012-03-05 20:18:21
6189
转载 代理模式
代理类其实就是代理模式的应用。Proxy模式为其他对象提供一种代理以控制这个对象的访问。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层,这个访问层也叫代理。Proxy模式是最常见的模式,在我们生活中处处可见。1、实现二维数组。C++中数
2012-01-03 23:15:35
3225
转载 C++ Virtual详解
Virtual是C++ OO机制中很重要的一个关键字。只要是学过C++的人都知道在类Base中加了Virtual关键字的函数就是虚拟函数(例如函数print),于是在Base的派生类Derived中就可以通过重写虚拟函数来实现对基类虚拟函数的覆盖。当基类Base的指针point指向派生类Derived的对象时,对point的print函数的调用实际上是调用了Derived的print函数而不是Ba
2012-01-03 23:14:48
2724
原创 中级程序员必须懂的20大基础算法(1)——快速排序
算法的入门级研究一般都是从“排序”和“查找”开始的。“排序算法”和她的姊妹“查找算法”是很多复杂算法的基础,也是很多复杂系统的基础。比如Linux中最复杂的虚拟内存管理就是基于“红-黑树”查找算法的;Solaris是基于AVL树查找算法;MySQL是基于B树查找算法;P2P技术是
2011-10-07 18:52:33
9315
1
原创 算法的概念
问题 算法是什么?第一次接触到这个概念是10年前上大一的时候,《数据结构》这门课程首先遇到的。书上说,算法是一个用来解决一个良定义计算问题的工具。那么经历了这么多年程序员的生活,回头再想一想,算法到底是什么呢? 首先,算法是用来解决问题的,所以,我们要仔细思考一下什么是问题?个人的一点遇见认为,问题来自各个领域。农民有种地的问题,工人有领工资的问题,那么计算机算法研究的问题,主要是
2011-06-05 23:59:00
3396
转载 C语言中函数参数的入栈顺序
<br />对技术执着的人,比如说我,往往对一些问题,不仅想做到“知其然”,还想做到“知其所以然”。C语言可谓博大精深,即使我已经有多年的开发经验,可还是有许多问题不知其所以然。某天某地某人问我,C语言中函数参数的入栈顺序如何?从右至左,我随口回答。为什么是从右至左呢?我终究没有给出合理的解释。于是,只好做了个作业,于是有了这篇小博文。<br /><br />#include <stdio.h><br /><br />void foo(int x, int y, int z)<br />{<br />
2011-03-07 13:44:00
2623
3
原创 启动shell环境
6.3 启动shell环境<br />init_post函数来自同一个文件的814行:<br /> <br />811/* This is a non __init function. Force it to be noinline otherwise gcc<br /> 812 * makes it inline to init() and it becomes part of init.text section<br /> 813 */<br /> 814static noinline int init
2011-02-01 02:52:00
2174
原创 子系统的初始化
6.2 子系统的初始化<br />所以接下来说do_basic_setup函数,任然是来自init/main.c:<br /> <br />778/*<br /> 779 * Ok, the machine is now initialized. None of the devices<br /> 780 * have been touched yet, but the CPU subsystem is up and<br /> 781 * running, and memory and process m
2011-02-01 02:49:00
3245
原创 创建1号进程
6 后start_kernel时代<br />至此,start_kernel()函数完成了Linux内核的初始化工作。几乎每天内核部件都是由这个函数进行初始化的,下面让我们再来回顾一下其中最重要的部分:<br /> <br />● 调用setup_arch()函数,根据处理器硬件平台设置系统;解析linux命令行参数;设置0号进程的内存描述结构init_mm;系统内存管理初始化;统计并注册系统各种资源;以及其它项目的初始化等。<br />● 调用sched_init()函数来初始化调度程序。<br />
2011-02-01 02:42:00
2885
5
原创 安装根文件系统
5.12 安装根文件系统<br />start_kernel下步是另一个重要的函数,678行的vfs_caches_init,用于初始化VFS那些数据结构的slab缓存,来自fs/dcache.c:<br /> <br />2355void __init vfs_caches_init(unsigned long mempages)<br />2356{<br />2357 unsigned long reserve;<br />2358<br />2359 /* Base ha
2011-02-01 02:40:00
3057
原创 走进start_kernel尾声
5.11 走进start_kernel尾声<br />中断体系建立起来后,虽然后面还有很多行代码,但是都是些比较好理解的初始化函数了,也就是说start_kernel进入尾声了。5.11.1 初始化slab的后续工作<br />继续分析start_kenel的下一个函数,613行,profile_init函数,用于对系统剖析做相关初始化,系统剖析用于系统调用:<br /> <br />int __ref profile_init(void)<br />{<br /> int buffer_byt
2011-02-01 02:36:00
3402
原创 初始化定时器中断
5.10.4 初始化定时器中断<br />回到start_kernel,612行time_init函数:<br />void __init time_init(void)<br />{<br /> late_time_init = x86_late_time_init;<br />}<br /> <br />函数x86_late_time_init实际上是初始化tsc时钟源。在time_init中只是把该函数的地址赋给全局变量late_time_init,以后某个时刻肯定会调用它的,这里先提前详
2011-02-01 02:34:00
3270
原创 软中断初始化
5.10.3软中断初始化<br />open_softirq结束后,init_timers就结束了,整个内核就可以享受时钟服务了,接下来start_kernel的609行调用hrtimers_init。由于我们没有配置CONFIG_HIGH_RES_TIMERS,所以这个函数仅仅是把全局notifier_block变量hrtimer_cpu_notify加入通知链,供将来的内核各模块使用。<br /> <br />然后,start_kernel的610行调用softirq_init来初始化整个软中断系统:<
2011-02-01 02:33:00
2513
原创 初始化本地软时钟
5.10.2 初始化本地软时钟<br />native_init_IRQ结束后,init_IRQ也就结束了,回到start_kernel中,607行,prio_tree_init函数很简单:<br /> <br />void __init prio_tree_init(void)<br />{<br /> unsigned int i;<br /> <br /> for (i = 0; i < ARRAY_SIZE(index_bits_to_maxindex) - 1; i++)<
2011-02-01 02:32:00
2556
原创 设置APIC中断服务
5.10 初始化中断处理系统<br />start_kernel接下来要做的事是初始化中断处理系统。整个内核的中断系统的核心就是我们在“初始化中断描述符表”里面设置的那个中断描述符表。而这个表的前19个表项我们已经在“初始化异常服务”中设置为了一些中断和异常的服务。内核接下来会如何设置其余的表项呢?<br /> <br />前面提到过高级可编程中断控制器APIC,这里简单地提一下它的体系结构,简单地说就是由两部分组成:本地高级中断控制器(Local APIC,LAPIC),位于每个CPU中,主要负责传递中断
2011-02-01 02:30:00
4772
原创 初始化调度程序
5.9 初始化调度程序<br />回到start_kernel函数中,mm_init()执行后,所有的绝大多数内存管理的初始化都完毕,后面的代码可以开开心心的使用Linux复杂、庞大而又高效的内存管理器了。来看下一个函数,超级重点的进程调度初始化函数sched_init()。不过自从Linux 2.6.23(2007年5月),内核引入了一种所谓的完全公平调度程序(Completely Fair Scheduler,CFS),试图按照对 CPU 时间的“最大需求(gravest need)”运行任务;这有助于
2011-02-01 02:28:00
2907
原创 初始化非连续内存区
5.8.3 初始化非连续内存区<br />回到mm_init()函数,继续走,下一个函数pgtable_cache_init (),不知道咋的,是个空函数,也许是保留着以后开发吧。最后一个函数是vmalloc_init(),来自mm/vmalloc.c:<br /> <br />1088void __init vmalloc_init(void)<br />1089{<br />1090 struct vmap_area *va;<br />1091 struct vm_stru
2011-02-01 02:27:00
2241
原创 初始化slab分配器
5.8.2 初始化slab分配器<br />回到mm_init()函数,继续走,下一个函数kmem_cache_init(),也是重点函数,用于初始化内核slab分配体系。这个函数来自文件mm/slab.c<br /> <br />1375void __init kmem_cache_init(void)<br />1376{<br />1377 size_t left_over;<br />1378 struct cache_sizes *sizes;<br />1379
2011-02-01 02:25:00
2066
原创 启用伙伴算法
5.8 初始化内存管理<br />回到start_kernel,下一个函数执行mm_init()。这个函数很重要了,来自同一个文件。<br /> <br />static void __init mm_init(void)<br />{<br /> /*<br /> * page_cgroup requires countinous pages as memmap<br /> * and it's bigger than MAX_ORDER unless SPARSE
2011-02-01 02:22:00
3703
1
原创 初始化异常服务
5.7 初始化异常服务<br />继续走,start_kernel的583行,sort_main_extable,把编译期间,kbuild设置的异常表,也就是__start___ex_table和__stop___ex_table之中的所有元素进行排序。<br /> <br />584行,调用trap_init函数,重要的函数,初始化中断向量表。该函数来自arch/x86/kernel/traps.c<br /> <br />882void __init trap_init(void)<br /> 883{
2011-02-01 02:20:00
3190
原创 触碰虚拟文件系统
5.6 触碰虚拟文件系统<br />回到start_kernel中,下面我们该第一次接触文件系统了,582行执行vfs_caches_init_early:<br /> <br />void __init vfs_caches_init_early(void)<br />{<br /> dcache_init_early();<br /> inode_init_early();<br />}<br /> <br />vfs_caches_init_early调用两个函数dcache_
2011-02-01 02:19:00
2768
原创 利用early_res分配内存
5.5 利用early_res分配内存<br />回到start_kernel中,570行,page_alloc_init()函数:<br />void __init page_alloc_init(void)<br />{<br /> hotcpu_notifier(page_alloc_cpu_notify, 0);<br />}<br /> <br />这个函数会调用hotcpu_notifier函数。当然,在编译选项CONFIG_HOTPLUG_CPU起作用时,这个函数才有效。这个编译选
2011-02-01 02:13:00
2527
原创 初始化内存管理区列表
5.4 初始化内存管理区列表<br />回到start_kernel函数,569行的build_all_zonelists()函数,来自mm/page_alloc.c:<br /> <br />2815void build_all_zonelists(void)<br />2816{<br />2817 set_zonelist_order();<br />2818<br />2819 if (system_state == SYSTEM_BOOTING) {<br />2820
2011-02-01 02:11:00
3452
原创 设置每CPU环境
5.3 设置每CPU环境<br />回到start_kernel,563行调用mm_init_owner函数,将init_mm的owner字段指回init_task。这个函数可以说进入start_kernel以来最简单的函数了。继续走,setup_command_line也很简单:<br /> <br />static void __init setup_command_line(char *command_line)<br />{<br /> saved_command_line = allo
2011-02-01 02:09:00
6301
NFS文件系统
2012-04-08
数据结构与算法——面向对象C++设计模式
2011-11-27
高性能分布式监控系统Ganglia详解
2011-07-10
疯狂内核之——内核初始化
2011-05-30
疯狂内核之——Linux虚拟内存
2011-05-30
疯狂内核之——虚拟文件系统
2011-05-30
疯狂内核之——进程管理子系统
2011-05-30
疯狂内核之——Linux预备知识.pdf
2011-05-30
23种GoF设计模式Java版.pdf
2011-05-29
从8086到Pentium Ⅲ微型计算机及接口技术3
2010-09-24
Linux sysfs 文件系统机制详解
2009-12-14
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人