Page 1 of 1

Creating a kernel command line

Posted: Fri Oct 24, 2008 6:30 am
by ScorchOS
I'm new to these forums - be gentle ;)

I'm currently developing an operating system built on bkerndev (with some snippets from MikeOS), and I'm currently trying to modify the OS to support command line input.

I have created a file name 'cli.c' with a void function named 'cli_handle_string' which is linked at compile time and referenced from system.h.

The references are ok, but the problem I'm having is with an IF() function I've added to the keyboard driver. I am trying to get it so that when a user presses enter their input is sent as a string to the command handler. Any other characters are added to a string (I will refine this later!). At the moment enter does take you to the CLI function - but so does every other key! Does anyone know how I could distinguish 'enter' from the other characters - I have tried several ways. Here's some code:

Code: Select all

/* Handles the keyboard interrupt */
void keyboard_handler(struct regs *r)
{
    unsigned char scancode;	/* Holds scancode later */
    char *commandString;	/* This string will hold the command to be sent to the function */
    int cmd = 0;	/* This is the handler variable for me to add characters to the string */

    /* Read from the keyboard's data buffer */
    scancode = inportb(0x60);
    /* If the top bit of the byte we read from the keyboard is
    *  set, that means that a key has just been released */
    if (scancode & 0x80)
    {
        /* You can use this one to see if the user released the
        *  shift, alt, or control keys... */
    }
    else
    {
        /* Here, a key was just pressed. Please note that if you
        *  hold a key down, you will get repeated key press
        *  interrupts. */

        /* Just to show you how this works, we simply translate
        *  the keyboard scancode into an ASCII value, and then
        *  display it to the screen. You can get creative and
        *  use some flags to see if a shift is pressed and use a
        *  different layout, or you can add another 128 entries
        *  to the above layout to correspond to 'shift' being
        *  held. If shift is held using the larger lookup table,
        *  you would add 128 to the scancode when you look for it */
	if (kbdus[scancode]='\n') /* I have also tried other methods of checking, such as 'scancode = x', where 'x' is a Carriage Return or Newline scancode in hex) */
	{
		cli_handle_string(commandString);	/* if enter is pressed, send the command string to the CLI handler */
	}
	else 
	{
        	putch(kbdus[scancode]);			/* else, business as usual... */
		commandString[cmd] = kbdus[scancode];	/* add character to string - or array if you like! */
		cmd++;					/* increment my char array handler */
	}
    }
}

kbdus is the function to convert a scan code to an ASCII character.

Thanks in advance ;)

Re: Creating a kernel command line

Posted: Fri Oct 24, 2008 6:44 am
by Velko
There's a bug in your code.

Code: Select all

-   if (kbdus[scancode]='\n')
+   if (kbdus[scancode]=='\n') 

Re: Creating a kernel command line

Posted: Fri Oct 24, 2008 7:07 am
by ScorchOS
Thanks for your help! =D>

(I'm gutted it's something that simple that was tripping me up!)

Re: Creating a kernel command line

Posted: Fri Oct 24, 2008 7:49 am
by Brendan
Hi,
apolloopsys wrote:I'm new to these forums - be gentle ;)
Where I live, there's a saying - "Sometimes, you need to be cruel to be kind". I could be gentle, and you could spend the next 5 years working on a dead end. Alternatively I could be cruel, and you might spend the next 5 years working on something brilliant. If I hated you I'd be very gentle and maybe even give you praise (and then spend the next 5 years laughing at you). I don't know enough about you to dislike you so I'll be nice to you (and be little cruel in the hope of helping you to avoid wasting the next 5 years or so)... ;)
apolloopsys wrote:I'm currently developing an operating system built on bkerndev
That's a bad start - tutorial code is typically intended to illustrate specific concepts in an easily understood way, and typically isn't intended to be a viable OS design that an actual OS can be built from.
apolloopsys wrote:The references are ok, but the problem I'm having is with an IF() function I've added to the keyboard driver. I am trying to get it so that when a user presses enter their input is sent as a string to the command handler.
That tells me that you haven't got any keyboard driver interface, and haven't got any virtual terminal support.
apolloopsys wrote:

Code: Select all

/* Handles the keyboard interrupt */
The keyboard handler code tells me you haven't got a useful keyboard driver (which is needed to have a working keyboard driver interface, which is needed to have virtual terminal support, which is needed before you write any application including a command line interpreter).

My advice is to forget about writing a command line interpreter for at least 6 months. It's a waste of time until you've got code to build the command line interpreter on top of.

Start with inter-process communication (IPC). Will you use (synchronous or asynchronous) messaging, RPC, pipes, sockets, raw shared memory buffers, or something else? Do some research, make a decision, document how it's meant to work, then implement it, then test it (and fix it).

Now design an initial video driver interface. It receives data or commands or something (using the IPC you implemented) and then does whatever. It could be something as simple as receiving strings of ASCII (or maybe a protocol like VT100?) and displaying them on the screen. It could be a "text mode framebuffer only" video driver or something that handles full 3D and Unicode or something else. Do some research, make a decision, document how it's meant to work, then implement it, then test it (and fix it).

Next, do the same for your keyboard device driver interface. It sends commands or something (using the IPC you implemented) to something else. It could be something as simple as sending ASCII characters only (with no support for keycodes, control/alt/shift states, etc). Do some research, make a decision, document how it's meant to work, then implement it, then test it (and fix it).

Once these things are done you'll need some sort of virtual terminal support. It receives stuff from the keyboard (and mouse, and joystick, and touchscreen, and microphone, etc), processes it (maybe) and forwards it to the currently active application (or the currently active process, or the active window or whatever). It also receives stuff from the applications, processes it (maybe) and forwards it to the video driver (and the sound driver or sound mixer, maybe). I don't care if it's a simple thing (e.g. something that only deals with ASCII data) or something that supports multiple virtual terminals (and foreground/background jobs, and/or "alt+tab", etc) or a full GUI style thing, or something else. Do some research, make a decision, document how it's meant to work, then implement it, then test it (and fix it).

After all of this is done, you'll have some sort of document that describes how applications get key presses (and maybe data from the mouse, joystick, touchscreen, etc) from the virtual terminal layer (or the GUI, or whatever) and how they send video data (and maybe sound data, etc) to the virtual terminal layer (or the GUI, or whatever); and the virtual terminal layer (or whatever) will do the rest.

After all of this is done (and NOT before), you'll have something you can start writing your command line interpreter on top of. The command line interpreter talks to the virtual terminal layer (or GUI or whatever) - it should never talks directly to any device driver, and you definitely shouldn't need to insert pieces of the command line interpreter into a device driver's IRQ handler.


Cheers,

Brendan

Re: Creating a kernel command line

Posted: Fri Oct 24, 2008 3:26 pm
by ScorchOS
Where I live, there's a saying - "Sometimes, you need to be cruel to be kind". I could be gentle, and you could spend the next 5 years working on a dead end. Alternatively I could be cruel, and you might spend the next 5 years working on something brilliant. If I hated you I'd be very gentle and maybe even give you praise (and then spend the next 5 years laughing at you). I don't know enough about you to dislike you so I'll be nice to you (and be little cruel in the hope of helping you to avoid wasting the next 5 years or so)... ;)
I said 'be gentle' initially as a joke, as I've been in enough flame wars to know how ironic the statement is - but I appreciate the sentiment, and thank you for your help ;)

apolloopsys wrote:I'm currently developing an operating system built on bkerndev
brandon wrote: That's a bad start - tutorial code is typically intended to illustrate specific concepts in an easily understood way, and typically isn't intended to be a viable OS design that an actual OS can be built from.
The first few versions of my operating system were just going to be enhancements of a tutorial OS so I learn about implementing the theory I learn with a platform I understand.
Tutorial OS's are (by definition) there to teach, so I will only be using the code for as long as it continues to have an educational value to me. I understand that if I want to create a kernel worthy of respect I will need to break away from it and create something myself.
apolloopsys wrote:The references are ok, but the problem I'm having is with an IF() function I've added to the keyboard driver. I am trying to get it so that when a user presses enter their input is sent as a string to the command handler.
brandon wrote:That tells me that you haven't got any keyboard driver interface, and haven't got any virtual terminal support.
You would be correct. As 0.1 would be my first release I just wanted something that worked. What I was doing is using the 'kb.c' as a terminal keyboard driver, with the idea of using another one for apps/actual input. If you press enter you get sent to a function in cli.c, which parses a text string (for commands and parentheses) and runs the relevant function from a case statement (using the parentheses as parameters). There was even scope for a bit of multi-user support, but that would be more cosmetic than functional at this stage.

I accept that this is not the most elegant solution (as it communicates directly with drivers), and based on your advice on the following section I will be going back to the drawing board.
apolloopsys wrote:

Code: Select all

/* Handles the keyboard interrupt */
brandon wrote:The keyboard handler code tells me you haven't got a useful keyboard driver (which is needed to have a working keyboard driver interface, which is needed to have virtual terminal support, which is needed before you write any application including a command line interpreter).

My advice is to forget about writing a command line interpreter for at least 6 months. It's a waste of time until you've got code to build the command line interpreter on top of.

Start with inter-process communication (IPC). Will you use (synchronous or asynchronous) messaging, RPC, pipes, sockets, raw shared memory buffers, or something else? Do some research, make a decision, document how it's meant to work, then implement it, then test it (and fix it).

Now design an initial video driver interface. It receives data or commands or something (using the IPC you implemented) and then does whatever. It could be something as simple as receiving strings of ASCII (or maybe a protocol like VT100?) and displaying them on the screen. It could be a "text mode framebuffer only" video driver or something that handles full 3D and Unicode or something else. Do some research, make a decision, document how it's meant to work, then implement it, then test it (and fix it).

Next, do the same for your keyboard device driver interface. It sends commands or something (using the IPC you implemented) to something else. It could be something as simple as sending ASCII characters only (with no support for keycodes, control/alt/shift states, etc). Do some research, make a decision, document how it's meant to work, then implement it, then test it (and fix it).

Once these things are done you'll need some sort of virtual terminal support. It receives stuff from the keyboard (and mouse, and joystick, and touchscreen, and microphone, etc), processes it (maybe) and forwards it to the currently active application (or the currently active process, or the active window or whatever). It also receives stuff from the applications, processes it (maybe) and forwards it to the video driver (and the sound driver or sound mixer, maybe). I don't care if it's a simple thing (e.g. something that only deals with ASCII data) or something that supports multiple virtual terminals (and foreground/background jobs, and/or "alt+tab", etc) or a full GUI style thing, or something else. Do some research, make a decision, document how it's meant to work, then implement it, then test it (and fix it).

After all of this is done, you'll have some sort of document that describes how applications get key presses (and maybe data from the mouse, joystick, touchscreen, etc) from the virtual terminal layer (or the GUI, or whatever) and how they send video data (and maybe sound data, etc) to the virtual terminal layer (or the GUI, or whatever); and the virtual terminal layer (or whatever) will do the rest.

After all of this is done (and NOT before), you'll have something you can start writing your command line interpreter on top of. The command line interpreter talks to the virtual terminal layer (or GUI or whatever) - it should never talks directly to any device driver, and you definitely shouldn't need to insert pieces of the command line interpreter into a device driver's IRQ handler.


Cheers,

Brendan
Ok, you've convinced me! Perhaps I can experiment a little with bkerndev, but if I'm serious about this I need to do a lot more thinking about my kernel and I will follow the steps you outlined above. I am taking ApolloOS back to the drawing board so I produce something worth a second glance. :)

I understand that kernel development is very demanding and time-consuming, but creating something that works of this complexity is always going to be rewarding. I came to this project with the aim of learning how kernels (and indeed computer systems) work at a fundamental level, and I can see that I have plenty to learn!

Re: Creating a kernel command line

Posted: Sat Oct 25, 2008 7:30 am
by Combuster
Euhm Brandon F. is a totally different person than Brendan

IMO you're giving the former too much credit :)

Re: Creating a kernel command line

Posted: Sat Oct 25, 2008 4:02 pm
by ScorchOS
lol - I had actually made that mistake! :D

But all the same, his words do show some wisdom. I'll take a look at virtual terminals anyway (as hardware abstraction is still kind of important), and I was considering a complete code rewrite of ApolloOS for V.0.5 anyway - so it provides a good opportunity to consider how I want my kernel to work.

Re: Creating a kernel command line

Posted: Fri Oct 31, 2008 4:25 am
by negcit.K
I have not been here for a long time.
AND ,
Brendan wrote:Hi,
apolloopsys wrote:I'm new to these forums - be gentle ;)
Where I live, there's a saying - "Sometimes, you need to be cruel to be kind". I could be gentle, and you could spend the next 5 years working on a dead end. Alternatively I could be cruel, and you might spend the next 5 years working on something brilliant. If I hated you I'd be very gentle and maybe even give you praise (and then spend the next 5 years laughing at you). I don't know enough about you to dislike you so I'll be nice to you (and be little cruel in the hope of helping you to avoid wasting the next 5 years or so)... ;)
.........
Brendan
That's teach me a lot ! :D

Re: Creating a kernel command line

Posted: Thu Nov 13, 2008 4:16 am
by ScorchOS
Ok, I'm now writing a virtual terminal. I have an additional module named 'vterm.c' which slowly builds user input into a string. When the user presses enter it runs a string parse function. This seperates the command into one string (or character array) and any parentheses into another one (there is also a function to seperate parentheses).

I'm currently writing a command interpretter and some sample commands such as 'help' and a 'login user' and 'logout' commands (depending on which user you login depends on whether you can run 'example' - but I won't be adding password authentication just yet). There may also be one such as 'output msg' which would display 'msg' on the next line. It's not overly useful, but means that we finally have some obvious I/O going on!

This is just the pre-work for when I've built a floppy driver, so there should be some file handling routines and scope for running Apps - however it will take a few months development work to get to where I want to be (even with the interesting improvements/patches I've recieved from people!).

And yes, I took the advice and taken a look at how the kernel should work. There have been plenty of changes as a result, and Version 0.0.7 promises to be an interesting release (floppy support will start in version 0.0.8 ).

Re: Creating a kernel command line

Posted: Thu Nov 13, 2008 11:22 am
by eddyb

Code: Select all

    char *commandString;   /* This string will hold the command to be sent to the function */
    int cmd = 0;   /* This is the handler variable for me to add characters to the string */
That should go outside of the function, because they won't be stored...

Re: Creating a kernel command line

Posted: Fri Nov 14, 2008 9:01 pm
by Troy Martin
Well done apollo, the CLI is important!

For your sake I hope you've implemented a strncmp as well as strcmp so you can do a simple argument parsing system.

Re: Creating a kernel command line

Posted: Sun Jan 18, 2009 2:01 pm
by ScorchOS
Thanks for your replies (as you can tell by the long delay I've been hard at work on the CLI - the latest source is available via our SVN repo at http://code.google.com/apolloos (or via http://apolloopsys.googlepages.com/apollodev.zip for the absolute latest).

I'm currently ammending the code to work a bit more like strncmp - I've spent a lot of time trying to get it working with variable-sized strings which has resulted with code that mostly works but is a pain when you're parsing for parentheses. On top of that, I'm hoping to lose the need for NASM later (you can compile Intel syntax assembler using gcc, and once this is written into the build scripts then users of Unix environments such as Mac OSX, BSD and openSolaris will find life a lot easier!). Once this is sorted we'll have ApolloOS 0.0.7 as a release! I must spend less time working and studying....! lol :D