MyOS与真正操作系统相比,就是它没有编译器(正在制作中),这是个大问题,导致无法在系统里制作自己的应用级程序,但是我们仍要实现用户级应用程序的话,那么就需要在内核中自带(因为连硬盘都没有。。。),在内核中开辟一块区域用来模拟硬盘,然后开辟用户级内存,然后跳转之。
存在哪里呢?存在app.asm,并入到main.asm中,就是如此。如果进行复制的话,那么这个app就不能使用任何操作系统的函数,只能使用各种门来调用系统调用。
开辟用户级程序,有以下步骤:
1. 开辟一块4K内存,制作一个TSS,填入GDT这个TSS地址。
2. 开辟一块4K内存,制作一个页目录表,填入cr3.
3. 开辟一块4K内存,制作一个页表,填入页表
4. 再开辟一块4K内存,填入应用代码,并跳转到这里执行。
综上,哪怕应用程序什么都不做,最少也开辟了16K的内存。为什么呢?因为该系统最低也要开辟4KB的内存,再低就没有了,为什么呢?因为内存map最低就管理4KB为单位。
接下来实现用户级程序的启动。
首先开辟出那么多内存,并设置好,放置好
然后一个跳转就跳转到那里去了。
返回的话就得开启时间中断,让时间中断返回,进行调度,就是这样。
那么现在需要完成的是,还需要给use4k的map填充,这个分配就会依次进行,试一下。
实现了,感觉蛮正常的。
接下来开辟各种内存。
首先这个TSS开辟在哪里?
GDT它用的是物理地址还是线性地址?首先,GDT作为分段的依据,它在页转换之上,因此必然是虚拟地址,受cr3的控制(毕竟那两个分段都是000000....),但是在切换进程的时候,你必须创建一个TSS,但是此时页目录表并没有创建好,你无法知道TSS是创建在哪里的。因此必须要首先创建一个页目录表,然后创建一个页表填入页目录表,然后创建两个4K块,一个放应用程序,一个放TSS,这样TSS就有线性地址了,并且永远是一样的。。。
在切换进程的时候,调度进程读到这个地址,调度进程在哪里?它在内核里,它是按照内核的页目录表进行寻址的,内核早已分配完毕(4M),因此这个TSS实际上是内核里的。其实是内核内的内存调度。你开辟出1024个TSS段,开辟一个数组用来管理这些内存段,就是如此了。它是在内核里的,不用开辟。
于是就变成了
1. 根据TSS管理数组,制作一个TSS,填入GDT这个TSS地址。
2. 开辟一块4K内存,制作一个页目录表,填入cr3.
3. 开辟一块4K内存,制作一个页表,填入页表
4. 再开辟一块4K内存,填入应用代码,并跳转到这里执行。
那么接下来就是要管理这个TSS堆。同样是插入到文件里(你最好代码生成。。。)一个TSS管理数组TSS_Ctl,就是这样。
找到一个空闲TSS
设置这个TSS并插入到GDT
虽然说跳转到ring3,但是之前已经实现了两个进程的跳转了,现在最好实现管程跳转。一个管程它管什么呢?管进程的五个状态。进程是怎么开启的呢?任何代码都可以成为一个进程,只需要提供其地址,然后初始化TSS,然后跳转之就可以了,进程是谁开启的呢?进程自然是其他进程开启的。不能随便瞎开进程,意义不大了,这样的话,对进程分割一下吧。
一个鼠标进程 ,一个键盘进程,一个桌面绘图进程,这三个进程,通过键盘进程开启一个模拟用户进程,这个模拟用户进程就是一个计时程序,计时完毕就退出。
然后系统主程序的loop函数专门用来调度,就是这样,然后进程切换全在计时中断里进行jmp了。
现在的工作就是将键盘鼠标绘图切分成三个进程,然后再造一个进程调度函数进行调度。
在可预见的将来,不会使用磁盘去存放应用程序,也不会用磁盘去存放任何东西,磁盘仅仅是一个管理功能的多余累赘。
如果将app的创建进行打包的话,就执行上序的步骤即可,你最多弄一个appManager,对吧,一个appManager_createApp加上地址,就能创建一个应用程序,并将其添加到就绪队列中,你还是先把基建搭好吧
主进程来进行进程选择,并切换到其他进程,主进程不存在于进程表中
鼠标进程
键盘进程
桌面绘图进程
计时中断仅仅是切换到主进程
调度算法,一个表,几百个字节,一个进程计数,一个当前进程,轮询,删掉一个进程的话不用删,置零,然后向下走即可,还是说整个给它整顿一下呢?
实际上用链表是最好的。但是现在随便吧。叫processManager,只要以4字节为单位,存放TSS地址,最多255个。
也从来没有说等待进程队列,这个是以后的事情。
process_queue: {0}*4*256.
然后再是进程切换程序,是吧。