【Linux0.11 源码历险记 2】《保护模式》

2023-10-26

继续跟着stup.s 来看:

	lidt	idt_48		; load idt with 0,0
	lgdt	gdt_48		; load gdt with whatever appropriate
	...
idt_48:
	.word	0			; idt limit=0
	.word	0,0			; idt base=0L

gdt_48:
	.word	0x800		; gdt limit=2048, 256 GDT entries
	.word	512+gdt,0x9	; gdt base = 0X9xxxx

在实模式下,ds 是段基址,但是在保护模式下,段基址是放在gdt里的,利用ds到gdt里取出每一段的段基址,同时还有一些其他的信息。下面就是一个段描述符的价绍,其实我在另一篇帖子也提到过(https://blog.csdn.net/lyk82698/article/details/127609577
在这里插入图片描述
现在去找一个地址,就不再是简单的 ds + 偏移地址了。而是 ds 先去全局描述符表里找到对应的段描述符,然后根据段描述符里的内容作为段基址,结合偏移地址确定最终地址。而全局描述符表的位置,就放在寄存器 gdtr 里面。

47-16 15-0
gdt起始地址 gdt的长度限制

因此根据下面设置gdtr 表示gdt的限制和起始地址

gdt_48:
	.word	0x800		; gdt limit=2048, 256 GDT entries
	.word	512+gdt,0x9	; gdt base = 0X9xxxx

其中现在的 gdt 如图:

gdt:
	.word	0,0,0,0		; dummy

	.word	0x07FF		; 8Mb - limit=2047 (2048*4096=8Mb)
	.word	0x0000		; base address=0
	.word	0x9A00		; code read/exec
	.word	0x00C0		; granularity=4096, 386

	.word	0x07FF		; 8Mb - limit=2047 (2048*4096=8Mb)
	.word	0x0000		; base address=0
	.word	0x9200		; data read/write
	.word	0x00C0		; granularity=4096, 386

下面开A20 进入保护模式;

	call	empty_8042    ! 测试8042状态寄存器,等待输入缓冲器空,
	mov	al,#0xD1		  ! command write 0xD1命令码表示写数据到8042的P2端口
	out	#0x64,al

	call	empty_8042    !等待输入缓冲器空,看命令是否被接受
	mov	al,#0xDF		  ! A20 on
	out	#0x60,al
	call	empty_8042    !若此时输入缓冲器为空,则表示A20线也选通 

为了兼容。早期8086CPU 只有20根线,到32位后,需要向前兼容,一开始是限制地址只能20位的,这里就打开限制。

 well, that went ok, I hope. Now we have to reprogram the interrupts :-(
; we put them right after the intel-reserved hardware interrupts, at
; int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
; messed this up with the original PC, and they haven't been able to
; rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
; which is used for the internal hardware interrupts as well. We just
; have to reprogram the 8259's, and it isn't fun.

	mov	al,#0x11		; initialization sequence
	out	#0x20,al		; send it to 8259A-1
	.word	0x00eb,0x00eb		; jmp $+2, jmp $+2
	out	#0xA0,al		; and to 8259A-2
	.word	0x00eb,0x00eb
	mov	al,#0x20		; start of hardware int's (0x20)
	out	#0x21,al
	.word	0x00eb,0x00eb
	mov	al,#0x28		; start of hardware int's 2 (0x28)
	out	#0xA1,al
	.word	0x00eb,0x00eb
	mov	al,#0x04		; 8259-1 is master
	out	#0x21,al
	.word	0x00eb,0x00eb
	mov	al,#0x02		; 8259-2 is slave
	out	#0xA1,al
	.word	0x00eb,0x00eb
	mov	al,#0x01		; 8086 mode for both
	out	#0x21,al
	.word	0x00eb,0x00eb
	out	#0xA1,al
	.word	0x00eb,0x00eb
	mov	al,#0xFF		; mask off all interrupts for now
	out	#0x21,al
	.word	0x00eb,0x00eb
	out	#0xA1,al

上面就是对8259进行编码。具体咱就不看了。

下面就正式进入保护模式:

mov ax,#0x0001  ; protected mode (PE) bit
lmsw ax      ; This is it;
jmpi 0,8     ; jmp offset 0 of segment 8 (cs)

前两行,将 cr0 这个寄存器的位 0 置 1,模式就从实模式切换到保护模式了。进入保护模式,DS,CS等就变成了段选择子,他们相当于GDT的索引,进入GDT进行选择,同时还带着特权等级。

jmpi 0,8     ; jmp offset 0 of segment 8 (cs)

再往后,又是一个段间跳转指令 jmpi,后面的 8 表示 cs(代码段寄存器)的值,0 表示偏移地址。请注意,此时已经是保护模式了,之前也说过,保护模式下内存寻址方式变了,段寄存器里的值被当做段选择子。

8 用二进制表示就是
00000,0000,0000,1000

对照上面段选择子的结构,可以知道描述符索引值是 1,也就是要去全局描述符表(gdt)中找第一项段描述符。
所以,这里取的就是这个代码段描述符,段基址是 0,偏移也是 0,那加一块就还是 0 咯,所以最终这个跳转指令,就是跳转到内存地址的 0 地址处,开始执行。

下面就要进入 head.s 去执行了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Linux0.11 源码历险记 2】《保护模式》 的相关文章

随机推荐

  • 虚拟机 arm服务器,一种面向ARM多核处理器服务器平台的系统虚拟机

    主权项 1 一种面向ARM多核处理器服务器平台的系统虚拟机 基于KVM实现 采用宿主模型架构 其特征在于 该虚拟机主要包括 1 物理硬件 物理硬件进一步包括物理CPU 物理内存 物理外设 物理硬件是整个系统虚拟机的硬件基础设施 2 宿主OS
  • css样式表的作用和意义,什么是CSS?

    CSS是大家很熟悉的一个词了 但是如果问你 什么是CSS 你能回答得出吗 到底什么是CSS CSS有什么作用 CSS长什么样子 今天我们就给大家一一解答 CSS全称为Cascading Style Sheets 层叠样式表 中文翻译为 层叠
  • SUSE linux 使用LVM安装系统和管理

    引出 在我们安装好linux系统后会发现在需要修改磁盘分区的时候会比较困难 系统安装的 目录的文件系统要更改基本不太可能 其他目录如 home目录也比较困难 但是系统安装时要是采用的LVM管理的方式安装的话就会截然不通 一 首先普及下LVM
  • 嵌入式python智能实训总结_嵌入式智能家居心得体会 智能家居实训报告2000字

    家里装全套智能家居是一种什么体验 男士体验 5 半年后 我们发现有一篇回到第一篇文章 女性体验 第一篇 嗯 半夜哺乳 不用涂抹 第二篇 睡觉时忘记关灯 不要踢老公 第三 可以随时检查宝宝的状态 而且你可以监控老公是否不在家 第四 出行时 不
  • 软件测试之白盒测试

    白盒测试 一 白盒测试定义 白盒测试 又称结构测试 是在已知程序的内部工作过程的情况下 用来测试程序的内部结构 并判定其结果是否与预期的结果一致 一般说来 白盒测试相对简单 因为白盒测试是在已知程序的内部工作流程的情况下进行的 而且白盒测试
  • GIT常用命令以及使用详解图示

    1配置个人信息 方便提交代码管理 获取Git配置信息 执行以下命令 git config list 如果你还没有设置名字 user name 和 user email的话 可以用以下指令设置 git config global user n
  • 两种方法教你在postman设置请求里带动态token

    postman传递动态参数的最佳实践 问题描述 一 设置全局 环境变量传递 在postman中新增一个环境变量devToken 将获取到的token赋值给devToken 其他请求接口根据需要在请求时带上devToken 二 在每个请求中带
  • JAVA通过反射调用外部的jar包

    把外包jar的信息写在配置文件中 这样如果外部jar改变了 只需要修改properties相应的配置即可 config properties文件内容如下 jarUrl E MessageSend jar className org line
  • 高速USB转8串口产品设计-RS485串口

    基于480Mbps 高速USB转8路串口芯片CH348 可以为各类主机扩展出8个独立的串口 使用厂商提供的VCP串口驱动程序 可支持Windows Linux Android macOS等操作系统 使用单个CH348芯片即可实现USB一拖八
  • 离线 安装webssh

    1 安装包 和 webssh 代码准备 1 cmake 安装 安装参考文档 文档地址 下载地址 tar xvfz cmake 3 24 2 linux x86 64 tar gz 配置环境全局变量 vim etc profile 添加 ex
  • shell脚本初学(带参脚本传递、执行)(二)

    一 带有参数的shell脚本 脚本内获取参数的格式为 n n 代表一个数字 1 为执行脚本的第一个参数 2 为执行脚本的第二个参数 其中 0 为执行的文件名 包含文件路径 bin bash 指定编译器 test sh文件 echo Shel
  • C/C++和Python混合编程

    1 首先需要下载python源代码进行编译 源代码编译的过程访问如下链接 编译python源码 2 创建一个win32控制台项目 项目名称为 InvokePython 如图 3 然后将python源代码中的Include文件夹拷贝到该项目
  • 天线长度计算

    首先 理想天线的长度是半波长 平时说的四分之一波长天线 实际上需要考虑 地 才能构成完整的天线 也就是我们常说的 非平衡天线 天线本身只是天线的一部分 天线长度是波长的四分之一 波长 光速c 频率f 1 如 5GHz wifi天线长度计算
  • 二进制转换

    我们平时使用的十进制 十进制转二进制 整数情况 11表示成二进制数 11 2 5 余 1 5 2 2 余 1 2 2 1 余 0 1 2 0 余 1 得0结束 11的二进制表示为 从下往上 1011 小数情况 0 9表示成二进制数 0 9
  • DLNA协议

    一 DLNA协议 多屏互动技术的核心 dlna协议 利用网络技术 有线或者无线 将各种各样的设备互联 通过标准的协议 主流的是dlna协议 进行数据交互 实现媒体资源共享 比如 生活中常用的视频投屏技术 dlna协议提供的是设备互联资源共享
  • 2022 第十三届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B组题解

    2022 第十三届蓝桥杯大赛软件赛决赛 国赛 C C 大学B组题解 文章目录 第1题 2022 5分 第2题 钟表 5分 第3题 卡牌 10分 第4题 最大数字 10分 第5题 出差 15分 第6题 费用报销 15分 第7题 故障 20分
  • 【进程间通信 之 通信的建立】

    目录 前言 进程间通信的目的 进程间通信的方式 管道 1 匿名管道 简单示例1 消息传输 五个特性 四种场景 简单示例2 进程控制 对管道的深入理解 2 命名管道 简单示例3 不相关进程间通信 system V 共享内存 简单示例4 通知事
  • loadrunner11目标场景

    目标场景 设置一个运行目标 通过Controller的自动加载功能进行自动化负载 如果测试的结果达到目标 说明系统的性能符合测试目标 否则就提示无法达到目标 编辑目标场景 目标类型有5种
  • python-图像边缘化处理

    本文由本人原创 仅作为自己的学习记录 主要利用Sobel 用作边缘检测 它是一离散性差分算子 用来运算图像亮度函数的灰度值 在图像的任何一点使用此算子 将会产生对应的灰度矢量或是其法矢量 Sobel边缘检测通常带有方向性 可以只检测竖直边缘
  • 【Linux0.11 源码历险记 2】《保护模式》

    继续跟着stup s 来看 lidt idt 48 load idt with 0 0 lgdt gdt 48 load gdt with whatever appropriate idt 48 word 0 idt limit 0 wor