如何解决处理用户空间中的磁盘中断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 举报,一经查实,本站将立刻删除。