Issue With Keyboard Driver

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
balthasar
Member
Member
Posts: 30
Joined: Mon Mar 31, 2008 8:39 pm
Contact:

Issue With Keyboard Driver

Post by balthasar »

Im having issues impimenting my Keyboard Driver. Im using the latest JamesM Kernel (the User Mode one) and I can not impliment the keyboard driver. EDIT: It works in Ring 0 (Kernel) but not in Ring 3 (User Mode)

Here is the source code of the keyboard driver

Code: Select all

/*========================================================================================
Odyssey Diclonius Kernel Sources
(C) 2008 Odyssey Technologies

IMPORTANT:  This Odyssey software is supplied to you by Odyssey Technologies.
("Odyssey") in consideration of your agreement to the following
terms, and your use, installation, modification or redistribution of this 
Odyssey software constitutes acceptance of these terms.  If you do not agree 
with these terms, please do not use, install, modify or redistribute this Odyssey software.

The Odyssey Software is provided by Odyssey on an "AS IS" basis.  Odyssey MAKES NO 
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES 
OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING 
THE Odyssey SOFTWARE OR ITS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 

IN NO EVENT SHALL Odyssey BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL 
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT
OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE Odyssey SOFTWARE, HOWEVER
CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY
OR OTHERWISE, EVEN IF Odyssey HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
s========================================================================================*/

// keyboard.c -- Keyboard Driver

#include <keyboard.h>
#include <isr.h>
#include <syscall.h>

s8int lowercase[256] = { 0,  27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\t', 'q', 'w', 'e', 'r',
't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0,  '\\', 'z', 
'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, 
'+', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
s8int uppercase[256] = { 0,  27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', '\t', 'Q', 'W', 'E', 'R',
'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '"', 0,  '|', 'Z', 
'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, 
'+', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};

unsigned shift_state = 0;

static void do_kb(registers_t *regs)
{
   serial_write("****\n\r");
   u8int new_char;

   s32int new_scan_code = inb(0x60);

   switch(new_scan_code) {
       case 0x2a: 
           shift_state = 1; 
           break;

       case 0xaa: 
           shift_state = 0;
           break;

       case 0x1c:
           if (console == 1) {
               execute_command(); 
               monitor_write("nyu: $>\n");
           }
           else {
               new_char =(shift_state ? uppercase:lowercase)[new_scan_code];
               monitor_put(new_char);
           }
           break;

       default:
          if (new_scan_code & 0x80) {
             /* Ignore the break code */
          } else {
             new_char =(shift_state ? uppercase:lowercase)[new_scan_code];
             monitor_put(new_char);          
          }
          break;
    }

    outb(0x20,0x20);
}

void init_keyboard()
{
       register_interrupt_handler(IRQ1, &do_kb);
}

ChristianF
Member
Member
Posts: 79
Joined: Sun Jun 10, 2007 11:36 am

Re: Issue With Keyboard Driver

Post by ChristianF »

You ar in User Mode.
The Problem is that you have to give Ring 3 Tasks the Permission for Port-Operations.

I actually don't know how to do this but you have to set the iomap_base, which is in the Task State Segment.
42
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Issue With Keyboard Driver

Post by Brendan »

Hi,
OdinPG wrote:The Problem is that you have to give Ring 3 Tasks the Permission for Port-Operations.

I actually don't know how to do this but you have to set the iomap_base, which is in the Task State Segment.
The simplest way is to set IOPL to 3, but that gives the process access to all I/O ports and CLI/STI, so I wouldn't necessarily recommend it. Note: each task has it's own EFLAGS (and it's own IOPL within it's EFLAGS) so you wouldn't be giving all processes access to all I/O ports.

The I/O permission bitmap in the TSS is another way. If you use the same TSS for all tasks then this involves changing the TSS's I/O permission bitmap during task switches.

Letting the code cause a general protection fault, and then doing your own protection checks and emulating the I/O port instructions in the GPF handler is another way.

Lastly, you could provide kernel API functions for I/O port access so that the CPL=3 code calls the kernel API function instead of using I/O port instructions; and the kernel API function does your protection checks and then does the I/O port instruction.

Note: You can also combine some these techniques. For example, emulate the I/O port instructions in the general protection fault handler for a while, and then change IOPL to 3 if/when you're confident the process won't do anything nasty. You could also implement "all of the above" if you want.

However, IMHO for some things (like the PIC) device drivers should never have direct access - for these purposes you'd need kernel API functions (e.g. a "sendEOI()" kernel function, a "startDMA()" function, a "stopDMA()" function, etc). This is partly for abstraction (e.g. so that the device driver doesn't need to care if the EOI is sent to the PIC or to the I/O APIC), partly for extra protection (e.g. so a floppy driver can't do a DMA transfer to copy kernel data to floppy, modify it, and use DMA again to transfer the modified data back into the kernel), and partly so that device drivers don't stuff each other up (e.g. one driver setting the PCI configuration space "address" I/O port, then another driver setting the PCI configuration space "address" I/O port, then the first driver reading the wrong data from the PCI configuration space "data" I/O port).

Of course a lot of this depends on how much you trust device drivers (I don't trust them at all, while some OSs trust device drivers completely, even if they're binary blobs written by some random guy on the internet somewhere ;) ).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
balthasar
Member
Member
Posts: 30
Joined: Mon Mar 31, 2008 8:39 pm
Contact:

Re: Issue With Keyboard Driver

Post by balthasar »

The I/O permission bitmap in the TSS is another way. If you use the same TSS for all tasks then this involves changing the TSS's I/O permission bitmap during task switches.
how can i go about and doing this ?
My OS: NasuTek Ensemble http://code.google.com/p/ensemble/
User avatar
Adek336
Member
Member
Posts: 129
Joined: Thu May 12, 2005 11:00 pm
Location: Kabaty, Warszawa
Contact:

Re: Issue With Keyboard Driver

Post by Adek336 »

I think it's a riddle to be solved on your own, because there are a lot of details like how to load a task register, what is the alignment of the task register etc. which should be understood to be able to debug the code.
I believe some valuable resources would be googled under the terms "task register", "osdev hardware multitasking", "iopl".
itisiuk
Member
Member
Posts: 98
Joined: Mon Mar 24, 2008 1:46 pm

Re: Issue With Keyboard Driver

Post by itisiuk »

this website has a little info on the io bitmap
http://pdos.csail.mit.edu/6.828/2007/re ... 86/toc.htm

also look at the linux kernel v1.3, which gives an example of it implementation.

why not use system calls to write to the screen whilst in user mode
or streaming to read from the keyboard buffer then streaming to write back to the screen, e.g. stdin stdout??
i use a virtual filesys to do this which doesnt seem to have any problems with user mode + i think it works out better in the long run.
User avatar
balthasar
Member
Member
Posts: 30
Joined: Mon Mar 31, 2008 8:39 pm
Contact:

Re: Issue With Keyboard Driver

Post by balthasar »

itisiuk wrote:this website has a little info on the io bitmap
http://pdos.csail.mit.edu/6.828/2007/re ... 86/toc.htm

also look at the linux kernel v1.3, which gives an example of it implementation.

why not use system calls to write to the screen whilst in user mode
or streaming to read from the keyboard buffer then streaming to write back to the screen, e.g. stdin stdout??
i use a virtual filesys to do this which doesnt seem to have any problems with user mode + i think it works out better in the long run.
thanks for the link

yes i have tryed replacing monitor_write with Diclonius_monitor_write (the syscalls are all prefixed with Diclonius_) and that also didnt work :P

but ill try the io bitmap
My OS: NasuTek Ensemble http://code.google.com/p/ensemble/
ChristianF
Member
Member
Posts: 79
Joined: Sun Jun 10, 2007 11:36 am

Re: Issue With Keyboard Driver

Post by ChristianF »

Brendan wrote: However, IMHO for some things (like the PIC) device drivers should never have direct access - for these purposes you'd need kernel API functions (e.g. a "sendEOI()" kernel function, a "startDMA()" function, a "stopDMA()" function, etc). This is partly for abstraction (e.g. so that the device driver doesn't need to care if the EOI is sent to the PIC or to the I/O APIC), partly for extra protection (e.g. so a floppy driver can't do a DMA transfer to copy kernel data to floppy, modify it, and use DMA again to transfer the modified data back into the kernel), and partly so that device drivers don't stuff each other up (e.g. one driver setting the PCI configuration space "address" I/O port, then another driver setting the PCI configuration space "address" I/O port, then the first driver reading the wrong data from the PCI configuration space "data" I/O port).

Of course a lot of this depends on how much you trust device drivers (I don't trust them at all, while some OSs trust device drivers completely, even if they're binary blobs written by some random guy on the internet somewhere ;) ).
Hummm....
So you have a set of functions which could be accessed through System Calls?
Or how do you handle this, because i got to this point too. I don't want to set the I/O Bitmap. Why? There is an example: A "Driver" gets access to Keyboard Ports and sends a software reset commant. :twisted:
At this Point the Operating System can do nothing to prevent this...

Cheers Christian

EDIT:
An other point which i am interested in is, how much of the 65536 Ports do you check an execute in your Kernel?
42
Post Reply