我目前正在开发我的操作系统。我从前一天开始建造它。我的操作系统是基于命令的。
这是我的Kernel.c(主文件):
#include "include/screen.h"
#include "include/kb.h"
#include "include/string.h"
#include "data/userdata.c"
kmain()
{
clearScreen();
print("Halcyon OS 1.05 Beta ");
while (1)
{
print("\nhalcyon@halcyon ~\n$ ");
string ch = readStr();
if(strEql(ch,"cmd")!=0)
{
print("\nYou are already in cmd\n");
}
else if(strEql(ch,"clear")!=0)
{
clearScreen();
}
else if(strEql(ch,"help")!=0)
{
print("Halcyon help.");
}
else if(strEql(ch,"")!=0)
{
continue;
}
else
{
print("\nNo command found:");print(ch);
break;
}
}// end while loop!
}
这是kb.h(我已经为键盘支持了。):
#ifndef KB_H
#define KB_H
#include "screen.h"
#include "system.h"
#include "types.h"
string readStr()
{
char buff;
string buffstr;
uint8 i = 0;
uint8 reading = 1;
while(reading)
{
if(inportb(0x64) & 0x1)
{
switch(inportb(0x60))
{
/*case 1:
printch('(char)27); Escape button
buffstr[i] = (char)27;
i++;
break;*/
case 2:
printch('1');
buffstr[i] = '1';
i++;
break;
case 3:
printch('2');
buffstr[i] = '2';
i++;
break;
case 4:
printch('3');
buffstr[i] = '3';
i++;
break;
case 5:
printch('4');
buffstr[i] = '4';
i++;
break;
case 6:
printch('5');
buffstr[i] = '5';
i++;
break;
case 7:
printch('6');
buffstr[i] = '6';
i++;
break;
case 8:
printch('7');
buffstr[i] = '7';
i++;
break;
case 9:
printch('8');
buffstr[i] = '8';
i++;
break;
case 10:
printch('9');
buffstr[i] = '9';
i++;
break;
case 11:
printch('0');
buffstr[i] = '0';
i++;
break;
case 12:
printch('-');
buffstr[i] = '-';
i++;
break;
case 13:
printch('=');
buffstr[i] = '=';
i++;
break;
case 14:
printch('\b');
i--;
buffstr[i] = 0;
break;
/* case 15:
printch('\t'); Tab button
buffstr[i] = '\t';
i++;
break;*/
case 16:
printch('q');
buffstr[i] = 'q';
i++;
break;
case 17:
printch('w');
buffstr[i] = 'w';
i++;
break;
case 18:
printch('e');
buffstr[i] = 'e';
i++;
break;
case 19:
printch('r');
buffstr[i] = 'r';
i++;
break;
case 20:
printch('t');
buffstr[i] = 't';
i++;
break;
case 21:
printch('y');
buffstr[i] = 'y';
i++;
break;
case 22:
printch('u');
buffstr[i] = 'u';
i++;
break;
case 23:
printch('i');
buffstr[i] = 'i';
i++;
break;
case 24:
printch('o');
buffstr[i] = 'o';
i++;
break;
case 25:
printch('p');
buffstr[i] = 'p';
i++;
break;
case 26:
printch('[');
buffstr[i] = '[';
i++;
break;
case 27:
printch(']');
buffstr[i] = ']';
i++;
break;
case 28:
// printch('\n');
// buffstr[i] = '\n';
i++;
reading = 0;
break;
/* case 29:
printch('q'); Left Control
buffstr[i] = 'q';
i++;
break;*/
case 30:
printch('a');
buffstr[i] = 'a';
i++;
break;
case 31:
printch('s');
buffstr[i] = 's';
i++;
break;
case 32:
printch('d');
buffstr[i] = 'd';
i++;
break;
case 33:
printch('f');
buffstr[i] = 'f';
i++;
break;
case 34:
printch('g');
buffstr[i] = 'g';
i++;
break;
case 35:
printch('h');
buffstr[i] = 'h';
i++;
break;
case 36:
printch('j');
buffstr[i] = 'j';
i++;
break;
case 37:
printch('k');
buffstr[i] = 'k';
i++;
break;
case 38:
printch('l');
buffstr[i] = 'l';
i++;
break;
case 39:
printch(';');
buffstr[i] = ';';
i++;
break;
case 40:
printch((char)44); // Single quote (')
buffstr[i] = (char)44;
i++;
break;
case 41:
printch((char)44); // Back tick (`)
buffstr[i] = (char)44;
i++;
break;
/* case 42: Left shift
printch('q');
buffstr[i] = 'q';
i++;
break;
case 43: \ (< for somekeyboards)
printch((char)92);
buffstr[i] = 'q';
i++;
break;*/
case 44:
printch('z');
buffstr[i] = 'z';
i++;
break;
case 45:
printch('x');
buffstr[i] = 'x';
i++;
break;
case 46:
printch('c');
buffstr[i] = 'c';
i++;
break;
case 47:
printch('v');
buffstr[i] = 'v';
i++;
break;
case 48:
printch('b');
buffstr[i] = 'b';
i++;
break;
case 49:
printch('n');
buffstr[i] = 'n';
i++;
break;
case 50:
printch('m');
buffstr[i] = 'm';
i++;
break;
case 51:
printch(',');
buffstr[i] = ',';
i++;
break;
case 52:
printch('.');
buffstr[i] = '.';
i++;
break;
case 53:
printch('/');
buffstr[i] = '/';
i++;
break;
case 54:
printch('.');
buffstr[i] = '.';
i++;
break;
case 55:
printch('/');
buffstr[i] = '/';
i++;
break;
/*case 56:
printch(' '); Right shift
buffstr[i] = ' ';
i++;
break;*/
case 57:
printch(' ');
buffstr[i] = ' ';
i++;
break;
}
}
}
buffstr[i] = 0;
return buffstr;
}
#endif
最后是string.h(这个函数可以比较两个字符串。):
#ifndef STRING_H
#define STRING_H
#include "types.h"
uint16 strlength(string ch)
{
uint16 i = 1;
while(ch[i++]);
return --i;
}
uint8 strEql(string ch1,string ch2)
{
uint8 result = 1;
uint8 size = strlength(ch1);
if(size != strlength(ch2)) result =0;
else
{
uint8 i = 0;
for(i;i<=size;i++)
{
if(ch1[i] != ch2[i]) result = 0;
}
}
return result;
}
#endif
但问题是,即使输入像'cmd'这样的正确命令,它有时只会说'找不到命令:cm',有时它会起作用!它有时是正确的并说:'你已经在cmd了!'
此外,它将'cm'识别为'cmd'。
如果我在kernel.c中写道:“print(”Hello“);”那么它会打印出来:'地狱'不是'你好'!它错过了最后一个角色。
我不知道我的程序有什么问题。 我使用gcc编译它,平台是Linux Ubuntu。有时工作,有时不工作。但是如果我用Windows编译我的内核,命令永远不会起作用。
请帮忙!任何帮助将不胜感激。
答案 0 :(得分:2)
您的字符串长度函数错误:
uint16 strlength(string ch)
{
uint16 i = 1;
while(ch[i++]);
return --i;
}
假设字符串为&#34; cmd&#34;,则启动并检查第二个字符m
是否为空,然后是第三个字符,然后最后第四个字符为空。 i
从1开始,最多增加到3,最后减少到2。
它也会在零长度字符串上失败。
结果是,您的打印功能打印不够。
unit16 strlength(string ch) {
unit16 l = 0;
while (ch[l]) {
++l;
}
return l;
}
要找出比较失败的原因,我需要知道string
实际上是什么类型。
如果它是char *
,那么这实际上是未定义的行为,就像你写入一些随机存储器一样。
如果它是一个char [N]
,那么它也不会工作,因为该数组会在返回时衰减为指针。并且该指针指向具有自动存储的局部变量,因此在函数返回后它不再有效。
好的,它是一个指针。指针指向内存,然后存储实际数据。要使这项工作,你需要
通常会通过malloc
分配内存,但在操作系统开发的上下文中,您首先必须自己实现。
您在调用者中使用具有自动存储(在堆栈上)的缓冲区:
char buffer[20];
size_t num_read = read_into(buffer, 20);
// pass the pointer to the memory for the data plus the maximal characters this buffer can hold.
size_t read_into (char * buffer, size_t max) {
// read up to Max characters into the
// buffer, don't forget to count the 0 at the end.
}
从你的其余代码来看,你似乎对C编程来说还是个新手。编写操作系统内核是一项有趣的任务,在您首先理解基础知识时,您将会有更多的乐趣。
由于您使用未初始化的char *
写入随机存储位置,因此您不知道存储数据的位置。这可能是&#34;正常&#34;,空闲记忆。然后一切都会按预期工作。但是你也可以写入内存映射设备信息甚至你自己的代码,这使得无法预测会发生什么。