要求:实现一个内核进程
功能:实现从键盘接收一个按键,并在屏幕上显示
一般执行操作:(若有权限限制问题,输出前带上sudo)
1、在~/project0/build下编写bochsrc配置文件
2、(可多一步骤,清除缓存,make clean)生成系统镜像文件,make depend
3、编译,make
4、运行镜像文件,bochs -f bochsrc(有的是直接可以bochs)
编写代码环节:
1、改写~project0/src/geekoc中的main.c文件
实现从键盘接收一个按键,并在屏幕上显示的功能
void project0(){
Print("Exit hit Ctrl +D.\n"); //提示语句
Keycode keycode;
while(1){
if(Read_Key(&keycode)) { //读取键盘按键状态
if(!((keycode & KEY_SPECIAL_FLAG) || (keycode & KEY_RELEASE_FLAG))) {
int asciiCode = keycode & 0xff;
if((keycode & KEY_CTRL_FLAG)==KEY_CTRL_FLAG && asciiCode=='d') {//按下CTRL +D后退出
Print("\n---------SEE YOU!--------\n");
Exit(1);
}
else {//不是CTRL +D则输出字符
Print("%c",(asciiCode=='\r') ? '\n' :keycode);
}
}
}
}
}
并创建线程
struct Kernel_Thread *thread = Start_Kernel_Thread(&project0, 0 , PRIORITY_NORMAL, false);
最后,保存,并按照执行操作顺序,即可实现(有问题就是配置makefile内容或者版本不兼容的问题)
原理探究
geekos-0.3.0在~src/geekos下有文件Keyboard.c
其自带键盘初始化函数——Init_Keyboard,为设置初始化状态下存放键盘扫描码的缓冲区,并为键盘中断设置处理函数。(清零,建立缓冲队列,处理中断)
键盘中断处理函数——Keyboard_Interrupt_Handler,读取键盘扫描码,寻找对应的按键值,放入缓冲区(根据键盘扫描码,寻找按下的按键值)
geekos-0.3.0在~src/geekos下有文件irq.c
函数——Set_IRQ_Mask(irqMask),在按键按下或者松开都会产生扫描码
用户进程从键盘输入信息后,经等待函数进入按键操作等待队列,直至按键操作结束,进程才被唤醒
函数project0():
Keycode是按键键盘码,判断其是否为特殊键(crly\shift/alt等特殊键)或者释放按键(即:松开键盘),若不是则保存,并显示输出,一直到键盘码为crlt+d的按键键盘码后退出进程。
调用Start_ Kernel_ Thread 函数,将编写的地址传递,即:&project0(取地址符加函数名)。
附加说明:
Start_Kernel_Thread函数的结构体:
struct Kernel_Thread* Start_Kernel_Thread(
Thread_Start_Func startFunc, //线程函数地址
ulong_t arg, //线程函数参数
int priority, //优先级
bool detached //线程属性,false为内核线程,true为用户线程
);
参考文献