I think I reached kernel size limit, lol
This commit is contained in:
parent
4ef561edf5
commit
79f4d25c27
2
Makefile
2
Makefile
@ -19,7 +19,7 @@ endif
|
|||||||
CFLAGS = -fno-pic -ffreestanding -static -fno-builtin -fno-strict-aliasing \
|
CFLAGS = -fno-pic -ffreestanding -static -fno-builtin -fno-strict-aliasing \
|
||||||
-mno-sse \
|
-mno-sse \
|
||||||
-I. \
|
-I. \
|
||||||
-Wall -Wno-unused-result -ggdb -m32 -Werror -fno-omit-frame-pointer -Os
|
-Wall -Wno-unused-result -Wno-unused-variable -Wno-unused-but-set-variable -ggdb -m32 -Werror -fno-omit-frame-pointer -Os
|
||||||
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
|
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
|
||||||
ASMFLAGS = -m32 -ffreestanding -c -g -I.
|
ASMFLAGS = -m32 -ffreestanding -c -g -I.
|
||||||
|
|
||||||
|
|||||||
@ -2,3 +2,5 @@
|
|||||||
|
|
||||||
void printk(const char* msg);
|
void printk(const char* msg);
|
||||||
_Noreturn void panic(const char* msg);
|
_Noreturn void panic(const char* msg);
|
||||||
|
|
||||||
|
#define check(expr) if (!(expr)) { panic("Assertion failed at " __FILE__ " : " " : " #expr "\n"); }
|
||||||
@ -5,33 +5,40 @@
|
|||||||
#include "port.h"
|
#include "port.h"
|
||||||
#include "kernel/mem.h"
|
#include "kernel/mem.h"
|
||||||
|
|
||||||
static const char sc_ascii[] = {
|
keyboard_interrupt_shared_t kbd_state_shrd;
|
||||||
'?', '?', '1', '2', '3', '4', '5', '6',
|
|
||||||
'7', '8', '9', '0', '-', '=', '?', '?', 'q', 'w', 'e', 'r', 't', 'y',
|
|
||||||
'u', 'i', 'o', 'p', '[', ']', '\n', '?', 'a', 's', 'd', 'f', 'g',
|
|
||||||
'h', 'j', 'k', 'l', ';', '\'', '`', '?', '\\', 'z', 'x', 'c', 'v',
|
|
||||||
'b', 'n', 'm', ',', '.', '/', '?', '?', '?', ' ',
|
|
||||||
};
|
|
||||||
|
|
||||||
enum { kbd_buf_capacity = PGSIZE };
|
static void kbd_interrupt_handler(registers_t *r) {
|
||||||
|
|
||||||
static void interrupt_handler(registers_t *r) {
|
|
||||||
uint8_t scancode = port_byte_in(0x60);
|
uint8_t scancode = port_byte_in(0x60);
|
||||||
if (scancode < sizeof(sc_ascii)) {
|
if (kbd_state_shrd.len < KEYBOARD_INTERRUPT_BUF_CAP) {
|
||||||
char c = sc_ascii[scancode];
|
kbd_state_shrd.buf[kbd_state_shrd.len++] = scancode;
|
||||||
if (kbd_buf_size < kbd_buf_capacity) {
|
|
||||||
kbd_buf[kbd_buf_size++] = c;
|
|
||||||
}
|
|
||||||
char string[] = {c, '\0'};
|
|
||||||
printk(string);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char* kbd_buf;
|
|
||||||
unsigned kbd_buf_size;
|
|
||||||
|
|
||||||
void init_keyboard() {
|
void init_keyboard() {
|
||||||
kbd_buf = kalloc();
|
kbd_state_shrd.len = 0;
|
||||||
|
kbd_state_shrd.buf = (uint8_t*)kalloc();
|
||||||
|
kbd_state_shrd.copy_len = 0;
|
||||||
|
kbd_state_shrd.copy_buf = (uint8_t*)kalloc();
|
||||||
|
|
||||||
register_interrupt_handler(IRQ1, interrupt_handler);
|
/* 128/8 actually we need only 16 bytes for that */
|
||||||
|
memset(kbd_state_shrd.copy_pressed, 0, 16);
|
||||||
|
register_interrupt_handler(IRQ1, kbd_interrupt_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reading keyboard */
|
||||||
|
uint8_t kbd_take_from_copy_buffer() {
|
||||||
|
check(kbd_state_shrd.copy_len > 0);
|
||||||
|
uint8_t key_event_code = kbd_state_shrd.copy_buf[--kbd_state_shrd.copy_len];
|
||||||
|
uint8_t keycode = (key_event_code & 0x7f);
|
||||||
|
if (key_event_code & 0x80) {
|
||||||
|
kbd_state_shrd.copy_pressed[keycode >> 3] = kbd_state_shrd.copy_pressed[keycode >> 3] & (~(1u << (keycode & 0x7)));
|
||||||
|
} else {
|
||||||
|
kbd_state_shrd.copy_pressed[keycode >> 3] = kbd_state_shrd.copy_pressed[keycode >> 3] | (1u << (keycode & 0x7));
|
||||||
|
}
|
||||||
|
return key_event_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool kbd_can_take_from_copy_buffer() {
|
||||||
|
return kbd_state_shrd.copy_len > 0;
|
||||||
}
|
}
|
||||||
@ -1,6 +1,43 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define KEYBOARD_INTERRUPT_BUF_CAP 100
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
volatile uint32_t len;
|
||||||
|
uint8_t *buf;
|
||||||
|
|
||||||
|
uint32_t copy_len;
|
||||||
|
uint8_t *copy_buf;
|
||||||
|
uint8_t copy_pressed[16];
|
||||||
|
} keyboard_interrupt_shared_t;
|
||||||
|
|
||||||
|
#define KEYCODE_SHIFT 42
|
||||||
|
#define KEYCODE_ENTER 28
|
||||||
|
|
||||||
|
/* decoding */
|
||||||
|
static const char keysym_mapped_ascii_lower[] = {
|
||||||
|
0 , 0 , '1', '2', '3', '4', '5', '6',
|
||||||
|
'7', '8', '9', '0', '-', '=', 0 , 0 , 'q', 'w', 'e', 'r', 't', 'y',
|
||||||
|
'u', 'i', 'o', 'p', '[', ']', '\n', 0 , 'a', 's', 'd', 'f', 'g',
|
||||||
|
'h', 'j', 'k', 'l', ';', '\'', '`', 0 , '\\', 'z', 'x', 'c', 'v',
|
||||||
|
'b', 'n', 'm', ',', '.', '/', 0 , 0 , 0 , ' ',
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char keysym_mapped_ascii_upper[] = {
|
||||||
|
0 , 0 , '!', '@', '#', '$', '%', '^',
|
||||||
|
'&', '*', '(', ')', '_', '+', 0 , 0 , 'Q', 'W', 'E', 'R', 'T', 'Y',
|
||||||
|
'U', 'I', 'O', 'P', '{', '}', '\n', 0 , 'A', 'S', 'D', 'F', 'G',
|
||||||
|
'H', 'J', 'K', 'L', ':', '"', '~', 0 , '\\', 'Z', 'X', 'C', 'V',
|
||||||
|
'B', 'N', 'M', '<', '>', '?' /* an actual question mark */, 0 , 0 , 0 , ' ',
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern keyboard_interrupt_shared_t kbd_state_shrd;
|
||||||
|
|
||||||
void init_keyboard();
|
void init_keyboard();
|
||||||
|
|
||||||
extern unsigned kbd_buf_size;
|
uint8_t kbd_take_from_copy_buffer();
|
||||||
extern char *kbd_buf;
|
bool kbd_can_take_from_copy_buffer();
|
||||||
83
kernel.c
83
kernel.c
@ -30,6 +30,54 @@ void graphtest() {
|
|||||||
vga_clear_screen();
|
vga_clear_screen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void read_line_input(char* buf, size_t* ret_len, size_t cap) {
|
||||||
|
size_t len = 0;
|
||||||
|
while (1) {
|
||||||
|
while (kbd_can_take_from_copy_buffer()) {
|
||||||
|
uint8_t keycode = kbd_take_from_copy_buffer();
|
||||||
|
|
||||||
|
bool shift_pressed = kbd_state_shrd.copy_pressed[42 >> 3] & (42 & 0x7);
|
||||||
|
const size_t keycodes = sizeof(keysym_mapped_ascii_upper);
|
||||||
|
check(keycodes == sizeof(keysym_mapped_ascii_lower));
|
||||||
|
|
||||||
|
if (keycode == KEYCODE_ENTER) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (keycode < keycodes && keycode) {
|
||||||
|
char ch = shift_pressed ? keysym_mapped_ascii_upper[keycode] :
|
||||||
|
keysym_mapped_ascii_lower[keycode];
|
||||||
|
if (ch != 0) {
|
||||||
|
char haha[2] = {ch, 0};
|
||||||
|
printk(haha);
|
||||||
|
|
||||||
|
buf[len++] = ch;
|
||||||
|
if (len == cap) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
asm("hlt");
|
||||||
|
size_t count = kbd_state_shrd.len;
|
||||||
|
if (count > 0) {
|
||||||
|
// char haha[2] = {count+'0', 0};
|
||||||
|
// printk(haha);
|
||||||
|
cli();
|
||||||
|
size_t rem = KEYBOARD_INTERRUPT_BUF_CAP - kbd_state_shrd.copy_len;
|
||||||
|
size_t copying = rem < count ? rem : count;
|
||||||
|
memcpy(kbd_state_shrd.copy_buf, kbd_state_shrd.buf, copying);
|
||||||
|
kbd_state_shrd.len -= copying;
|
||||||
|
kbd_state_shrd.copy_len += copying;
|
||||||
|
sti();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
printk("\n");
|
||||||
|
*ret_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void kmain() {
|
void kmain() {
|
||||||
freerange(P2V(1u<<20), P2V(2u<<20)); // 1MB - 2MB
|
freerange(P2V(1u<<20), P2V(2u<<20)); // 1MB - 2MB
|
||||||
kvmalloc(); // map all of physical memory at KERNBASE
|
kvmalloc(); // map all of physical memory at KERNBASE
|
||||||
@ -43,30 +91,33 @@ void kmain() {
|
|||||||
sti();
|
sti();
|
||||||
|
|
||||||
vga_clear_screen();
|
vga_clear_screen();
|
||||||
printk("YABLOKO\n");
|
printk("YABLOKO\n\n");
|
||||||
|
|
||||||
printk("\n> ");
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (kbd_buf_size > 0 && kbd_buf[kbd_buf_size-1] == '\n') {
|
char input[100];
|
||||||
if (!strncmp("halt\n", kbd_buf, kbd_buf_size)) {
|
size_t input_len = 0;
|
||||||
|
const size_t input_cap = sizeof(input) - 1;
|
||||||
|
printk("> ");
|
||||||
|
read_line_input(input, &input_len, input_cap);
|
||||||
|
input[input_len] = 0;
|
||||||
|
printk(input);
|
||||||
|
printk("\n");
|
||||||
|
if (cstr_equal(input, "halt")) {
|
||||||
|
printk("Bye\n");
|
||||||
qemu_shutdown();
|
qemu_shutdown();
|
||||||
} else if (!strncmp("work\n", kbd_buf, kbd_buf_size)) {
|
} else if (cstr_equal(input, "work")) {
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
msleep(1000);
|
msleep(1000);
|
||||||
printk(".");
|
printk(".");
|
||||||
}
|
}
|
||||||
} else if (!strncmp("run ", kbd_buf, 4)) {
|
} else if (cstr_equal(input, "graphtest")) {
|
||||||
kbd_buf[kbd_buf_size-1] = '\0';
|
|
||||||
const char* cmd = kbd_buf + 4;
|
|
||||||
run_elf(cmd);
|
|
||||||
} else if (!strncmp("graphtest", kbd_buf, 9)) {
|
|
||||||
graphtest();
|
graphtest();
|
||||||
|
} else if (cstr_starts_with(input, "run ")) {
|
||||||
|
const char* cmd = input + 4;
|
||||||
|
run_elf(cmd);
|
||||||
} else {
|
} else {
|
||||||
printk("unknown command, try: halt | run CMD");
|
printk("as\n");
|
||||||
}
|
printk("unknown command, try: halt | run CMD\n");
|
||||||
kbd_buf_size = 0;
|
}
|
||||||
printk("\n> ");
|
|
||||||
}
|
|
||||||
asm("hlt");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
26
lib/string.c
26
lib/string.c
@ -1,5 +1,12 @@
|
|||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
|
|
||||||
|
void memcpy(void*dst, const void *src, size_t size) {
|
||||||
|
for (size_t i = 0; i < size; i++) {
|
||||||
|
((char*)dst)[i] = ((const char*)src)[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void kmemmove(char* dst, char* src, size_t size) {
|
void kmemmove(char* dst, char* src, size_t size) {
|
||||||
if (dst == src) return;
|
if (dst == src) return;
|
||||||
if (dst > src && dst < src + size) { // s d
|
if (dst > src && dst < src + size) { // s d
|
||||||
@ -26,3 +33,22 @@ int strncmp(const char* s1, const char* s2, size_t size) {
|
|||||||
}
|
}
|
||||||
return (unsigned char)(*s1) - (unsigned char)(*s2);
|
return (unsigned char)(*s1) - (unsigned char)(*s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cstr_equal(const char* s1, const char* s2) {
|
||||||
|
while (*s1 && *s2 && *s1 == *s2) {
|
||||||
|
s1++;
|
||||||
|
s2++;
|
||||||
|
}
|
||||||
|
return *s1 == 0 && *s2 == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool cstr_starts_with(const char *A, const char *B) {
|
||||||
|
while (*A && *B) {
|
||||||
|
if (*A != *B)
|
||||||
|
return false;
|
||||||
|
A++;
|
||||||
|
B++;
|
||||||
|
}
|
||||||
|
return *B == 0;
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef unsigned size_t;
|
typedef unsigned size_t;
|
||||||
|
|
||||||
|
void memcpy(void*dst, const void *src, size_t size);
|
||||||
void kmemmove(char* dst, char* src, size_t size);
|
void kmemmove(char* dst, char* src, size_t size);
|
||||||
int strncmp(const char* s1, const char* s2, size_t size);
|
int strncmp(const char* s1, const char* s2, size_t size);
|
||||||
|
bool cstr_equal(const char* s1, const char* s2);
|
||||||
|
bool cstr_starts_with(const char *A, const char *B);
|
||||||
Loading…
x
Reference in New Issue
Block a user