我正在制作一个命令行操作系统(命令行解释器)。如何从用户那里获得一行输入内容?
答案 0 :(得分:2)
我正在制作一个命令行操作系统。如何获得用户的输入行?
您首先需要的是一些启动代码(从固件获取诸如内存映射之类的东西),物理内存管理,虚拟内存管理,调度程序和某种进程间通信(IPC)。
接下来您需要的是某种设备枚举框架,以帮助创建一棵设备树来跟踪所有内容。然后扫描PCI总线以将它们添加到设备树中。
接下来,您将需要处理设备资源-确定IO端口范围,内存映射的IO范围和管理IRQ。这可能很麻烦(例如,用于ACPI的AML解释器来确定IO APIC输入,并使用“中断向量分配器”来处理MSI)。
接下来的事情是USB控制器驱动程序,USB集线器驱动程序,以及(对于过时的硬件)也许是PS / 2控制器驱动程序。这些都可以找到连接到它们的设备(例如USB键盘)并将它们添加到设备树中,然后与这些设备的驱动程序进行通信。在某些时候,您可能还需要担心容错能力,电源管理和热插拔(例如,如果USB控制器驱动程序崩溃,进入睡眠状态或被拔下/拔下;那么您将使用“设备树”来找出哪些其他驱动程序受到影响。
接下来,您需要键盘驱动程序。具体地说,是“ USB HID”(这是一个涵盖所有人类输入设备-键盘,鼠标,触摸板,操纵杆等的单一规范)的驱动程序,并且(对于过时的硬件)可能是PS / 2键盘驱动程序。请注意,您可能还需要一个用于触摸屏用户的屏幕键盘,以及一个或多个输入法编辑器,以协助某些语言(中文,日语,韩语等)的输入。
接下来,您将需要一些视频输出。通常,早期启动代码使用最少的“足以显示启动日志”代码(如果没有被漂亮的启动图像隐藏);但是您会想要一个实际上更好的东西(可能包括一个支持Unicode的字体引擎)。
上述所有操作的最终结果是,您将拥有一组(希望是“针对您的OS进行了标准化”并有文档说明)设备驱动程序接口以及设备驱动程序所依赖的所有内容;一种向进程发送“事件”(按键)的方法(我在开始时提到的进程间通信),以及一种用于显示输出(在屏幕上绘制内容)的方法。
完成所有操作后,您可以编写一个终端仿真层。这是一个东西(过程?),将所有漂亮的现代东西(例如OpenGL,事件)隐藏在一层历史性的纪念品下(这样,最终用户的计算机就可以模拟现实的虚拟现实环境了)从上世纪初开始就被用作美化的电传打印机)。这也使用了我在开始时提到的进程间通信(例如,管道-stdin,stdout)与子进程进行通信。
最后,您可以开始编写某种命令外壳。这只是一个通过其父进程(例如与终端仿真层)通信的过程。无论您用于进程间通信的任何内容(例如stdin,stdout)都允许用户启动其他进程并处理一些“转发”(例如,在子进程运行时,shell从终端仿真层接收的键盘输入都将被转发通过shell传递给它的子进程,然后shell从其子进程收到的输出被shell转发回shell的父/终端模拟器。
请注意,在编写命令外壳程序的一部分时,或者在编写命令外壳程序之前,您可能希望编写一些库来处理简单的杂务(例如,获取用户输入的全部内容并处理“ home”,“ end “,”删除“,”退格“等),以便所有程序(包括命令外壳本身)都可以使用这些库。
答案 1 :(得分:1)
您是否真的在实现一个操作系统似乎令人怀疑,但是如果您只是指一个 command shell ,那么它可能遵循以下结构:
int main()
{
char command_line[1024] ;
char* input = NULL ;
int errorlevel = 0 ;
do
{
// Show command prompt
putchar( '>' ) ;
fflush( stdout ) ;
// Get command line
input = fgets( command_line, stdin, sizeof(command_line) ) ;
if( input != NULL )
{
// Process command line
errorlevel = parseCommand( input, &errorlevel ) ;
}
} while( input != NULL ) ;
return errorlevel ;
}
其中parse parseCommand()
是具有以下接口的函数:
int parseCommand( const char* cmd_line, const int* current_errorlevel ) ;
fgets()
函数是您如何获得一行用户输入的问题的答案。
复杂的部分也许在于parseCommand()
的实现;用户输入是最简单的部分,但请先开始-玩得开心。
答案 2 :(得分:1)
不像每个人,我感谢您大胆地思考,但首先要关注基础知识,因为从小处着手很好。另外,您正在做的是制作命令行解释器,而不是操作系统。两者之间有很大差异。对于OS,您需要内核,GUI等。但是,这是查询的解决方案:
您可以使用gets,但此操作可能会收到警告
char *gets(char *str)
要克服上述限制,我们可以将fgets用作:
char *fgets(char *str, int size, FILE *stream)
在scanf中使用%[^ \ n]%* c
scanf(“%[^\n]%*c”, str);
使用for循环时,这一功能非常方便。
如果您进行创新思考,您将拥有光明的未来(人们对此缺乏信心)。 但是,在做大之前最好先刷基础。欢迎来到stackoverflow:)