《操作系统真象还原》第四章——保护模式入门

2024-03-19 19:28

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

前置知识

段描述符格式

  • 段界限:表示段边界的扩展最值
    • 此段界限是一个单位量,其单位要么是字节,要么是4KB,具体可由G位进行指定
    • 最终段界限=此段界限值*单位
    • 实际段界限计算公式:(此段界限值+1)*(G位)-1
  • G:粒度位,用于解释段界限的单位
    • 为0:表示段界限的单位表示为字节
    • 为1:表示段界限的单位表示为4KB
  • S描述符类型
    • 为0,表示系统段
    • 为1,表示非系统段(代码段或者数据段)
  • type:用于指示描述符的子类型
  • DPL:Descriptor Privilege Level,即描述符特权级
    • 特权级共有0、1、2、3,用于解释段界限的含义
  • P段存在位,用于指示描述符所对应的段是否存在
    • P位是由处理器负责检查的。每当通过描述符访问内存中的段时,如果P位是“0”,处理器就会产生一个异常中断
    • 该中断处理过程是由操作系统提供的,该处理过程的任务是负责将该段从硬盘换回内存,并将P位置1
  • D/B:标志位,为了能够在32位处理器上兼容运行16位保护模式的程序。该标志位对不同的段有不同的效果。
    • 对于代码段,此位称作“D”位,用于指示指令中默认的有效地址和操作数尺寸;
      • D=0表示指令中的有效地址或者操作数是16位的;
      • D=1,指示32位的有效地址或者操作数。
    • 对于栈段和向下扩展的数据段来说,该位被叫作“B”位,用于指定在进行隐式的栈操作时,是使用寄存器SP还是寄存器ESP,隐式的栈操作指令包括push、pop和call等。
      • 如果该位是“0”,在访问那个段时,使用寄存器SP;
      • 否则就是使用寄存器ESP。
  • AVL:表示软件是否可以使用(Available),通常由操作系统来用,处理器并不使用它。
  • L:用于设置是否是64位代码段
    • 为1,表示64位代码段
    • 为0,表示32位代码段

选择子

  • RPL:请求特权级
  • TI(table indicator):表示在GDT(全局描述符表)还是在LDT(局部描述符表)中索引描述符
    • 为0,在GDT中进行索引
    • 为1,在LDT中进行索引 
  • 3~15位,具体描述符的索引值,2^13=8192,故最多可以索引8192个段 

 GDT寄存器GDTR

  • 作用:用于指向GDT的内存地址
  • 访问格式:lgdt 48位内存数据

由上述GDTR寄存器的格式可以看出,GDT的大小占16位,也就是65536个字节,而每个描述符占8个字节,因此GDT最多可以容纳的描述符数量是65536/8=8192个 

控制寄存器CR0

控制寄存器是CPU的窗口,既可以用来展示CPU的内部状态,也可以用于控制CPU的运行机制

其中CR0的PE位是保护模式的开关

  • 为0时,表示在实模式下运行
  • 为1时表示在保护模式下运行 

进入保护模式

boot.inc

原书勘误,显存描述符应该为的最后应该是0x0b,而不是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

%include "boot.inc"SECTION loader vstart=LOADER_BASE_ADDR
;初始化栈指针地址
LOADER_STACK_TOP equ LOADER_BASE_ADDR
jmp loader_start;------------- 构建gdt及其内部的描述符 -------------GDT_BASE: dd 0x00000000dd 0x00000000;代码段描述符的低4字节部分,其中高两个字节表示段基址的0~15位,在这里定义为0x0000;低两个字节表示段界限的0~15位,由于使用的是平坦模型,因此是0xFFFFCODE_DESC:  dd 0x0000FFFFdd DESC_CODE_HIGH4;段描述符的高4字节部分DATA_STACK_DESC: dd 0x0000FFFFdd DESC_DATA_HIGH4;定义显存段的描述符;文本模式下的适配器地址为0xb8000~0xbffff,为了方便显存操作,显存段不使用平坦模型;因此段基址为0xb8000,段大小为0xbffff-0xb8000=0x7fff,;段粒度位4k,因此段界限的值为0x7fff/4k=7VIDEO_DESC: dd 0x80000007dd DESC_VIDEO_HIGH4GDT_SIZE equ $-GDT_BASEGDT_LIMIT equ GDT_SIZE-1times 60 dq 0 ;此处预留60个描述符的空位;------------- 构建选择子 -------------SELECTOR_CODE equ (0x0001<<3) + TI_GDT + RPL0SELECTOR_DATA equ (0x0002<<3) + TI_GDT + RPL0SELECTOR_VIDEO equ (0x0003<<3) + TI_GDT + RPL0;------------- 定义gdtr(指向GDT的寄存器) -------------gdt_ptr dw GDT_LIMITdd GDT_BASE;------------- 加载器的显式信息 -------------loadermsg db '2 loader in real .'loader_start:
;------------------------------------------
;INT 0x10 功能号:0x13 功能描述:打印字符串
;------------------------------------------
;输入:;AH:功能号;AL:显示输出方式;   0——字符串中只含显示字符,显示属性在BH中,显示后光标位置不变;   1——字符串中只含显示字符,显示属性在BH中,显示后光标位置改变;   2——字符串中含显示字符和显示属性,显示后光标位置不变;   3——字符串中含显示字符和显示属性,显示后光标位置改变;BH:页码;BL:属性;CX:字符串长度;(DH、DL):坐标(行、列);ES:BP 字符串地址
;无返回值mov sp,LOADER_BASE_ADDRmov bp,loadermsgmov cx,17mov ax,0x1301mov bx,0x001f;页号为0,蓝底粉红字mov dx,0x1800int 0x10;------------- 准备进入保护模式 -------------
;1.打开A20
;2.加载gdt
;3.置cr0的PE位为1;------------- 打开A20 -------------in al,0x92or al,0000_0010Bout 0x92,al;------------- 加载gdt -------------lgdt [gdt_ptr];------------- 置cr0的PE位为1 -------------mov eax,cr0or eax,0x00000001mov cr0,eaxjmp dword SELECTOR_CODE:p_mode_start;刷新流水线[bits 32]
p_mode_start:mov ax,SELECTOR_DATAmov ds,axmov es,axmov ss,axmov esp,LOADER_STACK_TOPmov ax,SELECTOR_VIDEOmov gs,axmov byte [gs:160],'p'jmp $

编译

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

磁盘写入

注意loader.S写入磁盘时count参数为2

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

运行

输出p说明GDT成功建立,如下调试所示

这篇关于《操作系统真象还原》第四章——保护模式入门的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

Python FastAPI入门安装使用

《PythonFastAPI入门安装使用》FastAPI是一个现代、快速的PythonWeb框架,用于构建API,它基于Python3.6+的类型提示特性,使得代码更加简洁且易于绶护,这篇文章主要介... 目录第一节:FastAPI入门一、FastAPI框架介绍什么是ASGI服务(WSGI)二、FastAP

高效管理你的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

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

数论入门整理(updating)

一、gcd lcm 基础中的基础,一般用来处理计算第一步什么的,分数化简之类。 LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } <pre name="code" class="cpp">LL lcm(LL a, LL b){LL c = gcd(a, b);return a / c * b;} 例题:

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联

poj 2104 and hdu 2665 划分树模板入门题

题意: 给一个数组n(1e5)个数,给一个范围(fr, to, k),求这个范围中第k大的数。 解析: 划分树入门。 bing神的模板。 坑爹的地方是把-l 看成了-1........ 一直re。 代码: poj 2104: #include <iostream>#include <cstdio>#include <cstdlib>#include <al