欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

哈工大操作系统学习L2 之 揭开钢琴的盖子

程序员文章站 2022-05-12 13:34:02
...

Open the OS

从打开电源开始

打开电源à计算机要开始工作了,计算机怎么工作? 这是我们最最基本, 也最最重要的常识…

从白纸到图灵机

计算机怎么工作? 说到底就是一个计算模型,下图为由图灵提出的模型:

哈工大操作系统学习L2 之 揭开钢琴的盖子
一台图灵机是如何实现加法的呢?通过控制器在纸带上读入3;在纸带上读入2;在纸带上读入+;控制器查表知道是5;在纸带上写下5。以上就是整个过程。那么如果有其它的运算呢?除了加法我们还能做什么?

从图灵机到通用图灵机

哈工大操作系统学习L2 之 揭开钢琴的盖子
图灵机就好像一个只会做一道菜的厨师,而通用图灵机则是一个能看懂菜谱的厨师。通用图灵机通过修改控制器,并且设置控制器的动作,进行工作。而这一系列的控制器动作也就是我们今天所说的程序。

从通用图灵机到计算机

1946年 冯·诺依曼提出存储程序思想,将程序和数据存放到计算机内部的存储器中,计算机在程序 的控制下一步一步进行处理。这是这一伟大思想奠定了今天的计算机基础。
计算机由五大部件组成:输入设备、输出设备、存储器、运算器、控制器
举个例子:
哈工大操作系统学习L2 之 揭开钢琴的盖子

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

指针IP及其指向的内容

计算机刚打开电源时,IP=? 是由硬件设计者决定。
对于X86PC机而言:

(1)x86 PC刚开机时CPU处于实模式
(2)开机时,CS=0xFFFF; IP=0x0000
(3)寻址0xFFFF0(ROM BIOS映射区)
(4)检查RAM,键盘,显示器,软硬磁盘
(5)将磁盘0磁道0扇区读入0x7c00处
(6)设置cs=0x07c0,ip=0x0000
哈工大操作系统学习L2 之 揭开钢琴的盖子
注意:实模式和保护模式对应,实模式的寻址CS:IP(CS左移4位+IP), 和保护模式不一样!

0x7c00处存放的代码

就是从磁盘引导扇区读入的那512个字节:

  1. 引导扇区就是启动设备的第一个扇区(开机时按住del键可进入 启动设备设置界面,可 以设置为光盘启动!)
  2. 启动设备信息被设置在CMOS中…(CMOS: 互补金属氧化物半导 体(64B-128B)。用来存储实 时钟和硬件配置信息。)
  3. 因此,硬盘的第一个扇区上存放着开机 后执行的第一段我们可以控制的程序。

操作系统的故事从这里开始…

引导扇区代码: bootsect.s

.s 表明是汇编语言的代码。

globl begtext,begdata,begbss,endtext,enddata,endbss
.text //文本段
begtext:
.data //数据段
begdata:
.bss //未初始化数据段
begbss:
entry start //关键字entry告诉链接器“程序入口”
start:
   mov ax, #BOOTSEG      mov ds, ax //此条语句就是0x7c00 ;ds=7c0,es=9000
处存放的语句!
   mov ax, #INITSEG      mov es, ax  // ;es=9000
   mov cx, #256 
   sub si, si            sub di,di  //连接
   rep movw  //将0x07c0:0x0000处的256个 字移动到0x9000:0x0000处
   jmpi go, INITSEG    //cs=go,ip=INITSEC
 BOOTSEG=0x07c0
  INITSEG=0x9000
  SETUPSEG=0x9020

(1).text等是伪操作符,告诉编译器产生 文本段,.text用于标识文本段的开始 位置。 此处的.text、.data、.bss表明这3个 段重叠,不分段!

jmpi go, INITSEG

jmpi (jump intersegment段间跳转): cs=INITSEG, ip=go

go: mov ax,cs //cs=0x9000
mov ds,ax mov es,ax mov ss,ax mov sp,#0xff00
load_setup: //载入setup模块
mov dx,#0x0000 mov cx,#0x0002 mov bx,#0x0200
mov ax,#0x0200+SETUPLEN int 0x13 //BIOS中断
jnc ok_load_setup
mov dx,#0x0000
mov ax,#0x0000 //复位
int 0x13
j load_setup //重读

其中:0x13是BIOS读磁盘扇区的 中断: ah=0x02-读磁盘,al=扇区数量(SETUPLEN=4),
ch=柱面号,cl=开始扇区,dh=磁头号,dl=驱动器号,es:bx=内存地址(即0x90200)
哈工大操作系统学习L2 之 揭开钢琴的盖子

读入setup模块后: ok_load_setup

Ok_load_setup: //载入setup模块
mov dl,#0x00 mov ax,#0x0800 //ah=8获得磁盘参数
int 0x13 mov ch,#0x00 mov sectors,cx
mov ah,#0x03 xor bh,bh int 0x10 //读光标
mov cx,#24 mov bx,#0x0007 //7是显示属性!  //修改开机logo时候需修改这24个字符
mov bp,#msg1 mov ax,#1301 int 0x10 //显示字符
mov ax,#SYSSEG //SYSSEG=0x1000 
mov es,ax 
call read_it //读入system模块,此处也是利用0x13 的BIOS中断
jmpi 0,SETUPSEG //转入0x9020:0x0000 执行setup.s
bootsect.s中的数据 //在文件末尾
sectors: .word 0 //磁道扇区数
msg1:.byte 13,10
.ascii “Loading system...//开机时候的logo
.byte 13,10,13,10

read_it //读入system模块

为什么读入 system模块还需要定义一个函数?
因为system模块可能很大, 要跨越磁道

read_it: mov ax,es cmp ax,#ENDSEG jb ok1_read 
ret
ok1_read:
mov ax,sectors 
sub ax,sread //sread是当前磁道已读扇区数,ax未读扇区数
call read_track //读磁道...

对于 jb ok1_read

ENDSEG=SYSSEG+SYSSIZE
SYSSIZE=0x8000 //该变量可根据
Image大小设定(编译操作系统时

引导扇区的末尾 //BIOS用以识别引导扇区

.org 510
.word 0xAA55 //扇区的最后两个字节

否则会打出非引导设备。
接下来可以转入setup执行了,jmpi 0, SETUPSEG 继续将控制权交给setup,(通过CS,IP)