HIT_OS_LAB3 操作系统的引导

news2025/1/11 7:47:08

操作系统实验三

3.1. 实验目的

  • 熟悉实验环境;
  • 建立对操作系统引导过程的深入认识;
  • 掌握操作系统的基本开发过程;
  • 能对操作系统代码进行简单的控制,揭开操作系统的神秘面纱。

3.2. 实验内容

3.2.1. 改写 bootsect.s 主要完成如下功能:

bootsect.s 可以在屏幕上输出提示信息
输出语句“BDSOS is booting…”
检查bootsect.s,以下代码用于打印信息

ljmp    $BOOTSEG, $_start  
_start:  
    mov $0x03,%ah  
    xor %bh,%bh  
    int $0x10  
	mov	$24, %cx
	mov	$0x0007, %bx		# page 0, attribute 7 (normal)
	#lea	msg1, %bp
	mov     $msg1, %bp
	mov	$0x1301, %ax		# write string, move cursor
	int	$0x10
    msg1:
	.byte 13,10
	.ascii "Loading system ..."
	.byte 13,10,13,10 
.org 510  
boot_flag:  
    .word   0xAA55  

因此,对bootsect.s的内容进行修改,使其输出所需的信息,然后删除其余代码,最终,bootsect.s的完整内容如下:

.code16  
.global _start   
.equ SETUPLEN, 4		# nr of setup-sectors  
.equ BOOTSEG, 0x07c0		# original address of boot-sector  
.equ INITSEG, 0x9000		# we move boot here - out of the way  
.equ SETUPSEG, 0x9020		# setup starts here  
.equ ROOT_DEV, 0x301  
ljmp    $BOOTSEG, $_start  
_start:  
 mov $0x03,%ah  
 xor %bh,%bh  
 int $0x10  
 mov $31,%cx  
 mov $0x0007,%bx  
 mov $msg1,%bp  
 mov $0x07c0,%ax  
 mov %ax,%es  
 mov $0x1301,%ax  
 int $0x10  
msg1:  
 .byte 13,10  
 .ascii "WangWeiOS is booting..."  
 .byte 13,10,13,10  
.org 510  
boot_flag:  
 .word   0xAA55 

最后,编译文件并执行,结果如下图,显示bootsect.s的修改是正确的,成功输出语句“BDSOS is booting…”
在这里插入图片描述

3.2.2. 改写 setup.s 主要完成如下功能:

首先,确保setup.s能够向屏幕输出信息,这个功能已经在前一个问题中在bootsect.s中完成,因此,将相应代码复制到setup.s中,然后删除多余代码,完整的setup.s代码如下:

       .code16
       .equ SETUPSEG, 0x9020
       .global _start
       ljmp $SETUPSEG, $_start	
       _start:
           mov $0x03,%ah
           xor %bh,%bh
           int $0x10
           mov $25,%cx
           mov $0x0007,%bx
           mov $msg2,%bp
           mov $0x07c0,%ax
           mov %cs,%ax
           mov %ax,%es
           mov $0x1301,%ax
           int $0x10
       inf_loop:
           jmp inf_loop
       msg2:
           .byte   13,10
           .ascii "Now we are in SETUP"
           .byte   13,10,13,10
       .org 510
       boot_flag:
           .word   0xAA55

接下来,对bootsect.s进行修改,以使其能够加载并跳转到setup.s的起始地址执行。检查原bootsect.s的内容,找到以下代码实现了这个功能:

        load_setup:
        	mov	$0x0000, %dx		# drive 0, head 0
        	mov	$0x0002, %cx		# sector 2, track 0
        	mov	$0x0200, %bx		# address = 512, in INITSEG
        	.equ    AX, 0x0200+SETUPLEN
        	mov     $AX, %ax		# service 2, nr of sectors
        	int	$0x13			# read it
        	jnc	ok_load_setup		# ok - continue
        	mov	$0x0000, %dx
        	mov	$0x0000, %ax		# reset the diskette
        	int	$0x13
        	jmp	load_setup
        ok_load_setup:
    	    ljmp	$SETUPSEG, $0

因此,对bootsect.s的代码进行修改,首先加载setup.s,然后显示语句“WangWeiOS is booting…”,最后跳转至setup.s。完成这些功能并删除多余代码后,bootsect.s的完整代码如下:

   	.code16
       	.equ SETUPLEN, 2		# nr of setup-sectors
       	.equ BOOTSEG, 0x07c0		# original address of boot-sector
       	.equ INITSEG, 0x9000		# we move boot here - out of the way
       	.equ SETUPSEG, 0x9020		# setup starts here
       	.equ ROOT_DEV, 0x301
       	ljmp    $BOOTSEG, $_start
       _start:
       	mov	$BOOTSEG, %ax
       	mov	%ax, %ds
       	mov	$INITSEG, %ax
       	mov	%ax, %es
       	mov	$256, %cx
       	sub	%si, %si
       	sub	%di, %di
       	rep	
       	movsw

       load_setup:
       	mov	$0x0000, %dx		# drive 0, head 0
       	mov	$0x0002, %cx		# sector 2, track 0
       	mov	$0x0200, %bx		# address = 512, in INITSEG
       	.equ    AX, 0x0200+SETUPLEN
       	mov     $AX, %ax		# service 2, nr of sectors
       	int	$0x13			# read it
       	jnc	ok_load_setup		# ok - continue
       	mov	$0x0000, %dx
       	mov	$0x0000, %ax		# reset the diskette
       	int	$0x13
       	jmp	load_setup

       ok_load_setup:
       	mov	$0x03, %ah		# read cursor pos
       	xor	%bh, %bh
       	int	$0x10
       	mov	$31, %cx
       	mov	$0x0007, %bx		# page 0, attribute 7 (normal)
       	mov     $msg1, %bp
       	mov	$0x1301, %ax		# write string, move cursor
       	int	$0x10
       	ljmp	$SETUPSEG, $0

       msg1:
       	.byte 13,10
       	.ascii "WangWeiOS is booting..."
       	.byte 13,10,13,10
       	.org 508
       root_dev:
       	.word ROOT_DEV
       boot_flag:
       	.word 0xAA55

最后,编译文件并执行,结果如下图,bootsect.s和setup.s的修改是正确的,成功显示语句“Now we are in SETUP”
在这里插入图片描述

setup.s 可以获取至少一个基本的硬件参数(如内存参数、显卡参数、硬盘参数等),将其存储在内存的特定地址,并在屏幕上输出。
在保持setup.s原有功能不变的同时,使其能够读取硬件参数。首先,在原setup.s文件中,有以下代码可以读取各项硬件信息:

        mov	$INITSEG, %ax	# get Cursor Poser
	    mov	%ax, %ds
	    mov	$0x03, %ah	
	    xor	%bh, %bh
	    int	$0x10		
	    mov	%dx, %ds:0      # get Memory Size
    	mov	$0x88, %ah 
	    int	$0x15
	    mov	%ax, %ds:2
	    mov	$0x0000, %ax        # get hd0 data
	    mov	%ax, %ds
	    lds	%ds:4*0x41, %si
	    mov	$INITSEG, %ax
	    mov	%ax, %es
	    mov	$0x0004, %di
	    mov	$0x10, %cx
	    rep
	    movsb

但是,读取出的数以无符号整数形式存在,需要对这些数进行处理,以十六进制形式显示。可以通过以下函数完成这个操作:

       print_hex:
           mov    $4,%cx
       print_digit:
           rol    $4,%dx
           mov    $0xe0f,%ax  
           and    %dl,%al  
           add    $0x30,%al
           cmp    $0x3a,%al
           jl     outp  
           add    $0x07,%al  
       outp:
           int    $0x10
           loop   print_digit
           ret
       print_nl:
           mov    $0xe0d,%ax
           int    $0x10
           mov    $0xa,%al
           int    $0x10
           ret

然后,结合以上两点信息,使setup.s在显示"Now we are in SETUP"之后,进一步打印"Memory Size:"、内存大小、“KB”、"Cursor Poser:"等信息,以满足要求。完整的setup.s代码如下:

       .code16
       .equ SETUPSEG, 0x9020	# this is the current segment
       .equ INITSEG, 0x9000	# we move boot here - out of the way
       .global _start
       ljmp $SETUPSEG, $_start	
       _start:
           mov $0x03,%ah       # print "Now we are in SETUP"
           xor %bh,%bh
           int $0x10
           mov $25,%cx
           mov $0x0007,%bx
           mov $msg2,%bp       
           mov $0x07c0,%ax
           mov %cs,%ax
           mov %ax,%es
           mov $0x1301,%ax
           int $0x10
       	mov	$INITSEG, %ax	# get Cursor Poser
       	mov	%ax, %ds
       	mov	$0x03, %ah	
       	xor	%bh, %bh
       	int	$0x10		
       	mov	%dx, %ds:0
       	mov	$0x88, %ah      # get memory size
       	int	$0x15
       	mov	%ax, %ds:2
           mov $0x03,%ah       # print "Memory Size:"
           xor %bh,%bh
           int $0x10
           mov $12,%cx
           mov $0x0007,%bx
           mov $msg3,%bp
           mov $0x1301,%ax
           int $0x10
       	mov	%ds:2 , %dx     # print memory size
           call print_hex
           mov $0x03,%ah       # print "KB"
           xor %bh,%bh
           int $0x10
           mov $2,%cx
           mov $0x0007,%bx
           mov $msg4,%bp
           mov $0x1301,%ax
           int $0x10
           call print_nl 
           mov $0x03,%ah       # print "Memory Size:"
           xor %bh,%bh
           int $0x10
           mov $12,%cx
           mov $0x0007,%bx
           mov $msg8,%bp
           mov $0x1301,%ax
           int $0x10
       	mov	%ds:0 , %dx     # print memory size
           call print_hex
           call print_nl
           mov $0x03,%ah       # print "Cylinders:"
           xor %bh,%bh
           int $0x10
           mov $10,%cx
           mov $0x0007,%bx
           mov $msg5,%bp
           mov $0x1301,%ax
           int $0x10
       	mov	$0x0000, %ax        # get hd0 data
       	mov	%ax, %ds
       	lds	%ds:4*0x41, %si
       	mov	$INITSEG, %ax
       	mov	%ax, %es
       	mov	$0x0004, %di
       	mov	$0x10, %cx
       	rep
       	movsb
       	mov	$INITSEG, %ax       # print Cylinders
       	mov	%ax, %ds
       	mov	%ds:4 , %dx     
           call print_hex
           call print_nl
           mov $0x03,%ah       # print "Headers:"
           xor %bh,%bh
           int $0x10
           mov $8,%cx
           mov $0x0007,%bx
           mov $msg6,%bp       
           mov $0x07c0,%ax
           mov %cs,%ax
           mov %ax,%es
           mov $0x1301,%ax
           int $0x10
       	mov	$INITSEG, %ax       # print Headers
       	mov	%ax, %ds
       	mov	%ds:6 , %dx     
           call print_hex
           call print_nl
           mov $0x03,%ah       # print "Sectors Per Track:"
           xor %bh,%bh
           int $0x10
           mov $18,%cx
           mov $0x0007,%bx
           mov $msg7,%bp
           mov $0x1301,%ax
           int $0x10
       	mov	$INITSEG, %ax       # print Sectors Per Track
       	mov	%ax, %ds
       	mov	%ds:18 , %dx     
           call print_hex
           call print_nl
       inf_loop:
           jmp inf_loop
       print_hex:
           mov    $4,%cx
       print_digit:
           rol    $4,%dx
           mov    $0xe0f,%ax  
           and    %dl,%al  
           add    $0x30,%al
           cmp    $0x3a,%al
           jl     outp  
           add    $0x07,%al  
       outp:
           int    $0x10
           loop   print_digit
           ret
       print_nl:
           mov    $0xe0d,%ax   
           int    $0x10
           mov    $0xa,%al    
           int    $0x10
           ret
       msg2:
           .byte   13,10
           .ascii "Now we are in SETUP"
           .byte   13,10,13,10
       msg3:
           .ascii "Memory Size:"
       msg4:
           .ascii "KB"
       msg5:
           .ascii "Cylinders:"
       msg6:
           .ascii "Headers:"
       msg7:
           .ascii "Sectors Per Track:"
       msg8:
           .ascii "Cursor Pose:"
       .org 510
       boot_flag:
           .word   0xAA55

最后,编译文件并执行,结果如下图。
在这里插入图片描述

  • 成功显示信息“Memory Size:3C00KB”。表明3C00KB即为15MB,又有15MB+1MB=16MB。查看bochs配置文件bochs/bochsrc.bxrc,发现有"megs: 16",则配置的bochs为16MB内存,所以这项信息正确。
  • 成功显示信息“Cursor Poser:1800”,光标位置为1800,也是正确的。
  • 成功显示信息“Cylinders:00cc”、“Headers:0010”、“Sectors Per Track:0026”。查看bochs配置文件bochs/bochsrc.bxrc,发现有“ata0-master: type=disk, path=“$OSLAB_PATH/hdc-0.11.img”, mode=flat, cylinders=204, heads=16, spt=38”,设定的cylinders=204=0x00CC,heads=16=0x0010,spt(Sectors Per Track)=38=0x0026,与所显示的信息相符,因此这几项信息也是正确的。

3.3. 实验报告

有时,继承传统意味着别手蹩脚。 x86 计算机为了向下兼容,导致启动过程比较复杂。 请找出 x86 计算机启动过程中,被硬件强制,软件必须遵守的两个“多此一举”的步骤(多找几个也无妨),说说它们为什么多此一举,并设计更简洁的替代方案。

实模式和保护模式切换:

  • 初始时,x86处理器以实模式运行,这是旧版处理器的工作模式。为了支持现代操作系统,处理器在启动后需要切换到保护模式。这一切换包括加载新的段描述符、设置新的全局描述符表(GDT)和禁用一些过时的实模式特性。
  • 实模式是为老软件和硬件设计的,而保护模式提供更强大和安全的特性。然而,切换过程增加了启动的复杂性,而在现代系统中,实模式的许多特性是多余的。
  • 直接从启动时开始在保护模式下运行,省略实模式和保护模式的切换,以简化启动过程。

BIOS中断调用:

  • 在启动过程中,操作系统通常需要与硬件交互。在x86中,传统方式是通过调用BIOS中断请求服务,例如,读取键盘输入、显示字符等。这导致了对中断向量表的依赖,增加了复杂性。
  • 随着计算机硬件和操作系统的发展,直接调用硬件驱动程序或使用更现代的接口方式可以更高效地进行硬件交互。
  • 直接使用现代的硬件抽象层和驱动程序模型,避免对BIOS中断的依赖。通过在内核中嵌入适当的驱动程序,而不是依赖BIOS中断调用,可以更为简洁地实现相同的功能。

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

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

相关文章

如何下载Linux源码,看这篇就够了!

文章目录 前言一、linux官网二、查找发布版本三、下载方式 前言 在工作中,我们难免会遇到需要去找某个版本的linux源码的情况,今天这篇文章就手把手教大家如何找到自己想要的linux源码版本 提示:以下是本篇文章正文内容,下面案例…

医学影像系统源码(MRI、CT三维重建)

一、MRI概述 核磁共振成像(英语:Nuclear Magnetic Resonance Imaging,简称NMRI),又称自旋成像(英语:spin imaging),也称磁共振成像(Magnetic Resonance Imag…

大数据Doris(二十):数据导入(Broker Load)介绍

文章目录 数据导入(Broker Load)介绍 一、​​​​​​​适用场景

docker通过nginx代理tomcat-域名重定向

通过昨天的调试,今天做这个域名就简单了, 正常我们访问网站一般都是通过域名比如,www.baidu.com对吧,有人也通过ip,那么这个怎么做呢?物理机windows可以通过域名访问虚拟机linux的nginx代理转向tomcat服务…

6.5对称二叉树(LC101-E)

算法: 其实就是比较左右子树是否可以翻转 比较的时候: 比较外面的节点是否相等,如示例1中的节点3 比较里面的节点是否相等,如示例1中的节点4 基本思路是这样的,那怎么遍历呢? 二叉树的题一定要掌握到…

开放式耳机井喷阶段,南卡品牌何以成为“头号玩家”?

对于耳机行业而言,过去两年的聚光灯属于开放式耳机这一才闯入赛道的品类。 在消费电子寒冬持续蔓延的时间节点,夺下属于自己的高光时刻实属不易,毕竟无论是过去数年间高歌猛进的智能可穿戴设备行业,还是更垂直的耳机赛道,现阶段均面临承压的局面。 一面是“前辈”们昔日的“爆…

HTB——常见端口及协议总结

文章目录 一、 常见端口二、HTTP协议三、FTP四、SMB 一、 常见端口 http协议:80、8000https协议:443、8443ftp协议:20(数据传输)、21(发送命令)smb协议:445 二、HTTP协议 https的…

【电源专题】POE 802.3af/at与802.3bt在握手阶段有什么差异

在文章:【电源专题】PSE如何与PD握手协商功率等级?中我们以PSE与PD设备在802.3af/at协议握手为例,讲到了PSE与PD协商时通过三个阶段:检测阶段、握手阶段、电压提升阶段。而对于802.3bt的握手存在明显的不同,所以本文就详细解释一下802.3bt协议为什么握手阶段与802.3af/at存…

《RN移动开发实战》3出版了,文末抽奖

前言 众所周知,传統的原生Android、iOS开发技术虽然比较成熟,但是多端重复开发的成本和开发效率的低下也是很多企业不愿意看到的,而不断崛起的跨平台技术让企业看到了曙光,“一次编写,处处运行”也不再是难以企及的目…

Mac上好用的翻译软件推荐 兼容m

Mac翻译软件可以用在学习,工作,生活当中,一款好用的翻译软件,具有翻译准确,翻译快速等基本特点,能够帮您提高工作效率。Mac上有什么好用的翻译软件呢?今天小编为大家整理了6款好用的Mac翻译软件…

YOLOv7改进:RefConv | 即插即用重参数化重聚焦卷积替代常规卷积,无额外推理成本下涨点明显

1.该文章属于YOLOV5/YOLOV7/YOLOV8改进专栏,包含大量的改进方式,主要以2023年的最新文章和2022年的文章提出改进方式。 2.提供更加详细的改进方法,如将注意力机制添加到网络的不同位置,便于做实验,也可以当做论文的创新点 3.涨点效果:RefConv,实现有效涨点! 论文地址 …

G2406C是一款高效的直流-直流降压开关稳压器,能够提供高达1A输出电流。

G2406C 1.5MHz,1A高效降压DC-DC转换器 概述: G2406C是一款高效的直流-直流降压开关稳压器,能够提供高达1A输出电流。G2406C在2.7V至5.5V的宽范围输入电压下工作,使IC是低压电源转换的理想选择。在1.5MHz的固定频率下运行允许使用具有小电感…

【算法】最短路计数(计算最短路的数量)

题目 给出一个 N 个顶点 M 条边的无向无权图,顶点编号为 1 到 N。 问从顶点 1 开始,到其他每个点的最短路有几条。 输入格式 第一行包含 2 个正整数 N,M,为图的顶点数与边数。 接下来 M 行,每行两个正整数 x,y,表示有…

Scrum Master 如何更好的支持PO?

在过去几年中,和许多Scrum Master交流时,我遇到一个令人担忧的模式。虽然我们有Scrum指南和其他补充资源,许多Scrum Master,特别是刚起步的Scrum Master们,还在日复一日的为如何帮助Product Owner而挣扎着。 以下是我…

《QT从基础到进阶·十九》QThread多线程使用

1、平时在写多线程的时候有时候会遇到下面一种情况: 情景: this是主线程,model是子线程,把model move到线程后可以在主线程通过emit开启子线程,emit CalcuSignal();开启子线程执行StartCalculateAll,里面有…

SpringBoot+MybatisPlus Restful示例

增删改查,分页 CREATE TABLE tbl_book ( id int NOT NULL AUTO_INCREMENT, type varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, name varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, desc_ription varchar(255) CHAR…

JavaScript基础入门04

目录 1.WebAPI 背景知识 1.1什么是 WebAPI 1.2什么是 API 2.DOM 基本概念 2.1什么是 DOM 2.2DOM 树 3.获取元素 3.1querySelector 3.2querySelectorAll 4.事件初识 4.1基本概念 4.2事件三要素 4.3简单示例 5.操作元素 5.1获取/修改元素内容 5.2获取/修改元素属性…

微服务版mall电商项目本地开发环境启动前后端服务详细指导教程

微服务版mall电商项目本地开发环境启动前后端服务详细指导教程 前言1 克隆mall-swarm 电商项目源码2 安装启动mall-swarm项目需要的第三方服务2.1 安装MySql8 并初始化数据2.2 安装Nacos2.3 安装Redis2.4 RabbitMQ安装2.5 ElasticSearch安装2.6 MongoDB安装2.7 Minio安装 3 启动…

多目标优化框架

随着模型越来越复杂,优化目标越来越多,传统算法都慢慢地无法胜任复杂优化任务,更为智能的优化方法也就应运而生了。其中有一类是进化优化算法,这类算法的思想来源是自然界的“优胜劣汰”法则,通过不停地保留好的个体最…

Linux学习-破解Root密码

破解root密码思路 1)重启系统,进入 救援模式 开启虚拟机A,在此界面按e键 在linux开头的该行,将此行的ro修改为rw 然后空格输入 rd.break 按 ctrl x 启动,会看到switch_root:/# 2)切换到硬盘操作系统环境 # chroot …