b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

[自制操作系统03]读取硬盘中的数据

电脑杂谈  发布时间:2020-08-24 19:19:53  来源:网络整理

读取硬盘数据_ps2硬盘读取_wii读取硬盘

通过[自制操作系统01]计算机启动过程的核心解释和[自制操作系统02]环境准备和引导区域的实现,我们实现了最简单的操作系统(仅一条机器指令).

今天,我们必须更进一步,逐步改进这个最简单的操作系统. 之前最简单的操作系统写在引导区的512字节中. 这么小的空间将来肯定不会用于编写操作系统的代码,因此它的主要任务是将更多数据从硬盘读取到内存内部,然后跳转到内存位置以开始运行.

我必须回顾每节课中提到的四个跳跃:

一次跳转: 按下电源按钮,CPU将强制将PC寄存器的值初始化为0xffff0,该位置是BIOS程序的入口地址. 两次跳转: 入口地址是跳转指令,跳转到0xfe05b的位置,开始执行三个跳转: 在执行了一些硬件检查之后,最后一步是将引导区域的内容加载(复制)到内存0x7c00,并跳转到它. 四级跳转: 引导区中的代码主要用于加载操作系统内核并跳转到加载点

事实上,我们可以无限跳. 只要某个链接的任务很复杂,我们就可以分两步走. 但是也完全有可能停止从第三次跳转中跳出,并将操作系统所需的所有指令和数据从硬盘加载到内存中并执行,但这显然不好.

1. 代码概述

我们别说什么,首先发送一份本章完整代码的副本

mbr.asm

;----BIOS把启动区加载到内存的该位置,所以需设置地址偏移量
section mbr vstart=0x7c00
;----设置堆栈地址
mov sp,0x7c00
;----卷屏中断,目的是清屏
mov ax,0x0600
mov bx,0x0700
mov cx,0
mov dx,0x184f
int 0x10
;----直接往显存中写数据
mov ax,0xb800
mov gs,ax
mov byte [gs:0x00],'m'
mov byte [gs:0x02],'b'
mov byte [gs:0x04],'r'
;----读取硬盘(第2扇区)并加载到内存(0x900)
mov eax,0x02	;起始扇区lba地址,LBA=(柱面号*磁头数+磁头号)*扇区数+扇区编号-1
mov bx,0x900    ;写入的内存地址,之后用
mov cx,4        ;待读入的扇区数
call read_disk
jmp 0x900
;----读硬盘方法,eax为lba扇区号,bx为待写入内存地址,cx为读入的扇区数
read_disk:
	mov esi,eax	;备份
	mov di,cx	;备份
	
;第一步,设置要读取的扇区数
	mov dx,0x1f2
	mov al,cl
	out dx,al
	mov eax,esi	;恢复
	
;第二步,设置LBA地址
	mov cl,8
	;0-7位写入0x1f3
	mov dx,0x1f3
	out dx,al
	;8-15位写入0x1f4
	mov dx,0x1f4
	shr eax,cl
	out dx,al
	;16-23位写入0x1f5
	mov dx,0x1f5
	shr eax,cl
	out dx,al
	;24-27位写入0x1f6
	mov dx,0x1f6
	shr eax,cl
	and al,0x0f	;lba的24-27位
	or al,0xe0	;另外4位为1110,表示lba模式
	out dx,al
	
;第三步,写入读命令
	mov dx,0x1f7
	mov al,0x20
	out dx,al
;第四步,检测硬盘状态
.not_ready:
	nop
	in al,dx
	and al,0x88	;第4位为1表示准备好,第7位为1表示忙
	cmp al,0x08
	jnz .not_ready
	
;第五步,读数据
	mov ax,di
	mov dx,256
	mul dx
	mov cx,ax
	
	mov dx,0x1f0
	.go_on_read:
		in ax,dx
		mov [bx],ax
		add bx,2
		loop .go_on_read
		ret
	
;----512字节的最后两字节是启动区标识
times 510-($-$$) db 0
db 0x55,0xaa

loader.asm

section loader vstart=0x900
mov byte [gs:0xa0],'l'
mov byte [gs:0xa2],'o'
mov byte [gs:0xa4],'a'
mov byte [gs:0xa6],'d'
mov byte [gs:0xa8],'e'
mov byte [gs:0xaa],'r'

Makefile

mbr.bin: mbr.asm
	nasm -I include/ -o out/mbr.bin mbr.asm -l out/mbr.lst
	
loader.bin: loader.asm
	nasm -I include/ -o out/loader.bin loader.asm -l out/loader.lst
	
os.raw: mbr.bin loader.bin
	../bochs/bin/bximage -hd -mode="flat" -size=60 -q target/os.raw
	dd if=out/mbr.bin of=target/os.raw bs=512 count=1
	dd if=out/loader.bin of=target/os.raw bs=512 count=4 seek=2
	
brun:
	make install
	make only-bochs-run
	
only-bochs-run:
	../bochs/bin/bochs -f ../bochs/bochsrc.disk -q
	
install:
	make clean
	make -r os.raw
	
clean:
	rm -rf target/*
	rm -rf out/*

第二,磁盘

wii读取硬盘_读取硬盘数据_ps2硬盘读取

如果您粗读代码,至少可以在mbr.asm中知道该代码. 前半部分是在屏幕上输出mbr字符串. 在上一课中,以直观的方式编写了此文档,以使操作系统降至最低. 代码,可选. 后半部分只是读取硬盘数据的多个扇区,将其加载到内存中的某个位置,然后跳转到该位置. 这是mbr的关键和责任.

然后如何读取硬盘中的数据,它从磁盘的结构开始. 我对硬件不是很了解,所以我只能提出一个大致的想法. 硬盘是一种磁盘,分为硬盘和软盘. 但是它们的逻辑结构是相同的:

拼盘

头(头)

曲目(曲目)

部门

汽缸(汽缸)

机械式硬盘

我不想担心它如何移动. 我只需要弄清楚. 确定磁头,圆柱体和扇区后,将确定512字节的区域. 够了这是硬盘的CHS表示法,即圆柱(圆柱),磁头(磁头),扇区(扇区),只要知道硬盘的CHS数量,就可以确定硬盘的容量,硬盘的容量=柱面数×磁头数×扇区数×512B.

如果您不考虑这种物理结构,则硬盘实际上由n个多个512字节区域组成. 我们可以从0开始编号,然后每512字节加一个,因此我们完全不需要考虑任何扇区. 圆柱体,这是我的最爱(似乎是软件工程师的想法),这种方法称为LBA表示法.

LBA = (柱面号 * 磁头数 + 磁头号) * 扇区数 + 扇区编号 - 1

因此,如果CPU需要处理硬盘,则它必须使用CHS表示法,至少要告诉硬盘柱面号,磁头和扇区号,或使用LBA表示法来告诉硬盘LBA号,然后给硬盘一个读取的Still write信号. 硬盘制造商有数千万,而CPU制造商也不同. 自然,必须有一个硬盘接口标准. 该标准称为ATA标准,也可以通常称为IDE硬盘接口技术标准. 该标准总共可以下载三卷AT_Attachment_with_Packet_Interface的内容,但是我们使用的并不多. 我找到了一篇相当真实的中文版论文“ IDE接口硬盘读写技术”. 这基本上是足够的.

三,IDE硬盘接口技术

CPU和设备通过IO接口进行交互,所以核心是该技术标准定义的IO接口是什么,它们的功能是什么

ps2硬盘读取_wii读取硬盘_读取硬盘数据

I / O地址读取(主机从硬盘读取数据)写入(主机数据写入硬盘)

1F0H

数据寄存器

数据寄存器

1F1H

错误寄存器(只读寄存器)

特征寄存器

1F2H

扇区计数寄存器

扇区计数寄存器

1F3H

扇区号寄存器或LBA块地址0〜7

扇区号或LBA块地址0〜7

1F4H

ps2硬盘读取_wii读取硬盘_读取硬盘数据

轨道号或LBA块地址的低8位8〜15

轨道号或LBA块地址的低8位8〜15

1F5H

轨道号或LBA块地址16〜23的高8位

轨道号或LBA块地址16〜23的高8位

1F6H

驱动器/磁头或LBA块地址24〜27

驱动器/磁头或LBA块地址24〜27

1F7H

命令寄存器或状态寄存器

命令寄存器

因此,如果您想编写一个程序来读取文件,则不难分析整个过程:

在1F3H〜1F6H处写入要在1F2H中读取的扇区数. 这四个端口写入计算出的起始LBA地址. 在1F7H处,写入读取命令的指令号并连续检查1F7H(此时已变为状态寄存器的含义). 如果第四步不忙,它将开始从1F0H读取数据到存储器中的指定位置,直到阅读完毕

这五个步骤与上面的代码相对应

读取硬盘数据_wii读取硬盘_ps2硬盘读取

最后,不要忘了我们的代码仍加载到引导区中,因此最后两个字节仍必须是引导区标识符0x55 0xaa

四,运行代码

写入mbr.asm之后,我们将写入另一个loader.asm,将其起始地址设置为0x900(因为这是读写磁盘后存储的内存位置,这是我们自己的定义),并将其放入在磁盘的第二个扇区中(也可以由我们自己设置,只要它与读取磁盘的代码一致)

loader.asm

section loader vstart=0x900
mov byte [gs:0xa0],'l'
mov byte [gs:0xa2],'o'
mov byte [gs:0xa4],'a'
mov byte [gs:0xa6],'d'
mov byte [gs:0xa8],'e'
mov byte [gs:0xaa],'r'

剩下的实质在于我们的Makefile,您可以参考上面的代码

执行make brun,您会看到以下效果,这意味着将加载程序代码从磁盘加载到内存的过程已经生效.

5. 开源项目和课程计划

如果您有兴趣制作一个自制的操作系统,则不妨按照这一系列课程进行观看,甚至可以加入我们(下面的官方帐户和微信助手)一起开发.

参考书

这本书“恢复操作系统真相”真是太棒了!强烈推荐

项目开源

项目开源地址:

当您看到本文时,代码可能编写了比文章更多的部分. 您可以通过提交记录历史记录查看历史代码. 我将慢慢整理提交历史和项目描述文档,并努力为每节课准备一个可执行代码. 当然,本文中的代码也很完整,并且完全可以使用复制和粘贴.


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/dianqi/article-306067-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 李俊杰
        李俊杰

        拉森舰可不是什么老旧军舰

      • 杜秋永
        杜秋永

        看看岛礁建设中还存在什么不足之处

      热点图片
      拼命载入中...