概要
wslで、kernel.elfのコンパイル、やってみた。
cで、書いたカーネルで、キーボード読み込みで、Shiftキーを認識して、テーブルを切り替えてみた。
サンプルコード
#include "kernel3.h"
#define ESC (0x1B)
#define BS (0x08)
#define EOT (0x04)
const uint8 lower_ascii_codes[256] = {
0x00, ESC, '1', '2', /* 0x00 */
'3', '4', '5', '6', /* 0x04 */
'7', '8', '9', '0', /* 0x08 */
'-', '=', BS, '\t', /* 0x0C */
'q', 'w', 'e', 'r', /* 0x10 */
't', 'y', 'u', 'i', /* 0x14 */
'o', 'p', '[', ']', /* 0x18 */
'\n', 0x00, 'a', 's', /* 0x1C */
'd', 'f', 'g', 'h', /* 0x20 */
'j', 'k', 'l', ';', /* 0x24 */
'\'', '`', 0x00, '\\', /* 0x28 */
'z', 'x', 'c', 'v', /* 0x2C */
'b', 'n', 'm', ',', /* 0x30 */
'.', '/', 0x00, '*', /* 0x34 */
0x00, ' ', 0x00, 0x00, /* 0x38 */
0x00, 0x00, 0x00, 0x00, /* 0x3C */
0x00, 0x00, 0x00, 0x00, /* 0x40 */
0x00, 0x00, 0x00, '7', /* 0x44 */
'8', '9', '-', '4', /* 0x48 */
'5', '6', '+', '1', /* 0x4C */
'2', '3', '0', '.', /* 0x50 */
0x00, 0x00, 0x00, 0x00, /* 0x54 */
0x00, 0x00, 0x00, 0x00 /* 0x58 */
};
const uint8 upper_ascii_codes[256] = {
0x00, ESC, '!', '@', /* 0x00 */
'#', '$', '%', '^', /* 0x04 */
'&', '*', '(', ')', /* 0x08 */
'_', '+', BS, '\t', /* 0x0C */
'Q', 'W', 'E', 'R', /* 0x10 */
'T', 'Y', 'U', 'I', /* 0x14 */
'O', 'P', '{', '}', /* 0x18 */
'\n', 0x00, 'A', 'S', /* 0x1C */
'D', 'F', 'G', 'H', /* 0x20 */
'J', 'K', 'L', ':', /* 0x24 */
'"', '~', 0x00, '|', /* 0x28 */
'Z', 'X', 'C', 'V', /* 0x2C */
'B', 'N', 'M', '<', /* 0x30 */
'>', '?', 0x00, '*', /* 0x34 */
0x00, ' ', 0x00, 0x00, /* 0x38 */
0x00, 0x00, 0x00, 0x00, /* 0x3C */
0x00, 0x00, 0x00, 0x00, /* 0x40 */
0x00, 0x00, 0x00, '7', /* 0x44 */
'8', '9', '-', '4', /* 0x48 */
'5', '6', '+', '1', /* 0x4C */
'2', '3', '0', '.', /* 0x50 */
0x00, 0x00, 0x00, 0x00, /* 0x54 */
0x00, 0x00, 0x00, 0x00 /* 0x58 */
};
const uint8 lower_ascii_codes_dvorak[256] = {
0x00, ESC, '1', '2', /* 0x00 */
'3', '4', '5', '6', /* 0x04 */
'7', '8', '9', '0', /* 0x08 */
'[', ']', BS, '\t', /* 0x0C */
'\'', ',', '.', 'p', /* 0x10 */
'y', 'f', 'g', 'c', /* 0x14 */
'r', 'l', '/', '=', /* 0x18 */
'\n', 0x00, 'a', 'o', /* 0x1C */
'e', 'u', 'i', 'd', /* 0x20 */
'h', 't', 'n', 's', /* 0x24 */
'-', '`', 0x00, '\\', /* 0x28 */
';', 'q', 'j', 'k', /* 0x2C */
'x', 'b', 'm', 'w', /* 0x30 */
'v', 'z', 0x00, '*', /* 0x34 */
0x00, ' ', 0x00, 0x00, /* 0x38 */
0x00, 0x00, 0x00, 0x00, /* 0x3C */
0x00, 0x00, 0x00, 0x00, /* 0x40 */
0x00, 0x00, 0x00, '7', /* 0x44 */
'8', '9', '[', '4', /* 0x48 */
'5', '6', '}', '1', /* 0x4C */
'2', '3', '0', 'v', /* 0x50 */
0x00, 0x00, 0x00, 0x00, /* 0x54 */
0x00, 0x00, 0x00, 0x00 /* 0x58 */
};
const uint8 upper_ascii_codes_dvorak[256] = {
0x00, ESC, '!', '@', /* 0x00 */
'#', '$', '%', '^', /* 0x04 */
'&', '*', '(', ')', /* 0x08 */
'{', '}', BS, '\t', /* 0x0C */
'"', '<', '>', 'P', /* 0x10 */
'Y', 'F', 'G', 'C', /* 0x14 */
'R', 'L', '?', '+', /* 0x18 */
'\n', 0x00, 'A', 'O', /* 0x1C */
'E', 'U', 'I', 'D', /* 0x20 */
'H', 'T', 'N', 'S', /* 0x24 */
'_', '~', 0x00, '|', /* 0x28 */
':', 'Q', 'J', 'K', /* 0x2C */
'X', 'B', 'M', 'W', /* 0x30 */
'V', 'Z', 0x00, '*', /* 0x34 */
0x00, ' ', 0x00, 0x00, /* 0x38 */
0x00, 0x00, 0x00, 0x00, /* 0x3C */
0x00, 0x00, 0x00, 0x00, /* 0x40 */
0x00, 0x00, 0x00, '7', /* 0x44 */
'8', '9', '[', '4', /* 0x48 */
'5', '6', '}', '1', /* 0x4C */
'2', '3', '0', 'v', /* 0x50 */
0x00, 0x00, 0x00, 0x00, /* 0x54 */
0x00, 0x00, 0x00, 0x00 /* 0x58 */
};
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';
}
}
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);
}
uint8 scan(void) {
static uint8 key = 0;
uint8 scan = inb(0x60);
if (scan != key)
return key = scan;
else
return 0;
}
void kernel_entry() {
char ch = 0;
char md = 0;
char sc = 0;
while (1)
{
sleep(0x00FFFFFF);
sc = scan();
if (sc == 0x2a)
{
md = 1;
}
else if (sc == 0x36)
{
md = 1;
}
else
{
if (sc > 0)
{
init_vga(WHITE, BLUE);
if (md == 1)
{
ch = upper_ascii_codes[sc];
md = 0;
}
else
{
ch = lower_ascii_codes[sc];
}
print_int(sc);
print_new_line();
print_char(ch);
}
}
}
}
以上。