开始GeekOS之旅了, What 's the next Step ? 不急,阅读下GeekOS自带的手册.
Introduction:
GeekOS is an educational operating system kernel.GeekOS tries to combine realism and simplicity. It is a realisticsystem because it targets a real hardware platform - the x86 PC.It strives for simplicitly in that it contains the bare minimum functionalitynecessary to provide the services of a modern operating system,such as virtual memory, a filesystem, and interprocess communication.
Overview of GeekOS
1.Memory
2.Interrupts and Threads
3.Devices
上面三个是重点,你需要去了解并深入. 因为下面的Project肯定会cover.
Project0
稍微了解了下GeekOS, 下面正式进入Project0
Project0会相对比较简单,因为它只是引导你入门GeekOS!
->目标 : 首先你需要添加个内核线程来向屏幕上输出"Hello from XXX" (xxx is your name),接着读取键盘的输入并回车后回显到屏幕上,除非你使用C-d来结束它! 就这么简单.
..来看下未解决之前的bochs的界面:
既然需要创建个内核模式的线程,就要读下它的关于线程的代码 src/geekos/kthread.c
大概浏览了下这个文件的代码,先不研究细节,直接找我们需要的函数, 我们需要一个创建的线程能够回调我们自定义的函数,根据这点,可以找到这么个函数
starut Kernel_Thread* Start_Kernel_Thread(Thread_Start_Func startFunc, ulong_t arg, int priority, bool detached);
上面是个函数原型,在这个函数上面有这个函数的参数解释:
startFunc: 这是回调函数入口
arg: 上面注解是 is pass to the new function,没看懂 先pass
priority: 这个按照字面就可以理解成 线程优先级了. 大部分可以设置为 PRIORITY_NORMAL
detached: 对于kernel threads 请传入false
依次看下来 也就第二个参数不解了,没事 我们找找看是否这个创建线程的函数是否被调用过, good, 在 448行被调用了
Start_Kernel_Thread(Repear, 0, PRIORITY_NORMAL, true);
既然它第二个参数传入0 ,那我们也传入0 !
我们先完成它这个任务的第一部分(输出Hello from Crazybaby),虽然很简单,但是Step by Step. 毕竟头脑堆栈有限. 呵呵!
关键代码如下:
25 void GoForIt(){
26 Print("Hello from Crazybaby\n");
27 }
52 Start_Kernel_Thread(GoForIt, 0, PRIORITY_NORMAL, false);
53
54 // TODO("Start a kernel thread to echo pressed keys and print counts");
虽然代码简单,这里有两点要注意:
1.GeekOS的打印需要用Print 因为它是个独立的OS 使用的是自身的lib!
2.第二段代码有个TODO, 虽然放在那是可以的, 因为我们是开启线程来打印的, 但是那么多字打印出来实在不雅 ,所以我们可以选择的把它注释掉. 第一次效果如下:
下面我们继续完成第二部分,读入输入的字符并回显 !
心想这还不easy, 谁知,自己滴滴嗒嗒写完 发现, 编译不支持 getchar 之类的函数
undefined reference to `getchar'
make: *** [geekos/kernel.exe] Error 1
唉 刚才还说了自己都忘了. 那就还是寻找 GeekOS提供的函数吧 !
看了下geekos下面的源文件, 文件很少 所以可以很快定位到 keyboard.c
根据每个函数头部的解释可以在文件最下面找到 Wait_For_Key 这个函数.
看下原型:
Keycode Wait_For_Key(void)
输入参数为 void , 不考虑
输出参数为 Keycode ,可以看一下Keycode的声明,用Vim定位了下KeyCode 没有在本文件中找到, 然后看下头文件发现是在 keyboard.h下. 找到
typdef ushort_t Keycode.
是个无符号short类型. 下面来看下程序简单流程图:
我们还需要 识别回车 和 C-d 这两个"信号"
剩下的就要靠下面这个大数组了:
首先判断C-d , (KEY_CTRL_FLAG | 0x64 ) == kecode
再判断 是否回车 13 == keyCode
还需要判断 键是否已经release 不然 你按下的时候已经上屏 松开又上屏一次!
下面是详细代码:
25 void GoForIt(){
26 Print("Hello from Crazybaby\n");
27 Keycode ret;
28 while (1) {
29 ret = Wait_For_Key();
30 if (!(ret & KEY_RELEASE_FLAG)) {
31 if ((KEY_CTRL_FLAG | 0x64) == ret) {
32 Print("%s\n", "GeekOS's Project0 is over!");.
33 break;
34 }
35 if (13 != ret) {
36 Print("%c", ret);
37 }
38 else
39 {
40 Print("\n");
41 }
42 }
43 }
44 }
测试结果:
Ok ,继续第二个Project!
原文链接: http://blog.csdn.net/crazyjixiang/article/details/6849353