
操作系统
guocaigao
学的是电子商务,自学编程,想做底层但基础差点,学过单片机,现在主攻C++,MFC
展开
-
特权级--ring3到ring0
还记得吗?我们用调用门和lcall指令实现特权级由低到高的转移.假设我们想由代码A转移到代码B,运用一个调用门G,即调用门G中的目标选择子指向代码B的段。实际上我们要考虑4个要素:CPL、RPL、DPL_B(代码B的DPL)、DPL_G(调用门G的DPL)。第一步,当A访问调用门G时,规则相当于访问一个数据段,要求CPL和RPL都小于或者等于DPL_G.也就是CPL和RPL需要在更高的特权原创 2013-01-15 17:29:28 · 1459 阅读 · 0 评论 -
一个简单的进程----跳到ring3
进程都是工作的特权级ring3下的,如何跳到ring3呢?我们用iret指令,不过在这之前我们要准备好ring3的堆栈,设置ring3的代码段,为了能在ring3模式下能够打印我们还要修改视频段,还记得前面《ring0到ring3》是如何做的吗?我们先写一个函数_set_gdt_desc来修改gdt,代码非常的简单,无非是设置gdt中的描述符。typedef unsigned int u32原创 2013-10-09 17:24:48 · 1272 阅读 · 0 评论 -
整理文件夹
目前我们所有的文件都在一个文件夹下,目录结构如下以后代码越来越多,管理起来很不方便,下面我们就仿照linux的目录结构来整理一下:新建一个boot文件夹,将bootsect.S、head.S、setup.S此文件夹下;新建include文件夹,在此文件夹下新建asm和linux文件夹,asm文件夹下添加io.h和system.h,linux文件夹下添加head.h;新建init文件夹并将mai原创 2013-10-09 14:57:48 · 1260 阅读 · 0 评论 -
设置中断门与陷阱门
通过前面中断的实验我们知道LABEL_IDT是放到内存中的一张表,里面是一个一个的门描述符,对应相应的中断向量。我们的工作就是在描述符中填充相应的内容。为了能在c中设置中断门,我们在head.S中添加.globl LABEL_IDT,这样在c中我们就可以使用了,我们在main.c中是这样声明的:typedef struct desc_struct {unsigned long a,b;原创 2013-09-23 16:46:01 · 2487 阅读 · 0 评论 -
改写load_system
前面提到过我们装载system的时候有问题,当system还很小的时候可以应付,后面如果变大我们没办法把它全部读入内存,下面我们就来修改启动扇区中的load_system将全部的system读入内存。 load_system: movb $0x00,%dl mov $0x0800,%ax int $0x13 movb $0x00,%ch原创 2013-09-14 14:12:54 · 1256 阅读 · 0 评论 -
加入库函数
加入一些实用的打印功能,这对我们的调试是大有帮助的,我们单独放到kliba.S文件中 .data.global disp_strdisp_pos: .4byte ((80 * 6 + 0) * 2) .text .globl disp_str,disp_int.code32/********************************************原创 2013-09-14 14:04:05 · 858 阅读 · 0 评论 -
拷贝自己
因为有可能在0x7c00处放东西所以将自己拷贝到0x90000处去执行 SETUPLEN = 4BOOTSEG = 0x7c0INITSEG = 0x9000SETUPSEG = 0x9020SYSSEG = 0x1000ENDSEG = SYSSEG + SYSSIZE.text .globl start/*程序从start处开始运行*/ .code1原创 2013-08-21 17:29:21 · 852 阅读 · 0 评论 -
调用门
门,顾名思义它是一扇门通向令一个地方,看一下门的结构里面有一个描述符和一个偏移值,门中定义了这扇门通向的目的地,当我们调用一个门的时候会到达这个地方:门中的选择子:门中的偏移值,也即下图的selector:offset这是我们代码中国定义的门的数据结构:#define Gate(Selector,Offset,PCount,Attr)\.2byte (Offset&0xff原创 2013-01-11 10:39:57 · 2544 阅读 · 0 评论 -
局部描述符表LDT
上一篇为了简单我们只涉及到GDT,其实LDT跟它差不多,跳转的时候选择子的第3位也就是TI位为0我们就用GDT,如果TI=1我们就用LDT。总结如下:TI=0时:CS:IP=全局描述符表中第1(0x8>>3)项描述符给出的段基址+0的偏移地址TI=1时:CS:IP=局部描述符表中第1(0x8>>3)项描述符给出的段基址+0的偏移地址局部描述符表在哪里?这要问ldtr寄存器了,ldt原创 2013-01-09 11:02:17 · 2913 阅读 · 0 评论 -
认识保护模式
想看懂linux内核必须要理解保护模式,也许它并不复杂只是书上讲的太抽象了,下面让我们来认识一下保护模式,在这里我们只考虑全局描述符表GDT。先来看下面两个重要的寄存器CS:代码段寄存器(Code Segment Register),其值为代码段的段值IP:指令指针寄存器,它用来存放代码段中的偏移地址。在程序运行过程中,它始终指向下一条指令的首地址,它与代码段寄存器CS联用确定下一条指原创 2013-01-07 17:33:24 · 1844 阅读 · 0 评论 -
关于链接地址
回过头来看我们的Helloworld程序,在Makefile中-Ttext 0x7c00,链接地址为0x7c00,code标号的偏移地址为0x15,则链接后其地址为0x7c15, 其他函数调用此函数时,也就会调用地址0x7c15,这时jmpl $0, $code语句反汇编后为:假如我们在Makefile中改为-Ttext 0x0,因为code标号的偏移地址为0x15,则链接后其地址为0原创 2013-08-21 16:51:40 · 1628 阅读 · 0 评论 -
特权级--ring0到ring3
内核要和用户程序分开,内核一定要安全,不能被用户程序干涉,但是有时候用户程序也需要读取内核的某些数据,怎么办呢?x86就引入了访问特权等级(0-3)的机制,x86 cpu共有4个特权级 level0 到 level3 其中level0特权级最高,level3特权级最高。处理器通过识别CPL、DPL、RPL这3中种特权级进行特权级检验。CPL(Current Privilege Level)是当原创 2013-01-15 11:21:11 · 2903 阅读 · 0 评论 -
从HelloWold开始一个操作系统
最近在阅读linux早起内核的源码,可惜全是AT&T汇编,和以前学的大不一样,我们何不用AT&T汇编从一个HelloWorld开始实现一个小型操作系统,记得以前有本书叫>是用nasm汇编从一个HelloWorld开始实现了作者自己的操作系统。这其实是一个引导程序,因为PC机启动时ROM BIOS中的程序会把默认启动驱动器上的引导扇区代码和数据读入内存。好吧,那就从HelloWorld开始。我们原创 2013-01-07 11:44:03 · 1848 阅读 · 0 评论 -
从进程到内核---ring3到ring0
这次我们用中断来实现从ring3到ring0的跳转,当我们用中断门实现从ring3到ring0的转移时,会从TSS加载ring0的堆栈STACKR0,然后将调用者ring3的ss、esp压入新堆栈STACKR0,然后EFLAGS压入堆栈,然后将当前ring3的cs和ip入栈,然后加载调用门中的新的cs和ip,使IF=0,开始执行中断服务函数。那么首先我们要准备TSS,其结构如下:typed原创 2013-10-10 13:05:44 · 7223 阅读 · 0 评论