进入保护模式

news2025/4/5 4:54:22

文章目录

  • 前言
  • 前置知识
  • 代码说明
  • 实验操作

前言

本博客记录《操作系统真象还原》第四章实验操作~

实验环境:ubuntu18.04+VMware , Bochs下载安装

实验内容:实现从MBR到LOADER,由LOADER实现进入保护模式

实验原理:计算机通电开机后,CPU的cs:ip寄存器,被硬件强制初始化为0xF000:0XFFF0 ,该位置存储着跳转指令,跳转向BIOS。这样首先运行BIOS软件(计算机系统的控制权 [CPU的使用权] 交接的第一棒就是BIOS啦!),BIOS会检查各种设备的情况,并且建立中断向量表。然后MBR找机会想把处理器使用权交出去。下一个接棒选手就是 主引导记录(MBR,Master Boot Record),BIOS知道MBR在0盘0道1扇区,因此它会将0盘0道1扇区中的MBR引导程序加载到物理地址0x7c00,然后继而跳去执行。这样BIOS就将处理器的使用权交给MBR。紧接着,MBR的接力棒就来到了Loader,Loader构建并且初始化GDT,然后用LGDT指令把GDT表的位置放了进去,并且初始化了三个段描述符(段描述符 代码段 数据段) 。从此,从16位实模式到了32位保护模式。

前置知识

前置知识可以食用 全局描述符表

代码说明

include/boot.inc

更新boot.inc文件:关于加载器的配置信息

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

LOADER_BASE_ADDR equ 0x900 
LOADER_START_SECTOR equ 0x2

;--------------   gdt描述符属性  -------------
DESC_G_4K   equ	  1_00000000000000000000000b    ;描述符中G的位次,其中结尾的b表示2机制。
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

代码说明

第 6 ~ 27 行是定义段描述符的属性。

第 29 ~ 35 行是定义选择子属性。

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个描述符的slot
   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 '2 loader in real.'

   loader_start:

;打印字符,"2 LOADER"说明loader已经成功加载
; 输出背景色绿色,前景色红色,并且跳动的字符串"1 MBR"
mov byte [gs:160],'2'
mov byte [gs:161],0xA4     ; A表示绿色背景闪烁,4表示前景色为红色

mov byte [gs:162],' '
mov byte [gs:163],0xA4

mov byte [gs:164],'L'
mov byte [gs:165],0xA4   

mov byte [gs:166],'O'
mov byte [gs:167],0xA4

mov byte [gs:168],'A'
mov byte [gs:169],0xA4

mov byte [gs:170],'D'
mov byte [gs:171],0xA4

mov byte [gs:172],'E'
mov byte [gs:173],0xA4

mov byte [gs:174],'R'
mov byte [gs:175],0xA4




;------------------------------------------------------------
;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, 17			 ; CX = 字符串长度
   mov	 ax, 0x1301		 ; AH = 13,  AL = 01h
   mov	 bx, 0x001f		 ; 页号为0(BH = 0) 蓝底粉红字(BL = 1fh)
   mov	 dx, 0x1800		 ;
   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	     ; 刷新流水线,避免分支预测的影响,这种cpu优化策略,最怕jmp跳转,
   jmp  SELECTOR_CODE:p_mode_start	     ; 刷新流水线,避免分支预测的影响,这种cpu优化策略,最怕jmp跳转,
					     ; 这将导致之前做的预测失效,从而起到了刷新的作用。

[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'

   jmp $

【这部分详细解读请看原书】

mbr.S

/boot/mbr.S

由于 loader.bin 超过了 512 字节,所以我们要把 mbr.S 中加载 loader.bin 的读入扇区数增大

在这里插入图片描述

实验操作

创建相应文件

(base) user@ubuntu:/home/cooiboi/bochs/include$ sudo vim boot.inc
(base) user@ubuntu:/home/cooiboi/bochs/boot$ sudo vim mbr.S
(base) user@ubuntu:/home/cooiboi/bochs/boot$ sudo vim loader.S

编译mbr.S和loader.S

sudo nasm -I include/ -o boot/mbr.bin boot/mbr.S
sudo nasm -I include/ -o boot/loader.bin boot/loader.S
(base) user@ubuntu:/home/cooiboi/bochs$ sudo nasm -I include/ -o boot/mbr.bin boot/mbr.S
(base) user@ubuntu:/home/cooiboi/bochs$ sudo nasm -I include/ -o boot/loader.bin boot/loader.S

将mbr和load分别写入磁盘中

sudo dd if=/home/cooiboi/bochs/boot/mbr.bin of=/home/cooiboi/bochs/boot/hd60M.img bs=512 count=1 conv=notrunc
sudo dd if=/home/cooiboi/bochs/boot/loader.bin of=/home/cooiboi/bochs/boot/hd60M.img bs=512 count=2 seek=2 conv=notrunc
(base) user@ubuntu:/home/cooiboi/bochs/boot$ sudo dd if=/home/cooiboi/bochs/boot/mbr.bin of=/home/cooiboi/bochs/boot/hd60M.img bs=512 count=1 conv=notrunc
1+0 records in
1+0 records out
512 bytes copied, 0.000242967 s, 2.1 MB/s
(base) user@ubuntu:/home/cooiboi/bochs/boot$ sudo dd if=/home/cooiboi/bochs/boot/loader.bin of=/home/cooiboi/bochs/boot/hd60M.img bs=512 count=2 seek=2 conv=notrunc
1+1 records in
1+1 records out
711 bytes copied, 0.000136065 s, 5.2 MB/s

启动Bochs

(base) user@ubuntu:/home/cooiboi/bochs$ sudo bin/bochs -f boot/bochsrc.disk

输出结果如下,左下角的字符串“2 loader in real”是在实模式下用 BIOS 中断 0x10 打印的。左上角第 3行的字符’P’,这是咱们在保护模式下输出的。一个程序历经两种模式,各模式下都打印了字符,为了区别实模式下的打印,所以字符串中含有“ inreal ” 。

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

这篇的文件目录与之前的博客再次改进MBR(从磁盘读入Loader加载器)一致。

参考资料

  • 《操作系统真象还原》
  • 《操作系统真象还原》第四章 ---- 剑指Loader 刃刺GDT 开启新纪元保护模式 解放32位

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

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

相关文章

Cadence PCB仿真分配电压网络电压时网络未自动识别问题解决方案

⏪《上一篇》   🏡《总目录》   ⏩《下一篇》 目录 1,问题概述2,分配方法3,避免方法4,总结1,问题概述 如下图所示在使用Allegro PCB SI为电源网络分配电压时,有些网络实际上是电源网络,但是未被自动识别,无法对齐分配电压,具体解决方法如下。 2,分配方法 第1…

最近新开源的基于单目稠密重建NeRF-SLAM

点云PCL免费知识星球&#xff0c;点云论文速读。文章&#xff1a;NeRF-SLAM: Real-Time Dense Monocular SLAM with Neural Radiance Fields作者&#xff1a;Antoni Rosinol John J. Leonard Luca Carlone编辑&#xff1a;点云PCL代码&#xff1a;https://github.com/ToniRV/N…

JavaScript 异步函数解析

前言 在学习 JavaScript 的过程中&#xff0c;理解并灵活运用异步相关知识是一件不容易的事情&#xff0c;这体现在代码可读性、健壮性上&#xff0c;好在 ES6 出现后挽回了这一局面&#xff0c;我们不再需要编写可读性不高的回调嵌套&#xff0c;也不用为了代码的健壮性而处处…

spring boot使用TaskScheduler实现动态增删启停定时任务

TaskScheduler 概述 TaskScheduler是spring 3.0版本后&#xff0c;自带了一个定时任务工具&#xff0c;不用配置文件&#xff0c;可以动态改变执行状态。也可以使用cron表达式设置定时任务。 被执行的类要实现Runnable接口 TaskScheduler是一个接口&#xff0c;它定义了6个…

具有梯度流的一类系统的扩散图卡尔曼滤波(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

FEW-SHOT TEXT CLASSIFICATION WITH DISTRIBUTIONAL SIGNATURES

摘要 在这篇文章中&#xff0c;我们利用元学习进行文本分类&#xff0c;元学习在计算机视觉中有相当好的效果&#xff0c;在这里&#xff0c;低层次的模式可以跨学习任务迁移的&#xff0c;&#xff0c;然而&#xff0c;直接将这个方法应用到文本中是具有挑战性的&#xff0c;…

【自学C++】C++输入cin

C输入cin C输入cin教程 在 C 语言 中我们需要捕获用户的键盘输入&#xff0c;可以使用 scanf 函数。scanf 函数在输入时&#xff0c;我们必须要指定输入的数据类型对应的格式化符&#xff0c;挺不方便。 在 C 中&#xff0c;我们要捕捉用户的输入&#xff0c;直接使用 std 命…

【目标检测】C-GhostNet

1、论文 论文题名:《GhostNet: More Features from Cheap Operations》 arxiv&#xff1a;https://arxiv.org/abs/1911.11907 github&#xff1a;https://github.com/huawei-noah/ghostnet 作者翻译&#xff1a;https://zhuanlan.zhihu.com/p/109325275 2、摘要 本篇论文是华…

2023/1/6 Vue学习笔记-2

1 收集表单数据 收集表单数据&#xff1a; 若&#xff1a;<input type"text">&#xff0c;则v-model收集的是value的值&#xff0c;用户输入的就是value值。 若&#xff1a;<input type"radio">&#xff0c;则v-modle收集的是value的值&…

String、StringBuffer和StringBuilder

String 类是不可变类&#xff0c;即一旦一个 String 对象被创建以后&#xff0c;包含在这个对象中的字符序列是不可改变的&#xff0c;直至这个对象被销毁。 Java 提供了两个可变字符串类 StringBuffer 和 StringBuilder&#xff0c;中文翻译为“字符串缓冲区”。 StringBuil…

Python和MySQL对比(3):用Pandas 实现MySQL的子查询、like_regexp、case when_if语法效果

文章目录一、前言二、语法对比数据表子查询like/regexpcase when/ifin三、小结一、前言 环境&#xff1a; windows11 64位 Python3.9 MySQL8 pandas1.4.2 本文主要介绍 MySQL 中的子查询、like/regexp、case when/if 如何使用pandas实现&#xff0c;同时二者又有什么区别。 注…

FPGA中二进制数的运算

一、B比特的二进制数可以表示的范围 无符号整数&#xff1a;0~2B-1 有符号整数&#xff1a;-2B-1~2B-1-1 二、有符号数&#xff08;补码&#xff09;与十进制数之间的转换 D&#xff1a;十进制数 B&#xff1a;二进制数aB-1aB-2a1a0的位数 aB-1:符号位 三、符号位拓展 在使…

Android 12 蓝牙适配 Java版

Android 12.0蓝牙适配前言正文一、Android版本中蓝牙简介二、新建项目① 配置build.gradle② 配置AndroidManifest.xml三、打开蓝牙① 打开蓝牙意图② 请求BLUETOOTH_CONNECT权限意图四、蓝牙扫描① 扫描者② 扫描回调③ 扫描方法④ 执行扫描⑤ 应用不推导物理位置五、页面显示…

基于Java+Springboot+vue体育用品销售商城平台设计和实现

基于JavaSpringbootvue体育用品销售商城平台设计和实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取…

Docker部署JAVA项目

一、 Docker安装 1、yum 包更新到最新 yum update 2、安装需要的软件包&#xff0c; yum-util 提供yum-config-manager功能&#xff0c;另外两个是devicemapper驱动依赖的 yum install yum-utils device-mapper-persistent-data lvm2 -y 3、 设置yum源 yum-config-manage…

等级保护----1、网络安全等级保护一级安全测评要求

文章目录一、安全测评通用要求1、安全物理环境1.1 物理访问控制1.2 防盗窃和防破坏1.3 防雷击1.4 防火1.5 防水和防潮1.6 温湿度控制1.7 电力供应2、安全通信网络2.1 通信传输2.2 可信验证3、安全区域边界3.1 边界防护3.2 访问控制3.3 可信验证4、安全计算环境4.1 身份鉴别4.2 …

使用关键字like进行模糊查询

【模糊查询】&#xff1a;使用关键字like [支持%或者下划线匹配&#xff0c;%匹配任意多个字符&#xff0c;一个下划线只匹配任意一个字符。] 实例&#xff1a; 查询名字中带有字母o的员工&#xff1a; select * from emp where ename like %o%; 找出名字以T结…

2000-2021.3月土地交易高频数据库(含爬取代码和数据)

2000-2021.3月土地交易高频数据库&#xff08;含爬取代码和数据&#xff09; 1、时间跨度&#xff1a;2000-2021年3月1日 2、指标&#xff1a;年份、电子监管号、所在省份、所在城市、所在区县、经度、纬度、项目名称、项目位置、面积、土地来源、土地用途、供地方式、土地使…

Python CV 实现风格化图片转换

前几天遇到一个风格化图片转换的需求&#xff0c;效果像这样&#xff1a; 像这样&#xff0c;需要用纯色圆形填充图像&#xff0c;形成风格化的图片样式。 实现原理 整体原理还是比较简单的&#xff0c;有点类似与马赛克的处理方式。 假设图片宽 w 像素&#xff0c;高 h 像素…

FLStudio21中文版下载及水果软件2023功能介绍

如今&#xff0c;越来越多的音乐人选择使用音乐制作软件来进行音乐的创作&#xff0c;一台电脑、一款软件以及一个外接MIDI就是一个小型的音乐工作站&#xff0c;而如今非常流行的FL Studio&#xff08;在国内被称为“水果”&#xff09;成了音乐界无论萌新还是大佬们的首选&am…