本文参考书籍
操作系统真相还原
Linux内核完全剖析:基于0.12内核
x86汇编语言 从实模式到保护模式
ps:基于x86硬件的pc系统
计算机概述
计算机的硬件组成基本分为控制器、运算器、存储器和输入输出设备。
计算机系统除了基本硬件外,还包含了计算机软件,计算机软件主要分为系统软件如操作系统和应用软件如在特定操作系统上的应用程序,整体结构大致如下;
| 应用软件如QQ |
| 系统软件(操作系统) |
| 硬件 |
传统的PC的组成结构如下图(摘自0.12内核):
其中,CPU通过地址线、数据线和控制信号组成的本地总线与系统其它部分进行数据通信;地址线用于提供内存或I/O设备的地址,指明需要读写的具体位置;数据线用于在CPU和内存或I/O设备之间提供数据传输的通道,而控制线则负责指挥执行的具体读写操作,在CPU中,如果是传统x86运行于实模式下,则寻址空间为1M,如果运行于保护模式下,则寻址空间为4G。
控制器和存储器接口一般集成在计算机主板上,这些控制器一般都是集成的电路芯片为主的功能电路,例如,中断控制器由8259A或其他兼容芯片构成,DMA控制器通常是采用8237A芯片构成,定时计算器则是8253芯片等功能电路组成。
总线是系统地址总线、数据总线和控制线与扩展设备控制器的标准连接接口组成,这些总线接口标准通常有相应的标准,如ISA总线等。
操作系统对应的相关技术(基于x86)
1、基本的汇编语言;
2、C语言;
3、编译链接器;
4、汇编与C语言混合编程
5、相关X86硬件知识,如实模式编程和保护模式编程等;
基于x86实模式相关介绍
计算机的启动过程
1.在通电的时候,cpu的cs:ip寄存器强制初始化为0xF000:0xFFF0,由于开机的时候处于实模式,在实模式的段基址要乘以16,即地址左移四位,于是cpu执行的内存地址为0xFFFF0,该地址便是bios的入口地址。
2.由于在实模式下,16位cpu的寻址能力只有1MB,此时0xFFFF0距离1MB只有16个字节,而这段空间需要完成bios代码的运行,明显空间不足,此时此处的代码只是一个跳转指令,此时跳转到bios代码处执行,然后进行内存检查、显卡等外设信息检查,当通过后,并初始化好硬件后,开始建立数据结构,中断向量表IVT并填写中断例程。
3.当bios检查完后并初始化完成后,bios会校验启动盘中位于0盘0道1扇区的内容,如果此扇区末尾的两个字节分别是魔数0x55和0xaa,bios便认为此扇区中存在可执行的程序,便加载到物理地址0x7c00处,随后就会跳入0x7c00处执行,此时的jump会将0xFFF0更新成0,此时就会跳入到物理地址0x7c00处执行。
相关解释:此时加载的0盘0道1扇区的内容,其实就是主引导程序mbr,由于该段内容可能软盘、硬盘或者其他介质中,此时需要找个该保存的地方,此时直接告诉存储的位置就不用代码去依次去存储设备中查找该启动程序;其中为什么选择0x7c00地址是由于历史原因,x86要求物理地址0x0-0x3FF存放中断向量表,不能更新该处地址,按照DOS1.0的要求最小内存32KB来说,为了尽量多的预留空间,免得被覆盖,所有就把启动程序放在32KB的末尾,由于本身改段程序只有512字节,但还要给栈分配空间,所有要大于512个字节的空间,就预留1KB,此时32KB减去1KB就是0x7c00。
实模式相关简介
1.cpu中的寄存器大致分为两类,第一类是内部使用,对程序员不可见,只能给cpu内部的数据提供存储空间,如全局描述符表寄存器GDTR、中断描述符表寄存器IDTR、指令指针寄存器IP、控制寄存器CR0-3等,虽然有些寄存器是对程序员不可见,但是还是需要在启动的时候初始化相应寄存器的值,如GDTR,不过初始化的方法时通过cpu提供的指令lgdt来初始化,避免了程序员直接操作;第二类是对程序员可见的寄存器,如段寄存器、通用寄存器(AX、BX)等。
2.在实模式下,默认用到的寄存器都是16位的。首先介绍一下段寄存器,由于在实模式下,内存寻址能力要达到1MB,段寄存器16位的寻址能力只有64KB,而且cpu在实模式下也是基于分段机制,所以访问的地址是段基址:段内偏移,由于都是16位的寄存器,所以在实模式下cpu的寻址方式就是段基址左移4位+段内偏移此时就能到达1MB的寻址空间。在cpu的执行过程中,cpu的取指令执行时依靠cs:ip两个寄存器来进行执行的,当cpu执行时不跨段执行时,就是已当前ip寄存器的值+当前执行指令的长度,当进行跨段访问执行时,就会加载新的段基址,已新的段基址的值来进行取值执行。
3.实模式是在cpu有了保护模式之后,为了区别就的模式就把旧的模式称为实模式,在实模式情况下,程序中用到的地址都是真实的物理地址,段基址+段内偏移就是对应到内存中的物理地址,在实模式下,执行的代码都是工作在最高特权级下,所以具有安全隐患,此时的操作系统和用户程序不会有权限的区分,用户程序都可以执行一些具有破坏性的代码,用户程序可以随意更改自己的段基址,用户程序都可以覆盖其他运行的程序,所以cpu保护模式的出现,极大的改善了这一问题。
实模式面临的问题主要是相关寄存器不足使用,执行代码安全性不足等问题
基于x86保护模式相关介绍
随着cpu的发展,以及实模式下的相关不足,cpu就提供了保护模式,在cpu发展到32位之后,地址总线和数据总线也发展到32位,其寻址能力达到了4GB,除了段寄存器外,通用寄存器、指令指针寄存器、标志寄存器都由原来的16位扩展到了32位,为了兼容实模式,寄存器的低16位可以单独使用,但是高16位并不能单独使用,相应的运行代码也有权限检查等。此时的32位的寻址也进行了扩展,由于在实模式下是按照段基址+段内偏移进行访问的,此时32位的cpu段内偏移就可以访问到4GB的地址,但是还是按照段基址+段内偏移的方式来访问,此时是根据段选择子来进行段基址的选择,此时再访问内存段的时候也会根据选择子的信息验证是否超越了界限。
由实模式进入到保护模式,需要进行三个步骤,1.打开A20总线,2.加载gdt,3.将cr0的pe位置1,执行完成后就进入到了保护模式下运行。
x86保护模式的相关内容有系统寄存器和系统指令,内存管理、分段机制、分页机制、特权保护、中断和异常处理和任务管理等内容。待后文分析。
Linux内核相关介绍
目前的操作系统分析基于linux0.12,linux内核的主要用途就是为了与计算机硬件进行交互,实现对硬件的编程控制和接口操作,调度对硬件资源的访问,并为计算机上的用户程序提供一个高级的执行环境和对硬件的虚拟接口。
Linux内核采用了单内核模式,操作系统提供服务的流程为:应用主程序使用指定的参数值执行系统调用指令(int 0x80),使cpu从用户态(User Mode)切换到核心态(Kernel Mode),然后操作系统根据具体的参数值调用特定的服务程序,而这些服务程序则根据需要再调用底层的一些支持函数以完成特定的功能,在完成了应用程序所要求的服务后,操作系统又使cpu从内核态切换回用户态,从而返回到应用程序中继续执行后面的指令。因此概要地说,单内核模式大概分为3个层次:调用服务的主程序层、执行系统调用的服务层和支持系统调用的底层函数。
Linux内核主要包含了5个模块,分别是:进程调度模块、内存管理模块、文件系统模块、进程间通信模块和网络接口模块等。
Linux分析的内容主要包括Linux内核对内存的管理和使用、中断机制、系统调用机制、进程控制、文件系统等相关内容进行分析。并且会介绍相关的理论基础知识。