《Linux0.11源码解读》理解(三) 执行setup

news2024/11/27 6:13:05

上一节的最后jmpi把cs:ip设置为0x9020:0000。于是CPU开始执行setup,它的作用是获取机器系统数据至内存,关中断并挪动system,为32位模式转换做准备

加载系统信息至内存

同样是调用BISO中断,寄存器作为入参和返回值,分别取得内存信息、显卡显示模式、显示参数、第一第二块的硬盘信息等并置于内存中。详细参见: flash-linux0.11-talk/setup.s at main · dibingfa/flash-linux0.11-talk · GitHub

; Get memory size (extended mem, kB)
	mov	ah,#0x88
	int	0x15
	mov	[2],ax
; Get video-card data:
	mov	ah,#0x0f
	int	0x10
	mov	[4],bx		; bh = display page
	mov	[6],ax		; al = video mode, ah = window width
; check for EGA/VGA and some config parameters
...
; Get hd0 data
...
; Get hd1 data
...

最后存储在内存中的信息及其位置如下,其覆盖了bootsect的大部分区域(0x9000~0x901FD,只有2字节未被覆盖),bootsect使命已完成:

关中断并挪动system

为了将第一节中的BIOS中断替换为操作系统的中断,以让后续main函数适应保护模式下的中断。在此之前不对任何中断进行相应,将标志寄存器(EFLAGS,32bit,含状态/控制/系统标志)中的IF置0。

接着通过ds:si和es:di指定源地址和目的地址,将位于0x10000直到0x90000的内容复制到0x00000处。显然本次内存复制有3个意义:
1)将位于0x10000的system挪到了最开始的0地址。
2)由于第一节所知BIOS的中断向量表也在0地址,故BIOS的中断向量也被擦出了。
3)将位于0x7c00的boostsec、位于0x1000的system所占有的内存现在均已不需要(bootsec已执行完,system搬到0地址),等于空间被回收利用了。
洗牌后内存是这个样子:

为32位模式建立全局描述符表和中断描述符表

实模式下,ds存的是段基址(16位),段基址×16+偏移地址=物理地址(20位)
保护模式下,ds存的是段描述符索引/段选择子。该索引指示出在全局描述符表gdt中,我们所用的段描述符(64位)是哪一项。该段描述符里面存着段地址。
段地址+偏移地址=线性地址,线性地址经分页转换后是物理地址。

cpu是如何知道gdt存储位置的呢?32位cpu为了兼容16位系统,同时有16/32/48位寄存器。

lgdt    gdt_48    ;lgdt表示把后面的值放在gdtr寄存器

gdtr就是个48位cpu寄存器,存储了个gdt_48标签,该标签处内容的高32位是gdt的真正的内存地址,低12位是gdt的容量。 

gdt_48:
    .word   0x800           ; 每个gdt项占8byte, 一共256个gdt, 总量2048byte
    .word   512+gdt,0x9     ; gdt base = 0X90200+gdt
......

gdt:
    .word   0,0,0,0     ; .word 16bit一组, 多个.word表示由低到高排列

    .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

上述代码里的gdt标签处内容便是全局描述符在内存中的真正数据: 现在咱们程序都属于setup,setup的位置是0x90200,所以0X90200+gdt就是实际数据的内存位置。实际上gdt可以存放在内存任何位置,因此通过这种方法来让cpu进行定位。

此外能看出目前全局描述符表有三个段描述符,第一个为空,第二个是代码段描述符,第三个是数据段描述符。由于第二/第三个段描述符的段基址都是 0,因此在保护模式下,段选择子查找到无论是代码段还是数据段,取出的段基址都是 0,那么线性将直接等于程序员给出的逻辑地址(准确说是逻辑地址中的偏移地址)。

中断描述符表也与此类似。只不过现在已关中断无需中断服务程序,于是基地址是0,中断描述符表也是空的:

lidt	idt_48		; load idt with 0,0
...
idt_48:
	.word	0			; idt limit=0
	.word	0,0			; idt base=0L

最后给一张gdtr和idtr的示意图: 

 

为32位模式打开A20地址线

最大寻址空间为4GB需要32根地址线,而原本16位CPU支持的最大1MB空间需要20根地址线,分别对应0~19号地址线。现在32位CPU即便有32根地址线,为了兼容老的20根地址线的模式,于是设计成只能使用其中的20位,因此第21位(20号地址线)需要被打开:

mov al,#0xD1        ; command write
out #0x64,al        ; CPU对外设的操作通过端口读写指令来完成;读端口IN,写端口OUT。
mov al,#0xDF        ; A20 on
out #0x60,al

这段代码就向i8042发送命令:先把命令发送到0x64端口,然后紧接着把这个命令的参数发送到0x60端口。然后我们可以通过读0x60端口,获得i8042返回给我们的数据。这样,就通过i8042控制芯片的输出引脚和A20构成的一个与门电路,缺省A20是on,再写入一个on等于打开了A20。

为保护模式对中断控制器重编程 

因为中断号是不能冲突的, 在保护模式下Intel 把 0 到 0x1F 号中断都作为保留中断,比如 0 号中断就规定为除零异常,软件自定义的中断都理应放在这之后。但是 IBM 在原 PC 机中搞砸了,跟保留中断号发生了冲突,以后也没有纠正过来。所以,我们不得不重新对其进行编程。代码就省略了。反正重新编程之后,8259 这个芯片的引脚与中断号的对应关系如下:

 

进入保护模式

将cr0这个寄存器的位 0 置 1,模式就从实模式切换到保护模式了。 

mov ax,#0x0001  ; protected mode (PE) bit
lmsw ax      ; Load Machine Status Word,但只有操作数的低4位(PE,MP,EM,TS)被存入CR0,其他位不受影响。
jmpi 0,8     ; jmp offset 0 of segment 8 (cs)

 jmpi则将cs:ip设置为8:0,注意现在已是保护模式,那么cs内容便是段选择子:

 

于是8(00000,0000,0000,1000)意味着描述符索引值是 1,也就是cpu要去全局描述符表中找索引 1 的描述符。回顾上面提到的gdt表,第1项为代码段描述符,他的段基址是 0。所以,这里cs:ip 为8:0的查表的结果即位:段基址0+偏移地址0=线性地址0 。由于我们还未分页,线性地址即是物理地址,于是最终跳转到内存的0地址处,开始执行。

现在setup终于执行完毕了。 

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

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

相关文章

javaweb系列-Vue.js

w2.1 Vue概述 一个完整的html页面包括了视图和数据,数据是通过请求 从后台获取的,那么意味着我们需要将后台获取到的数据呈现到页面上,很明显, 这就需要我们使用DOM操作。正因为这种开发流程,所以我们引入了一种叫做M…

NLP大模型微调答疑

什么情况用Bert模型,什么情况用LLaMA、ChatGLM类大模型,咋选? 答:Bert 的模型由多层双向的Transformer编码器组成,由12层组成,768隐藏单元,12个head,总参数量110M,约1.1…

虚拟机02 mysql安装和配置

第一步:在课程资料中,找到数据库安装文件,然后上传安装文件到Linux中。文件位置如图所示: 第二步:打开Linux,到工作目录中创建一个mysql目录,然后将安装文件上传到mysql中 第三步&#xff1a…

chatgpt赋能Python-pycharm与python关联

Pycharm与Python关联:让你的编程更加高效 作为一名有10年Python编程经验的工程师,我深知Python编程的重要性。而作为一个Python开发者,我发现Pycharm的出现真正改变了Python编程的方式。本文将介绍Pycharm与Python的关联,并探讨这…

算法设计与分析:分支限界法

目录 第1关:0/1背包问题 任务描述: 相关知识: 分支限界法基本思想: 常见的分支限界法: 示例:0/1背包问题 对于0/1背包的优化: 题目描述: 编程要求: 测试说明&am…

chatgpt赋能Python-pycharm中怎么粘贴代码

PyCharm是Python编程领域中最受欢迎的集成开发环境之一。它是由JetBrains开发的一款跨平台IDE软件,旨在优化Python项目的开发过程。PyCharm拥有强大的代码编辑器、调试器、代码跟踪器和内置的版本控制工具,可以帮助开发人员编写高效、优质的Python代码。…

超级详细Git操作 之git log 命令的参数详解

git log命令主要用于查看Git版本演变历史(也就是提交历史),同时根据追加的参数和选项不同,也会有不同的展示效果。 但默认git log命令显示出的x效果实在太丑,不好好打扮一下根本没法见人,打扮好了用alias命…

chatgpt赋能Python-pycharm怎么重新配置python环境

Pycharm重新配置Python环境方法概述 如果您是Python编程的专业人士或者是刚开始学习Python,您可能已经听说了Pycharm这个IDE。Pycharm不仅可以提高您Python编程的效率,而且也大大改善了整个开发过程。不过,如果您需要使用Pycharm重新配置Pyt…

深度学习用于医学预后-第二课第四周1-4节随堂作业

作业名:C2_W4_lecture.ipynb 作业地址: github --> bharathikannann/AI-for-Medicine-Specialization-deeplearning.ai --> AI for Medical Prognosis --> Week 4 One-hot encode categorical variables 首先我们来看一下哪些特征是分类特征…

Maven高级篇

分模块开发与设计 ssm_pojo拆分 新建模块拷贝原始项目中对应的相关内容到ssm_pojo模块中 实体类(User)配置文件(无) ssm_dao拆分 新建模块拷贝原始项目中对应的相关内容到ssm_dao模块中 数据层接口(UserDao&#x…

spring学习笔记(2)

目录 RESTful Web 服务是干啥用的? 这个是什么意思?“OpenJDK 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release.” 构建一个RESTful Web服务 GB有多大 点击…

IBM 创新方案+SNP数据转型助一汽大众实现数据平稳、高效迁移

近日,IBM 采用基于SNP Bluefield技术迁移的IBM Rapid Move创新数据迁移方案, 成功为一汽-大众实施了企业运营数据系统从 ECC 到 S/4 的升级项目。该项目系统切换耗时仅三天,不仅助客户高效、平稳迁移了系统数据,升级了数据底座,还…

第六讲:“声音”写具体

爸爸又打呼了!“呼噜一呼噜一像一股巨浪腾空而起,以每秒八十米的速度向上冲刺,力图掀开天花板,掀翻整座住宅楼;“呼噜一一呼噜一-”,像一台轰鸣的坦克在穿行,床垫在抖动,吊灯在摇晃,墙灰在簌籁(…

【办公软件篇】Listary搜索神器清除搜索历史记录

【办公软件篇】Listary搜索神器清除搜索历史记录 装机必备搜索神器—【蘇小沐】 文章目录 【办公软件篇】Listary搜索神器清除搜索历史记录1.实验环境 (一)删除搜索历史记录总结 1.实验环境 官网地址:Listary Discussions 系统版本Windows…

chatgpt赋能Python-pycharm怎么添加库函数

PyCharm怎么添加库函数 作为一位拥有10年python编程经验的工程师,我可以告诉大家,PyCharm是一个非常优秀的Python集成开发环境,它可以帮助我们更加高效地编写Python代码。但是在使用PyCharm的时候,我们经常需要使用一些库函数&am…

Vue3——简易个人空间(下半部分)

书接上回: 好友列表页面实现: 根据提供的api从云端将10个用户读进来 根据提供的api获得如下的json格式的数据,里面有四个用户的信息。 这里使用ajax进行实现要先在项目中安装jquery,使用命令行安装 npm i jquery然后在用户列表页面要先引入jquery i…

数据结构——插入排序与希尔排序

🌇个人主页:_麦麦_ 📚今日名言:喜你成疾,药石无医。——《玫瑰与鹿》 一、前言 在本篇文章,我们将为小伙伴们进行排序概念的基本讲解并具体讲解其中的两种基础排序:插入排序和希尔排序&#xff…

BSQ格式数据转换为RSD缺省的BIP格式数据

李国春 RSD内部统一以BIP格式排列数据,并且文件格式(非TFS)数据倒放(North Down)。早期是为了和设备无关位图(DIB)一致节省一点处理时间。现在设备处理能力增强了这点时间已经无关紧要&#xf…

目标检测复盘 -- 1.mAP及其他评价指标

前言 为什么想单独做一个目标检测篇,主要是感觉自己是个半吊子,满瓶不响、半瓶晃荡,找工作的过程中,也被很多面试官问到哑口无言,基础真的不扎实,自己非常虚,想好好地、静下心来捋一下&#xf…

Linux环境搭建及问题解决方案

本文介绍了Linux环境搭建的过程以及遇到的问题和解决方案,并且介绍了常用的Linux命令. 一、Linux环境搭建 整体所需的环节 安装VMware安装Linux (这边我选的是Server版本)安装配置Samba(Samba是一种Linux和Windows之间进行文件共…