《30天自制操作系统》笔记(11)——高分辨率
- 格式:pdf
- 大小:62.66 KB
- 文档页数:1
第四天C语言与画面显示的练习好多天都没有看这本书,一个人学点东西真不容易。
第四天其实我觉得挺简单的,如果对指针很熟悉的人第四天很容易就看的懂。
对于C语言指针不懂的人就很难理解了。
这一天的前面两个小结是展示了如何实现对内存的写入,前面看完的人就知道,对显示器的控制其实就是控制内存中的vram这个区域,内存中vram区域每个地址代表了显示器当中的每个像素点,所以对vram控制就能控制显示器的显示画面。
文中使用了naskfunc.nas这个文件中的函数来实现内存的写入,很明显,作者是想讲指针的原理告诉读者,这样编制的目的就是为了让读者明白何为指针,harmian函数中调用了write_mem8()这个函数,将内存中vram部分全部设定为15。
15就是白色的意思,所以,之后显示器出现了全白画面,我们也可以将其换成其他数字显示出其他颜色。
后面的篇幅介绍了如何实现条纹图案,运用了& | 这样的运算符号。
这是计算机的运算符号,和我们人类一样有自己的运算法则,我们习惯使用加减乘除,但是计算机的运算法则是与或非。
例如1010and1101=1000意思就是两个数字全为1的时候输出1,有一个为0就输出0,这种逻辑运算高中应该所有人都接触过,大学的数字电路重点学习了这种运算法则。
注意看write_mem8(i,i&0x0f). 用这个运算法则处理过的结果就是有些和0x0f数值不一致的地址区域变成了其他颜色。
有些内存地址写入的数值就不是15了。
第四天后面的大部分都在介绍指针,我们学习过操作系统和计算机组成原理以后就能很清晰的理解指针这个概念,不然是不能很好理解指针这个概念的,指针的产生就是为了对内存进行操作,作者用了写入内存这个函数很好的展示了指针的作用,后来指针因为一些原因被有人说是unsafe的,因为指针在内存移位的时候,也就是指向下一位内存地址的时候可能会出现类型的不同而在程序代码中无法操作,比如上一个变量类型是int,下一个变成了char,后来c#取消了指针转而使用‘代表‘。
30天自制操作系统day02:将二进制操作系统映像用汇编C重写第一天直接给了一个helloos.img,让虚拟机直接运行,虚拟机直接运行后,在屏幕上显示“hello world'这就是我们这个所谓的操作系统的最简单的形式了。
这个“操作系统”功能简单到,只能打印出“hello world'这个操作系统实际上是:helloos.img这个文件里的二进制数组成的。
文件helloos.img其实就是操作系统的映像文件。
那么今天我们就看看如何写代码来生成helloos.img这个映像文件。
除了我们用二进制编辑器,直接写来生成helloos.img外,我们还可以用汇编来写:文件:helloos.nasDB0xeb, 0x4e, 0x90, 0x48, 0x45, 0x4c, 0x4c, 0x4fDB0x49, 0x50,0x4c, 0x00, 0x02, 0x01, 0x01, 0x00DB0x02, 0xe0, 0x00, 0x40, 0x0b, 0xf0, 0x09, 0x00DB0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00DB0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x29, 0xffDB0xff, 0xff, 0xff, 0x48, 0x45, 0x4c, 0x4c, 0x4fDB0x2d, 0x4f, 0x53, 0x20, 0x20, 0x20, 0x46, 0x41DB0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00RESB16DB0xb8, 0x00, 0x00, 0x8e, 0xd0, 0xbc, 0x00, 0x7cDB0x8e, 0xd8, 0x8e, 0xc0, 0xbe, 0x74, 0x7c, 0x8aDB0x04, 0x83, 0xc6, 0x01, 0x3c, 0x00, 0x74, 0x09DB0xb4, 0x0e, 0xbb, 0x0f, 0x00, 0xcd, 0x10, 0xebDB0xee, 0xf4, 0xeb, 0xfd, 0x0a, 0x0a, 0x68, 0x65DB0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72DB0x6c, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00RESB368DB0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaaDB0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00RESB4600DB0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00RESB1469432然后再用nask.exe helloos.nas helloos.img把汇编代码编译成二进制就行了。
第三天,进入32位模式并导入C语言遇到了一些伤心事,睡不着觉,本来想着明天来写这个第三天的理解的,╮(╯▽╰)╭,睡不着觉太痛苦了,干脆爬起来写点东西吧。
第三天开始正式介绍启动器了(IPL),这里读起来很轻松,没有遇到什么障碍,而且涉及的汇编语言也没有去咬文爵字的必要,汇编代码开始就是初始化磁盘,读盘AH,0X02.最后是调用磁盘BIOS,理解了计算机启动的原理也很清楚为什么启动区要写这些代码了,因为后面的系统的启动需要调用这些代码,很合情合理,调用磁盘BIOS其实就是调用在BIOS里面关于磁盘的函数,书上也解释的非常清楚了,一个读盘,一个写盘,寻道什么不拉不拉的,明白计算机储存的人就知道为什么这么做。
至于后面的关于内存的方面我有的犯糊涂,既然BX寄存器的位数有限,只能表示64K的地址,那么EBX又是如何实现表示4g内存地址的呢?书上并没有提及。
接下来的汇编代码很容易理解,就是读磁盘,为了不让电脑一次性读的太多就分成几段几段一读,具体是怎么读的我也不去深究了,没有意义的东西。
写到这里我突然醒悟一个问题,其实C语言是一个很重要的工具,我一直以为操作系统的源代码应该有很多汇编语言才对,但是。
除了引导区以外,其他地方就基本见不到汇编代码了,因为,其他的什么中断,图形界面,内存调度等等全部是用C语言写的。
除非你要调用到BIOS里面的函数,跳出32位模式重新进入16位模式。
我C语言的基础不是太好,一个学期学完的,学完了以后指针是什么都不理解,苦不堪言。
当时的C语言非常的抽象,我们学的时候只知道应该这么做,但是不知道为什么这么做,其实C语言当中p[i]和i[p]是一样的,老师在教我们的时候并没有说明这个其实是基地址,说了一个词,叫做数组,其实C语言中并没有数组这个东西。
数组是偷换的概念,*(p+i)是和p[i]等价的,我了个去,所以*(i+p)自然也就和*(p+i)等价了。
苦不堪言啊,没有学习底层的东西对理解这些抽象的东西带来了巨大的困难,如果所有的教学都像这本书一样该多好啊,从0101010二进制开始讲起,我相信每个人的学习基础都会牢靠许多。
30天自制操作系统学习理解第二天,汇编语言学习与Makefile入门汇编语言我觉得并不是研究的重点,所以我并没有careX86的汇编语言,因为之前我学习过MIPS汇编语言,今后ARM汇编语言也更加有价值。
所以,这本书的X86汇编语言我不是很理解,helloos.nas当中的代码其实就是在制作引导区,这个一定要明白,电脑启动的时候其实是先执行引导区的内容的,引导区一般含有一些对内存进行操作的代码,比如将软盘当中的一些代码复制到内存当中去,搞懂这个以后我终于是明白了操作系统的运行的基本原理。
大家应该知道一些非常小巧的Linux操作系统,比如puppy Linux系统,这个系统是将自己的全部代码加载到内存当中去的,这样执行速度非常快,书上的这个系统也是如此,有一些系统,比如debian,Ubuntu,Windows是将一些代码加载到内存当中而不是全部,这导致了系统启动变得十分缓慢。
也没办法的,因为这些系统要考虑到每个设备的驱动问题兼容问题,他们有许多的增加的功能,系统包含的东西太多无法直接在内存中响应,所以内存很关键啊,要是我想写一个操作系统一定是要全部加载到内存的!!!因为Windows实在是太卡了(/笑)(目前为止我只读到了06day,没有看到书上的操作系统离开内存的操作,所有的操作都是先加载到内存当中然后再执行的。
2333好不专业的说法)。
Helloos中ORG,也就是最初地址,这个地址就是操作系统在内存开始读的地址。
后面他写了很多汇编代码,其实我真想搞懂这些代码为什么这么写,但是实在是精力有限了,我们只能认为这些代码是引导区必须的,什么MOV AX,0就是初始化寄存器啊,mov AH,0X0e 调用BIOS用来显示文字啦,不拉不拉。
实在是不行了,没办法深究,如果想搞懂为什么要这么写这些汇编语言估计就得翻翻Intel CPU手册了。
暂且理解到这里吧。
CPU在引导区读取了这些代码之后就陷入了死循环,因为JMP fin这个指令。
一、实验主要内容1、制作真正的IPL,即启动程序加载器,用来加载程序。
添加的代码关键部分如下:MOV AX,0x0820MOV ES,AXMOV CH,0 ;柱面0MOV DH,0 ;磁头0MOV CL,2MOV AH,0x02 ;AH=0x02:读盘MOV AL,1 ;执行1个扇区MOV BX,0MOV DL,0x00 ; A驱动器(现在都只有一个驱动器了)INT 0x13 ;调用磁盘BIOSJC error这里有JC指令,是一些特定指令中的一种,后面知识点收录有。
JC就是jump if carry,如果进位标志位1的话,就跳转。
就是成功调用0x13就会跳转到error处。
INT 0x13又是一个中断,这里AH是0x02的时候是读盘的意思,就是要把磁盘的内容写入到内存中。
今天实验用到了4个软中断,都记在知识点里了。
至于CH\DH\CL\AL三个寄存器呢,就分别是柱面号、磁头号、扇区号、执行的扇区数。
那么含有IPL的启动区位于:C0-H0-S1 (Cylinder, magnetic Head, Sector)然后ES\BX和缓冲地址有关。
2、缓冲区地址0x0820MOV AL,[ES:BX] ; ES*16+BX -> AL说是原来16位的BX只能表示0~65535,后来就引入了一个段寄存器,用MOV AL,[ES:BX] ;ES*16+BX -> AL这样的方法就可以表示更大的地址,就够当时用了,可以指定1M内存地址了。
那么这里我们就是将0X0820赋值给ES,BX为0,这样ES*16后就访问0X8200的地址,那么就是讲软盘数据转载到0X8200到0X83ff的地方。
3、试错以及读满10个柱面MOV AX,0x0820MOV ES,AXMOV CH,0MOV DH,0MOV CL,2readloop:MOV SI,0 ; 记录失败的次数,SI达到5就停止retry:MOV AH,0x02MOV AL,1MOV BX,0MOV DL,0x00INT 0x13JNC next ; 没出错就跳到nextADD SI,1 ; SI加一CMP SI,5 ; SI和5比较JAE error ; SI >= 5 时跳转到errorMOV AH,0x00MOV DL,0x00INT 0x13 ; 重置驱动器,看上面AH变为0X00和0X02功能不同JMP retrynext:MOV AX,ESADD AX,0x0020MOV ES,AXADD CL,1CMP CL,18JBE readloopMOV CL,1ADD DH,1CMP DH,2JB readloopMOV DH,0ADD CH,1CMP CH,CYLSJB readloop这里很明显,从CL\DH\CH依次循环计数,就是读取完一个磁头的扇区后换一个磁头,到这个柱面都结束了就换一个柱面,一直读完10个柱面。
主 题题: 《操作系统原理》学习笔记内 容容:《操作系统原理操作系统原理》》学习笔记学习笔记三三————存储管理存储管理存储管理主存储器又称为内存储器,它是处理机可以直接访问的存储器。
主存速度快,但容量有限。
存储管理主要是对主存的管理,同时也涉及到主存和外存交换信息。
一、存储管理的目的与功能计算机的系统结构是以内存储器为中心。
受系统地址总线的限制,内存空间并不能做的很大。
16位地址总线,内存最大64KB 。
32位地址总线,内存最大4GB 。
在多道系统中,多个用户作业要同时使用有限的内存空间。
内存储器成为系统的“瓶颈”资源。
如何充分利用和有效管理内存空间,是操作系统必须完成的主要任务。
在多道系统中,存储管理的目的是为系统中并发运行的多道作业提供相互独立的存储空间,并为用户使用存储器提供方便。
主存储器的存储空间分为两个部分:系统区:用于存放操作系统的程序和数据。
用户区:存放系统应用程序和用户的程序和数据。
存储管理主要是对用户区的存储空间进行管理。
操作系统中存储管理的功能主要有五个方面:存储分配。
为进入系统的多个作业合理地分配存储空间每个作业的程序及其数据存放在内存空间的什么区域。
使用连续的内存区域,还是把它分成若干块来占用不连续的存储空间。
合理组织作业占用的空间,以达到既便于程序运行时存取信息,又能够最大限度地减小空间的浪费,使内存空间得到充分的利用地址变换。
用户作业调入内存空间时所处的位置是根据内存空间当时的状况决定的。
一般情况下,同一个程序在每次调入内存时所占用的位置是完全不同的。
为了保证程序在使用内存的不同区域时仍能正确地执行,必须把在程序执行时要访问的存储单元的位置,由用户在编制程序时所定的地址变换成它们在内存的实际地址。
地址变换又称为地址重定位。
存储保护。
在整个内存空间中既存放着系统的程序和数据,又有多个用户的程序和数据。
保证系统的程序和数据不被用户非法访问和破坏。
保证每一个用户信息的安全。
一、实验主要内容1、分割源文件分割文件的优劣:的分割:Makefile根据的分割后应增加的功能:2、整理Makefile和头文件Makefile里有很多相似的普通规则,这时候为了更加简洁,我们可以引入一般规则,像下面这样:会首先寻找普通的生成规则如果没有找到,就尝试用一般规则。
普通生成规则要优于一般规则。
将c文件里重复的声明添加到.h头文件中,然后在其余.c文件中增加#include “”表示告诉编译器,这里要替换成指定的内容,然后进行编译。
头文件名用(”“)表示该头文件与源文件位于同一个文件夹里,而尖括号(<>)则表示该头文件位于编译器所提供的文件夹里。
3、设定GDT这个函数用来将指定的段上限(limit)和地址赋值给名为GDTR的48位寄存器。
给GDTR赋值唯一的办法是指定一个内存地址,从指定的地址读取6个字节(48位),然后赋值给GDTR寄存器,完成这一任务的就是LGDT。
该寄存器的低16位(即内存的最初2个字节)是段上限,它等于“GDT的有效字节数-1”。
今后我们还会偶尔用到上限这个词,意思都是表示量的大小,一般为“字节数-1”剩下的高32位(即剩余的4个字节),代表GDT的开始地址。
DWORD[ESP+4]里存放段上限(0x0000ffff),DWORD[ESP+8]里存放地址(0x00270000)。
若是按字节写出来就成了FF FF 00 00 00 27 00 00。
用图来描述栈就美滋滋:为了执行LGDT,作者希望把它们排列成[FF FF 00 27 00 00]的样子。
所以就先”MOV AX, [ESP+4]”读取最初的0xffff,然后再写到[ESP+6]里。
结果就成了[FF FF FF FF 00 27 00 00],如果从[ESP+6]开启读6个字节的话正好是想要的结果,即如下图:然后讲set_segmdesc函数:这个函数是按照CPU的规格要求,将段的信息归结成8个字节写入内存。
主 题: 《操作系统原理》学习笔记内 容:《操作系统原理》学习笔记六——作业管理操作系统为用户提供了使用计算机的十分简单且便利的方式。
用户如何向计算机提交作业和控制自己作业的运行,以及计算机如何合理安排和按照用户的要求完成作业的规定的任务等,都是由操作系统的作业管理实现的。
一、作业的组织:1、作业与作业步计算机广泛应用在各个不同领域中,它们为人类完成形形色色的工作,这些交给计算机系统完成的工作就是作业(JOB)。
作业是用户在一次算题过程中或一次事物处理中,要求计算机系统所做的工作的集合。
作业的形态是用户编制的程序和要处理的数据。
计算机通过编译或汇编、连接、装配、运行等步骤,最终由计算机送出用户所需要的运行结果。
从计算机管理的角度看,上述一系列的由计算机执行的任务就是作业。
计算机在完成用户提交的作业过程中,是通过执行一系列有序的工作步骤进行的,每个步骤完成作业的一部分特定工作。
把计算机系统完成一个作业所需的一系列有序的相对独立的工作步骤称为作业步。
作业的各个作业步虽然功能相对独立,但它们之间相互关联,往往是一个作业步的执行需要使用上一个作业步的执行结果。
2.作业的分类根据计算机系统对作业处理方式,一般把作业分成两大类:批量型作业、交互型作业。
在大型计算机系统的批处理系统中运行的作业称为批量型作业,又称批处理作业。
批处理系统一次可以成批接收多个用户作业,并把它们放入磁盘中等待运行。
操作系统的作业调度按照一定的算法从多个等待的作业中选择某些作业装入内存空间投入运行。
批量型作业在输入计算机系统前,须由用户使用作业控制语言向系统说明如何控制作业的运行。
在小型计算机系统中的分时系统中运行的作业称为交互型作业,又称终端作业。
在分时系统中,用户通过各自的终端向计算机系统发出各种操作命令,告诉操作系统如何控制作业运行。
操作系统也通过终端向用户报告运行情况和结果。
3.作业的状态在从用户把作业提交给系统直到作业完成的整个活动过程中,在系统的安排下作业要经历若干阶段。
主 题: 《操作系统原理》学习笔记内 容:《操作系统原理》学习笔记五——设备管理输入设备和输出设备在主机之外,它们统称为外部设备、外围设备。
外部设备是计算机与外部世界进行信息交换的装置。
设备管理是指对计算机系统中除处理机和主存储器以外的所有其它设备的管理。
一、设备分类和设备管理功能:目前的计算机系统,特别是大型计算机都配置有多种设备,它们大部分是用于完成输入输出(I/O)工作。
有的是做为外存储器保存文件信息。
这些设备需要按照不同的种类进行管理和提供给用户使用,操作系统的设备管理提供了有关的功能。
1、设备的分类从数据的传输和组织特性分为两类:l块设备。
以一定大小的数据块为单位输入输出数据的,并且在设备中的数据也是以物理块为单位进行组织和管理的。
l字符设备。
以字符为单位输入输出数据的设备,并且以字符为单位对设备中的信息进行组织和处理。
设备按其所属关系分为:l系统设备。
在操作系统生成时已登记在系统中的标准设备称为系统设备。
l用户设备。
在系统生成时并未登记到系统中,由用户根据其运行需要向系统提供的设备称为用户设备。
设备的处理程序也是由用户提供的。
从系统对资源分配的角度分为:l独占设备。
由一个用户作业独占。
l共享设备。
同时分配给多个用户作业共享使用。
l虚拟设备。
使用虚拟技术把独占设备改造成共享设备。
2.设备管理的设计目标2.1向用户提供使用设备的方便、统一的接口。
面对用户把设备复杂的物理特性屏蔽起来,由操作系统承担起对设备的控制和管理。
向用户提供一个使用设备的统一接口。
2.2设备独立于用户程序。
用户程序不能直接对物理设备进行操作。
操作系统把物理设备逻辑化,仅向用户提供逻辑设备。
用户在程序中使用的是逻辑设备,由操作系统建立逻辑设备与物理设备的联系。
这种特性称为设备无关性2.3充分提高设备利用率和工作效率使设备和处理机能够做到高度的并行工作。
各个设备之间也要能够并行工作从而达到提高设备利用率的目的为各个作业或进程合理地分配各种设备,处理好多个进程对设备的竞争与共享。
《30天自制操作系统》笔记(11)——高分辨率
进度回顾
上一篇介绍了定时器的初始化和使用方法。接下来就该实现多任务了。不过原作者在这之前
写了关于提高分辨率的章节,本篇也总结一下设置显示器高分辨率的方法好了。本篇内容过
于简单,算是小小的休息一下。
启用高分辨率的思路:检测显卡是否支持某种分辨率;如果支持,则通过INT 0x10指令启用
之;否则使用任意显卡都支持的低分辨率。
VBE
历史上秦始皇扫平中原一统六国,其历史功绩之一便是在这之后统一了度量衡,从此全国人
民在计算度量买卖的时候都有统一的标准了。秦始皇能够强制废除六国的货币、度量标准,
但是显卡公司里没有一个能够成为秦始皇,也就造成了设置显示器分辨率的各种麻烦。
然而天下大势分久必合,显卡公司虽然无法合并为一,但市场不接受各自为政的混乱标准,
因此多家显卡公司协商成立了VBE(Video Electronics Standards Association)即视频电子
标准协会。VBE制作了专用的BIOS,基本上可以兼容所有的显卡分辨率设置。这个BIOS就称
为"VESA BIOS extension"(VBE)。可以说VBE就是显卡公司之间统一的度量衡。
回到顶部(go to top)
设置低分辨率