从零开始写一个操作系统内核 笔记(二)

BIOS加载流程

在这里插入图片描述
如上图
1、当计算机系统上电开机或者按了复位按键时,CPU会将代码指针指向4G空间最后64K的最后16字节,即0xFFFFFFF0地址。

2、然后会执行一条JMP指令,跳转到ROM BIOS程序,进行一系列的硬件自检和初始化操作。
3、将自检的后结果数据复制到1M末端的64K处。
4、跳转到0x7c00处,准备从硬盘或其他设备加载操作系统的引导程序。

汇编语言 介绍

下面 举个例子 来了解下汇编语言:
mov ax,3FH //将;立即数 3FH传递给 ax寄存器
add bx,ax // bx =bx + ax
add cx,ax //cx = cx + bx

tips:0x3f 通常 16进制数 前面加 0x表示。
在汇编语言中 也可以写成 十进制
mov ax,63
mov ax,0x3FH
这两句话都是一样的效果。
当然 你还可以写成 mov ax,00111111B 二进制表示其实也是一个意思。

8066 cpu 通过复位触发 后CS 会变成0xFFFF IP = 0x0000
当 ip 超出 0x000F 如 ip=0x0011 那么 cs + ip 会产生溢出 此时 会变为 0x0001 ,绕回到达最低位。
jmp 0xf000:0xe05b 这个指令会改变 cs 为 0xf000 ip为 0xe05b
借此来实现跳转指令。

硬盘工作原理

硬盘内部有 多个磁盘 每个磁盘 其实就是 向DVD一样的碟片 但是不同的是上下两面都可以读写,有2个盘面,每个盘面 都有一个磁头读写内容。
在这里插入图片描述
盘片由电机驱动旋转,一般现在的硬盘 转速 分为 3600 转/分 和 7200转/分 也有少数能达到 一万多转/分。

在这里插入图片描述

如上面 4-4 1个盘片 会有2个盘面 上图有 6个盘片 就有12个盘面, 然后每个盘面 从最外面一圈是0磁道,1个圆形磁道 有 63个扇区,扇区和扇区之间会以空白来间隔,每个山区会以扇区头开始,然后有 512 字节的数据区,扇区头包含了山区的信息.主要有本扇区的磁道号,磁头号,扇区号,用来供硬盘定位使用。 当要写入内容时,从第一个盘面0磁道开始写,写完第一个盘面的血第二个 盘面的磁道 以此类推 所有盘片的0磁道都会被写入数据,cpu处理速度远高于磁盘的读写,当最外面的磁道被写完后,步进电机就会被驱动 向磁盘内侧移动达到磁道1 因为移动的过程属于机械运动对于cpu 内存来说是很慢的,所以如果数据 不是连续的存储在磁道中要寻找数据那将会非常费时的。

主引导扇区

硬盘的第一个扇区是0道1扇区,又称为 0头0柱1扇区。这个扇区是主引导扇区。如果从硬盘开始启动,Bios 会读取硬盘主引导扇区的内容。将它加载到0x0000:0x7c00处,(物理地址 0x07c00) 然后通过jmp指令 跳转到 0x7c00 ,为什么是 0x7c00 得去问当初这么设定的人。
所以其实操作系统本身是无法直接启动的,得通过引导程序将它加载到内存才能正常启动,所以引导区坏了的话,电脑是没法启动的。

虚拟机

虚拟机顾名思义,就是通过创建一个与真实环境在软件上隔离但同时共享硬件资源的电脑,做到和真实环境有着一样的能力。就我所知道的虚拟机广泛的用途之一就是 调试病毒 如果在真实环境下调试病毒 直接在真实环境下调试分析病毒是有很大风险的稍有不慎 自己的本机就被病毒给破坏 利用虚拟机技术 就能很好的避免这一点。当然利用虚拟机也可以用来教学 来模拟不同情况下的编程实验,这样就不需要花费更高的成本去购买专门的硬件资源。主流的虚拟机软件包括 VMWare 、virtual pc 和virtualbox等,其中只有virtualbox开源和免费的。
虚拟机使用的是虚拟的文件而不是真实的硬盘分区,通过读取一个文件系统 虚拟盘,将磁盘操作转换成对问价操作,从而使软件系统以为是在操作真实的硬盘。

虚拟硬盘 简介

虚拟硬盘 由于不同的厂家的虚拟机 都有其自己的实现方式,VHD 虚拟硬盘规范起源于Connectix 公司的虚拟软件Connectix Virtual PC,2003 年微软收购可它,改名为MicroSoft VirtualPC。微软公司正式发布了VHD虚拟硬盘格式规范。
VDI是VirtualBox 自己的虚拟机硬盘 规范,VMDK是VMWare 的虚拟硬盘规范。

创建VHD步骤:

在这里插入图片描述
在这里插入图片描述

VHD 包含固定大小 和 可变大小 两种格式 书里面 用的是 固定大小的 这种盘的格式比较简单 就是初始化固定字节数的 文件 填充为 00 最后一个扇区也会存一些扇区信息。
在这里插入图片描述
在这里插入图片描述
再来看看 可变的
在这里插入图片描述
开头是一个标志,conectix 后面的数据包含了 文件的创建日期、VHD的版本号、创建该文件的应用程序名和版本、创建该文件的应用程序所属的操作系统.该虚拟硬盘的参数(磁头数、每面次磁道数、每磁道扇区数)、VHD类型(固定尺寸还是动态增长)、虚拟硬盘容量等。
所以 比起 动态的磁盘大小 固定大小的磁盘大小结构就比较简单了、只是初始化了 指定大小的字节数。

要写磁盘 就要了解 写入的两种模式 分别是 CHS模式,LBA模式

CHS 模式 根据磁头,磁道和扇区 的索引来访问 硬盘 。
LBA 模式(逻辑扇区号) 不考虑 扇区的物理位置(磁头号、磁道号),
0面 0 道 1扇区 逻辑扇区0
0面0道 2扇区。逻辑扇区1
0面0道 3扇区。 逻辑扇区2
0面0道 17扇区。逻辑扇区16
0面1道 1扇区。逻辑扇区17
0面1道 2扇区。逻辑扇区18
。。。。
0面1道 17扇区。 逻辑扇区23
这样所有扇区 都会有一个区别于 其他扇区的编号。
LBA = C * 磁头总数 * 每道扇区数 + H * 每道扇区数 + (S -1)

LBA 优点

简化了程序访问操作 只要给定一个 编号 就可以找到特定的盘,而不需要记住一系磁盘 硬件数据 磁道号 磁头数 盘面数等等。

可以直接使用hex编译的工具将 00 替换成 512 个字节 编译好的 asm二进制文件。
这里我的电脑是用Mac 由于 这本书推荐的工具是在windows下才可以使用的。
最近用Go习惯了,就用Go写一个写Vhd文件LBA写入的工具吧。
github地址:https://github.com/qiaojinxia/VhdWriter

好了 万事俱备让我们开始 写第一个操作系统吧!

org  0x7c00;
// org 0x7c00, org 的意思是origin, 中文意思是“起始,起源,” org 后面的7c00 是物理
//内存地址,假设物理内存是一个byte类型的大数组,例如byte[] memory, 如果你有2 G内容,
//换算成字节就是2097152, 也就相当于memory数组有2097152字节,于是当虚拟机上电,然后
//new一块内存 byte[] memory = new byte[2097152]. org 0x7c00 的意思是将本汇编编
//译后的二进制数据从memory[0x7c00]处写入memory.
jmp  entry
//jmp entry 中的jmp 其实就是c语言中的语句goto, jmp entry 其实是让cpu跳转到entry 
//处,执行entry下面的代码,如果entry是一个函数名字的话,jmp entry 相当于调用entry函
//数,类比于java就是函数调用:entry();
entry:
    mov  ax, 0 //ax寄存器清零
    mov  ss, ax //ss清零
    mov  ds, ax //ds清零
    mov  es, ax //es清零
    mov  si, msg //等价于c语言里的  si = *msg si 存储指向数据msg的一个指针
print:
	//al 是一个八位寄存器 是ax的低八位 al = *si 取si指向第一个byte的值
	mov al,[si] 
	add si,1 //对si指针 + 1 那么原来指向 0x0a 下一个字节 是0x0a
	cmp al,0//看看msg的最后字节是 0 这是用来判断是不是读到数据末尾
	je fin//条件跳转 如果上面的条件 符合 就执行跳转 到fin执行阻塞死循环
	mov ah,0x0e //ah 是ax高8位
	mov bx,15//要把寄存器ah设置为0x0e, 把要输出的字符的ascii值放入到寄存器al, 同时要把寄存器设bh的值设置成0,字符的颜色可以通过寄存器bl的值来设定。
	int 0x10//向屏幕输出中断 这句话 和上面两句 就理解成 print(data,int args1,int arg2) 后面两个参数 就是调用需要传入的。
	jmp print // 将上面的 理解成 如下c语言逻辑:
//	do { 
// char al = *si; 
//si++; 
//if (al == 0) { 
//goto fin 
//}	
fin:
    HLT //不在执行指令。直到被其他设备的信号或中断信号来激活
    jmp  fin//如果有键盘输入中断 那么这句话就会被执行然后 跳转到 fin形成一个死循环
msg:
	DB 0x0a,0x0a //ascii表的 换行符
	db "hello,world!"//这里初始化 12个byte
	db 0x0a //换行符 
	db 0//结尾  换成c语言就是字符串 "\n\nhello,world!\n\n0"

nasm -o caomao.bin caomao.asm
./main vhd caomaoos.vhd -n=0 -w=caomao.bin vaild e
写入成功后:
在这里插入图片描述

启动虚拟机看看是不是有结果了。
在这里插入图片描述
hello,world 是不是很简单啊,一个最最最基本的hello,world就出来了,恭喜你你的第一个操作系统已经写出来了,是不是很有成就呢。

发布了85 篇原创文章 · 获赞 5 · 访问量 4719

猜你喜欢

转载自blog.csdn.net/weixin_41315492/article/details/104084358
今日推荐