上节提到,现在cs:ip指向0地址,此处存储着作为操作系统核心代码的system模块,是由head.s和 main.c以及后面所有源代码文件编译链接而成。head.s(以下简称head)紧挨着main.c,我们先执行head。

重新设置内核栈

_pg_dir:
_startup_32:mov eax,0x10mov ds,axmov es,axmov fs,axmov gs,axlss esp,_stack_start

标号 _pg_dir表示页目录,意为在设置分页机制时,页目录会存放在这里,也会覆盖这里的代码。setup.s(以下简称setup)已经设置了gdt,现在要对段描述符重新设置包括ds/es/fs/gs。都被设置为0x10(00010000),在保护模式下即段选择子为2,指向数据段描述符。根据我们之前gdt表的内容,数据段的基地址是0,于是ds/es/fs/gs的基地址也是0。

lss 指令相当于让 ss:esp 这个栈顶指针(esp是sp的32为扩展),指向了 _stack_start 这个标号的位置(对比lds mem,reg:将段描述符mem的高位存储在 reg 寄存器的高位,而段描述符的低位存储在ds寄存器的低位)。当然之前在bootsec所设置的栈顶0x9ff00位置现在变成了0:stack_start:

// include/linux/mm.h
#define PAGE_SIZE 4096// kernel/sched.c
long user_stack [ PAGE_SIZE>>2 ] ;
struct {long * a;short b;} stack_start = { & user_stack [PAGE_SIZE>>2] , 0x10 };

其实从第三节得知我们已经在setup的内存(位于0x90200)设置了idt、gdt。现在则通过call setup_idt和setup_gdt重新设置位于head的内存(位于0x90000)的idt、gdt。为何重复设置?

因为位于setup的内存会在将来设计缓冲区时被覆盖,而且也不能将setup中的idt和gdt直接copy到现在的位置(在执行setup的时候copy无意义,因为如果先执行setup后移动system会覆盖掉copy的idt、gdt;如果先移动system后执行setup则会覆盖掉head内容),于是我们不得不在head重新设置它们。

设置IDT

即便是setup里面的idt也都是空的,现在由head程序正式设置。

setup_idt:lea edx,ignore_int  ;lea将ignore_int偏移地址(16bit)/而mov将第二操作数的内存内容 放入edxmov eax,00080000h   ;将段选择子0x0008置入eax高16位mov ax,dx           ;将ignore_int偏移地址置入eax低16位mov dx,8E00h        ;interrupt gate - dpl=0, presentlea edi,_idt        ;lea将_idt所代表偏移地址放入edimov ecx,256         ;cx用来计数,256次
rp_sidt:mov [edi],eax       ;[]寄存器间接寻址,表示eax的内容赋予“以edi的内容作为地址指针的”内存。mov [edi+4],edxadd edi,8dec ecxjne rp_sidtlidt fword ptr idt_descr   ;fword ptr是48位指针,用于远程跳转retidt_descr:dw 256*8-1    ;db字节(1 byte)类型,dw字类型(2 byte),dd双字类型(4 byte)dd _idt_idt:DQ 256 dup(0) ;伪操作,用来定义操作数占用的字节数

ignore_int作为默认中断处理程序函数地址,会放入中断描述符内。中段描述符结构如下:

这段代码意为将eax作为低32bit、edx作为高32bit填充一个中断描述符,并以cx作为计数器一共填充256次(共256项),以此来初始化整个IDT。最后通过lidt加载中断描述符至idtr让cpu识别。

重新设置GDT

setup_gdt:lgdt gdt_descrret
...
.align 2
.word 0
gdt_descr:.word 256*8-1     ; gdtr内容是gdt的界限, 以及gdt所在的地址.long _gdt           ; 每个gdt项占8byte, 一共256个gdt项, gdt总量2048byte.align 3
_gdt:   .quad 0x0000000000000000;   ;.quad为4word/8byte(等同.word 0,0,0,0). NULL desp.quad 0x00c09a0000000fff  ; 代码段, 0fff=>4096, 4096*4096=16Mb.quad 0x00c0920000000fff  ; 数据段, 除了基地址以外,其他同上.quad 0x0000000000000000  ; TEMPORARY - don't us.fill 252,8,0                ; space for LDT's and TSS's etc

对照gdt项所设置内容0x00c09a0000000fff的二进制和全局描述符格式:


g(granularity)粒度位如为0,段限长以1字节为单元;为1,段限长以4K字节为单元;dpl描述符特权级0和3级;p段存在位,该位为1指示描述符存在。于是0x00c09a00表示g为1,p为1,那么此代码段限长为4096*4K=16M。

重置了idt/gdt,接着又重新执行了一遍刚刚执行过的代码。为什么要重新设置这些段寄存器呢?因为修改了 gdt,所以要重新设置一遍,做个刷新,这样修改才能生效。

call setup_idt ;设置中断描述符表
call setup_gdt ;设置全局描述符表
mov eax,10h
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
lss esp,_stack_start

检验A20地址线是否打开

需要检验A20地址线是否打开,因为这会影响保护模式是否有效。这里通过如果没打开A20则0x100000会回滚到0x000000来判断,并不断循环直到A20开启为止:

 xor eax,eax         ; 异或,清空eax
1:  inc eax             ; check that A20 really IS enabledmov 0x000000,eax  ; loop forever if it isn'tcmp 0x100000,eaxje 1b               ; zf为0则跳转(通常搭配cmp,如源操作数和目标操作数相等,则跳转)

在检测到保护模式有效后,如果是486之前的cpu,会配备数学协处理器芯片以增强浮点计算能力。大概是先检查数学协处理器芯片是否存在。方法是修改控制寄存器CR0,在假设协处理器存在的情况下执行一个协处理器指令,如果出错的话则说明协处理器芯片不存在。这段代码不贴出来了,详细参见:flash-linux0.11-talk/head.s at main · dibingfa/flash-linux0.11-talk · GitHub

开启分页机制,为进入main函数做准备

设置完协处理器后,将要开启分页机制,这是head的最后阶段也是执行main函数前的最后阶段。

...jmp after_page_tables
...
after_page_tables:push 0push 0push 0push L6push _mainjmp setup_paging
L6:jmp L6

可以看到将main函数参数、L6以及main函数地址都压栈,然后跳转到设置分页的标号。这些压栈是为了开启分页后执行main函数。

此外,即便main函数退出,程序也不会结束,因为我们看到程序到L6这边,是个死循环。

《Linux0.11源码解读》理解(四) head之重新设置IDT/GDT相关推荐

  1. faster rcnn源码解读(四)之数据类型imdb.py和pascal_voc.py(主要是imdb和roidb数据类型的解说)

    转载自:faster rcnn源码解读(四)之数据类型imdb.py和pascal_voc.py(主要是imdb和roidb数据类型的解说) - 野孩子的专栏 - 博客频道 - CSDN.NET ht ...

  2. mobx 源码解读(四):讲讲 autorun 和 reaction

    原文地址:mobx autorun 文本是 mobx 源码解读系列 第四篇 本系列文章全部采用 mobx 较新版本:v5.13.0 mobx 源码解读 issue,欢迎讨论 技术前提 在阅读之前,希望 ...

  3. open3D源码解读第四篇

    2021SC@SDUSC 文章目录 open3D体素化 VoxelGrid.h VoxelGridIO 小结 open3D体素化 本篇解读voxel(体元/体素)的基本类Voxel,以及VoxelGr ...

  4. c 取地址 虚拟地址 物理地址_通过linux0.11源码理解进程的虚拟地址、线性地址、物理地址...

    进程的地址有三种,分别是虚拟地址(逻辑地址).线性地址.物理地址.在分析之前先讲一下进程执行的时候,地址的解析过程.在保护模式下,段寄存器保存的是段选择子,当进程被系统选中执行时,会把tss和ldt等 ...

  5. 【转】[Hadoop源码解读](四)MapReduce篇之Counter相关类

    转自:http://www.cnblogs.com/lucius/p/3449922.html 当我们定义一个Counter时,我们首先要定义一枚举类型: 1 public static enum M ...

  6. 实践编译LINUX0.11源码,感觉真爽。

    简单是很简单.依据如下URL,轻松搞定. 下一步,就是看DOCTOR.赵的书,还有BOCHS的深入功能了?? http://hi.baidu.com/no9527/item/925a241528647 ...

  7. BaseRecyclerViewAdapterHelper源码解读(四) 上拉加载更多

    上拉加载 上拉加载无需监听滑动事件,可自定义加载布局,显示异常提示,自定义异常提示. 此篇文章为BaseRecyclerViewAdapterHelper源码解读第四篇,开源库地址,如果没有看过之前3 ...

  8. Alamofire源码解读系列(九)之响应封装(Response)

    本篇主要带来Alamofire中Response的解读 前言 在每篇文章的前言部分,我都会把我认为的本篇最重要的内容提前讲一下.我更想同大家分享这些顶级框架在设计和编码层次究竟有哪些过人的地方?当然, ...

  9. Alamofire源码解读系列(五)之结果封装(Result)

    本篇讲解Result的封装 前言 有时候,我们会根据现实中的事物来对程序中的某个业务关系进行抽象,这句话很难理解.在Alamofire中,使用Response来描述请求后的结果.我们都知道Alamof ...

  10. AFNetworking 3.0 源码解读(十)之 UIActivityIndicatorView/UIRefreshControl/UIImageView + AFNetworking...

    我们应该看到过很多类似这样的例子:某个控件拥有加载网络图片的能力.但这究竟是怎么做到的呢?看完这篇文章就明白了. 前言 这篇我们会介绍 AFNetworking 中的3个UIKit中的分类.UIAct ...

最新文章

  1. 蓝桥杯【介绍】和【如何准备才可以拿奖】
  2. android微信小程序自动填表_微信小程序自动化,记录趟过的坑!
  3. SAP-SAP预制凭证相关的表
  4. carsim学习笔记4——路面的一些设置1
  5. C#时间格式转换、日期操作函数、常用转换语法
  6. 姓名性别电话邮箱html表单,HTML form标签语法、属性、规范和示例详细说明-立地货...
  7. 量子纠缠(三)——波尔和爱因斯坦之争
  8. 【重磅推出】推荐系统系列教程之九:解密“看了又看”和“买了又买”(Item-Based)...
  9. centos下设置自启动和配置环境变量的方法
  10. Hibernate的事务管理
  11. 北京理工大学语音识别技术.ppt
  12. cloudera manager安装使用
  13. 第二篇:从 GPU 的角度理解并行计算
  14. windows命令行压缩解压缩
  15. 拯救微信多号党的超实用工具,电脑版PC微信双开、多开、防撤回补丁工具
  16. MFC控件背景透明处理
  17. idea git输错密码的处理 win10
  18. 易语言 html 服务器,易语言模拟网页Web服务器源代码
  19. K-means聚类算法的应用——Python数据工程No.5
  20. 软件测试藏宝图中文版

热门文章

  1. 电子商务中的几个概念
  2. 敲桌子游戏 案例描述:从1开始数到数字100, 如果数字个位含有7, 或者数字十位含有7,或者该数字是7的倍数,我们打印敲桌子,其余数字直接打印输出。
  3. vue中使用filter筛选列表信息
  4. Salesforce数据安全篇 - 对象/字段 / 记录级别的权限配置(OLS / FLS / RLS)
  5. 获取当天00:00:00时间的方法
  6. [论文翻译][2015][28]Bayesian Estimation of the DINA Model With Gibbs Sampling(基于Gibbs采样的DINA模型贝叶斯参数估计方法)
  7. JSON不对称反序列化映射方案
  8. Unity 本地外部摄像头编辑器能播放 打包之后无法播放
  9. 计算机毕业设计Java高校开放式实验室管理系统(源码+系统+mysql数据库+lw文档)
  10. 5培训python的5个就业方向,吃香行业