Homemade Operating System Antz day10-Implementing Shell (Part I)

Keywords: Linux github Makefile

I've standardized the style of system code, similar to subcontracting linux to differentiate the functions of each part.

Antz System Update Address

Linux Kernel Source Code Analysis Address

Github project address

In the previous task, we have completed simple graphics by directly operating the graphics driver.

Need to know the previous part:

Direct operation graphics card refer to day03

See day09 for a simple graphical implementation

Makefile

Project directory

The graphical implementation and rules of console are implemented in main/bootpack.c.

Keyboard interrupt processing is implemented in interrupt/int.c. Keyboard interrupt processing is realized. Keyboard interrupt processing is performed twice, once pressed and once popped up. In response processing, only the first pressed processing is needed.

1. Keyboard keys

How to judge that the interrupt comes from the keyboard? (The code is as follows)

    // gdt initialization operation...
    // fifo Load Operation...
    if (fifo8_status(&keyfifo) != 0) {  // True says that the interrupt comes from the keyboard
        i = fifo8_get(&keyfifo);
        io_sti();
        // I i s the value returned by the interrupt, which can be analyzed to get the key information. I convert it to hexadecimal and store it in a char array below.
        sprintf(s, "%02X", i);
        // Turn two interruptions into one. See below.
    }

Get s, is to get the keyboard key information.

As I said at the beginning, there will be two interruptions next time, so can we use a flag to distinguish between push and bounce?

    if (flag){
        keyshow(); // Display this button, treat the interrupt pressed as a key position information, and shield the interrupt bounced up with the method of flag below.
    }
    // Shield
    if(flag==1){
        flag = 0 ;
    }else {
        flag = 1 ;
    }

This is a very clumsy implementation, and I tested it several times and found that there is a bug, that is, when two keys are pressed at the same time, the shielding method will become another one.

For example, the first step is to identify a key position by pressing it. Then, after pressing two keys at the same time, the key position is identified by popping up.

This situation should be considered later.

Key Recognition

The data returned by the key has been stored in the char array s above, just need to display the data of s on the screen.

int write_x = 55 ; //x, y coordinates of key display position
int write_y = 57 ;

void key(struct BOOTINFO *binfo,char s[40]){
    //Display data at specified locations
    showkeys(binfo->vram, binfo->scrnx,  write_x,  write_y, COL8_FFFFFF, s);
    // Move the cursor to the right after display
    write_x += 19 ;
    // If it goes beyond the right boundary, line change
    if(write_x>155){
        write_x = 55 ;
        write_y += 19 ;
    }
    // If you go beyond the lower boundaries, refresh this page and open a new page
    if(write_y>180){
         new_pe(binfo);
    }

}

Result:

Obviously, we need to write a conversion mechanism that corresponds data representing hexadecimal digits to keyboard keystrokes.

The keyboard needs to display letters and special symbols, as well as some functional keys such as shift, backspace, etc.

The test recorded press data of several keys.

Keyboard press

F1 3B

F2 3C

F3 3D

F4 3E

A 1E

B 30

Backspace OE

Space 39

Now that the correspondence is known, it is easy to establish a correspondence.

First of all, realize these special button functions.

I intend to implement F1 as a clear function to refresh the page. Backspace implements fallback. Enter implements confirmation and return functions.

void showkey(struct BOOTINFO *binfo,char s[40]){
    // Enter key 
    if(strcmp(s,"1C")==0){ 
            write_x = 55 ;  // The cursor moves to the start of the next line.
            write_y += 19 ;
            showkeys(binfo->vram, binfo->scrnx, 0, write_y, COL8_FFFFFF, "AntzOS>");
    }
    // F1 refresh this page
    else if(strcmp(s,"3B")==0){
            new_pe(binfo);
    }
    // Space cursor moved one bit backward
    else if(strcmp(s,"39")==0){
            showkeys(binfo->vram, binfo->scrnx,  write_x,  write_y, COL8_FFFFFF, " ");
            write_x += 19 ;
    }
    // Backspace deletes backspace
    else if(strcmp(s,"0E")==0){
            // Regression
            write_x -= 19 ;
            //Re-cover the area
            area_flash(binfo->vram, binfo->scrnx , COL8_000000,  write_x,     write_y,     write_x+19, write_y+19);
    }
    // Other keys
    else {
            showkeys(binfo->vram, binfo->scrnx,  write_x,  write_y, COL8_FFFFFF, s);
            write_x += 19 ;
    }
    if(write_x>155){
        write_x = 55 ;
        write_y += 19 ;
        //putfonts8_asc(binfo->vram, binfo->scrnx, 4, 57, COL8_FFFFFF, "AntzOS>");
    }
    if(write_y>180){
         new_pe(binfo);
    }

}

Letter recognition is the same, of course, more perfect and more concise than the above, but I can only do this step in a hurry.

3. Reflections triggered by Bug

There was not much connection with AntzOs implementation from the beginning, but I found a lot of strange little problems when I tested the interruption of keys.

Whether Caps Lock (case key) is turned on does not affect the return information of the interrupt to one of your keys, that is, the so-called case interrupt is actually indistinguishable, so how can modern systems distinguish it? Similarly, we distinguish the two interrupts of pressing and bouncing, and we can get the status of the Caps Lock key, thus making the so-called case distinction between the current key.

Press twice to cause rule substitution, will it be due to the interruption of response time?

Posted by msielski on Sun, 03 Feb 2019 13:42:15 -0800