wslで、最小のカーネルをコンパイル その6

# 概要
wslで、kernel.elfのコンパイル、やってみた。
cで、書いたカーネルで、キーボード読み込みを、実行してみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/0565eaad-6647-9ff2-0218-b41ee127b023.png)

# サンプルコード

kernel3.h
```
#ifndef KERNEL_H
#define KERNEL_H

typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;

#define NULL 			0
#define VGA_ADDRESS 	0xB8000
#define BUFSIZE 		2200

uint16 * vga_buffer;

enum vga_color {
	BLACK,
	BLUE,
	GREEN,
	CYAN,
	RED,
	MAGENTA,
	BROWN,
	GREY,
	DARK_GREY,
	BRIGHT_BLUE,
	BRIGHT_GREEN,
	BRIGHT_CYAN,
	BRIGHT_RED,
	BRIGHT_MAGENTA,
	YELLOW,
	WHITE,
};
#define KEYBOARD_PORT 	0x60
#define KEY_A 			0x1E
#define KEY_B 			0x30
#define KEY_C 			0x2E
#define KEY_D 			0x20
#define KEY_E 			0x12
#define KEY_F 			0x21
#define KEY_G 			0x22
#define KEY_H 			0x23
#define KEY_I 			0x17
#define KEY_J 			0x24
#define KEY_K 			0x25
#define KEY_L 			0x26
#define KEY_M 			0x32
#define KEY_N 			0x31
#define KEY_O 			0x18
#define KEY_P 			0x19
#define KEY_Q 			0x10
#define KEY_R 			0x13
#define KEY_S 			0x1F
#define KEY_T 			0x14
#define KEY_U 			0x16
#define KEY_V 			0x2F
#define KEY_W 			0x11
#define KEY_X 			0x2D
#define KEY_Y 			0x15
#define KEY_Z 			0x2C
#define KEY_1 			0x02
#define KEY_2 			0x03
#define KEY_3 			0x04
#define KEY_4 			0x05
#define KEY_5 			0x06
#define KEY_6 			0x07
#define KEY_7 			0x08
#define KEY_8 			0x09
#define KEY_9 			0x0A
#define KEY_0 			0x0B
#define KEY_MINUS 		0x0C
#define KEY_EQUAL 		0x0D
#define KEY_SQUARE_OPEN_BRACKET 0x1A
#define KEY_SQUARE_CLOSE_BRACKET 0x1B
#define KEY_SEMICOLON 	0x27
#define KEY_BACKSLASH 	0x2B
#define KEY_COMMA 		0x33
#define KEY_DOT 		0x34
#define KEY_FORESLHASH 	0x35
#define KEY_F1 			0x3B
#define KEY_F2 			0x3C
#define KEY_F3 			0x3D
#define KEY_F4 			0x3E
#define KEY_F5 			0x3F
#define KEY_F6 			0x40
#define KEY_F7 			0x41
#define KEY_F8 			0x42
#define KEY_F9 			0x43
#define KEY_F10 		0x44
#define KEY_F11 		0x85
#define KEY_F12 		0x86
#define KEY_BACKSPACE 	0x0E
#define KEY_DELETE 		0x53
#define KEY_DOWN 		0x50
#define KEY_END 		0x4F
#define KEY_ENTER 		0x1C
#define KEY_ESC 		0x01
#define KEY_HOME 		0x47
#define KEY_INSERT 		0x52
#define KEY_KEYPAD_5 	0x4C
#define KEY_KEYPAD_MUL 	0x37
#define KEY_KEYPAD_Minus 0x4A
#define KEY_KEYPAD_PLUS 0x4E
#define KEY_KEYPAD_DIV 	0x35
#define KEY_LEFT 		0x4B
#define KEY_PAGE_DOWN 	0x51
#define KEY_PAGE_UP 	0x49
#define KEY_PRINT_SCREEN 0x37
#define KEY_RIGHT 		0x4D
#define KEY_SPACE 		0x39
#define KEY_TAB 		0x0F
#define KEY_UP 			0x48
char get_ascii_char(uint8);
uint32 strlen(const char *);
uint32 digit_count(int);
void itoa(int, char *);
#endif







```
kernel3.c
```
#include "kernel3.h"

uint32 vga_index;
static uint32 next_line_index = 1;
uint8 g_fore_color = WHITE, 
	g_back_color = BLUE;
int digit_ascii_codes[10] = {
	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39
};
uint32 strlen(const char * str) {
	uint32 length = 0;
	while(str[length])
		length++;
	return length;
}
uint32 digit_count(int num) {
	uint32 count = 0;
	if (num == 0)
		return 1;
	while(num > 0)
	{
		count++;
		num = num / 10;
	}
	return count;
}
void itoa(int num, char * number) {
	int dgcount = digit_count(num);
	int index = dgcount - 1;
	char x;
	if (num == 0 && dgcount == 1)
	{
		number[0] = '0';
		number[1] = '\0';
	}
	else
	{
		while(num != 0)
		{
			x = num % 10;
			number[index] = x + '0';
			index--;
			num = num / 10;
		}
		number[dgcount] = '\0';
	}
}
char get_ascii_char(uint8 key_code) {
	switch(key_code)
	{
		case KEY_A: return 'A';
		case KEY_B: return 'B';
		case KEY_C: return 'C';
		case KEY_D: return 'D';
		case KEY_E: return 'E';
		case KEY_F: return 'F';
		case KEY_G: return 'G';
		case KEY_H: return 'H';
		case KEY_I: return 'I';
		case KEY_J: return 'J';
		case KEY_K: return 'K';
		case KEY_L: return 'L';
		case KEY_M: return 'M';
		case KEY_N: return 'N';
		case KEY_O: return 'O';
		case KEY_P: return 'P';
		case KEY_Q: return 'Q';
		case KEY_R: return 'R';
		case KEY_S: return 'S';
		case KEY_T: return 'T';
		case KEY_U: return 'U';
		case KEY_V: return 'V';
		case KEY_W: return 'W';
		case KEY_X: return 'X';
		case KEY_Y: return 'Y';
		case KEY_Z: return 'Z';
		case KEY_1: return '1';
		case KEY_2: return '2';
		case KEY_3: return '3';
		case KEY_4: return '4';
		case KEY_5: return '5';
		case KEY_6: return '6';
		case KEY_7: return '7';
		case KEY_8: return '8';
		case KEY_9: return '9';
		case KEY_0: return '0';
		case KEY_MINUS: return '-';
		case KEY_EQUAL: return '=';
		case KEY_SQUARE_OPEN_BRACKET: return '[';
		case KEY_SQUARE_CLOSE_BRACKET: return ']';
		case KEY_SEMICOLON: return ';';
		case KEY_BACKSLASH: return '\\';
		case KEY_COMMA: return ',';
		case KEY_DOT: return '.';
		case KEY_FORESLHASH: return '/';
		case KEY_SPACE: return ' ';
		default: return 0;
	}
}
uint16 vga_entry(unsigned char ch, uint8 fore_color, uint8 back_color) {
	uint16 ax = 0;
	uint8 ah = 0,
		al = 0;
	ah = back_color;
	ah <<= 4;
	ah |= fore_color;
	ax = ah;
	ax <<= 8;
	al = ch;
	ax |= al;
	return ax;
}
void clear_vga_buffer(uint16 ** buffer, uint8 fore_color, uint8 back_color) {
	uint32 i;
	for(i = 0; i < BUFSIZE; i++)
	{
		(* buffer) [i] = vga_entry(NULL, fore_color, back_color);
	}
	next_line_index = 1;
	vga_index = 0;
}
void init_vga(uint8 fore_color, uint8 back_color) {
	vga_buffer = (uint16 *) VGA_ADDRESS;
	clear_vga_buffer(&vga_buffer, fore_color, back_color);
	g_fore_color = fore_color;
	g_back_color = back_color;
}
void print_new_line() {
	if (next_line_index >= 55)
	{
		next_line_index = 0;
		clear_vga_buffer(&vga_buffer, g_fore_color, g_back_color);
	}
	vga_index = 80 * next_line_index;
	next_line_index++;
}
void print_char(char ch) {
	vga_buffer[vga_index] = vga_entry(ch, g_fore_color, g_back_color);
	vga_index++;
}
void print_string(char * str) {
	uint32 index = 0;
	while(str[index])
	{
		print_char(str[index]);
		index++;
	}
}
void print_int(int num) {
	char str_num[digit_count(num) + 1];
	itoa(num, str_num);
	print_string(str_num);
}
uint8 inb(uint16 port) {
	uint8 ret;
	asm volatile("inb %1, %0": "=a"(ret): "d"(port));
	return ret;
}
void outb(uint16 port, uint8 data) {
	asm volatile("outb %0, %1": "=a"(data): "d"(port));
}
char get_input_keycode() {
	char ch = 0;
	while ((ch = inb(KEYBOARD_PORT)) != 0)
	{
		if (ch > 0)
			return ch;
	}
	return ch;
}
void wait_for_io(uint32 timer_count) {
	while (1)
	{
		asm volatile("nop");
		timer_count--;
		if (timer_count <= 0)
			break;
	}
}
void sleep(uint32 timer_count) {
	wait_for_io(timer_count);
}
void test_input() {
	char ch = 0;
	char keycode = 0;
	do
	{
		keycode = get_input_keycode();
		if (keycode == KEY_ENTER)
		{
			print_new_line();
		}
		else
		{
			ch = get_ascii_char(keycode);
			print_char(ch);
		}
		sleep(0x2FFFFFF);
		print_char(0x30);
	} while(ch > 0);
}
void kernel_entry() {
	init_vga(WHITE, BLUE);
	print_string("Type here, one key per second, ENTER to go to next line");
	print_new_line();
	test_input();
	test_input();
	test_input();
	test_input();
}






```

以上。