处理用户空间中的磁盘中断MIT 6.828 JOS实验5

问题描述

我将尝试使这个问题尽可能地笼统。背景是我现在正在尝试6.828 LAB 5挑战。

挑战!实施带或不带DMA的中断驱动的IDE磁盘访问。您可以决定是将设备驱动程序移入内核,还是将其与文件系统一起保留在用户空间中,或者(如果您真的想融入微内核的精神)将其移至自己的单独环境中。

我试图将驱动程序保留在用户空间中,但是我发现有关计时器中断的问题,请参见下面粘贴的代码,这是我在注释中加上的原因:

int
ide_read(uint32_t secno,void *dst,size_t nsecs)
{
    int r;

    assert(nsecs <= 256);

    ide_wait_ready(0);

    outb(0x1F2,nsecs);
    outb(0x1F3,secno & 0xFF);
    outb(0x1F4,(secno >> 8) & 0xFF);
    outb(0x1F5,(secno >> 16) & 0xFF);
    outb(0x1F6,0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F));

    // between issuing disk cmd and set to sleep,there might be a timer IRQ
    // comes in,and fs -> RUNNABLE,then disk IRQ comes,and we handle it
    // then fs goes to sleep,with cpu halted,we missed wake up
    sys_ide_sleep(dst,nsecs,0);

    return 0;
}

sys_ide_sleep系统调用如下:

static void
sys_ide_sleep(void *chan,size_t nsecs,int op)
{
    int r;
    if (op == 0)
    {
        outb(0x1F7,nsecs > 1 ? 0xc4 : 0x20);   // CMD 0x20 means read sector
    }
    else
    {
        outb(0x1F7,nsecs > 1 ? 0xc5 : 0x30);   // CMD 0x30 means write sector
        outsl(0x1F0,chan,PGSIZE / 4);
    }
    curenv->chan = chan;
    curenv->env_status = ENV_IDE_SLEEPING;
    curenv->op = op;
    sched_yield();
}

我想到了在系统调用中传递一个共享的布尔变量的地址,一旦IRQ被确认并处理,我们就设置is_finished = true。所以我想出了sys_ide_sleep(&is_finished),在我们决定使用sched_yield()产生cpu之前,我们可以像这样进行检查:

if (*is_finished == false)
{
    sched_yield();
}

但是我不知道是否有任何更优雅或更好的方法可以做到这一点(我不认为以这种方式与内核共享内存是好方法),任何评论或回答都将不胜感激。谢谢!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...