让MBR使用硬盘

news2024/12/24 2:37:57

前提知识:

BIOS中断

BIOS 和 DOS 都是存在于实模式下的程序,由它们建立的中断调用都是建立在中断向量表(Interrupt Vector Table,IVT)中的。它们都是通过软中断指令 int 中断号来调用的。中断向量表中第 0H~1FH 项是 BIOS 中断。,0x20~0x27 是 DOS 中断。而 Linux 内核是在进入保护模式后才建立中断例程的。

中断向量表中的中断例程是由 BIOS 建立的,它从物理内存地址 0x0000 处初始化并在中断向量表中添加各种处理例程。

硬件自己的功能调用例程及初始化代码就存放在这 ROM中。根据规范,第 1 个内存单元的内容是 0x55,第 2 个存储单元是 0xAA,第 3 个存储单位是该 rom 中以512 字节为单位的代码长度。从第 4 个存储单元起就是实际代码了

硬盘扇区表示

描述 0 盘 0 道 1 扇区用的便是其中的一种:CHS 方法,即柱面 Cylinder 磁头 Header 扇区 Sector(另外一种是 LBA 方式,暂不关心),“0 盘”说的是 0 磁头,因为一张盘是有上下两个盘面的,一个盘面上对应一个磁头,所以用磁头 Header 来表示盘面。“0 道”是指 0 柱面,柱面 Cylinder指的是所有盘面上、编号相同的磁道的集合,形象一点描述就是把很多环叠摞在一起的样子,组合在一起之后是一个立体的管状。“1 扇区”才是我们要解释的部分,将磁道等距划分成一段段的小区间,由于磁道是圆形的,确切地说是圆环,这些被划分出来的小区间便是扇形,所以称为扇区。在 CHS 方式中扇区的编号是从 1 开始的,不是 0,不是 0,原谅我说了两次,良苦用心你懂的,所以 0 盘 0 道 1 扇区其实就相当于 0 盘 0 道 0 扇区,它就是磁盘上最开始的那个扇区。

而LBA 方式中,扇区编号是从 0 开始的。LBA 的定义,是一种逻辑上为扇区址的方法,全称为逻辑块地址(Logical Block Address)。

SSD固态硬盘控制器管理LBA到物理存储的映射关系,并负责数据的读取和写入。它使用逻辑地址映射到闪存芯片中的特定页或块,而不是基于CHS模式的物理位置。
在这里插入图片描述

访问外设有两种方式:
(1)内存映射:通过地址总线将外设自己的内存映射到某个内存区域(并不是映射到主板上插的内存条中)。
(2)端口操作:外设都有自己的控制器,控制器上有寄存器,这些寄存器就是所谓的端口,通过 in/out指令读写端口来访问硬件的内存。

硬盘的随机存取是靠磁头臂不断移动实现的,磁头臂移动到目标位置的时间称为寻道时间,如果存储的数据不连续,这一块那一片的,磁头就得不断调整位置,这是机械式硬盘不可避免的,这便是硬盘的瓶颈所在,所以一般的硬盘都将寻道时间作为重要参数。

在这里插入图片描述

在这里插入图片描述

(1)先选择通道,往该通道的 sector count 寄存器中写入待操作的扇区数。
(2)往该通道上的三个 LBA 寄存器写入扇区起始地址的低 24 位。
(3)往 device 寄存器中写入 LBA 地址的 24~27 位,并置第 6 位为 1,使其为 LBA 模式,设置第 4位,选择操作的硬盘(master 硬盘或 slave 硬盘)。
(4)往该通道上的 command 寄存器写入操作命令。
(5)读取该通道上的 status 寄存器,判断硬盘工作是否完成。
(6)如果以上步骤是读硬盘,进入下一个步骤。否则,完工。
(7)将硬盘数据读出。

一旦 command 寄存器被写入后,硬盘就开始工作

32位CPU在实模式下使用32位寄存器

32 位处理器可以执行16 位的程序,包括实模式和16 位保护模式。为此,在16 位模式下,处理器把所有指令都看成是16 位的。举个例子,机器指令码0x40 在16 位模式下的含义是 inc ax
当处理器在16 位模式下运行时,也可以使用32 位的寄存器,执行32 位的运算。为此,必须使用指令前缀0x66 来临时改变这种默认状态,因为同一个指令码,在16 位模式下和32 位模式下具有不同的解释。
因此,当处理器在16 位模式下运行时,机器指令码对应的指令不再是inc ax,而是 66 40对应的指令也不再是inc ax,而是inc eax

loader加载地址

我们的 MBR 受限于 512 字节大小的,在那么小的空间中,没法为内核准备好环境,更没法将内核成功加载到内存并运行。loader 在哪里?如何跳过去执行?这就是新款 MBR 的使命,简而言之就是,负责从硬盘上把 loader 加载到内存,并将接力棒交给它。

MBR 从第 2 扇区(设定)中把它读出来。读出来放到哪里呢?

loader 加载到内存后不能被覆盖,尽量把 loader 放在低处,多留出一些空间给内核,作者将 loader 的加载地址选为 0x900。

代码附加详细解释

boot.inc

1 ;-------------loader 和 kernel-----------
2 LOADER_BASE_ADDR equ 0x900      ;宏定义
3 LOADER_START_SECTOR equ 0x2

主引导程序 :

;主引导程序 
;------------------------------------------------------------
%include "boot.inc" 
SECTION MBR vstart=0x7c00    ;告诉编译器,把我的起始地址编译为 0x7c00,段内偏移0x7c00     
   mov ax,cs      	;BIOS 是通过 jmp 0:0x7c00 跳转到 MBR 的,故cs 此时为 0
   mov ds,ax		;初始化
   mov es,ax
   mov ss,ax		;FS 和 GS 附加段寄存器是在 32 位CPU 中增加的
   mov fs,ax		;16位
   mov sp,0x7c00	;初始化栈指针
   mov ax,0xb800	;显存映射地址
   mov gs,ax

; 清屏
;利用0x06号功能,上卷全部行,则可清屏。
; -----------------------------------------------------------
;INT 0x10   功能号:0x06	   功能描述:上卷窗口
;------------------------------------------------------
;输入:
;AH 功能号= 0x06
;AL = 上卷的行数(如果为0,表示全部)
;BH = 上卷行属性
;(CL,CH) = 窗口左上角的(X,Y)位置
;(DL,DH) = 窗口右下角的(X,Y)位置
;无返回值:
   mov     ax, 0600h
   mov     bx, 0700h
   mov     cx, 0                   ; 左上角: (0, 0)
   mov     dx, 184fh		   ; 右下角: (80,25),
				   ; 因为VGA文本模式中,一行只能容纳80个字符,共25行。
				   ; 下标从0开始,所以0x18=24,0x4f=79
   int     10h                     ; int 10h

   ; 输出字符串:1 MBR
   mov byte [gs:0x00],'1'
   mov byte [gs:0x01],0xA4

   mov byte [gs:0x02],' '
   mov byte [gs:0x03],0xA4

   mov byte [gs:0x04],'M'
   mov byte [gs:0x05],0xA4	   ;A表示绿色背景闪烁,4表示前景色为红色

   mov byte [gs:0x06],'B'
   mov byte [gs:0x07],0xA4

   mov byte [gs:0x08],'R'
   mov byte [gs:0x09],0xA4
	 							 ;三个参数
   mov eax,LOADER_START_SECTOR	 ; 起始扇区lba地址
   mov bx,LOADER_BASE_ADDR       ; 写入的地址
   mov cx,1			 ; 待读入的扇区数
   call rd_disk_m_16		 ; 以下读取程序的起始部分(一个扇区)
  
   jmp LOADER_BASE_ADDR
       
;-------------------------------------------------------------------------------
;功能:读取硬盘n个扇区
rd_disk_m_16:	   
;-------------------------------------------------------------------------------
				       ; eax=LBA扇区号
				       ; ebx=将数据写入的内存地址
				       ; ecx=读入的扇区数
      mov esi,eax	  ;备份eax,out会修改al的值
      mov di,cx		  ;备份cx
;读写硬盘:
;第1步:设置要读取的扇区数
      mov dx,0x1f2
      mov al,cl
      out dx,al            ;读取的扇区数

      mov eax,esi	   ;恢复ax

;第2步:将LBA地址存入0x1f3 ~ 0x1f6

      ;LBA地址7~0位写入端口0x1f3
      mov dx,0x1f3                       
      out dx,al                          

      ;LBA地址15~8位写入端口0x1f4
      mov cl,8
      shr eax,cl
      mov dx,0x1f4
      out dx,al

      ;LBA地址23~16位写入端口0x1f5
      shr eax,cl
      mov dx,0x1f5
      out dx,al

      shr eax,cl
      and al,0x0f	   ;lba第24~27位
      or al,0xe0	   ; 设置7~4位为1110,表示lba模式
      mov dx,0x1f6
      out dx,al

;第3步:向0x1f7command端口写入读命令,0x20,硬盘开始工作 
      mov dx,	0x1f7
      mov al,0x20                        
      out dx,al

;第4步:检测硬盘状态
 .not_ready:
      ;同一端口,写时表示写入命令字,读时表示读入硬盘状态
      nop				;为了增加延迟,目的是减少打扰硬盘的工作
      in al,dx			;将 Status 寄存器的值读入到 al 寄存器
      and al,0x88	   ;第4位为1表示硬盘控制器已准备好数据传输,第7位为1表示硬盘忙
      cmp al,0x08
      jnz .not_ready	   ;若未准备好,继续等。

;第5步:从0x1f0端口读数据
      mov ax, di		
      mov dx, 256		;256 超过了 8 位寄存器表示的范围
      mul dx
      mov cx, ax	   ; di为要读取的扇区数,一个扇区有512字节,每次读入一个字,
			   ; 共需di*512/2次,所以di*256
      mov dx, 0x1f0
  .go_on_read:
      in ax,dx
      mov [bx],ax	;bx 只会访问到 0~FFFFh 的偏移,此处加载的程序不能超过 64KB
      add bx,2		 
      loop .go_on_read
      ret

   times 510-($-$$) db 0
   db 0x55,0xaa

loader的测试程序:

%include "boot.inc"
section loader vstart=LOADER_BASE_ADDR

; 输出背景色绿色,前景色红色,并且跳动的字符串"1 MBR"
mov byte [gs:0x20],'2'
mov byte [gs:0x21],0xA4     ; A表示绿色背景闪烁,4表示前景色为红色

mov byte [gs:0x22],' '
mov byte [gs:0x23],0xA4

mov byte [gs:0x24],'L'
mov byte [gs:0x25],0xA4   

mov byte [gs:0x26],'O'
mov byte [gs:0x27],0xA4

mov byte [gs:0x28],'A'
mov byte [gs:0x29],0xA4

mov byte [gs:0x2a],'D'
mov byte [gs:0x2b],0xA4

mov byte [gs:0x2c],'E'
mov byte [gs:0x2d],0xA4

mov byte [gs:0x2e],'R'
mov byte [gs:0x2f],0xA4

jmp $		       ; 通过死循环使程序悬停在此

注意我们通过dd命令将loader的二进制文件放在2扇区

测试结果:
在这里插入图片描述


用于学习笔记:操作系统真象还原第三章

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

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

相关文章

关于30KW储能PCS逆变器的设计方案。它包括双向DCDC和三电平逆变PCS

关于30KW储能PCS逆变器的设计方案。它包括双向DCDC和三电平逆变PCS。资料中提供了仿真源码,其中包含并网和离网两个模型 30KW储能PCS逆变器双向变流器设计方案资料 1.此系列为30KW储能PCS逆变器设计方案资料,双向DCDC和三电平逆变PCS; 2.仿真…

使用Android Jetpack Compose构建菜单(Menu)

Android Jetpack Compose是一种现代化的声明式UI工具,它让构建美观且功能强大的界面变得更加简单和直观。在本文中,我们将介绍如何使用Jetpack Compose构建一个简单的下拉菜单。 一、什么是下拉菜单? 下拉菜单是一种用户界面元素&#xff0…

无迹卡尔曼滤波在目标跟踪中的作用(二)

在上一节的内容中,我们介绍了UKF中最重要的内容—无迹变换UT,今天我们将具体介绍UKF是如何实现的。 好了,话不多说,开整!!! UKF算法的实现 我们知道,我们可以使用状态方程和观测方…

04 Web全栈 闭包/this指针

专业术语 变量、常量、数据类型形参、实参匿名函数、具名函数、自执行函数函数声明、函数表达式堆、栈同步、异步、进程、线程 执行上下文 当函数执行时,会创建一个执行上下文的环境,分为创建和执行两个阶段 创建阶段 创建阶段,指函数被调…

Android开发有必要深耕Framework吗?该如何着手?

前言 前段时间朋友在找 Android 高级开发工作,想进一步提升自己的能力,看了很多招聘信息,都要求熟练掌握 Framwork,了解底层原理等,发现是不是该深入研究底层技术…… 同时在网上也看到过相关问题,有很多…

iOS应用上架指iOS应用上架指南:综合详解

目录 引言 一、基本需求信息。 二、证书 一.证书管理 二.新建证书 三.使用appuploader服务同步证书 三、打包 三、审核 四、整体架构流程 五、代码实现 六、总结 转载自iOS开发上架的文章:iOS应用全面上架指南 引言 上架IOS应用到app store,…

An unexpected connection driver error occured

安装下载好rabbitmq,我在springboot整合mq,启动的时候报错了 An unexpected connection driver error occured 后来又报 Failed to check/redeclare auto-delete queue(s). 综合就是连接问题,端口有问题 我试过添加账户,提高权限&…

Docker 环境安装

博文目录 文章目录 CentOS 安装 Docker Engine安装 Docker升级 Docker卸载 Docker阿里云镜像加速 使用 DNF 命令安装最新 Docker Docker 官方文档 下载与安装 Linux 版本选择 Docker 官方文档 下载与安装 CentOS CentOS 安装 Docker Engine 安装 Docker 卸载旧版。卸载docke…

充分条件、必要条件

关于对充分条件、必要条件、充要条件的最简单扼要的理解: 充分条件:有A就一定有B,则A是B的充分条件; 必要条件:无A就一定无B,则A是B的必要条件; 充要条件:有A就一定有B&#xff0…

(区间dp)牛客·分离与合体

别人写dfs&#xff0c;我写bfs&#xff0c;个人觉得对于这个题bfs更好理解。 思路都大同小异啦…… 1、dp[i][j]:第i到第j获得最大的价值 2、p[i][j]:第i到第j获得最大价值时(i-k-j)&#xff0c;记录值k 3、bfs求路径&#xff0c;层次遍历嘛#include<bits/stdc.h> using…

精通 H.264,从压缩原理到前沿应用的全方位了解

H.264&#xff0c;也称为 AVC&#xff08;Advanced Video Coding&#xff09;&#xff0c;是一种广泛使用的视频编码标准。它是一种高效的压缩算法&#xff0c;可用于对音频和视频数据进行高质量的压缩和编码。以下是关于 H.264 编码的一些重要信息&#xff1a; 压缩原理&…

机器学习笔记 - 结合深度学习的基于内容的图像实例检索 通过学习DCNN表示进行检索

一、概述 上一篇,利用现成的DCNN模型进行检索。 机器学习笔记 - 结合深度学习的基于内容的图像实例检索 利用现成的DCNN模型进行检索_坐望云起的博客-CSDN博客一种方案是,为分类任务而进行大规模训练的DCNN直接充当图像检索任务的现成特征检测器,也就是说,可以提出在DCNN的…

5G驻留提升优化

故提出基于5-4两两邻区对的精细化的驻留比分析办法&#xff0c;围绕“一核心、二场景、四维度、五方案”这一方法&#xff0c;助力驻留比提升&#xff0c;“一核心”指基于5-4两两邻区对&#xff0c;选取次数TOP邻区对分析&#xff0c;“二场景”指5G小区为宏站还是室分&#x…

飞鱼星 企业级智能上网行为管理系统 权限绕过信息泄露漏洞

一&#xff1a;漏洞描述 飞鱼星 企业级智能上网行为管理系统 存在权限绕过以及信息泄露漏洞&#xff0c;可以获取管理员权限以及用户密码 二: 漏洞影响 飞鱼星 企业级智能上网行为管理系统 三: 漏洞复现 title“飞鱼星企业级智能上网行为管理系统” 访问主页使用Burp抓包 …

避免游离指针或引用以保护共享数据

在对共享数据进行保护时&#xff0c;有可能被外界的指针修改。如下例&#xff1a; #include<iostream> #include<thread> #include<mutex> #include<windows.h>using namespace std;class user_data {public:int a;char c;void change_data(void) { a…

Log On Yarn

序言 整理下各种部署在Yarn上的应用如何查看日志的问题.当然我觉得使用自定义的日志收集器来收集就更好了.这样子也解决了集群日志的问题cuiyaonan2000163.com 只用Flink做个引子,其它的服务也是这样的,没有什么差别 Flink 比如我们提交了一个任务同时知道他的ApplicationId…

transformer零基础学习

声明&#xff1a;以下文章链接仅用于个人学习与备忘。 基础知识 1&#xff1a;零基础解析教程 [推荐] https://zhuanlan.zhihu.com/p/609271490 2&#xff1a;Transformer 详解 [推荐] https://wmathor.com/index.php/archives/1438/ 3&#xff1a;如何从浅入深理解transfor…

Flutter开发笔记:Flutter 布局相关组件

Flutter开发笔记 Flutter 布局与布局组件 - 文章信息 - Author: Jack Lee (jcLee95) Visit me at: https://jclee95.blog.csdn.netEmail: 291148484163.com. Shenzhen ChineAddress of this article:https://blog.csdn.net/qq_28550263/article/details/131419782 【介绍】&am…

随笔-当曾经的小弟当了你的领导,阁下该如何应对

前几天&#xff0c;从小龙那得到一个招聘信息&#xff0c;想着被优化的C朋友&#xff0c;就转发给了他。过了会C朋友给我回了信息&#xff1a; C朋友&#xff1a;入职A&#xff08;我现在的公司&#xff09;需要穿正装吗&#xff1f; 我&#xff1a;需要啊&#xff0c;办手续…