打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
菜鸟windows下写个操作系统

前面已经用MBR(Main Boot Record)显示了字符串,证明了位于0柱面0磁头1扇区的512字节的代码被BIOS成功导入了:0x0000:0x7C00,并运行成功。

但MBR始终空间有限,只有512字节,别说运行内核了,就是运行一个稍微大一点的程序都做不到,那MBR得实现一个类似于BIOS的功能,从硬盘别的扇区将代码加载进内存,然后JMP过去运行。

我们初步设计:BIOS----->MBR----->LOAD----->内核(kernel)

这个MBR 的目的很简单,我们读硬盘的 第三个扇区,其实你想读第几个扇区都没问题,主要是郑钢老师说他觉得这样安全,那就按郑老师说的办,我们会将LOAD的代码放进第三个扇区里,LOAD的主要是用来实现实模式进入保护模式要做的很多工作,比如创建GDT(全局描述符表)、创建内存映射(线性地址和物理地址的映射)等等,这里涉及到了保护模式的知识,咱们还是遵照用到哪学到哪的想法,先来完善MBR。

既然要读硬盘,那有必要来了解一下硬盘的相关知识。

CPU要和外部硬件交朋友打波波,需要一个I/O接口,这个I/O接口可以是一个小芯片也可以是一个电路板,这取决于多复杂,你可以理解I/O接口就是一个翻译器,CPU讲中文,外部硬件(声卡,显卡,硬盘等)讲英文,两边交朋友需要通过一个翻译器才能交流起来。

想想我们会碰到几个问题:

1。CPU不可能直接和硬件相连,硬件总是日新月异的,只会越来越多,不可能将所有的硬件设备和CPU连接起来。

2。CPU只能同一时间和一个小朋友聊天,这么多硬件同时和CPU说话,CPU不知道该听谁的回答谁的。

所以引入了总线结构(比如一个公共道路,排着队上去),然后ICH芯片(输入输出控制设备集中器),主要是连接不同的总线,协调各个I/O接口对CPU的访问,但有很多硬件还没有开发出来,或者将要开发出来,为了方便,所以弄了个PCI接口,如果有什么新的硬件开发出来,直接插入PCI扩展槽。

其实细说来说,CPU是通过端口(PORT)来和外围的小伙伴交朋友的,端口就是一堆的寄存器,位于I/O接口的电路中。

每一个I/O接口都有可能有几个端口,分别用于不同的目的.

例如:连接硬盘的就有好几个端口,分别是命令端口0x20,表明从硬盘读数据,写入端口0x30,表明向硬盘写数据,状态端口(硬盘工作是否正常,操作是否成功,发生了哪些错误),参数端口(读写的扇区数量、LBA的逻辑地址)、数据端口

每个端口都有自己的数据宽度,在早期的系统中,有8位的,有16位的,现在有些端口还有32位的,那到底是8位还是16位,这是那些设备和I/O制造者的自由。

ICH集成了两个PATA/SATA接口,分别是主硬盘接口和从硬盘接口。

主硬盘接口的端口寄存器:0x1F0----0x1F7

从硬盘接口的端口:0x170----0x177

在Intel系统中,只允许存在65536个端口,端口号是:0x0000-0xFFFF,因为是独立寻址,所以不能使用MOV指令,取而代之的是in和out命令。

in ax,dx 【硬编码0xED】

in al,dx 【硬编码0xEC】

目的操作数只能使用寄存器al[8位],ax【16位】,源操作数dx。从外部硬件读取数据,通过硬编码得知只有一个字节,之所以如此简短,是因为

in和out不能使用别的通用寄存器和内存单元,但可以使用立即数,这样硬编码就变为两字节,例如:

in al,0xf0 【硬编码E4 F0】,由于只有两字节,后面的立即数不能超过255,否则出现错误。

out dx,al

out dx,ax

目的操作数dx,源操作数al或者ax,CPU通过端口向外部设备发送消息。

终于要进入正题了,开始讲讲硬盘了。

1。我们要了解读写硬盘的基本单位是扇区,也就是说每次读一个扇区或者写一扇区。

2。从硬盘读写数据最原始的办法,是采用CHS模式,向硬盘控制器发送柱面、磁头、扇区号,太麻烦了,我不关心物理地址的换算,我只想0代表0号扇区,10000代表10000扇区,不要让我去换算,你们内部搞定,那我们就采用LBA逻辑扇区,切记他是从0号开始的,CHS是从1号开始的,LBA的0号扇区就是CHS的1号扇区,到时候别搞错了。

3。最早的LBA编址方法是LBA28,也就是2的28次方个扇区,每个扇区是512字节,换算后可以管理128GB的硬盘,现在用的比较多的是LBA48,换算后,可以管理131072TB硬盘。

目前我们总共分配也才分100M的硬盘映像,所以用LBA28【28位】完全足够了。

接着看0x1F6端口是个杂项,包含了很多内容,如下图,前4位用来设置模式,后4位设置LBA的最后高4位,

0x1F7是状态端口,当al=0xEC时,是硬盘识别

al=0x20时,是读取扇区

al=0x30时,是写入扇区

一旦把命令写入0x1F7端口寄存器,硬盘就开始工作了,所以要把前面的设置好了,最后再设置0x1F7,让他开始工作。

[完整代码后面会详细介绍]

我们先设置读入的扇区号,还有写进内存的地址[下面的两个常量会放进boot.inc里,然后在mbr.s最开始的地方引用

%include 'boot.inc'

在后面去添加:

mov eax,LOAD_READ_SECTION ;LOAD_READ_SECTION起始扇区的LBA地址

mov bx,LOAD_BASE_ADDRESS ;LOAD_BASE_ADDRESS 写入的地址

mov cx,1 ;要读取的扇区数

CALL Read_Disk_Section

jmp LOAD_BASE_ADDRESS

这个要放进的内存地址LOAD_BASE_ADDRESS只要是在实践二【实模式布局图】里的注明的可用区域都行,我就选了个0x900,没有为什么,看个人喜好。

1。设置要读取的扇区数,通过上图,我们知道寄存器是0x1F2,8位使用AL

Read_Disk_Section:

mov esi,eax ;保存,后面有用

mov di,cx ;保存,后面有用

mov dx,0x1F2

mov al,cl

out dx,al ;将要读取的扇区数写入硬盘控制器,如果al为0,那是代表要读入256个扇区进去

2。设置LBA的扇区号,因为我们使用的是LBA28位,所以需要设置28位。

看上图:0x1F3 LBA Low 这是低8位0----7

0x1F4 LBA Mid 这是中8位8---15

0x1F5 LBA High 这是高8位 16---23

那还差四位放哪里?这时候就需要看一下0x1F6的图了:

0x1F6 高4位放控制信息,低4位放LBA的扇区号的最高4位

所以程序如下:

mov eax,esi ;恢复eax

mov dx,0x1F3

out dx,al ;低8位放入硬盘控制器的0x1F3端口

mov cl,8

shr eax,cl

mov dx,0x1f4

out dx,al ;中8位

shr eax,cl

mov dx,0x1f5

out dx,al ;高8位

shr eax,cl

mov dx,0x1f6

and al,0x0f

or al,0xe0

out dx,al ;最后

3。向端口0x1F7写入0x20读状态,请求读硬盘,也是8位,不过他会先反馈你一个状态,到底是硬盘是忙还是不忙,如果不忙了有空闲了,你才能接着操作,如图:

所以代码如下:

mov dx,0x1F7

mov al,0x20

out dx,al

这条要读硬盘的代码运行后,硬盘就会忙开了,你需要循环去读他的返回的状态[0x1F7不仅是读写端口,也是状态端口],是否硬盘已经忙完,准备就绪了,所以代码如下:

loop_Read_Disk_Stats:

nop ;可写可不写,给CPU一点缓冲的时间

in al,dx

and al,0x88

cmp al,0x08

jnz loop_Read_Disk_Stats

4。最后就是连续取出数据了,需要使用0x1F0的端口。

mov dx,256 ;我们打算以字的形式来取,一个扇区是512字节,换算成字就是256

mov ax,di ;ax是几个扇区

mul dx ;ax得到总共有多少个字

mov cx,ax

mov dx,0x1F0

;------------------------

loop_Readin_Mem:

in ax,dx

mov [bx],ax

add bx,2

loop loop_Readin_Mem

完整代码如下:

我把boot.inc建到了include文件夹下面了,-I就是告诉编译器有一个库文件,可以在那里面找找。

再 dd if=\目录\mbr.bin of=\目录\c.img bs=512 count=1 conv=notrunc

boot.inc的内容为:

那好了MBR,我们还要建一个测试的LOAD,要不然怎么知道加载成功了没有,我们在CODE下再vim load.s,代码如下:

dd if=\目录\load.bin of=\目录\c.img bs=512 count=1 seek=2 conv=notrunc

这个seek是跳过的意思,跳过两个扇区,我们的物理扇区是从1开始数的,跳过两个就是写入第三个扇区,而LBA是逻辑扇区是从0开始数的,所以里面的扇区号是2。

最后显示成功图:

大功告成。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
一种可以穿透还原卡和还原软件的代码
从头开始编写操作系统(7) 第6章:引导加载器4 - xiaoxiaoyaya的专栏 - ...
手工恢复硬盘分区表
解读分区表的秘密
硬盘软故障排除的基本知识
GPT分区数据格式分析
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服