1-操作系统启动前的工作

【README】

1.本文总结自B站《操作系统(哈工大李治军老师)》的视频讲解,非常棒,墙裂推荐;


【1】计算机上电  

1)    问题: 这神秘的黑色背后发生了什么 ?计算机是怎么工作的?


【2】从白纸到图灵机

计算3+2的加法:

  • 控制器从纸带上读取已经写好的3 2 +;读取后,执行加法逻辑得到5,并把5再次送入到纸带上;但问题是,这个控制器只会做加法,不能做其他,这就是问题所在了

【3】从图灵机到通用图灵机

如果一个控制器,像一个只会做饼的厨师那样,就显得很低级,不灵活,没法扩展了;
我们需要的是能够看懂菜谱的厨师一样的控制器;能够灵活与扩展,不仅仅只会做加法,还会做其他算术或逻辑运算;

厨师读到菜谱1,可以做菜品1;

厨师读到菜谱2,可以做菜品2;

控制器也一样:

先预先设置控制器动作逻辑;

然后读取数据对象,根据预设动作进行相应的计算;

 通用图灵机:能够设置控制器动作逻辑的控制机;其中控制器动作逻辑就是应用程序;


【4】从通用图灵机到计算机

冯诺依曼存储程序思想,在1946年提出 :
4.1)存储程序的主要思想:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制下一步步处理;

把程序或指令存储到内存(主存)里,然后用一条指令指针(IP或PC)指向某条指令;把该指令载入到控制器(取指),从而形成控制逻辑,即指令描述了控制器如何工作,接着控制器根据指令进行相应操作(执行);

 小结:计算机怎么工作的呢? 取指+执行;  

4.2)冯诺依曼计算机由5大部件组成:

  • 输入设备;
  • 输出设备;
  • 存储器;
  • 运算器;
  • 控制器;

那windows系统启动的黑色背景如何产生的

  • 经过刚刚的分析,控制器是在指令下工作的,指令是由PC或IP的指向得到的;那计算机启动时,PC或IP指向的第一条指令是什么?

【5】打开电源,计算机执行的第一句指令是什么?

 【问题】打开电源,计算机执行的第一句指令是什么?

1)BIOS:Basic Input Output System, 基本输入输出系统;(开机时,唯一有程序的地方)
开机执行步骤:

  • 步骤1:开机后,CS=0xFFFF, IP=0x0000 ;CS-Code Segment-代码段寄存器;IP=Instruction Point=指令指针寄存器;
  • 步骤2:读取CS和IP的值,并把CS的地址左移4位与IP寄存器的地址相加,得到BIOS程序所在地址 0xFFFF0 ;
  • 步骤3:从只读存储器ROM中 CS:IP地址上读取BIOS程序到控制器,控制器根据BIOS程序进行相应操作;
  • 步骤4:BIOS程序首先检查 ram,主板,键盘,显示器,软硬磁盘;
  • 步骤5:接着BIOS程序把磁盘的0磁道0扇区(即第1个扇区512字节)的数据读取到以0x7c00为首地址的内存单元中;其中0磁盘0扇区即第1个扇区就是操作系统的引导程序所在扇区(又称引导扇区),1个扇区512k;
  • 步骤6:设置cs=0x07c0,ip=0x0000;所以可以得到内存地址0x7c00;

接下来,控制器就会执行内存地址0x7c00保存的程序,即操作系统引导扇区的程序


【5.1】0x7c00存放的代码是什么 ?

 

1)引导扇区代码示例 :

Bootsect.s 中的 .s 指的是 汇编代码assembly;其中bootsect指的是引导扇区,boot sector;
所以引导扇区代码,是一段汇编代码;

2)为什么要用汇编代码? 而不用C呢?

  • C语言无法控制某个变量在内存中的哪个位置上存储;
  • 而因为汇编的每一条指令都转为了机器指令,汇编可以控制变量存储的内存地址
  • 又引导扇区需要对程序进行完整控制,包括变量存储的内存地址;

3)Bootsect.s 引导扇区的代码要做什么事情呢?

引导扇区程序(0x7c00处存放的代码)的汇编指令执行步骤:

表1 引导扇区汇编程序bootsect执行步骤

步骤

指令

描述

1

mov ax,#BOOTSEG

#BOOTSEG=0x07c0;

2

mov ds,ax

把 0x07c0送入ds寄存器;

3

Mov ax,#INITSEG

#INITSEG=0x9000;

4

Mov es,ax

把 0x9000送入es寄存器

5

Mov cs,#256

把256赋值给cs寄存器;

6

Sub si si

把0x0000送入si寄存器;

7

Sub di di

把0x0000送入di寄存器;

8

Rep movw

重复移动256个字=512字节;

源地址:ds:si=0x07c0:0x0000;即0x7c00;

目标地址:es:di=0x9000:0x0000;即0x90000;

即把0x7c00的代码拷贝到0x90000内存地址

9

jmpi go, INITSEG

jump intersegment-段间跳转:

目标地址=cs:ip=INITSEG:go=0x9000:go;

下面进入到go为标号(锚点)的汇编指令执行

 补充,寄存器列表:

  • 1.    AX――累加器(Accumulator),使用频度最高
  • 2.    BX――基址寄存器(Base Register),常存放存储器地址
  • 3.    CX――计数器(Count Register),常作为计数器
  • 4.    DX――数据寄存器(Data Register),存放数据
  • 5.    SI――源变址寄存器(Source Index),常保存存储单元地址
  • 6.    DI――目的变址寄存器(Destination Index),常保存存储单元地址
  • 7.    BP――基址指针寄存器(Base Pointer),表示堆栈区域中的基地址
  • 8.    SP――堆栈指针寄存器(Stack Pointer),指示堆栈区域的栈顶地址
  • 9.    IP――指令指针寄存器(Instruction Pointer),指示要执行指令所在存储单元的地址。IP寄存器是一个专用寄存器。

4)为什么要把0x7c00的引导扇区程序拷贝到0x90000呢?
为了腾出空间,腾出空间干什么呢 ?

5)jmpi go, INITSEG 是什么作用(引导扇区代码最后一条指令)?

jump intersegment-段间跳转:

目标地址=cs:ip=INITSEG:go;

图 1 启动盘结构图

表1中的步骤9 执行了 jmpi go, INITSEG;意思是跳转到目标地址=cs:ip=INITSEG:go=0x9000:go 去执行;所以接着执行上图的 go标号的汇编指令,步骤如下:

步骤

指令

描述

go标号

1

Mov ax,cs

把cs=0x9000赋值给ax

2

Mov ds,ax

把值0x9000赋值给ds

3

Mov es,ax

把值0x9000赋值给es

4

Mov ss,ax

把值0x9000赋值给ss

5

Mov sp,#0xff00

把值0xff00赋值给sp

load_setup标号

载入setup模块

7

Mov dx,#0x0000

8

Mov cx,#0x0002

ch=0x00 cl=0x02

9

Mov bx,#0x0200

0x0200赋值给bx

10

Mov ax,#0x0200+SETUPLEN

//SETUPLEN=4; 把0x0204赋值给ax;

ah=0x02 al=0x04

11

Int 0x13

//BIOS中断,读取磁盘数据

12

Jnc ok_load_setup

//跳转到 ok_load_setup标号(锚点)

13

Mov dx,#0x0000

14

Mov ax,#0x0000

// 复位

15

Int 0x13

16

J load_setup

// 重读

 最重要的指令是 int 0x13,这是一个BIOS中断;这个中断从磁盘读取数据,磁盘寻址如下:
从ch:cl(柱面号:开始扇区=0x00:0x02)开始读取磁盘数据,共计读取ah:al(0x02:0x04读磁盘:扇区数量)个扇区到内存地址es:bx(0x9000:0x0200);
即从第2个扇区读取4个扇区的数据(setup数据)到内存0x90200,因为第1个扇区存储了引导扇区程序

6)接着,读入setup模块后,执行 ok_load_setup 锚点

Int 0x10 表示 一种BIOS中断,用于显示字符;显示的字符为 #msg1 即bp寄存器;
ok_load_setup标号的程序执行步骤如下:
      表3 ok_load_setup汇编程序执行过程

步骤

指令

描述

ok_load_setup标号

// 载入setup模块

1

Mov dl,#0x00

把0x00赋值给dl

2

Mov ax,#0x0800

把0x0800赋值给ax,即ah:al=08:00

3

Int ox13

//BIOS中断,读取磁盘数据

4

Mov ch,#0x00

把0x00赋值给ch

5

Mov sectors,cx

把cx赋值给sectors

Mov ah,#0x03

把0x03赋值给ah

7

Xor bh,bh

异或运算,把0x00赋值给bh

8

Int 0x10

//BIOS中断,读光标

9

Mov cx,#24

把24赋值给cx,表示要输出24个字符;

10

Mov bx,#0x0007

0x0007赋值给bx;其中0007是显示属性;

11

Mov bp,#msg1

把msg1赋值给bp;bp存储要显示的字符;

msg1是偏移;就是把 Loading system字符串打到屏幕上的光标位置

其中byte13,10 分别是换行和回车ascii码

12

Mov ax,#1301

把1301赋值给ax

13

int 0x10

//BIOS中断,显示字符

14

Mov ax,#SYSSEG

//SYSSEG=0x1000

15

Mov es,ax

把ax赋值给es;

16

Call read_it

//读取system模块

read_it 仍然是13号中断,把操作系统后面的代码读入到内存;读完之后,bootsect汇编文件执行完成;

Jmpi 0,SETUPSEG

// SETUPSEG=0x9020

jump intersegment-段间跳转:

目标地址=cs:ip=SETUPSEG:0=SETUPSEG:0;

即下面跳转到SETUPSEG为标号(锚点)的汇编指令执行;

 如果我们要把 Loading System字符串修改为 diyos is loading字符串(长度15)在屏幕上显示的话,还需要把第9条汇编指令修改为 mov cx,#15;

小结:

  • bootsect.s 文件中的汇编代码干的事情就是,把操作系统读入到内存,打出一个logo或字符串(diyos is loading);

Bootsect.s 汇编程序执行完成后,就需要把控制权交给下一个程序执行,即setup程序;
如何跳转到setup程序呢?

  • 执行 jmpi 0, SETUPSEG 即可;根据图1,我们知道SETUPSEG 的汇编程序在启动盘的第2~5个扇区;


【总结】计算机启动过程 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/329586.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

傅里叶变换公式_理解1维傅里叶变换

上个学期,学习了信号与系统。虽然知道了傅里叶变换的作用以及如何使用。但是对于它的本质,也就是FT是如何探测到频率的尚有疑惑。而恰好在知乎上发现了一些很好的回答。故将这些回答整理在这。感性理解1维FT知友Heinrich写的傅里叶分析之掐死教程&#x…

ASP.NET Core的配置(3): 将配置绑定为对象

出于编程上的便利,我们通常不会直接利用ConfigurationBuilder创建的Configuration对象读取某个单一配置项的值,而是倾向于将一组相关的配置绑定为一个对象,我们将后者称为Options对象。我们在《ASP.NET Core的配置(1)&…

11 个简练的 Java 性能调优技巧

转载自 11 个简练的 Java 性能调优技巧想要让你的项目一直高性能运作吗?以下有一些技巧你可以拿去消除缓存瓶颈,还有一些其他的性能调优建议。 大多数开发者认为性能优化是一个复杂的话题,它需要大量的工作经验和相关知识理论。好吧&#xff…

pre1-flink理论-批处理与流处理+简单示例

【README】 1.本文包含了 批处理与流处理的代码示例; 批处理:把数据 攒在一起(或攒一段时间或攒一定内存大小),然后再处理,这叫批处理;流处理:数据每来一个就处理一个;…

python表单提交的两种方式_Flask框架学习笔记之表单基础介绍与表单提交方式

本文实例讲述了Flask框架学习笔记之表单基础介绍与表单提交方式。分享给大家供大家参考,具体如下:表单介绍表单是HTML页面中负责数据采集功能的部件。由表单标签,表单域和表单按钮组成。通过表单,将用户输入的数据提交给服务器&am…

高级 | Java中获取类名的3种方法

转载自 高级 | Java中获取类名的3种方法获取类名的方法 Java 中获取类名的方式主要有以下三种。 getName() 返回的是虚拟机里面的class的类名表现形式。 getCanonicalName() 返回的是更容易理解的类名表示。 getSimpleName() 返回的是类的简称。 都有什么区别? 通过…

Asp.net 面向接口可扩展框架之核心容器

新框架的容器部分终于调通了!容器实在太重要了,所以有用了一个名词叫“核心容器”。 容器为什么那么重要呢?这个有必要好好说道说道。 1、首先我们从框架名称面向接口编程说起,什么是面向接口编程?(这个度娘回答一下) 解读一下:类是个体的定义…

pre2-flink单机部署与job提交

【README】 本文记录了flink单机部署,以及flink job2种提交方式; 【1】flink 单机部署 step1)下载flink 包; Apache Flink: Stateful Computations over Data Streamshttps://flink.apache.org/ step2)解压 tar -z…

到底什么是跨域?附解决方案

转载自 到底什么是跨域?附解决方案什么是跨域 要了解跨域,先要说说同源策略。 同源策略是由 Netscape 公司提出的一个著名的安全策略,所有支持 JavaScript 的浏览器都会使用这个策略。 所谓同源是指,域名,协议&#xf…

vue 字典_【开源】基于Vue的前端组件库HeyUI

说道vue组件库,目前主流的基本就是iview和element。今天又发现一个很不错的。HeyUI。组件也很丰富,入门比较简单。反正开源框架我们有不嫌多,多多益善啊。感兴趣的可以看看。关于HeyUIHeyUI 是一套基于 Vue2.0 的开源 UI 组件库,主…

(译)java8-流定义

【README】 本文翻译自 Stream In Java - GeeksforGeeks , 主要介绍了java8流; 【1】流 1)流定义:流是支持各种方法的对象序列(一系列对象),这些方法可以流水线化调用以产生期望结果&#xff…

基于CefSharp构建基于Chromium的应用程序

chromium是google chrome浏览器所采用的内核,最开始由苹果的webkit发展而出,由于webkit在发展上存在分歧,而google希望在开发上有更大的自由 度,2013年google决定自己开发webcore的分支,叫做Blink引擎,而后…

最新后端架构师技术图谱

转载自 最新后端架构师技术图谱深呼吸,慢慢学,技术长路漫漫… 数据结构二叉树完全二叉树平衡二叉树二叉查找树(BST)红黑树B-,B,B*树LSM 树队列集合链表、数组字典、关联数组栈树BitSet常用算法KPM 算法选择…

ansible脚本-Playbook(一)

Playbook组成部分: task 任务:包含目标主机上执行的操作,使用模块定义这些操作,每个任务都是一个模块的调用Variables变量:存储和传递数据,变量可以自定义,可以在playbook当中定义为全局变量&a…

三级pc技术_第十九周PC、笔电、数码周边新品汇总:AMD英特尔激战正酣

【dogkeji-科技犬】各位网友周末好,又到了2020年第十九周的PC、笔电、数码周边新品发布汇总时刻(2020年5月4日至2020年5月9日),那么本周有那些PC、笔电、数码周边新品发布呢?通过科技犬的汇总我们来一起回顾一下吧。AM…

【DDD/CQRS/微服务架构案例】在Ubuntu 14.04.4 LTS中运行WeText项目的服务端

在《WeText项目:一个基于.NET实现的DDD、CQRS与微服务架构的演示案例》文章中,我介绍了自己用Visual Studio 2015(C# 6.0 with .NET Framework 4.6.1)开发的DDD/CQRS/微服务架构的案例项目:WeText。文章发出后反响很好…

es6 dsl与sql对比

【README】 1.本文总结了 dsl 与 sql的对比写法; 2.es采用 7.2.1 版本; 【1】创建es索引 1)新建一个数据库事务执行日志索引 put localhost:9200/txlog { "mappings" :{ "properties":{"APPNAME"…

echarts line 去掉最外围方框_干货 | 关于射频芯片最详细解读

传统来说,一部可支持打电话、发短信、网络服务、APP应用的手机,一般包含五个部分部分:射频部分、基带部分、电源管理、外设、软件。射频部分:一般是信息发送和接收的部分;基带部分:一般是信息处理的部分&am…

服务器性能指标(一)——负载(Load)分析及问题排查

转载自 服务器性能指标(一)——负载(Load)分析及问题排查平常的工作中,在衡量服务器的性能时,经常会涉及到几个指标,load、cpu、mem、qps、rt等。每个指标都有其独特的意义,很多时候…

HoloLens开发手记 - HoloLens shell概述 HoloLens shell overview

使用HoloLens时,shell是由你周围的世界和来自系统的全息图像构成。我们将这种空间成为混合世界(mixed world)。 shell包含了一个可以让你将全息图像和应用放置在世界中的开始菜单(Start Menu)。当一个应用已经被放置在…