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库都各自建立了文件夹。