• 13
  • 12月

上次说到一个普通的接收用户输入的操作,居然成了整个课设的难点。确实是相当让人头痛。

不过顺藤摸瓜,亦步亦趋的方法在最坏的情况下总是能解决问题的。

用户输入用的是键盘,内核肯定要处理键盘操作的。那就从键盘操作的最底层找起。于是找到了键盘中断的底层处理代码keyboard.s,根据调用关系找到调用它的tty_read函数。继续向调用关系树的上方找的时候发现内核中没有函数调用tty_read。那好,就分析tty_read吧。

仔细分析了一下这个函数,其实功能很简单,其实不过是把read_q里的东西倒腾到secondary里,顺便做了一些必要的转换工作罢了。而read_q中的字符就是由键盘中断读取到的键盘输入。在没有输入函数的时候,最简单的方法就是循环检测这个队列,看看有没有输入回车。

理论分析很快就搞定了,但在实际修改的时候又遇到了很多麻烦。

最开始犯了一个错误是把读取输入队列的函数放到了处于用户态的进程1之中,弄出了一个困扰了我好几天的奇怪问题:可以正常读取队列头指针处的键盘输入,但只要读完之后increase一下头指针,下一次读取就再也得不到新的键盘输入了。最后发现只要把这些代码放入main函数MOVE_TO_USER_MODE之前就OK了。产生这个问题的具体原因我至今还不是非常明白。估计是遇到了内核的保护机制,内核区的内存对用户区的程序是只读的,若用户态程序修改时会给它一个副本(?)(在内存页式管理中实现的?)。

另一下问题则更另人郁闷。实验环境是Windows下跑的bochs里面运行的字符界面的linux0.11。对文件所有的修改都是在linux0.11下的vi里做的,编译也是用里面的make。vi好在已经在Windows下用过一个学期了(gVim)问题不大,但make对我来说可是个完全陌生的东西。这下在完成第二个要求的时候就遇到了很大的麻烦:虽然我基本分析明白了生成最小内核所需的文件,但只要小改一下代码或Makefile文件,make一下就会生成好几屏的错误报告。而字符界面的linux没有滚屏功能,这下我根本弄不明白到底最开始是哪里出了错误。为了减小代码,最终我不得不采取了一个极其笨拙、极其不geek的办法:把用不到的函数一个个清空内容。

就这样,好不容易在验收前那个上午把东西搞定了。验收时发现,全系只有我一个人用的是改内核代码的方法成功的。其他人有用汇编自己写了一段代码搞定的(体积是够小,但与linux还有什么关系?),另外大部分人居然用的是自己编写一个实现输入输出的程序,替换sh让内核启动时执行(这个与内核就更没什么关系了)。

看到了自己的成果与收获,小小骄傲一下。呵呵

[tags]linux,编程[/tags]

标签:

您可以对这篇文章发表一条评论,或者在您自己的网站中引用 (Trackback) 它

对《软分课程设计2》有 1 条评论

  1. TualatriX 说:

    哇,好厉害!在研究内核吗?
    我的电邮,你能看到吧。

发表一条评论

所有标签:.net Ajax Java javascript Linux map MySQL RSS TD-SCDMA Ubuntu vim web Win7 乱码 基础知识 备份 奥运会 希望泉 性能 缓存 编程