Day27
今天修了修昨天的bug,然后为应用程序添加了LDT,最后整理了一下各种文件。
一些感想
为应用程序设置LDT
之前设置了GDT,为操作系统的各个部分提供了段保护。但是应用程序还是有可能去干扰其它的应用程序(并不是通信,而是随意修改应用程序)。在一般情况下,应该把应用程序隔离开来,不让出错的应用程序干扰到其它应用程序的运行。
LDT的设置方法和GDT类似,具体可以看下面的代码。
优化应用程序大小
应用程序在使用中会需要用到各种其它已经写好的函数。因此需要连接其它的.obj文件,但是如果链接了其它不需要的.o的话,就会白白浪费应用程序占用的体积。
此外,一个函数一个.o太麻烦了,所以把他们集中到一起,写成一个库,会更方便一些。
先来修复bug
harib24a
用ncst打开应用程序之后,应用程序并不能通过点击x关闭。原因是这时候隐藏的控制台的缓冲区始终不会接收到消息(enter除外,所以enter可以关闭)。因此收到消息的时候要先把任务唤醒
task_run(task, -1, 0);
把这句话加到点击和shitf+F1和鼠标点击处理的后面,就可以正常关闭程序了。
应用程序运行时关闭命令行窗口
harib24b
说是关闭,其实就是先把命令行隐藏起来,等到打开的应用程序关闭之后,再关闭命令行。
首先如果点击了一下x,就会隐去图层。
else // 命令行窗口
{
task = sht->task;
sheet_updown(sht, -1); // 暂且隐藏该图层
keywin_off(key_win);
key_win = shtctl->sheets[shtctl->top - 1];
keywin_on(key_win);
io_cli();
fifo32_put(&task->fifo, 4);
io_sti();
}
当然这里并没有真正的释放命令行所占的资源,所占的资源要在获得命令行传来的消息之后再发送。
if(2024 <= i && i <= 2279) // 只关闭命令行窗口
{
sht2 = shtctl->sheets0 + (i - 2024);
memman_free_4k(memman, (int)sht2->buf, 256 * 165);
sheet_free(sht2);
}
对于命令行来说,要增加命令行的窗口是否存在的逻辑。如果不存在的话,光标/重绘等操作就不要进行。
最后,对于API关闭命令行窗口也要修改一下。
if(i == 4) // 只关闭命令行窗口
{
timer_cancel(cons->timer);
io_cli();
fifo32_put(sys_fifo, cons->sht - shtctl->sheets0 + 2024); // 2024~2279
cons->sht = 0;
io_sti();
}
保护应用程序
harib24c
harib24d
添加对应用程序的保护。
破坏应用是寻找应用程序(带有”Hari”标记),并修改其中数据段的内容。
所以接下来要要设置LDT,用于只对某个应用程序有效。
现在增加任务的LDT描述符,用于存放任务的LDT编号
#define AR_LDT 0x0082
struct TASK
{
int sel, flags; // sel代表GDT编号
int level, priority;
struct FIFO32 fifo;
struct TSS32 tss;
struct SEGMENT_DESCRIPTOR ldt[2];
struct CONSOLE *cons;
int ds_base, cons_stack;
};
然后在任务初始化的时候,设定任务的LDT
taskctl->tasks0[i].tss.ldtr = (TASK_GDT0 + MAX_TASKS + i) * 8;
...
set_segmdesc(gdt + TASK_GDT0 + MAX_TASKS + i, 15, (int) taskctl->tasks0[i].ldt, AR_LDT);
```最后把任务创建到LDT中
```c
set_segmdesc(task->ldt + 0, finfo->size - 1, (int)p, AR_CODE32_ER + 0x60);
set_segmdesc(task->ldt + 1, segsiz - 1, (int)q, AR_DATA32_RW + 0x60);
...
start_app(0x1b, 0 * 8 + 4, esp, 1 * 8 + 4, &(task->tss.esp0));
指定了LDT的代码段数据段。每个任务的LDT段号都是独立的,所以不会影响到其它任务。
LDT是对于每个应用程序来说的,所以都设定为0和1没有问题的。
优化应用程序的大小
harib24e
为了节省各种应用程序的体积(引用不需要的函数),把各种api都拆成了不同的obj。从这里开始的三个小节都是文件的整理,所以比较简略。
库
harib24f
把之前分割的不同的文件放到一起,就成了一个链接库。
整理make环境
harib24g
把各种应用程序分到了不同的文件夹里。操作系统的内核、api库都各自建立了文件夹。