前提
首先要明白实现输入输出的关键是什么!
输入输出的关键时访问设备,而访问设备中的关键时实现I/O端口的编码、指令实现等。I/O的编址的主要方式分为端口映射和内存映射。这两种映射的区别优劣势就不赘述了,在任意一本OS书上或者谷歌一下都可以。接下来进入正提。
NEMU设备
这里主要分析的是nemu/src/device/中的代码:
- mmio.c(内存映射IO)
- port-io.c(端口映射IO)
- device.c(提供初始化设备和控制函数)
- keyboard.c(键盘设备,这里模拟的是i8042)
- serial.c(串口设备模拟)
- timer.c(时钟设备)
- vga.c(模拟vga设备和功能)
功能实现
串口功能
需要实现in和out指令,这两个指令在system.c中
make_EHelper(in) {
// TODO();
switch(id_dest->width){
case 4: rtl_li(&t0, pio_read_l(id_src->val)); break;
case 2: rtl_li(&t0, pio_read_w(id_src->val)); break;
case 1: rtl_li(&t0, pio_read_b(id_src->val)); break;
}
operand_write(id_dest,&t0);
print_asm_template2(in);
#if defined(DIFF_TEST)
difftest_skip_ref();
#endif
}
make_EHelper(out) {
//TODO();
switch(id_dest->width){
case 4: pio_write_l(id_dest->val, id_src->val); break;
case 2: pio_write_w(id_dest->val, id_src->val); break;
case 1: pio_write_b(id_dest->val, id_src->val); break;
}
print_asm_template2(out);
#if defined(DIFF_TEST)
difftest_skip_ref();
#endif
}
实验结果
时钟功能
在完成了_DEVREG_TIMER_UPTIM方法后发生了个小bug,测试timetest时不报错,但是也米有输出。但是在native环境下是正常的:
但是在x86-nemu下会有不现实输出,接下来祭出我的输出检测大法!!
通过输入可以看出问题是程序运行后弹出界面,但是无法运行uptime函数,在界面退出后运行了一次uptime函数,然后直接结束了。这个问题我继续想办法解决。!!找到问题的原因了。。自己实现的_DEVREG_TIMER_UPTIM函数有问题,导致时钟一直读取不到!!!!被自己蠢哭了。
找到了问题就会很快解决啦。这两天工作有点忙,立下个flag,4月27号周六休息的时候争取给PA2画下个短暂的句号。
4月27日晚,先来填个坑,PA2已经实现,思路介绍后面有时间补更新。
先更新下跑分结果
跑分实验结果
emmmmm,我这个电脑好像太。。。。。太古老了,哈哈
key成功截图
vga成功截图
后续我会写一下完整的思路,做完PA2后尝试了下接下来的实验。感觉接下的实验难度开始提升了,自己需要好好总结思考下。