一、刚开机时,CPU寻址,到磁盘的0磁道0扇区读入0x7c00处,在这里执行引导扇区的代码,为bootsect.s。在这里执行汇编代码,剩下的所有OS都是从这里开始加载的。(中间如何加载,因为没有学过汇编,之后再仔细学一下)在这里我们可以修改第一个很简单的东西,就是开机的logo。就比如win10的小窗户是可以修改掉的
如图,等回来一定要试一试。
二、操作系统的接口。什么是接口。做个比喻。
我将插头插入插座,就有电了,然后我就可以用电做很多事情。但是这个插座背后用了火线也好零线也好,你都不用管,因为已经给你包装好了。直接用即可。操作系统的接口是什么呢。就是函数。比如命令行:
再比如图形界面中的按钮。
所以就像printf函数,这也是操作系统的一个接口。确切的说是因为这个printf函数展开成了write函数。而write函数是系统接口函数。下面存一张系统接口函数的表格
三、系统调用。
首先提出一个问题。假设有这样一个接口函数。通过这个接口函数,你可以访问内存地址为100的数据。但是你可以是否直接访问内存地址为100的数据呢。答案是不行。
首先我们的硬件设计了一种内核态和用户态,也就是说内核态可以访问任何数据,而用户态不能访问内核数据。
然后我们引进DPL和CPL。DPL为目标态,CPL为现在所处状态。当满足DPL>=CPL才能访问。开机启动初始化时DPL自动初始化成为0.代表内核态。那我们如何进入内核中呢。就是通过接口。硬件提供了主动进入内核的唯一方法。那就是中断指令int,int 指令将CS中的CPL改成0,进入内核。这是用户程序发起调用内核代码的唯一方式。比如上面提到的printf函数。如图
我大概解释一下意思。printf并不是真正的接口函数,而是变成了write函数来进入内核的。所以我先将第二张图的宏展开。。
int write(int fd,const char *buf,count)而我们知道printf是%d,a这样的格式,所以先由C将printf转换成write函数的格式再调用write函数,下面又是一段汇编代码。大概意思是,定义一个long 型的res返回值。然后将NR_name展开也就是NR_write置给了eax,NR_write已经被宏定义为4,所以eax为4,接着就进入了int 0x80指令,这句话干了非常多的事情。首先我们进入了内核,但是我们应该用内核中的哪种方法呢。内核中的write函数的地址是多少呢,就是因为这个我们才将eax赋值为4。然后用4和idt表表示出这个函数的地址。
又是汇编看不懂QAQ,但是大概意思就是这样。填表时,用宏定义,故意将DPL设置为了3.而将CPL设置为了0.这样就可以在访问到这一步的情况下,将CPL设置为了0.
参考--李治军老师的PPT