操作系统 李治军 操作系统基础(一)

参考材料: 中国MOOC课程
参考笔记(一):系统调用博客备份jieqiong1
作业:系统调用参考

操作系统基础(一)

L1 什么是操作系统

CPU告诉内存,地址为300的acsii码,通过总线控制器,通过PCI总线发送到图形控制器写入到显存地址。实际上就用了printf(“Hello!”),应用软件=>操作系统=>计算机硬件。将计算机硬件叫做裸机,给计算机硬件穿上衣服。

什么是操作系统
进阶里面有高阶操作系统,本课程主要讲单机CPU如何管理各模块。
我们到底要学习什么内容?
要学什么
有些人主要学习里面接口如何使用,这是比较初级。我们实际上要进入操作系统,fork背后到底是什么,为什么进程可以管理CPU。最后达到设计并实现操作系统。CMU层次比较高,主要是硬件搭建软件,我们的目标是改。
在这里插入图片描述
主要里面有八个项目实现。
CMU学习

在这里插入图片描述

L2 揭开钢琴的盖子 (open the os )

复习:硬件=>OS=>App App与OS之间是接口连接
我们的目标是穿过接口,看操作系统的内部(老师有个有趣的灵魂)
操作系统L2
开机后干什么事?尽量寻找?主动积极。。。鸡汤。。。。
图灵机
从白纸到图灵机,再到通用图灵机。图灵机就像一个只会做一道菜的事,因为控制器里面只有一个计算逻辑。
在这里插入图片描述
首先把控制器的逻辑读取进去,然后变成某一状态,然后数据对象按照该逻辑计算。
在这里插入图片描述
首先把程序放入到内存中,通过Ip指针(指令指针)指向一行程序地址, 载入到控制器解释执行。总结为四个字:取指执行。
打开电源,计算机执行的第一条指令是??
在这里插入图片描述
CS:IP 这边对汇编要求非常高。一个扇区512个字节,0磁道0扇区是引导扇区。
在这里插入图片描述
bootsect.s .s是一段汇编代码。为什么不用C语言写,C是高级语言,执行的时候是编译后执行,但是汇编不同,汇编是通过编译成机械指令,会对细节严格控制。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里面最重要的是0x10,bls 10中断
将在光标位置打印字符,下面开始读取操作系统。
在这里插入图片描述
以上皆为boot过程 将图标打印在屏幕上,然后引导到setup

L3 操作系统启动

在这里插入图片描述
简单回顾bootsect。我们刚一上电的时候,操作系统放在磁盘上,我们第一步就是将操作系统载入到内存中,
bootsect.s操作系统引导系统。bootsect将setup载入进去,然后中断后将系统导入。
在这里插入图片描述
int 0x15用来获取内存大小。[2]就是在当前位置移2位,到0x90002。
int 0x10取光标位置
为什么是setup 就是因为操作系统开始接管硬件,并且开始管理。
在这里插入图片描述
jmpi 0,8非常重要 。cs 和ip 都只有16位,左移4位,最多也就是20位,大概1M。也就是现在这中寻址方式肯定不行了,前面的16位模式不能使用了,要切成32位寻址。
在这里插入图片描述
在这里插入图片描述
之前CS里面放的是地址,现在不是,是选择子,基本上就是表的index。
在这里插入图片描述
0 , 8是由于寻址过程是以字节为单位,所以第一行为0 第二位8
在这里插入图片描述
上表是硬件规定好的,所以提取段基址按照红色部分来。setup做了什么事,总结一下。读了一些硬件参数,把system移到0地址,然后启动保护模式,之后采用高级命令,将指针模式改变并跳到0地址。
BIOS只会从0位读取,BIOS读boot,bootsect读setup
在这里插入图片描述
MAKEFILE是什么?通常操作系统叫镜像image,Makefile就是生成镜像。
在这里插入图片描述
这里面管理是树状结构,依赖关系。
system中第一模块就是head.s
在这里插入图片描述
保护模式是32位汇编代码
在这里插入图片描述main.c是C函数,但是head.s是汇编函数,之间需要跳转,但是其实与C函数之间跳转模式是一样的。C函数是通过压栈实现的。
在这里插入图片描述
main一旦返回就是死循环,就是死机。
在这里插入图片描述
main是永远不会退出的函数
在这里插入图片描述
Linux0.11不支持鼠标
在这里插入图片描述
移动12位就是2的12次方,然后就是4K,将4K作为一页,一页一页的初始化。
在这里插入图片描述
90002是在setup中检测
boot=>setup=>head=>main
boot:将操作系统从磁盘中读出来
setup:获得一些参数,启动保护模式
head:初始化了GDT表和页表,跳转main
main:将更多的东西初始化
以上内容,就是读取,下面就是初始化。获得初始化关键的数据结构,完成操作系统的控制。

L4 操作系统接口

系统启动的时候,初始化GDT IDT表,就有了初始化的数据结构。PPT之类的应用软件在内存上方。操作系统要立起来。
在这里插入图片描述
借口内容是,应用层如何连接到操作系统。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
操作系统接口就是系统调用。
在这里插入图片描述

L5 系统调用的实现

在这里插入图片描述
在这里插入图片描述
lizhijun在内核中,main()用户程序也是在内存中,为什么不直接跳进去将其打印(jmp,mov)。这样就可以直接访问ROOT密码这是不安全的。所以不能随意的调用数据。那怎么做到不直接访问,那应该怎么调用?CPL数值放在寄存器,DPL放在GDT表。
在这里插入图片描述
通过一种硬件设计。将内存分割几段,用了几个段寄存器。DPL其实在GDT里面初始化。PL 特权级
在这里插入图片描述
**加粗样式**
在这里插入图片描述
内嵌汇编编写
问题:这里面printf为什么要下方到内核中才能打印?还是不下放也可以。还是说这里面打印在屏幕上只能通过这个流程。
关于中断异常与中断的区别
在这里插入图片描述
设置系统中断门,0x80。addr中断地址。CS最后两位就是CPL
在这里插入图片描述
4是函数指针,每一个系统调用函数指针占用4个字节,相当于32位
在这里插入图片描述
在这里插入图片描述

作业(一):
在这里插入图片描述
实验报告:https://www.shiyanlou.com/courses/reports/1357367

作业(二):
在这里插入图片描述
这里面遇到问题主要是两个系统之间的文件交换出了问题。说明书里面并没有说清楚,在HDC文件根目录是无法构建文件的参考
实验报告:https://www.shiyanlou.com/courses/reports/1359329
从Linux 0.11现在的机制看,它的系统调用最多能传递几个参数?
你能想出办法来扩大这个限制吗?

(1)最多三个
(2)
1.采用其他寄存器扩大
2.采用系统调用门

向linux 0.11添加一个系统调用foo()的步骤:
1、在内核中编写系统调用处理函数。
2、在include/unistd.h中添加系统调用的功能号(#define __NR_foo **)
3、在include/linux/sys.h中声明新的系统调用处理函数以及添加系统调用处理程序指针数组表中该项的索引值。
4、在make file中添加新系统调用所在文件的编译、链接规则(依赖关系)。
5、修改system_call.s中系统调用总数。
/6、在应用程序中提供接口,调用系统调用。

参考:https://blog.csdn.net/wangyi_lin/article/details/6921110

猜你喜欢

转载自blog.csdn.net/weixin_42174342/article/details/84036599