1

I am working an a very basic operating system for a learning experience, and I am trying to start with key presses. I am making a freestanding executable, so no standard library. How would I go about taking input from a keyboard? I have figured out how to print to the screen through video memory.

/*
* kernel.c
* */

void cls(int line) { // clear the screen
    char *vidptr = (char*) 0xb8000;
    /* 25 lines each of 80 columns; each element takes 2 bytes */
    unsigned int x = 0;
    while (x < 80 * 25 * 2) {
        // blank character
        vidptr[x] = ' ';
        // attribute-byte - light grey on black screen
        x += 1;
        vidptr[x] = 0x07;
        x += 1;
    }
    line = 0;
}

void printf(const char *str, int line, char attr) { // write a string to             video memory
    char *vidptr = (char*) 0xb8000;
    unsigned int y =0, x = 0;
    while (str[y] != '\0') {
        // the character's ascii
        vidptr[x] = str[y];
        x++;
        // attribute byte - give character black bg and light gray fg
        vidptr[x+1] = attr;
        x++;
        y++;
    }
}

void kmain(void) {
    unsigned int line = 0;
    cls(line);
    printf("Testing the Kernel", line, 0x0a);
}

and my assembly:

    ;; entry point
bits 32                          ; nasm directive - 32 bit
global entry
extern _kmain                    ; kmain is defined in the c file

section .text
entry:  jmp start

    ;multiboot spec
    align 4
    dd 0x1BADB002            ; black magic
    dd 0x00                  ; flags
    dd -(0x1BADB002 + 0x00)  ; checksum. m+f+c should be zero

start:
    cli                      ; block interrupts
    mov esp, stack_space     ; set stack pointer
    call _kmain
    hlt                      ; halt the CPU

section .bss
resb 8192                        ; 8KB for stack
stack_space:
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • You would have to poll the keyboard for keystrokes or use IRQs to read characters from the keyboard port(0x60) as they come in. The IRQ method is preferred but interrupt handlers involve setting up your own GDT, your own IDT, and writing a keyboard handler (which would likely have some kind of ring buffer implementation). would have to handle key translation, and interrupt handlers would have to also handle end of interrupts).If you are writing a serious OS I'd recommend looking at interrupt handling now rather than later. – Michael Petch Mar 15 '19 at 21:27
  • 2
    Are you asking how to read the keyboard on a bare metal x86 based PC? – n. m. could be an AI Mar 15 '19 at 21:27
  • I wrote some testcode for a kernel related question previously (uses multiboot) in this SO answer: https://stackoverflow.com/a/37635449/3857942 . This is a very rudimentary and incomplete test as it doesn't have any ring buffer and the interrupt prints directly to the display. I was using the original poster's code and realize now the keyboard routine does unnecessary port 0x64 accesses (doesn't hurt anything but degrades performance) AND it doesn't set up a GDT. If using QEMU `-kernel` option that's not an issue. I feel like I should go back and revise that code now. – Michael Petch Mar 15 '19 at 21:42
  • The code was only meant to demonstrate how to get interrupts going and how to get keystrokes and do some *minimal* keyboard mapping.It falls short of being a real keyboard handler but that example may give you some ideas. – Michael Petch Mar 15 '19 at 21:44
  • @MichaelPetch The IRQ interface is unavailablein protected mode. – fuz Mar 16 '19 at 07:43
  • @fuz IRQs are available in protected mode with a proper IDT and remapping the the master PIC so that it doesn't conflict with the reserved/used CPU exceptions. Maybe you are thinking of BIOS calls are unsupported? Of course you can also use APIC for the interrupts as well. The code at the link in my earlier comment creates a protected mode interrupt handler to process the incoming keyboard scan codes. It is an incomplete implementation but enough to build on. – Michael Petch Mar 16 '19 at 07:52
  • @MichaelPetch I did mean the BIOS interface with “IRQ interface.” What did you mean when you said “You would have to poll the keyboard for keystrokes or use IRQs to read characters from the keyboard port(0x60) as they come in?” – fuz Mar 16 '19 at 09:26
  • 1
    @MichaelPetch I see. I thought you meant using the BIOS services for keyboard access. – fuz Mar 16 '19 at 11:38

0 Answers0