《操作系统真象还原》第三章——完善MBR

2024-03-16 16:52

本文主要是介绍《操作系统真象还原》第三章——完善MBR,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前置知识

显卡与显存

为了显示文字,通常需要两种硬件,一是显示器,二是显卡。

  • 显卡的职责是为显示器提供内容,并控制显示器的显示模式和状态。
  • 显示器的职责是将那些内容以视觉可见的方式呈现在屏幕上。

除此以外,还需要知道的是

  • 显卡未必一定是独立的插卡。为了节省使用者的成本,有的显卡会直接做在主板上,这样的显卡也有个名字,叫集成显卡。
  • 显卡控制显示器的最小单位是像素。

那么,什么是显存呢?

显存就是存放要在显示器上显示的内容的器件,因为它位于显卡上,故称显示存储器(Video RAM,VRAM),简称显存,要显示的内容都预先写入显存。

显卡的工作是周期性地从显存中提取这些比特,并把它们按顺序显示在屏幕上。如果是比特“0”,则像素保持原来的状态不变,因为屏幕本来就是黑的;如果是比特“1”,则点亮对应的像素。

因此,为了给出要显示的字符,处理器需要访问显存,把字符的ASCII码写进去。但是,显存是位于显卡上的,访问显存需要和显卡这个外围设备打交道。同时,多一道手续自然是不好的,这当中最重要的考量是速度和效率。 

为此,计算机系统的设计者们,决定把显存映射到处理器可以直接访问的地址空间里,也就是内存空间里。

如图所示,8086可以访问1MB内存。其中,0x00000~9FFFF属于常规内存,由内存条提供;0xF0000~0xFFFFF由主板上的一个芯片提供,即ROM-BIOS。而0xB8000~0xBFFFF这段物理地址空间,是留给显卡的,由显卡来提供,用来显示文本。

屏幕是如何显示内容的

  • 显卡在任何时候都认为你发送的是ASCII码。
  • 屏幕上的每个字符对应着显存中连续2字节,前一个是字符的ASCII代码,后面是字符的显示属性,包括字符颜色(前景色)和底色(背景色)

如图所示,字符的显示属性(1字节)分为两部分

  • 低4位定义的是前景色,高4位定义的是背景色
  • 色彩主要由R、G、B这3位决定
  • K是闪烁位,为0时不闪烁,为1时闪烁
  • I是亮度位,为0时正常亮度,为1时呈高亮。

操作显存显示内容

编写mbr.S代码

;主引导程序MBR,由BIOS通过jmp 0:0x7c00跳转;------------------------------------------
;vstart=0x7c00表示本程序在编译时,起始地址编译为0x7c00
SECTION MBR vstart=0x7c00
;使用通用寄存器中的值(0)初始化其余寄存器mov ax,csmov ds,axmov es,axmov ss,axmov fs,ax
;初始化栈指针mov sp,0x7c00
;存入显存的段基址mov ax,0xb800mov gs,ax
;------------------------------------------;------------------------------------------
;利用0x06号功能进行清屏
;INT 0x10 功能号:0x06 功能描述:上卷窗口清屏
;输入:;AH 功能号:0x06;AL=上卷的行数(如果为0,则表示全部);BH=上卷的行属性;(CL,CH)=窗口左上角(X,Y)位置;(DL,DH)=窗口右下角(X,Y)位置
;返回值;无返回值mov ax,0x0600mov bx,0x0700mov cx,0        ;左上角(0,0)mov dx,0x184f   ;右下角(80,25);0x18=24,0x4f=79int 0x10        ;调用BIOS中断函数
;------------------------------------------;将要显示的字符串写入到显存中mov byte [gs:0x00],'1';在第一个字节的位置写入要显示的字符“1”;在第二个字节的位置写入显示字符(也就是字符1)的属性,其中A表示绿色背景,4表示前景色为红色mov byte [gs:0x01],0xA4mov byte [gs:0x02],' 'mov byte [gs:0x03],0xA4mov byte [gs:0x04],'M'mov byte [gs:0x05],0xA4mov byte [gs:0x06],'B'mov byte [gs:0x07],0xA4mov byte [gs:0x08],'R'mov byte [gs:0x09],0xA4jmp $times 510-($-$$) db 0db 0x55,0xaa

编译

nasm -o mbr.bin mbr.S

将程序写入磁盘

dd if=./osCode/mbr.bin of=./bochs/hd60M.img bs=512 count=1 conv=notrunc

运行

./bin/bochs -f boot.disk

从硬盘中加载程序到内存

 

 

boot.inc

;-----loader and kernel-----
LOADER_BASE_ADDR equ 0x900;loader在内存中位置
LOADER_START_SECTOR equ 0x2;loader在磁盘中的逻辑扇区地址,即LBA地址

mbr.S

;主引导程序MBR,由BIOS通过jmp 0:0x7c00跳转;------------------------------------------
%include "boot.inc"
;vstart=0x7c00表示本程序在编译时,起始地址编译为0x7c00
SECTION MBR vstart=0x7c00
;使用通用寄存器中的值(0)初始化其余寄存器mov ax,csmov ds,axmov es,axmov ss,axmov fs,ax
;初始化栈指针mov sp,0x7c00
;存入显存的段基址mov ax,0xb800mov gs,ax
;------------------------------------------;------------------------------------------
;利用0x06号功能进行清屏
;INT 0x10 功能号:0x06 功能描述:上卷窗口清屏
;输入:;AH 功能号:0x06;AL=上卷的行数(如果为0,则表示全部);BH=上卷的行属性;(CL,CH)=窗口左上角(X,Y)位置;(DL,DH)=窗口右下角(X,Y)位置
;返回值;无返回值mov ax,0x0600mov bx,0x0700mov cx,0        ;左上角(0,0)mov dx,0x184f   ;右下角(80,25);0x18=24,0x4f=79int 0x10        ;调用BIOS中断函数
;------------------------------------------;------------------------------------------
;将要显示的字符串写入到显存中mov byte [gs:0x00],'1';在第一个字节的位置写入要显示的字符“1”;在第二个字节的位置写入显示字符(也就是字符1)的属性,其中A表示绿色背景,4表示前景色为红色mov byte [gs:0x01],0xA4mov byte [gs:0x02],' 'mov byte [gs:0x03],0xA4mov byte [gs:0x04],'M'mov byte [gs:0x05],0xA4mov byte [gs:0x06],'B'mov byte [gs:0x07],0xA4mov byte [gs:0x08],'R'mov byte [gs:0x09],0xA4mov eax,LOADER_START_SECTOR;起始扇区地址mov bx,LOADER_BASE_ADDR;要写入的内存地址mov cx,1;待读入的扇区数目call rd_disk_m16;调用磁盘读取程序jmp LOADER_BASE_ADDR;;------------------------------------------
;函数功能:读取硬盘的n个扇区
;参数:;eax:LBA扇区号;bx:要写入的内存地址;cx:待读入的扇区数目rd_disk_m16:
;out命令,通过端口向外围设备发送数据
;其中目的操作数可以是8为立即数或者寄存器DX,源操作数必须是寄存器AL或者AX
;因此需要将之前ax中保存的值进行备份mov esi,eaxmov di,cx;正式读写硬盘
;第一步:设置要读取的扇区数目mov dx,0x1f2mov ax,cxout dx,axmov eax,esi;恢复eax的值;第二步:将LBA的地址存入0x1f3~0x1f6;LBA的0~7位写入端口0x1f3mov dx,0x1f3out dx,al;LBA的8~15位写入端口0x1f4mov cl,8shr eax,cl;ax左移8位mov dx,0x1f4out dx,al;LBA的16~23位写入端口0x1f5shr eax,clmov dx,0x1f5out dx,al;LBA的24~27位写入端口0x1f6shr eax,cl;左移8位and al,0x0f;与0000 1111相与,取后四位or al,0xe0;设置7~4位为1110,表示lba模式mov dx,0x1f6out dx,al;第三步,向0x1f7端口写入读命令,0x20mov dx,0x1f7mov al,0x20out dx,al;第四步,检测硬盘状态.not_ready:nop;空操作,什么也不做,相当于sleep,只是为了增加延迟in al,dx;由于读取硬盘状态信息的端口仍旧是0x1f7,因此不需要再为dx指定端口号;取出状态位的第3位和第7位;其中第3位若为1表示硬盘控制器已经准备好数据传输,第7位为1表示硬盘忙and al,0x88;cmp为减法指令,此处是为了判断第7位是否为1,如果为1,则减法的结果应该为0cmp al,0x08;JNZ是条件跳转指令,它表示"Jump if Not Zero",;也就是如果零标志位(ZF)不为0,则进行跳转。否则不进行跳转jnz .not_ready;若未准备好,则继续等;第五步,从0x1f0端口读取数据mov ax,di;di是之前备份的要读取的扇区数mov dx,256;mul指令表示乘法操作,当只有一个操作数时,被乘数隐含在al或者ax中mul dx;一个扇区512字节,每次读取两个字节,需要读取di*256次mov cx,ax;cx在此时表示要循环读取的次数mov dx,0x1f0.go_on_read:in ax,dxmov [bx],ax;通过循环将输入写入bx寄存器所指向的内存,每次读入2个字节的数据add bx,2loop .go_on_readrettimes 510-($-$$) db 0db 0x55,0xaa

 

编译

其中-I选项表示指定代码中包含的头文件(boot.inc)路径

nasm -I include/ -o mbr.bin mbr.S

将MBR程序写入磁盘的MBR扇区内

dd if=./osCode/mbr.bin of=./bochs/hd60M.img bs=512 count=1 conv=notrunc

实现内核加载器

loader.S

%include "boot.inc"SECTION vstart=LOADER_BASE_ADDR
;------------------------------------------
;将要显示的字符串写入到显存中mov byte [gs:0x00],'2';在第一个字节的位置写入要显示的字符“1”;在第二个字节的位置写入显示字符(也就是字符1)的属性,其中A表示绿色背景,4表示前景色为红色mov byte [gs:0x01],0xA4mov byte [gs:0x02],' 'mov byte [gs:0x03],0xA4mov byte [gs:0x04],'L'mov byte [gs:0x05],0xA4mov byte [gs:0x06],'O'mov byte [gs:0x07],0xA4mov byte [gs:0x08],'A'mov byte [gs:0x09],0xA4mov byte [gs:0x0a],'D'mov byte [gs:0x0b],0xA4mov byte [gs:0x0c],'E'mov byte [gs:0x0d],0xA4mov byte [gs:0x0e],'R'mov byte [gs:0x0f],0xA4jmp $

 编译

nasm -I ./include/ -o loader.bin loader.S

将程序写入磁盘的2号扇区内

由于0号扇区内写入的是MBR程序,因此loader程序需要写入2号扇区内

dd if=./osCode/loader.bin of=./bochs/hd60M.img bs=512 count=1 seek=2 conv=notrunc

运行 

 

这篇关于《操作系统真象还原》第三章——完善MBR的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/816105

相关文章

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

龙蜥操作系统Anolis OS-23.x安装配置图解教程(保姆级)

《龙蜥操作系统AnolisOS-23.x安装配置图解教程(保姆级)》:本文主要介绍了安装和配置AnolisOS23.2系统,包括分区、软件选择、设置root密码、网络配置、主机名设置和禁用SELinux的步骤,详细内容请阅读本文,希望能对你有所帮助... ‌AnolisOS‌是由阿里云推出的开源操作系统,旨

五大特性引领创新! 深度操作系统 deepin 25 Preview预览版发布

《五大特性引领创新!深度操作系统deepin25Preview预览版发布》今日,深度操作系统正式推出deepin25Preview版本,该版本集成了五大核心特性:磐石系统、全新DDE、Tr... 深度操作系统今日发布了 deepin 25 Preview,新版本囊括五大特性:磐石系统、全新 DDE、Tree

Linux操作系统 初识

在认识操作系统之前,我们首先来了解一下计算机的发展: 计算机的发展 世界上第一台计算机名叫埃尼阿克,诞生在1945年2月14日,用于军事用途。 后来因为计算机的优势和潜力巨大,计算机开始飞速发展,并产生了一个当时一直有效的定律:摩尔定律--当价格不变时,集成电路上可容纳的元器件的数目,约每隔18-24个月便会增加一倍,性能也将提升一倍。 那么相应的,计算机就会变得越来越快,越来越小型化。

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

1、简述linux操作系统启动流程

1、简述linux操作系统启动流程 启动第一步--加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它。这是因为BIOS中包含了CPU的相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息、PnP特性等等。开机时将ROM中的指令映射到RAM的低地址空间,CPU读取到这些指令,硬件的健康状况进行检查,按照BIOS中设置的启

第三章 UML类图简介(设计模式笔记)

第三章 UML类图简介 3.1类 3.2接口 名字层必须有<> 3.3 泛化(继承)关系 箭头终点端指向父类(空心三角形) 3.4 关联(组合1)关系 B类是A类的成员变量 ,称A关联B。 箭头终点端指向B 3.5 依赖(组合2)关系 B类是A类的某个方法的参数 ,称A依赖B。 箭头终点端指向B(虚线) 3.6 实现关系 箭头终点端指向接口(虚线,空心

操作系统是怎么为不同的程序分配所需的内存空间的

操作系统为不同的程序分配内存空间的过程涉及多个关键步骤,确保每个程序都有其所需的内存资源,同时避免程序之间的冲突。以下是操作系统如何为程序分配内存空间的详细过程: 1. 内存管理的基础概念 虚拟内存:现代操作系统使用虚拟内存机制来为程序提供隔离的内存空间。每个程序运行在其独立的虚拟地址空间中,这使得程序间的内存互不干扰。物理内存:实际的 RAM(随机存取存储器),由操作系统和硬件共同管理。虚拟

操作系统安全保护

操作系统安全概述 概念:满足安全策略要求,具有响应安全机制及安全功符合特定安全标准,在一定约束条件下 能抵御常见网络安全威胁,保障自身安全运行及资源安全 安全等级:根据安全功能和安全保障要求分为 用户自主保护级  系统审计保护级 安全标记保护级 结构化保护级 访问验证保护级 操作系统作用: 负责计算系统的资源管理、支撑和控制各种应用程序运行,为用户提供计算机系统管理接口 是构成网络信息

Linux操作系统命令集(一)

最近开了操作系统的课,弄着虚拟机的linux系统命令学学 文件和目录操作命令: ls:列出目录内容 示例:ls -l 以长格式列出目录内容cd:切换目录 示例:cd /home/user 切换到 /home/user 目录mkdir:创建目录 示例:mkdir new_directory 创建名为 new_directory 的目录rmdir:删除空目录touch:创建空文件或更新文件的时间戳