1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Posted at

概要

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

写真

image.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();
}






以上。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?