
Linux内核
文章平均质量分 96
墨篙和小奶猫
车联网以及嵌入式开发 优化理论 故障诊断
展开
-
操作系统&文件管理之FCB
操作系统的外存(主要指磁盘)管理模块根据各磁盘块的当前状态(忙和闲:磁盘管理程序可配置bitmap数据结构,用来统一表示各磁盘块忙闲情况)可分为两类,一是空闲磁盘块的调度管理,二是已占用了磁盘块的文件管理。本文便讨论已使用了外存存储设备的文件的索引和读取管理。前面提到操作系统的磁盘管理为了和内存管理配合,也是将磁盘分割为最小单元进行统一调度,和内存的页帧概念对应,磁盘管理模块以磁盘块作为最小单元管理原创 2017-09-13 23:58:39 · 37647 阅读 · 4 评论 -
缓冲技术之四:LRU缓冲管理策略分析
1. LRU 调度算法 缓存淘汰算法:LRU(Least recently used,最近最少使用)算法是调度场景下(内存调度、缓存淘汰等)常用到的算法,其原理是根据数据的最近访问时间来安排数据淘汰的顺序。其实常用的LRU算法是LRU-K算法体系下LRU-1特例算法。LRU算法的核心归根结底还是在链表基础上改装而来。其运行逻辑如下: 1.新数据插入链表首部(最新被使用的数据,优先级最高,位于链首原创 2017-11-27 23:22:18 · 1311 阅读 · 0 评论 -
系统内核之堆管理
相比于栈内存而言,堆这片内存的管理模式更为复杂,因为程序可能随时发出请求,并且申请一段内存,申请内存的大小不固定,释放的时间也不确定。栈在面向过程的程序设计中远远不够,因为栈上的数据在函数返回时就会被释放掉,所以无法将数据传递至函数外部,而类似于全局变量或模块间共享对象,这是要在编程序编译阶段就要存在的,以及一些规模超大的数据对象,这些数据存在栈上显然是不合理的。针对程序内部最为常见的动态分配内存的原创 2017-12-25 15:07:59 · 2220 阅读 · 0 评论 -
极致优化思想系列之二:操作系统内核极致提升时间效率的设计点滴
《极致优化思想系列》是我用来收集一些不同目的诉求场景下的一些前人的精巧的极致设计思想,这些设计思路充满了艺术性,以此系列来作为敦促自我驱动不断进步之意。《极致优化》的第二篇文章关注的便是“时间效率”这个最常见的criteria。由于时间效率的优化技术方方面面皆有,故而顺延着前一篇文章的节奏,本篇的内容限定在操作系统领域。本文始终留白,留待日后不定期添加新的成员。1. Linux动态链接下的INT和I原创 2017-12-25 22:59:14 · 328 阅读 · 0 评论 -
Linux动态链接之一:Linux下动态链接和地址无关性处理
1. 动态链接技术的诉求来源 静态链接:从目标文件到可执行文件,将所需的所有的模板链接,最终生成单一的可执行文件模块; 动态链接:单一的可执行文件模块被拆分成若干个模块,在程序运行过程中动态进行链接的方案。静态链接可以使得开发者可以专注地开发自己的程序模块,但随着程序规模的增大,静态链接的一次性链接装配存在浪费内存和磁盘空间、模块更新困难等问题。甚至说基本的字符串公用库函数,每个程序内部处理都要原创 2017-12-26 15:37:39 · 6433 阅读 · 0 评论 -
Linux动态链接之二:优化加速之延迟绑定PLT
1. PLT延迟绑定的提出 动态链接速度损耗主要两方面: 1.对全局和静态的数据访问都要进行复杂的GOT定位,然后再间接跳转寻址; 2.动态链接的很多工作是在程序运行时完成的,动态链接器需寻找并装载目标共享对象、符号查找、地址重定位等,如果不加以优化,会出现程序启动过慢的情况。 故而需要出台一些优化动态链接策略的方法。动态链接下,模块之间包含大量的函数引用(全局变量往往较少,过多的全局变量会原创 2017-12-26 16:44:48 · 1802 阅读 · 0 评论 -
极致优化思想系列之一:操作系统内核极致提升空间效率的设计点滴
《极致优化思想系列》是我用来收集一些不同目的诉求场景下的一些前人的精巧的极致设计思想,这些设计思路充满了艺术性,以此系列来作为敦促自我驱动不断进步之意。《极致优化》的第一篇文章关注的便是“空间效率”这个最常见的criteria。而谈到空间的极致压榨利用,相信可能除了数据库便是操作系统了,由于数据库的技术暂时涉猎较少,故而本文先留白,留待日后不定期添加新的成员。1. 操作系统内存映射管理 先引入Li原创 2017-12-25 22:50:41 · 728 阅读 · 0 评论 -
Linux动态链接之三:动态链接相关结构
无论是静态链接还是动态链接,初始都是操作系统读取可执行文件的FILE_HEADER,以检查文件格式、操作权限等属性,然后根据段表获取各个”segment”的VMA虚拟装载位置、文件地址和操作属性RWXP等,再根据相似属性原则相连原则完成装载,而后将控制权交给文件头结构中e_entry入口地址(ELF程序的入口虚拟地址,可重定位文件不可执行,故而为0,静态链接的可执行文件便是指向运行库main初始化函原创 2017-12-26 22:30:39 · 1647 阅读 · 0 评论 -
Linux动态链接之四:动态链接的步骤
动态链接的步骤基本上分为3步: 1.启动动态链接器本身 2.装载所需要的共享对象 3.重定位和初始化1. 动态链接其ld.so自举 动态链接器入口地址即是自举代码的入口,当OS将进程控制权交给动态链接器时,动态链接器的自举代码开始执行。自举代码执行逻辑: 1.找到动态链接器自己的GOT段,GOT中第一项即是.dynamic段的偏移地址,然后找到该动态链接器本身的.dynamic段; 2.原创 2017-12-26 23:24:05 · 1098 阅读 · 0 评论 -
Linux动态链接之五:运行时显式加载共享文件.so
动态链接更多是从.lib等模块分离组装的角度来看待问题,实际上,如果动态链接可以实现,那么在运行过程中动态加载.so对象也是可行的,这种共享对象被称为DLL,它其实和普通.so对象并无本质区别,只是程序的视角不同。运行时链接的技术手段常用来做插件、驱动加载等处理,因为不需要开始就全部加载进入进程,可以有效地减少程序启动时间和内存使用。对于Web服务器需要长期连续运行的场景,如果某个模块更新,显然不能原创 2017-12-27 00:09:28 · 1408 阅读 · 0 评论 -
Linux动态链接之六:共享库管理和版本控制
1. 共享库的兼容性 1.兼容更新:所有的更新只是在原有的共享库基础上添加一些内容,所有原有的接口都保持不变; 2.不兼容更新:共享库更新改变了原有的接口,使用该共享库原有的接口的程序可能不能运行或运行不正常。谈到共享库和DLL等库文件的兼容性,则不得不谈到ABI(相比于API对应于源代码级别的接口管理,二进制层次的ABI对应的则是操作系统和底层机器码)对于不同的语言来说,主要包括一些诸如函数调原创 2017-12-27 11:05:56 · 1690 阅读 · 0 评论 -
Linux动态链接之七:共享库的创建和安装
创建共享库和一般的共享对象.so基本一致,主要还是GCC的两个参数-shared –fPIC(意义不用多说,分别指明共享和PIC地址无关)在前面说过gcc指令其实对于与cl\ld等具体程序的调用封装,故而完全可以在gcc指令传输一系列参数(比如传输一些参数给汇编器cl,一些参数给ld),-Wl便是在gcc指令中声明传给链接器ld的参数: $gcc -shared -Wl, -soname, m原创 2017-12-27 15:26:19 · 2872 阅读 · 0 评论 -
Windows下动态链接之一:DLL插件机制的装载和使用
目录:Windows和Linux下动态链接的原则不同映像基地址RVADLL文件的符号导出声明PE文件头下的DataDirectoryDLL文件的符号导出表PE文件的符号导入表DLL显式运行时加载链接demo1. Windows和Linux下动态链接的原则不同Linux系统以.so共享对象设计共享库,并在设计共享对象的过程,花费很多精力实现.so对象的代码段.text多进程共享,提升原创 2017-10-18 23:18:23 · 5878 阅读 · 0 评论 -
Windows下动态链接之二:DLL优化加速
1. Windows动态链接下的导入函数的调用过程 在ELF结构下,函数调用因为有全局符号介入的可能,所以除非用static关键词修饰,否则只要是函数调用,无论是否是模块内还是模块外,都需要经过.got.plt间接跳转,来实现ELF结构下代码段的地址无关性。在PE文件结构下,是不存在全局符号介入的,所以对于模块内部的函数调用,编译器将产生直接调用指令CALL XXXXXXXX(不是相对地址偏移,原创 2017-12-27 17:08:59 · 2170 阅读 · 0 评论 -
Windows下动态链接之三:DLL Hell !
不止Linux下关于共享库存在版本兼容性困扰问题,Windows下DLL共享库的使用问题更甚。很多Windows的应用程序在发布release版本时会一次性将所有用到的DLL一起打包形成一个大的安装包,用户只需一键安装,无需关注具体的DLL文件的配置问题。但也正是这种黑盒操作导致了可能存在某次安装,将系统中的新版本DLL文件被旧版本DLL给覆盖掉,虽然安装的程序可以运行了,但是其他程序可能出现问题了原创 2017-12-27 17:26:16 · 1195 阅读 · 1 评论 -
运行库:Linux下glibc和Windows下MSVC CRT对比
任何一个C程序要想要得到实现,都离不开背后的一套庞大的代码来进行支持(至少包括入口函数,以及其所依赖的函数所构成的函数集合等),这样一套背后代码被称为运行库,C语言的运行库叫做CRT(Runtime Library)。C语言的运行库某种程度上就是C语言的程序和不同操作系统平台之间的抽象层。它将不同的操作系统API抽象成相同的库函数(银弹理论的又一次胜利)。比如可以在不同OS上使用fread来读取文件原创 2017-12-28 13:45:27 · 4200 阅读 · 0 评论 -
缓冲技术之三:Linux下I/O操作buffer缓冲块使用流程
0. Linux下缓冲池技术的简单介绍 Linux文件系统中,存在着著名的三大缓冲技术用以提升读写操作效率:inode缓冲区、dentry缓冲区、块缓冲。其中所谓的块缓冲便是我们前面一直在讨论的缓冲池技术,常用来配备IO操作,用来减少IO读取次数,以提升系统效率。本文便是此前《换成技术》系列的两篇文章的基础上继续讨论缓冲池技术。对于块缓冲体系而言,需要提及的两个概念分别是page cache和bu原创 2017-11-26 22:58:20 · 3165 阅读 · 0 评论 -
缓冲技术之一:缓冲问题的来源和解决方法
缓冲技术某种程度上而言也是符合银弹理论,增加了一层抽象层–缓冲区,用于解决上下游机器介质速度不匹配导致的程序速度缓慢的问题。缓冲器是一个存储器,它可以是硬件级的,即独立于内存外设置的专门硬件缓冲器(内存页表起始地址寄存器),也可以是软件级的,即由软件在内存中开辟一块缓冲区域(buffer,cache)。硬件要花钱,所以一般用在关键的地方。1. 引入缓冲技术的原因 1.Cache缓存,减少读块设备的原创 2017-11-07 23:46:34 · 5683 阅读 · 4 评论 -
缓冲技术之二:缓冲池BufferPool的简单实现
在文章缓冲技术中提到无论是单缓冲、双缓冲或循环缓冲,均仅是进程专属缓冲配备,而一旦考虑到操作系统的分时并行特性,任一时刻只有一个进程的缓冲体系在工作之中,而其他进程的缓冲体系并不在工作(要么是迁移到swap cache外设磁盘上要么是占据物理内存,显著减少可用物理内存容量),所以采用公用缓冲池架构为多个并发进程提供缓冲服务是当前主流的手段(操作系统、数据库)。由于完整地提供操作系统级别的缓冲池涉及到原创 2017-11-26 18:17:38 · 7390 阅读 · 2 评论 -
Linux磁盘空闲空间调度管理
操作系统的磁盘管理为了和内存管理配合,也是将磁盘分割为最小单元进行统一调度,和内存的页帧概念对应,磁盘管理模块以磁盘块作为最小单元管理磁盘(常见的磁盘块为1KB,对应2个512B扇区,磁盘块是OS概念,磁盘驱动读取是以扇区作为最小单元)。1.数组表格和链表管理继承内存页帧的段页式管理思想,自然可以想到磁盘管理的空闲空间表法和空闲块链法。前者是指为所有空闲区建立一张空闲表,每个空闲项表示该空闲区的序号原创 2017-08-29 23:33:55 · 5655 阅读 · 1 评论 -
Linux内存管理
操作系统的内存是整个计算机缓存计算体系的关键部分。CPU是指令操作和计算的核心,但是CPU只相当于机械臂,相应的程序的指令集合和数据段等信息必须加载到内存中,类似于送上流水线,等待CPU读写执行更新,从而完成计算任务。内存相比于硬盘读写速度更快(100倍),当价格也更高(8G内存条在博客编写时价格在800rmb,2t引动硬盘大概在600rmb,比较可知,1G内存空间是1G硬盘空间价格的300倍左右)原创 2017-09-29 23:44:02 · 419 阅读 · 0 评论 -
运行库:Windows下MSVC CRT运行库封装fread()函数解析
在介绍运行库的过程中,强调过运行库是具体语言实现的程序和操作系统之间的抽象层。经验表明,任何系统级的软件工程,IO功能的封装历来是最具有挑战性的。以下以Windows下MSVC CRT运行库中封装的文件读取函数fread()的实现思路为demo,演示运行库的功能封装。#define size_t unsigned intsize_t fread( void * buffer, siz原创 2017-10-18 23:25:51 · 1140 阅读 · 0 评论 -
Linux内核:基于int指令的经典系统调用过程分析
众所周知,代码运行可以存在多种不同的特权级别,而针对Linux系统,即为:用户模式(user mode)和内核模式(kernel mode)。在用户模式下,CPU的功能空间受到极大的限制,是没有权利访问多少系统资源的,诸多关键资源的使用无法直接调配,如:硬件设备读取、磁盘文件读取等;诸多情况无法直接处理,如开关中断、页中断、断电等。这些资源的调配和硬件中断的响应处理都是内核态下由系统内核代码进行应对原创 2017-10-21 12:13:58 · 1929 阅读 · 1 评论 -
Windows系统:解析文件句柄Handle的详细机制
1. 用户程序和运行库层面的文件”句柄” FILE*IO初始化时讨论了在运行库层面的文件句柄管理机制,工作流程如下FILE *file ->ininfo* pioinfo\[\]\[\] -> ioinfo1.在程序中提供给IO函数的文件句柄是封装在FILE*指针里面的;2.FILE结构体总共包括两方面内容:a.该文件配备的缓冲大小、地址等信息;b.该文件在进程打开文件列表中的下标_file;原创 2017-10-21 20:20:39 · 7717 阅读 · 0 评论 -
Linux内核:IO设备通信的控制方式
IO设备与主机(CPU、内存)之间的通信不是直接的,而是通过设备控制器,设备控制器是IO设备和主机之间的中介。IO设备和进程之间的数据传送方式主要有4种:1.程序控制方式:又被称为“忙等”模式,即当要在内存和IO设备之间进行信息传输时,由CPU向相应的设备发出命令,由设备控制器控制IO设备进行实际操作。在IO设备工作时,CPU执行一段循环测试程序,不断测试IO设备的完成状况,根据完成状况决定下一步操原创 2017-11-07 23:11:22 · 5089 阅读 · 0 评论 -
Linux内核:IO设备的抽象管理方式
I/O设备是人们使用计算机的途径,无意相当于计算机的五官,不同的使用方式需要配备不同的设备,如输入文字一般用键盘,但在某些应用场合,需要扫描仪,输入声音需要话筒,打印信息需要打印机,实时控制RT领域需要传感器。 摘自《操作系统原理及应用》一书关于IO设备从不同角度的分类 使用目的 1.存储设备:alias外存、辅助存储器 2.输入/输出设备 按传输速率分类 1.低速设备:几~几百Bytes原创 2017-11-07 23:32:20 · 1550 阅读 · 0 评论 -
运行库:程序进入main()之前发生了什么
1、linux下glibc运行库运行逻辑正常可执行文件用glibc运行的函数调用顺序 _start -> __libc_start_main -> exit -> _exit;_start: xorl %ebp, %ebp //异或操作,将结果赋值到第一个参数上, ebp设置为0正好可以体现出_start作为最外围函数的地位 popl %esi //将当前堆栈中argc弹出赋原创 2017-10-13 00:28:32 · 871 阅读 · 0 评论 -
运行库:I/O初始化之“文件”句柄管理
此前讨论过一般认为的程序入口main()函数并非实际上程序真正的入口,在进入main()程序员设计的运算逻辑之前,运行库需要完成一系列的准备工作,包括参数入栈、堆初始化以及I/O初始化。在操作系统中,I/O一般是指代硬件外设或磁盘,但从软件的角度,任何具有输入输出操作的都可抽象为“文件”,一般在系统中都是用句柄Handle(类似指针)来指代进程中需要打开的某一具体文件,而进程中也配备中一个二维数组“原创 2017-10-13 17:56:26 · 946 阅读 · 0 评论 -
程序员的自我修养:MiniCRT自制C语言运行库
程序员的自我修养一书中,在最后一章专门介绍一款小型的C语言运行库,并给出了详细的代码实现。阅读该代码实现,可以对C语言运行库提供的语言抽象层得到更深的理解。Talk is cheap, show code!minicrt.h: MiniCRT的文件头#ifndef __MINI_CRT_H__#define __MINI_CRT_H__#endif/*定义C++相关的函数,以使得函数的兼容性得到原创 2017-11-05 01:20:37 · 1786 阅读 · 1 评论 -
缓冲技术之五:缓冲池的LRU管理策略C++实现
/*LRU事实上属于一类被称为内存置换算法(FIFO、LRU、LFU):都是指在有限的容量下,设计一个如何管理和更新数据项的策略本程序是实现LRU-1算法,但是和常见的LRU算法不同,一般常规的LRU算法是直接用一个LRU双向链表队列实现管理,这种双向链表会导致查找元素的时间复杂度位O(n),故而我的程序是在LRU双向链表的基础上附加一个map关联容器用以加速索引过程,将查找元素的操作的时间原创 2017-11-28 17:22:21 · 2078 阅读 · 0 评论 -
程序员的自我修养:MiniCRT++运行库部分实现C++特性
前面的文章展示了如何通过自制的运行库实现堆初始化和IO初始化,以及标准输入输出功能,这些都是标准的C功能实现。而对于C++而言,则拥有更多的复杂特性,如new/delete、STL、异常处理、流等,这些特性显然是语言层的,故而需要GCC库提供相应的实现。对于C++而言,其毕竟是在C的基础上衍生而来的,故而C++运行库显然只需要实现这些C++特有的特性,而其他和C共享的功能如基本文件操作、堆管理等都可原创 2017-11-14 22:33:31 · 698 阅读 · 0 评论 -
Linux文件系统之一:inode节点和inode节点包含的block寻址信息
索引节点的提出对于存储在磁盘空间上的文件,实现快速的读写和索引是影响用户使用体验的关键。和PCB类似的文件控制模块FCB提供了足够的文件属性,在搜索匹配过程中,显然文件名匹配是搜索过程的关键,并且是唯一标识符,可FCB拖家带口,比较时显然过于臃肿,其他信息暂时都用不上。操作系统一般又是将FCB组成的文件目录放在磁盘上,对较为庞大的文件系统,显然需要多次进行磁盘IO读写。举例:假设一个FCB数据结构大原创 2017-09-19 23:48:04 · 4982 阅读 · 0 评论 -
Linux文件系统之二:硬盘分区partition的组织和管理
在Linux文件系统之一:inode节点的提出一文中通过顺延FCB的管理思想,为加速文件系统的管理效率引出并介绍了inode节点的概念。考虑到当前主机的主要存储设备都是硬盘,故而谈及文件系统filesystem必须要结合硬盘分区partition的硬件概念。1. Partition分区和MBR 对于主机而言,由于可能同时存在多种文件管理场景,诸如作为博客服务器的主机,可能既需要管理博文这一类长文章原创 2017-12-04 23:29:55 · 3033 阅读 · 0 评论 -
Linux文件系统之三:硬链接和软链接
Linux文件系统不得不提及的一个概念便是Link链接(软链接和硬链接),不像Windows下的快捷方式让人容易理解,Linux下的链接存在一定的迷惑性。要谈及Link链接概念,则必须首先介绍Linux下的的文件的读取方式: 1.由一层一层的目录取得文件相关的inode映射数据; 2.找到目标文件的target inode节点,去该节点提取该文件存放的Block区域信息 3.在block中提取原创 2017-12-05 00:10:55 · 397 阅读 · 0 评论 -
线程局部存储TLS
1. 运行库支持多线程操作的更改 多线程编程时,其实线程的访问权限是很高的,可以访问进程内存里的所有数据,甚至包括其他线程的堆栈,但是这种毫无边界的感觉就和不知边界的亲戚一样,显然是需要制衡的。所以线程需要配备只有本线程专属的线程专属存储空间(Thread Local Storage, TLS),即系统为线程单独开辟的存储空间。对于C/C++标准库来说,线程相关的部分是不属于标准库的内容的,它跟网原创 2017-12-28 22:46:44 · 887 阅读 · 0 评论