计算机系统结构与操作系统实验三(2)-进入保护模式

news2024/12/23 15:37:24

📍实验要求

从实模式到保护模式的转变:
在刚进入loader尚在实模式下时,在第2行显示:real-Zhangsan
在变为保护模式后,在第3行显示:protect-Zhangsan
加载gdt、将cr0的PE位置为1

📍实验过程

老规矩,我还是新建一个项目文件,并创建相应文件夹和文件
在这里插入图片描述

📍📍mbr.S

加载loader.bin的函数call rd_disk_m_16的扇区数增加为4个
在这里插入图片描述
根据中断打印原来的内容"1 MBR"
在这里插入图片描述
mbr.S👇

;主引导程序 
;------------------------------------------------------------
%include "boot.inc"
SECTION MBR vstart=0x7c00         
   mov ax,cs      
   mov ds,ax
   mov es,ax
   mov ss,ax
   mov fs,ax
   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

   ; 输出字符串: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,4			 ; 待读入的扇区数
   call rd_disk_m_16		 ; 以下读取程序的起始部分(一个扇区)
  
   jmp LOADER_BASE_ADDR
       
;-------------------------------------------------------------------------------
;功能:读取硬盘n个扇区
rd_disk_m_16:	   
;-------------------------------------------------------------------------------
				       ; eax=LBA扇区号
				       ; ebx=将数据写入的内存地址
				       ; ecx=读入的扇区数
      mov esi,eax	  ;备份eax
      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~27or al,0xe0	   ; 设置74位为1110,表示lba模式
      mov dx,0x1f6
      out dx,al

;3步:向0x1f7端口写入读命令,0x20 
      mov dx,0x1f7
      mov al,0x20                        
      out dx,al

;4步:检测硬盘状态
  .not_ready:
      ;同一端口,写时表示写入命令字,读时表示读入硬盘状态
      nop
      in al,dx
      and al,0x88	   ;4位为1表示硬盘控制器已准备好数据传输,第7位为1表示硬盘忙
      cmp al,0x08
      jnz .not_ready	   ;若未准备好,继续等。

;5步:从0x1f0端口读数据
      mov ax, di
      mov dx, 256
      mul dx
      mov cx, ax	   ; di为要读取的扇区数,一个扇区有512字节,每次读入一个字,
			   ; 共需di*512/2次,所以di*256
      mov dx, 0x1f0
  .go_on_read:
      in ax,dx
      mov [bx],ax
      add bx,2		  
      loop .go_on_read
      ret

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

📍📍include/boot.inc

boot.inc

;-------------	 loader和kernel   ----------

LOADER_BASE_ADDR equ 0x900 
LOADER_START_SECTOR equ 0x2

;--------------   gdt描述符属性  -------------
DESC_G_4K   equ	  1_00000000000000000000000b   
DESC_D_32   equ	   1_0000000000000000000000b
DESC_L	    equ	    0_000000000000000000000b	;  64位代码标记,此处标记为0便可。
DESC_AVL    equ	     0_00000000000000000000b	;  cpu不用此位,暂置为0  
DESC_LIMIT_CODE2  equ 1111_0000000000000000b
DESC_LIMIT_DATA2  equ DESC_LIMIT_CODE2
DESC_LIMIT_VIDEO2  equ 0000_000000000000000b
DESC_P	    equ		  1_000000000000000b
DESC_DPL_0  equ		   00_0000000000000b
DESC_DPL_1  equ		   01_0000000000000b
DESC_DPL_2  equ		   10_0000000000000b
DESC_DPL_3  equ		   11_0000000000000b
DESC_S_CODE equ		     1_000000000000b
DESC_S_DATA equ	  DESC_S_CODE
DESC_S_sys  equ		     0_000000000000b
DESC_TYPE_CODE  equ	      1000_00000000b	;x=1,c=0,r=0,a=0 代码段是可执行的,非依从的,不可读的,已访问位a清0.  
DESC_TYPE_DATA  equ	      0010_00000000b	;x=0,e=0,w=1,a=0 数据段是不可执行的,向上扩展的,可写的,已访问位a清0.

DESC_CODE_HIGH4 equ (0x00 << 24) + DESC_G_4K + DESC_D_32 + DESC_L + DESC_AVL + DESC_LIMIT_CODE2 + DESC_P + DESC_DPL_0 + DESC_S_CODE + DESC_TYPE_CODE + 0x00
DESC_DATA_HIGH4 equ (0x00 << 24) + DESC_G_4K + DESC_D_32 + DESC_L + DESC_AVL + DESC_LIMIT_DATA2 + DESC_P + DESC_DPL_0 + DESC_S_DATA + DESC_TYPE_DATA + 0x00
DESC_VIDEO_HIGH4 equ (0x00 << 24) + DESC_G_4K + DESC_D_32 + DESC_L + DESC_AVL + DESC_LIMIT_VIDEO2 + DESC_P + DESC_DPL_0 + DESC_S_DATA + DESC_TYPE_DATA + 0x0b

;--------------   选择子属性  ---------------
RPL0  equ   00b
RPL1  equ   01b
RPL2  equ   10b
RPL3  equ   11b
TI_GDT	 equ   000b
TI_LDT	 equ   100b

📍📍loader.S

  1. 实模式输出real-luohaojia
    在这里插入图片描述
  2. 设置好在屏幕上输出的位置 和 字符串长度(长度要刚刚好,是多长就多长,比如我这里real-luohaojia就是14个字符)
    在这里插入图片描述
  3. 变为保护模式后,设置输出:protect-luohaojia
    在这里插入图片描述
    loader.S
 %include "boot.inc" 
 section loader vstart=LOADER_BASE_ADDR 
 LOADER_STACK_TOP equ LOADER_BASE_ADDR 
 jmp loader_start 
 
 ;构建 gdt 及其内部的描述符 
 GDT_BASE: dd 0x00000000 
 dd 0x00000000 
 
 CODE_DESC: dd 0x0000FFFF 
 dd DESC_CODE_HIGH4 

 DATA_STACK_DESC: dd 0x0000FFFF 
 dd DESC_DATA_HIGH4 

 VIDEO_DESC: dd 0x80000007;limit=(0xbffff-0xb8000)/4k=0x7 
 dd DESC_VIDEO_HIGH4 ;此时 dpl 为 0 

 GDT_SIZE equ $ - GDT_BASE 
 GDT_LIMIT equ GDT_SIZE - 1 
 times 60 dq 0 ; 此处预留 60 个描述符的空位 
 SELECTOR_CODE equ (0x0001<<3) + TI_GDT + RPL0 
; 相当于(CODE_DESC - GDT_BASE)/8 + TI_GDT + RPL0 
SELECTOR_DATA equ (0x0002<<3) + TI_GDT + RPL0 ; 同上 
SELECTOR_VIDEO equ (0x0003<<3) + TI_GDT + RPL0 ; 同上 

;以下是 gdt 的指针,前 2 字节是 gdt 界限,后 4 字节是 gdt 起始地址 

gdt_ptr dw GDT_LIMIT 
dd GDT_BASE 
loadermsg db 'real-luohaojia' 

loader_start: 

;------------------------------------------------------------ 
;INT 0x10 功能号:0x13 功能描述:打印字符串 
;------------------------------------------------------------ 
;输入: 
;AH 子功能号=13H 
;BH = 页码 
;BL = 属性(若 AL=00H 或 01H) 
;CX=字符串长度 
;(DH、 DL)=坐标( 行 、 列) 
;ES:BP=字符串地址 
 ;AL=显示输出方式 
 ; 0—字符串中只含显示字符,其显示属性在 BL 中 
;显示后,光标位置不变 
 ; 1—字符串中只含显示字符,其显示属性在 BL 中 
;显示后,光标位置改变 
 ; 2—字符串中含显示字符和显示属性。显示后,光标位置不变 
 ; 3—字符串中含显示字符和显示属性。显示后,光标位置改变 
 ;无返回值 
 mov sp, LOADER_BASE_ADDR 
 mov bp, loadermsg ; ES:BP = 字符串地址 
 mov cx, 15 ; CX = 字符串长度 
 mov ax, 0x1301 ; AH = 13, AL = 01h 
 mov bx, 0x001f ; 页号为 0(BH = 0) 蓝底粉红字(BL = 1fh) 
 mov dx, 0x0100 ; ***字符开始位置****
 int 0x10 ; 10h 号中断 
 
 ;-------------------- 准备进入保护模式 ------------------------------- 
 ;1 打开 A20 
 ;2 加载 gdt 
 ;3 将 cr0 的 pe 位置 1 
 
 
;----------------- 打开 A20 ---------------- 
in al,0x92
or al,0000_0010B
out 0x92,al

;----------------- 加载 GDT ---------------- 
lgdt [gdt_ptr]


;----------------- cr0 第 0 位置 1 ---------------- 
mov eax, cr0
or eax, 0x00000001
mov cr0, eax

jmp dword SELECTOR_CODE:p_mode_start ; 刷新流水线

 [bits 32] 
p_mode_start:
  mov ax, SELECTOR_DATA 
  mov ds, ax 
  mov es, ax 
  mov ss, ax 
  mov esp,LOADER_STACK_TOP 
  mov ax, SELECTOR_VIDEO 
  mov gs, ax 
 
  mov byte [gs:320], 'P' 
  mov byte [gs:321],0xB6  ; A==Green B==blue 4==red 6==orange
  mov byte [gs:322], 'r'  
  mov byte [gs:323],0xB6
  mov byte [gs:324], 'o'
  mov byte [gs:325],0xB6
  mov byte [gs:326], 't'
  mov byte [gs:327],0xB6
  mov byte [gs:328], 'e'
  mov byte [gs:329],0xB6 
  mov byte [gs:330], 'c' 
  mov byte [gs:331],0xB6
  mov byte [gs:332], 't'
  mov byte [gs:333],0xB6 
  mov byte [gs:334], '-'
  mov byte [gs:335],0xB6 
  mov byte [gs:336], 'l'
  mov byte [gs:337],0xB6 
  mov byte [gs:338], 'u'
  mov byte [gs:339],0xB6 
  mov byte [gs:340], 'o'
  mov byte [gs:341],0xB6 
  mov byte [gs:342], 'h'
  mov byte [gs:343],0xB6 
  mov byte [gs:344], 'a'
  mov byte [gs:345],0xB6 
  mov byte [gs:346], 'o'
  mov byte [gs:347],0xB6 
  mov byte [gs:348], 'j'
  mov byte [gs:349],0xB6 
  mov byte [gs:350], 'i'
  mov byte [gs:351],0xB6
  mov byte [gs:352], 'a'
  mov byte [gs:353],0xB6 

  jmp $ 

📍📍makefile

写入磁盘,从第2块开始,共4块
在这里插入图片描述
makefile

.PHONY:build burn

mbr_source=boot/mbr.S
mbr_target=boot/mbr.bin
loader_source=boot/loader.S
loader_target=boot/loader.bin
hard_disk=/home/lhj/Public/bochs/bin/hd60M.img

build:
		nasm -I boot/include/ -o $(mbr_target) $(mbr_source)
		nasm -I boot/include/ -o $(loader_target) $(loader_source)
burn:
		dd if=$(mbr_target) of=$(hard_disk) bs=512 count=1 conv=notrunc
		dd if=$(loader_target) of=$(hard_disk) bs=512 count=2 seek=2 conv=notrunc

📍📍run.sh

这里记得改为本实验代码目录
在这里插入图片描述

📍一键运行

在这里插入图片描述
在这里插入图片描述

📍查看gdt表和验证PE是否为1

在这里插入图片描述

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

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

相关文章

建议收藏 | 可视化ETL平台--Kettle

Kettle的介绍 学习目标 知道什么是ETL及Kettel是开源的ETL工具 了解kettle环境的安装流程 1.ETL介绍 ETL&#xff08;Extract-Transform-Load的缩写&#xff0c;即数据抽取、转换、装载的过程&#xff09;&#xff0c;对于企业或行业应用来说&#xff0c;我们经常会遇到各种…

redis可视化工具 Another Redis Desktop Manager

Redis API 官方文档&#xff1a;Redis 命令参考 — Redis 命令参考 Redis 可视化工具下载&#xff1a; Releases qishibo/AnotherRedisDesktopManager GitHub&#xff08;github&#xff09; 使用&#xff1a; 1、新建连接 点击 新建连接 创建新的连接 切换语言 地址&a…

前端Vue自定义商品订单星级评分 爱心评分组件

随着技术的发展&#xff0c;开发的复杂度也越来越高&#xff0c;传统开发方式将一个系统做成了整块应用&#xff0c;经常出现的情况就是一个小小的改动或者一个小功能的增加可能会引起整体逻辑的修改&#xff0c;造成牵一发而动全身。 通过组件化开发&#xff0c;可以有效实现…

数据分类分级的概念、方法、标准及行业实践

数据战略上升为国家战略&#xff0c;数据资产成为国家各行各业的核心资产。在数字化时代&#xff0c;数据分类分级成为数据资产管理的重要组成部分。 通过数据分类分级管理&#xff0c;可有效使用和保护数据&#xff0c;使数据更易于定位和检索&#xff0c;满足数据风险管理、…

领略大数据分析的魅力:迈向FineBI的世界

版权声明&#xff1a;本文为 小异常 原创文章&#xff0c;非商用自由转载-保持署名-注明出处&#xff0c;谢谢&#xff01; 本文网址&#xff1a;https://sunkuan.blog.csdn.net/article/details/131698171 文章目录 一、FineBI介绍&#xff08;6.0版本&#xff09;1、使用人群…

高并发的哲学原理(三)-- 基础设施并发:虚拟机与 Kubernetes(k8s)

上篇文章说到&#xff0c;Apache 无法处理海量用户的 TCP 连接&#xff0c;那要是由于宇宙时空所限&#xff0c;你的系统就是无法离开 Apache&#xff0c;该怎么承接高并发呢&#xff1f;有办法&#xff1a;既然单机不行&#xff0c;那就把单机虚拟化成多个 Linux 机器&#xf…

关于typescript的类型推断一些理解

我们先看一段代码&#xff1a; interface defaultObjType {[key: string]: any; } interface SquareConfig {color?: string | defaultObjType;width?: number; } let obj:SquareConfig {color: {qw:123}, }if(obj.color && obj.color.qw) { // 这里报错&#xff…

【重要】MThings V0.6.0更新要点

我们听到了您的声音并采取了行动&#xff01;现在为您提供了一次全面的软件升级&#xff0c;让您的体验更加顺畅、稳定和安全。立即更新&#xff0c;畅享新功能&#xff01; 下载地址&#xff1a; http://gulink.cn/download 01. [新增]支持系统数据、历史数据、告警功能个人版…

Liunx命令大全及基础知识扫盲

文章目录 1,ifconfig命令2,ens10和eth103&#xff0c;查看PCI地址 1,到达最后一行 ctrl end 1,ifconfig命令 ifconfig 是一个用于配置和显示网络接口信息的命令行工具 1&#xff0c;ifconfig这将显示所有网络接口的详细信息&#xff0c;包括接口名称、MAC 地址、IP 地址、子…

2023中国企业绿电国际峰会

会议时间/地点/主办方 2023年11月16-17日&#xff0c;中国上海&#xff0c;ECV International 会议形式 峰会采用“线下线上”的方式同步进行&#xff0c;中英双语同声传译&#xff0c;线上、线下并行进行和实时互动。 峰会背景 当下全球气候问题正在不断显现&#xff0c;对…

conda修改环境保存地址

可以在命令行中通过conda config指令进行修改 如&#xff1a; 添加环境目录envs_dirs conda config --add envs_dirs F:\conda_env\envs 添加pkgs_dirs conda config --add pkgs_dirs F:\conda_env\pkgs 也可以直接进入Anaconda Nacigator进行修改

Java反序列化:URLDNS的反序列化调试分析

URLDNS链子是Java反序列化分析的第0课&#xff0c;网上也有很多优质的分析文章。 笔者作为Java安全初学者&#xff0c;也从0到1调试了一遍&#xff0c;现在给出调试笔记。 一. Java反序列化前置知识 Java原生链序列化&#xff1a;利用Java.io.ObjectInputStream对象输出流的w…

Openlayers实战:加载OpenStreetMap(快速显示无加载不出状态)

Openlayers官方一直演示的都是用Openstreetmap, 但是目前国内使用通用的new OSM(), 是加载不出来OSM地图的。在我们的实战中代码中,不但能够加载出Openstreetmap, 而且速度非常的快,这就涉及到一个曲线救图的处理方式,请参考源代码。 效果图 源代码 /* * @Author: 大剑师…

如何提取音频中的纯人声?分享三个方法给大家!

在处理音频文件时&#xff0c;有时候我们只希望提取其中的纯人声&#xff0c;以便进行后续处理或编辑。本文将介绍三种简单有效的方法&#xff0c;帮助您提取音频中的纯人声。方法一使用记灵在线工具&#xff0c;方法二使用Audacity&#xff0c;方法三则为您补充其他可选方案。…

Linux—实操篇:实用指令

目录 1、指定运行级别 1.1基本介绍 1.2、示例 1.3、CentOS7 后运行级别说明 2、找回root密码 3、帮助指令 3.1、man指令 3.2、help指令 4、文件目录指令 4.1、pwd 指令 4.2、ls 指令 4.3、cd 指令 4.4、mkdir 指令 4.5、rmdir 指令 4.6、touch 指令 4.7、cp 指…

Unified Named Entity Recognition as Word-Word Relation Classification

原文链接&#xff1a;https://arxiv.org/pdf/2112.10070.pdf AAAI 2022 介绍 NER主要包括三种类型&#xff1a;flat、overlap和discontinuous。目前效果最好的模型主要是&#xff1a;span-based和seq2seq&#xff0c;但前者注重于边界的识别&#xff0c;后者可能存在exposure b…

保护用户数据隐私:Web3 技术在电商行业中的应用

电商行业一直是全球经济发展的重要推动力。然而&#xff0c;随着电商行业的不断发展&#xff0c;中心化的支付、物流和数据存储方式逐渐暴露出安全隐患和隐私问题。这时&#xff0c;Web3 技术以其去中心化、安全性和透明性等特点&#xff0c;为电商行业带来了新的解决方案和可能…

关于var、let、const相同与不同

相同&#xff1a;var、let、const都可以声明变量 var milliaA "milliaA" let milliaB "milliaB" const milliaC "milliaC"console.log(milliaA,milliaB,milliaC) 不同&#xff1a; 一、变量提升&#xff0c;var有提升&#xff0c;let、cons…

初识 Redis - 分布式,内存数据存储,缓存

目录 1. 什么是 Redis 1.1 Redis 内存数据存储 1.2 Redis 用作数据库 1.3 Redis 用作缓存 (cache) 1.4 用作消息中间件 1. 什么是 Redis The open source , in-memory data store used by millions of developers as a database, cache, streaming engine, and message br…

使用 Elastic 时间序列数据流探索 Nginx 指标

作者&#xff1a;Lalit Satapathy Elasticsearch 最近发布了用于指标的时间序列数据流。 这不仅为 Elastic Observability 提供了更好的指标支持&#xff0c;而且还有助于降低存储成本。 我们在之前的博客中讨论过这个问题。 在本博客中&#xff0c;我们通过回顾什么是时间序列…