Emulando a Linus Torvalds: crea tu propio sistema operativo desde 0 (VIII)

Volvemos a la serie de tutoriales sobre como crear nuestro propio sistema operativo. Supongo que este capítulo os gustará mucho porque por fin podremos interactuar con nuestro sistema operativo. Hoy leeremos la entrada del teclado. Para ello el esquema es similar al del timer. Tenemos que usar los IRQ igualmente así que empezaremos igual que con el timer.

ND_IRQ_InstallHandler(1,&ND_Keyboard_Handler);

Nuestro handler de teclado sin embargo es algo más complejo ya que vamos leyendo las teclas y las vamos depositando en un buffer.

extern "C"
void ND_Keyboard_Handler(struct regs* r)
{
    unsigned char scancode = ND::Keyboard::GetChar();
    if(scancode!=255)
    {
		ND::Screen::PutChar(scancode);
		stringBuffer[stringPos]=scancode;
		stringPos++;
    }
}

http://gist.github.com/634afddcb3e977ea202d

Podemos comprobar como llamamos a una función llamada ND::Keyboard::GetChar. Allí obtenemos el caracter y después si no es un caracter vacío (aquí he usado 255, habría que usar un sistema mejor) ponemos el caracter en pantalla y lo almacenamos en un buffer simple de chars (esto también es susceptible de mejora, el sistema actual puede desbordarse).

nsigned char ND::Keyboard::GetChar()
{
	unsigned char scancode;
	scancode=(unsigned char)ND::Ports::InputB(0x60);
	if(scancode & ND_KEYBOARD_KEY_RELEASE)
	{
		return 255;
	}else{
		return en_US[scancode];
	}
}
 
char* ND::Keyboard::GetString()
{
	while(stringBuffer[stringPos-1]!='\n')
	{
	}
	stringPos=0;
	return stringBuffer;
}

http://gist.github.com/2d4f13e0b1a281c66884

Aquí podemos ver como se obtiene la tecla que ha sido pulsada. En 0x60 siempre va a estar la última tecla pulsada. De hecho se puede leer directamente sin tener que usar el IRQ, pero entonces no sabremos indentificar cuando se ha producido un cambio. Allí comprobamos con la operación AND que el código de obtuvimos corresponde a una tecla que se ha dejado de pulsar.

En ese caso devolvemos 255 (porque luego lo ignoraremos) y en caso contrario la tecla ha sido pulsada. En ese caso devolvemos la posición de un array llamado en_US. ¿Qué información contiene este array? Este array es lo que llamaríamos un keymap o un mapa de caracteres. Como sabrán diferentes idiomas tienen diferentes teclados y no son compatibles ya que sobreescriben las teclas. Así en_US nos dará la tecla correspondiente a cada código y funcionará en un teclado americano.

unsigned char en_US[128]=
{
	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, /* Ctrl */
	'a','s','d','f','g','h','j','k','l',';',
	'\'','`',0, /* Left Shift */
	'\\','z','x','c','v','b','n','m',',','.','/', 0,/* Right shift */
	'*', 0, /* Alt */
	' ',
	0, /* Caps lock*/
	0,0,0,0,0,0,0,0,0,0, /* F1-F10 keys */
	0, /* Num lock */
	0, /* Scroll lock */
	0, /* Home key */
	0, /* Up arrow */
	0, /* Page up */
	'-',
	0, /* Left arrow */
	0,
	0, /* Right arrow */
	'+',
	0, /* End key */
	0, /* Down arrow */
	0, /* Page down */
	0, /* Insert key */
	0, /* Delete key */
	0,0,0,
	0, 0, /* F11-F12 Keys */
	0
};

http://gist.github.com/bf52085aec05f3070b65

También había una función definida que obtenía una frase. El propósito es simplemente obtener acceso más fácilmente a los strings desde las aplicaciones que lo necesiten, de momento solo una. Hablo de NextShellLite, una versión reducida del posible futuro shell que tendría NextDivel. El propósito de NextShellLite es únicamente el de proveer de un shell reducido para ir probando poco a poco nuevas funcionalidades. No voy a poner el código del shell aquí pero lo he incluido dentro del código de NextDivel.

De momento no funciona como un programa aparte sino como una función que llama el kernel, principalmente porque todavía no añadimos la opción de ejecutar ejecutables. Y claro, unas imágenes de como funciona el shell con las nuevas funciones de entrada de teclado.


8 comentarios

  1.   daryo dijo

    excelente tuto ! gracias 🙂

  2.   PopArch dijo

    La verdad nunca segui el tuto por que en la primera parte me daba un error al tratar de compilar pero no recuerdo que error era

  3.   El Gato López dijo

    Perdón por mi ignorancia crasa… desde donde se escriben esos códigos?? ¿¿desde la terminal??

    1.    AdrianArroyoCalle dijo

      Los códigos son parte del código fuente. No lo pongo completo porque sino el post es todo código y nada explicación. Te recomiendo que te leas los tutoriales desde el principio si quieres seguirlo. También puedes consultar el código fuente completo aquí (http://github.com/AdrianArroyoCalle/next-divel)

  4.   Kady dijo

    Como seria la mejora para que no ocurriera desbordamiento?

    1.    Plock dijo

      Kady ¿ya revisaste el codigo del repositorio? ahi se establece el tamaño maximo, asi como funciones para controlarlo, ahi puedes realizar el cambio en tamaño o bien implementar una forma razonable de liberar el buffer cuando se llegue a saturar
      te dejo el link para que lo cheques https://github.com/AdrianArroyoCalle/next-divel/blob/master/src/start/ND_Keyboard.cpp

  5.   Nico dijo

    Hola muy interesante, van a continuar con esta “serie” de Emulando a Linus Torvals?
    Me pueden recomendar algún libro, información para poder hacer un kernel como este?

    Saludos!!

  6. Hola. Gracias por el tutorial. Por favor, ¿nos puedes recomendar un libro sobre esto que has hecho que no sea “Sistemas Operativos” de Tanenbaum? Muchas gracias por adelantado.
    Saludos.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

*

  1. Responsable de los datos: Miguel Ángel Gatón
  2. Finalidad de los datos: Controlar el SPAM, gestión de comentarios.
  3. Legitimación: Tu consentimiento
  4. Comunicación de los datos: No se comunicarán los datos a terceros salvo por obligación legal.
  5. Almacenamiento de los datos: Base de datos alojada en Occentus Networks (UE)
  6. Derechos: En cualquier momento puedes limitar, recuperar y borrar tu información.