Page 1 of 1
STDIO
Posted: Thu Dec 12, 2013 10:46 pm
by BMW
I have started thinking about implementing basic IO in my OS, with some of the stdio functions. I have a few questions about how IO is usually implemented.
I will be implementing simple console IO for a start and my questions will be based around this. For now I just want simple input and output with the console. What I want is for each process to run in its own console/terminal, which is a full screen 80x25 text mode display and I can switch between each processes console with a keyboard shortcut.
Therefore each console will need an output buffer to store the current console text which will be copied to the video memory when the console is switched to. I am planning to have this buffer stored in user space, so processes can write to it using functions such as putchar() and printf(), and it can be flushed to the video memory using fflush() or will be flushed automatically upon a newline character being output. Is this a usual way to do this? How would I set up the buffer? Would I set it up with an initialization routine that executes before the main() function (e.g. crt0.o)? How would the buffer location be known by the functions that use the buffer? Global variable?
And each process would have its own input buffer, stored in user space. The kernel knows the location of the active processes buffer and writes keyboard input to it. Processes read the input from this buffer using functions such as getchar(). Is this the usual or acceptable way to do it? What happens if the buffer is full and the process is ignoring input? Does old input get overwritten?
I want the IO system to be compatible with other forms of IO such as file IO later, so I will be using a FILE struct which represents an stdio stream.
Are there any parts or problems I have overlooked?
Re: STDIO
Posted: Fri Dec 13, 2013 5:34 pm
by skeen
I think this sounds quite good actually.
I'm doing something similar;
I spawn 'x' virtual terminals at boot up, each virtual terminal opens stdio and stdout to the multiplexer terminal, for reading a writing and writing, by default. The multiplexer terminal, is the only terminal to have access to the physical terminal device, and selects the active virtual terminal (which gets the write the physical terminal, and gets to read from it). That is the multiplexer terminal is in essence nothing, but a multiplexer for mapping multiple virtual terminals to a single physical.
The physical terminal writes to the textmode screen output (which invokes the text screen driver), and reads from the keyboard buffer (which is written to by the keyboard driver).
This allows a decoupling like you suggest, virtual terminals can be created on request, and possibly be unmapped (for background tasks and such). The multiplexer terminal can be toggled to the next virtual terminal by using the function keys in my solution.
The keyboard buffer is indeed limited in size, and if its full when new key inputs come in, then these new inputs are discarded. This should however almost never be the case, as the physical terminal should be reading the keyboard buffer almost all the time.
Disclaimer; I'm building a microkernel and hence there's a lot more decoupling then one may think that there should be, and a lot of separate components can without a doubt be merged.
Edit; I wanted to all that, all these components except from the driver are user space services.
Edit2; The way I setup my system is, such that the terminals are running beforehand, or created before the program starts, when a program is to be created, it's passed it's corresponding terminal file node, which crt0 takes care of opening as stdin / stdout / stderr.
Re: STDIO
Posted: Sat Dec 14, 2013 12:00 pm
by Geri
i will implement it to stdio functions be directly part of the application itself, to compile them together. only necessary functions will be compiled in, others will be stripped out. it does not significantly incrases the executable size, most stdio function can implemented very easily just from 10-20 line of c code.
Re: STDIO
Posted: Sat Dec 14, 2013 12:08 pm
by BMW
skeen wrote:I think this sounds quite good actually.
I'm doing something similar;
I spawn 'x' virtual terminals at boot up, each virtual terminal opens stdio and stdout to the multiplexer terminal, for reading a writing and writing, by default. The multiplexer terminal, is the only terminal to have access to the physical terminal device, and selects the active virtual terminal (which gets the write the physical terminal, and gets to read from it). That is the multiplexer terminal is in essence nothing, but a multiplexer for mapping multiple virtual terminals to a single physical.
The physical terminal writes to the textmode screen output (which invokes the text screen driver), and reads from the keyboard buffer (which is written to by the keyboard driver).
This allows a decoupling like you suggest, virtual terminals can be created on request, and possibly be unmapped (for background tasks and such). The multiplexer terminal can be toggled to the next virtual terminal by using the function keys in my solution.
The keyboard buffer is indeed limited in size, and if its full when new key inputs come in, then these new inputs are discarded. This should however almost never be the case, as the physical terminal should be reading the keyboard buffer almost all the time.
Disclaimer; I'm building a microkernel and hence there's a lot more decoupling then one may think that there should be, and a lot of separate components can without a doubt be merged.
Edit; I wanted to all that, all these components except from the driver are user space services.
Edit2; The way I setup my system is, such that the terminals are running beforehand, or created before the program starts, when a program is to be created, it's passed it's corresponding terminal file node, which crt0 takes care of opening as stdin / stdout / stderr.
Thanks!
So does the multiplexer terminal have direct access to the text mode video memory, or does it print its buffer using system calls?
Re: STDIO
Posted: Sat Dec 14, 2013 2:19 pm
by skeen
The multiplexer terminal is just another process, which just happens to have the sufficient permissions to open the physical terminal file node, for reading and writing.
The physical terminal is just another process, which just happens to have the sufficient permissions to open the keyboard buffer and screen service file nodes.
The keyboard buffer is just another process, which the keyboard driver sends non-blocking messages to, whenever a key is pressed.
The screen service is just another process, which handles actually outputting the input to the driver.
That is, everything is tied together using pipes, which are implemented using message passing, my only syscalls are send and receive (and sendrecv).
Again, you'll likely want something simpler, my over usage of decoupling is by design.
Re: STDIO
Posted: Sat Dec 14, 2013 2:32 pm
by skeen
A simple way to get io implemented however, is to build newlib and fill in the stubs in libgloss.
What you could do, is to simply have whatever passed to the write function of libgloss, be written to the screen. Ignoring the file descriptors for now, and with them, ignoring open, fstat, close and such. And have each read call try to read the keyboard buffer.
This is how I got my first to implemented. Writing to the screen and reading the kernel space keyboard buffer using sys calls. Then I went on to implement my VFS, and actually implement the libgloss stubs, by having a sys call in each stub.
To keep the functionality I had, I simply kept my old code in there, with an added condition on the file descriptor id (0-2 are mapped for stdio). - when I had the time I implemented the character devices for keyboard and screen, and I removed that hacky bit of code, with regular general file operation code, which however forces me to open stdio files in crt0.
Then I moved on to break the system, literally into bits, by decoupling the parts.
Re: STDIO
Posted: Sat Dec 14, 2013 8:29 pm
by BMW
So would the idea detailed in my first post (maybe with a few tweaks) be good?
Re: STDIO
Posted: Mon Dec 16, 2013 9:12 am
by skeen
Whether an idea is good or bad, is a very subjective measure.
In my book, the way to go, is to try the idea, and figure for one self if it's good or bad idea one had.