Page 1 of 1
Help With Keyboard Input
Posted: Sun Aug 19, 2007 3:49 pm
by pcmattman
My kernel is now a microkernel, and I've become stuck when I try to get user input in a userland process. The problem is, to read from the keyboard I need to use an IRQ, and I haven't yet figured out how to make IRQs work for userland processes (ie. a network card driver can't just ask to be notified whenever its IRQ fires) so there is no userland driver for the keyboard.
Now, whenever I call the 'read' function for stdin (which resides in kernel space and is hence called via a syscall), I must enable interrupts to let the keyboard IRQ fire. Unfortunately, this causes a GPF.
If I just put some data into the string passed and then return, it's corrupted when it gets displayed.
Any ideas?
Posted: Sun Aug 19, 2007 11:57 pm
by os64dev
you don't enable interrupts for userland processes unless you are writing an exo-kernel i guess. Normally with micro-kernels youre kernel will catch the input and sends a message to the active window(thread). So if you create a message queue for each process then you can start adding message to the queue.
The data corruption can be due to a mis match in the memorymap between the kernel and the user space. If a pointer is used for a string it should be defines in shared memory and the pointre must be altered to match the differences in the memory map. for instance
Code: Select all
#define kernel_base 0xC0000000
#define user_base 0x00000000
char * string = 0xC8000000;
char * sameStringInUserLand = (char *)(((int_ptr)string - kernel_base) + user_base)
As for the GPF i think you run in 32 bit protected mode and therefore i cant help you. I only work ing 64 bit long mode and the interrupt stack model is quite different between the two and most likely that's were the problem is. The interrupt stack from user->kernel is different from user->user, kernel->kernel.
Posted: Mon Aug 20, 2007 12:06 am
by pcmattman
os64dev wrote:The data corruption can be due to a mis match in the memorymap between the kernel and the user space. If a pointer is used for a string it should be defines in shared memory and the pointre must be altered to match the differences in the memory map. for instance
Code: Select all
#define kernel_base 0xC0000000
#define user_base 0x00000000
char * string = 0xC8000000;
char * sameStringInUserLand = (char *)(((int_ptr)string - kernel_base) + user_base)
What I meant was, I pass an address to the function and that is what gets modified. Somehow the data I get back is corrupted though.
Is it possible that the GPF is caused by my enabling interrupts in an ISR (interrupt gate) handler? All my tasks run in ring0 at the moment (some problems with getting into ring3 that I am dealing with afterwards) so it can't be faulty stacks.
Posted: Mon Aug 20, 2007 12:26 am
by os64dev
What I meant was, I pass an address to the function and that is what gets modified. Somehow the data I get back is corrupted though.
That does sound like a stack issue or alignment issue. Do you use the internal debugger of bochs, because then you can see what happens if you do a step, by step execution of instructions.
Is it possible that the GPF is caused by my enabling interrupts in an ISR (interrupt gate) handler? .
both this problem and the one above can also point to a wrong interrupt entry and exit routine. If the stack alligned? do you pop the registers in the reverse order of the push? Does any interrupt work at all?[/quote]
All my tasks run in ring0 at the moment (some problems with getting into ring3 that I am dealing with afterwards) so it can't be faulty stacks.
Deal with it sooner because i also posponed it and it bit me really hard in the face, you code wil grow and grow and grow and suddenly it doesn't work. Try figuring it out then. It is a lot easier with a small code base. Also ring3 does impose limitation regarind to ring0 so you will need to no them.
Posted: Mon Aug 20, 2007 1:02 am
by pcmattman
os64dev wrote:Is it possible that the GPF is caused by my enabling interrupts in an ISR (interrupt gate) handler? .
both this problem and the one above can also point to a wrong interrupt entry and exit routine. If the stack alligned? do you pop the registers in the reverse order of the push? Does any interrupt work at all?
Interrupts work properly and the stack is aligned (at least, I'm pretty sure it is). It's just this one special case that's causing trouble.
I'm pretty sure that my popping is correct, you can check in "isr.inc" in my CVS (link in sig).
Deal with it sooner because i also posponed it and it bit me really hard in the face, you code wil grow and grow and grow and suddenly it doesn't work. Try figuring it out then. It is a lot easier with a small code base. Also ring3 does impose limitation regarind to ring0 so you will need to no them.
Ok, I'll try to figure that out now and come back to this keyboard input bug later.
Posted: Mon Aug 20, 2007 1:24 am
by distantvoices
Regarding User processes (services) & delivery of IRQ events:
You can register the task to receive an IRQ notification by a kind of general IRQ handler which simply deals out HWIRQ Messages with the kernel. Some sorta register_irq/unregister_irq call should do the trick. The kernel then sends IRQ Messages to the registered task which fetches the message and does what needs to be done.
HTH
Posted: Mon Aug 20, 2007 2:33 am
by pcmattman
distantvoices wrote:You can register the task to receive an IRQ notification by a kind of general IRQ handler which simply deals out HWIRQ Messages with the kernel. Some sorta register_irq/unregister_irq call should do the trick.
Sounds like a plan, maybe I will get around to having a "tty" driver
.