操作系统原理(linux)
文章平均质量分 83
BIOS(BIOS中断服务程序),Intel风格x86汇编的内核引导主程序,从实模式下怎么进入保护模式,怎么实现中断调用,怎么实现特权级检查,怎么实现任务的创建,怎么实现多任务的管理;怎么加载全部内核代码。内存管理系统,进程调度,文件系统,,,
庾志辉
这个作者很懒,什么都没留下…
展开
-
Linux内核源码分析--文件系统(四、Bitmap.c)
总结的来说其实Bitmap.c程序就是操作文件系统中的两个位图:i节点位图和逻辑块位图;拿逻辑块位图来说吧,申请一个新的逻辑块时,首先是在8块逻辑块位图中查找一个空闲的比特位,找到以后转换成逻辑块号,然后就通过逻辑块号找到真正的逻辑块,通过函数把该逻辑块映射到缓存区中,当然最后要对缓存区做些属性设置;释放一个逻辑块时也一样,首先做些检查,然后释放缓存块,最后也是设置下逻辑块位图(当然也是根据逻辑块号转换成8块逻辑块位图中的某个比特位)。原创 2015-02-21 16:17:41 · 3026 阅读 · 0 评论 -
全面解析C语言中可变参数列表
全面解析c语言中可变参数列表问题:1、大众版:大家习惯的使用方式;2、真实版:真正的使用方式;3、实际原理:具体原理,本质;4、自己实现可变参数列表:理解本质后,自己用自己的方法来实现可变参数列表;5、可变参数列表缺陷:可变参数列表中存在的一些缺陷,以及提供的修改思路和方案。原创 2015-02-11 15:27:15 · 10350 阅读 · 2 评论 -
Linux内核源码分析--文件系统(三、buffer.c)
前面已经大概的分析了下高速缓存区相关知识,这里再来分析下几个重要的函数;1、清缓存:把缓存区数据和设备进行同步; 2、缓存块插入到双链表/hash链表中,从双链表/hash链表中删除缓存块; 3、查找缓存块号; 4、从设备上读取数据到缓存中; 5、缓存区初始化函数;原创 2015-02-10 14:52:56 · 3672 阅读 · 0 评论 -
Linux内核源码分析--文件系统(二、高速缓存区)
从块设备中读取数据是很慢的(I/O操作相对于内存操作来说是比较慢的),所以为了不让CPU浪费宝贵的时间来等待读取块设备上的数据,就在内存中开辟了一段内存地址用来预获取最近使用过的多块设备块上的数据。当CPU需要访问块设备上的数据时,首先会在缓冲区中查找,如果有幸能找到,那么就直接拿过来使用;如果找不到就没办法,需要从块设备上把查找的数据块读取到高速缓存中(一般会多读取几个存放起来),然后CPU再从高速缓存区中读取需要的数据块;所以总结来说CPU只读内存上的数据,如果要读块设备上的数据,必须先放到高速缓存中,原创 2015-02-09 22:14:06 · 4602 阅读 · 0 评论 -
memcopy()函数c语言实现和汇编实现比较
首先来看汇编实现的memcpy函数,是利用宏函数来实现的,用汇编指令rep和movsb配合循环把数据以字节为单位从ds:esi传送到es:edi中,把循环次数放在ecx中。当然这样拷贝的才是真正的内存拷贝,其他的函数都稍微有点牵强;其实我感觉c语言来实现还是比较简单的,就是把输入的数据强制转换成字符来操作,因为在c语言中没有比字符更小的单位了。原创 2015-02-07 11:06:25 · 2545 阅读 · 0 评论 -
Linux 新内核中主次设备号范围
作者:李强,华清远见嵌入式学院讲师。 设备驱动中,设备号设一个很重要的概念和变量。不论是主设备号,还是次设备号,在设备驱动中都占据了很重要的地位。那么他在Kernel中是如何操作的?这个数据结构都是通过那些函数可以很容易的在我们写Linux设备驱动模块时被我们所使用呢? 在include/linux/type.h文件中我们能看到一个关于dev_转载 2015-01-28 15:58:02 · 1981 阅读 · 0 评论 -
Linux内核源码分析--内存管理(二、函数实现技巧)
仔细的分析了一下各个内存管理函数的实现,发现里面涉及到了几个技巧,如果知道了这几个技巧,那么阅读内存管理源码将会事半功倍(主要是这几个技巧在几个函数中都出现过),当然也会选择性的分析几个比较重要的函数实现; 1、向上取整:以一个页面为了例,如果地址是1,那么向上取整就是4096;如果地址是 4095,向上取整就是4096;如果地址是4098,向上取整就是4096 x 2....... #define CODE_SPACE(addr) ((((addr)+4095)&~4095) <原创 2015-01-23 17:33:24 · 3371 阅读 · 3 评论 -
Linux内核源码分析--内存管理(一、分页机制)
最开始的地方是在head汇编中,如果看boot中那三个汇编的应该记得(那三个汇编还是比较重要的)。首先是分页机制,在CR0的第31位(PG位)置1表示开启分页机制,顺便也介绍下其他几个控制寄存器:CR1保留,没用;CR2 用来记录页面异常时线性地址(不懂没关系,后面会介绍);CR3 当前CPU使用的页目录表的地址(有此可见系统中不仅仅只有一个页目录表,但是在某一时刻有效的页目录表只有一个);当然有关页面操作的前提是CR0的第31位必须打开,也就是必须是在分页机制开启的时候那几个控制寄存器才有效。原创 2015-01-22 16:30:52 · 5567 阅读 · 4 评论 -
Linux内核源码分析--系统时间初始化(kernel_mktime()函数)
从boot文件中的几个汇编程序执行后跳转到init文件中的main.c程序开始继续执行,该main.c函数式为系统运行的环境进行初始化的。首先来看系统时间的初始化(因为系统时间的初始化开始程序就在init文件中),其中主要还是由kernel中的mktime.c程序中的kernel_mktime函数计算时间的。 先看下time_init(void)函数及相关结构是怎么实现的:原创 2015-01-19 23:14:24 · 3819 阅读 · 0 评论 -
BCD码转换成二进制和ASCII码
BCD码转换成二进制和ASCII码;用BCD码表示:十位上的十进制数为 2 == BCD码表示为 0010;个位上的十进制数9 === BCD码表示为 1001;所以总的来说 十进制数 29 用BCD码表示为:0010 1001;转换过程:把BCD码 0010(十进制数为十位上的 2)右移4位(其实表示当作一个个位数,或者说单纯的数值),然后乘以10 还原到十进制的权重(因为这个数本来表示的就是十进制数中的十位)。处理完十位上的数,接着处理个位上的数。因为BCD码的权重和二进制的前四位权重是一样(2^n,n原创 2015-01-17 16:32:10 · 34241 阅读 · 3 评论 -
C程序代码中内嵌as汇编(四、宏函数)
先来回忆下C语言中宏是怎么定义的,最基本的是定义常量:#define MAX_LEN 1024 这是最简单的常数宏定义,其中宏名按规定是要大写的,宏名在预编译时会由后面的值替代掉(预编译四大步骤:1、用宏名后面的值替换宏名;2、加载包含的头文件内容;3、判断逻辑假,并且去掉逻辑假代码;4、删除注释)。 C语言中宏函数定义格式:#define FUN_NAME(a, b, c)原创 2015-01-16 15:15:36 · 2077 阅读 · 0 评论 -
C程序代码中内嵌as汇编(三、跳转)
在内联汇编中使用跳转语句是非常常见的,比如:比较两个数,返回较大数时,就会用到跳转;先看下汇编和运行结果,然后再一步步分析下: 运行结果: 代码分析: #include void fun(int a, int b) { printf("a=%d原创 2015-01-14 18:16:34 · 4681 阅读 · 1 评论 -
C程序代码中内嵌as汇编(二、占位符)
本篇blog只给几个例题来进行快速学习内嵌as汇编。 第一、输入参数中包含输出参数 #include int main(void) { char string1[]={"this is yzh test code!"}; int len = 25; char string2[30]= {'\0'}; //asm volatil原创 2015-01-14 16:59:54 · 2118 阅读 · 0 评论 -
C程序代码中内嵌as汇编(一、基础知识)
汇编代码是最接近机器码,所以也是执行效率最高的,在操作系统中有将近10%的关键性代码是由汇编编写的,而还有部分代码是由C代码嵌入汇编构成的。C代码中嵌入汇编可以提高程序的执行效率,同时这种程序还既有高级语言的特性,可以灵活的和其他模块进行配合工作; c程序内嵌as汇编有比较多的规则,可以从最简单、最基本的开始学起直到后面学习现在通用的内嵌方式。原创 2015-01-14 14:51:06 · 1779 阅读 · 0 评论 -
as汇编基础程序设计--函数设计及函数堆栈传参问题
其实上面的重点是 .type print_fun, @function ,这是定义函数的方式,后面一般接着是函数入口地址标识符;函数传参问题: 在as汇编和C语言中函数调用时传参的标准是使用堆栈来操作的,而有些其他汇编(如:ARM汇编)是通过ax,bx等,当参数超过4个参数时用堆栈进行压栈传入。来模拟下传参问题(假设有三个参数):原创 2015-01-14 10:57:20 · 1808 阅读 · 0 评论 -
as汇编基础程序设计--基础知识点
1、数据类型,as汇编和C语言类似,也有数据类型之分。数据类型为了区分数据存放所需要的空间(也就是字节数),浮点型操作没怎么了解,浮点型操作时对数据类型应该有特殊的限制。.section .data output: .ascii "xxxxx%d\n" (后面不添加'\0') .asciz "xxxxxx%d\n" (后面添加'\0') .int 2,3,4原创 2015-01-14 10:29:04 · 1164 阅读 · 0 评论 -
as汇编基础程序设计--gdb调试汇编
开始命令:gdb test; 设置断点:break *_start + 1(cpu运行到 _start+1 的地址上会停止,break可以简写b) 开始运行:run (会运行到第一个断点位置上,一般和断点一起使用) 单步调试:step (会一行一行执行代码,遇到函数会进入函数中执行,step可以简写s) 单步调试:next (和上面的命令类似但,但遇到函数不会进入,直接跳过函数,next可以简写n) 顺序执行:cont (当原创 2015-01-10 17:08:50 · 2647 阅读 · 0 评论 -
as汇编基础程序设计--调用C库和内存访问
as汇编中的内存访问:movl (%ebx), eax(把ebx寄存器指向的地址上的值传送给eax);movl 4(%ebx), eax(把ebx指向的地址的位置往上偏移4字节的地址上的值传送给eax中);movl -4(%ebx),eax(把ebx执行的地址位置往下偏移4个字节的地址上的值传送给eax);movl 4(%ebx, %ecx, 4), eax (把 ebx+4*ecx+4地址上的数据传送给eax);这样一解释,上面的movl $2, 4(%edi),movl (%edi, %ecx, 4),原创 2015-01-09 16:13:16 · 1453 阅读 · 0 评论 -
AT&T风格的基础汇编程序--Hello word
为了看懂Linux内核源代码,所以不得不重新学习下汇编语言。汇编语言大体可以分为两个风格,官方的intel风格和unix系列的AT&T风格。Intel风格汇编是比较常见的,一般大学时会学习点基础的(至少我大学时学过点基本指令),这一类代表性的有NASM汇编、as86等(我熟悉的就只有NASM汇编,不过这一类汇编都大同小异)。而AT&T风格的汇编是比较少见的,一般只有做Linux开发的才会接触,尤其是做linux c语言开发的,有时候为了追踪代码,迫不得已编译成汇编来检查(如果在Linux下用C语言开发过的,原创 2015-01-08 17:10:30 · 2219 阅读 · 0 评论 -
x86架构保护模式下界限问题
在保护模式下有很多界限问题,下面集中来看下: 若段界限是0xFFFFF,粒度是4KB,那么实际界限值是多少?若粒度G=0,那么段界限就是实际的界限值;但粒度为4KB,那么界限值就是:(描述符段界限 + 1)× 4KB - 1;为什么会这样?因为段界限是段长度减去1,若粒度G=0,那么段界限就是实际的界限值;若为4KB,则段长度是:(描述符界限 + 1)× 4;然后再减去1;所有:原创 2015-01-04 17:13:39 · 1772 阅读 · 1 评论 -
x86架构中的保护模式
在x86架构中所谓保护模式其实就是段的存储方式能够达到一种保护机制。也正因为有了保护模式(段的存储方式)所以才会有特权模式,以及后面的多任务之说; 在实模式下段的存储很简单,就是代表一个段基地址;如:ds(ds=0x7c00),那么数据段的基地址就是0x7c00;再比如:ds:ax(ds=0x0000;ax=0x7c00)那么段基地址就是0x00;物理地址就是:(ds * 16)原创 2015-01-04 09:38:28 · 3339 阅读 · 1 评论 -
x86汇编--程序加载器
加载器程序就是如何把一个程序从磁盘上加载到内存空间执行:步骤思考(实模式下的加载器): 第一、确定从磁盘哪个扇区中加载,以及加载到内存中的什么地方; 第二、最基本的设置数据段,和堆栈段,代码段一般不用设置(跳转的时候已经设置了); 第三、读取要加载的文件的头文件(大小一般不超过512字节,视情况而定),一般头文件包含:程序大小,入口地址,段的数量,要调整的段基地址; 第四、分析头文件,读取剩余扇区内容; 第五、调整头文件中各个原创 2014-12-05 16:32:44 · 2852 阅读 · 0 评论 -
x86汇编--RTC中断(时间显示器)
可以用前一篇操作系统内核加载器(x86汇编)的加载器来加载这个RTC中断程序,就可以显示时间了。原创 2014-12-11 17:03:51 · 2846 阅读 · 0 评论 -
x86汇编--保护模式下的冒泡排序
其实这个代码本身(冒泡排序)没有什么意思,而有用的是怎么从实模式下进入保护模式,以及怎么 使用段选择子和段描述符。原创 2014-12-19 15:55:03 · 1986 阅读 · 0 评论 -
x86汇编--微内核设计
微内核程序:微内核程序就稍微复杂点了,还是按步骤分析下:1、设计一个打印例程,就是把字符串打印到屏幕终端,用来显示一些提示信息;2、后面都是用来加载用户程序了,其实说到底微内核就是为各个用户程序提供环境,和加载执行用户程序,不过这简单的里面却还是比较复杂的;3、首先只加载用户程序的头部程序到内核临时内存中,然后分析整个用户程序的大小,最后把所有的用户程序都加载到指定位置;4、在上一步中还漏了一步,就是当指定用户程序大小后,需要向内核申请一个同样大小的空间用来存放它。其实这就是简单内存管理;5、开始为用户程序原创 2014-12-27 10:03:12 · 1768 阅读 · 0 评论