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 \
|
||||
-mno-sse \
|
||||
-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)
|
||||
ASMFLAGS = -m32 -ffreestanding -c -g -I.
|
||||
|
||||
|
||||
@ -2,3 +2,5 @@
|
||||
|
||||
void printk(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 "kernel/mem.h"
|
||||
|
||||
static const char sc_ascii[] = {
|
||||
'?', '?', '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', ',', '.', '/', '?', '?', '?', ' ',
|
||||
};
|
||||
keyboard_interrupt_shared_t kbd_state_shrd;
|
||||
|
||||
enum { kbd_buf_capacity = PGSIZE };
|
||||
|
||||
static void interrupt_handler(registers_t *r) {
|
||||
static void kbd_interrupt_handler(registers_t *r) {
|
||||
uint8_t scancode = port_byte_in(0x60);
|
||||
if (scancode < sizeof(sc_ascii)) {
|
||||
char c = sc_ascii[scancode];
|
||||
if (kbd_buf_size < kbd_buf_capacity) {
|
||||
kbd_buf[kbd_buf_size++] = c;
|
||||
}
|
||||
char string[] = {c, '\0'};
|
||||
printk(string);
|
||||
if (kbd_state_shrd.len < KEYBOARD_INTERRUPT_BUF_CAP) {
|
||||
kbd_state_shrd.buf[kbd_state_shrd.len++] = scancode;
|
||||
}
|
||||
}
|
||||
|
||||
char* kbd_buf;
|
||||
unsigned kbd_buf_size;
|
||||
|
||||
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
|
||||
|
||||
#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();
|
||||
|
||||
extern unsigned kbd_buf_size;
|
||||
extern char *kbd_buf;
|
||||
uint8_t kbd_take_from_copy_buffer();
|
||||
bool kbd_can_take_from_copy_buffer();
|
||||
93
kernel.c
93
kernel.c
@ -30,6 +30,54 @@ void graphtest() {
|
||||
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() {
|
||||
freerange(P2V(1u<<20), P2V(2u<<20)); // 1MB - 2MB
|
||||
kvmalloc(); // map all of physical memory at KERNBASE
|
||||
@ -43,30 +91,33 @@ void kmain() {
|
||||
sti();
|
||||
|
||||
vga_clear_screen();
|
||||
printk("YABLOKO\n");
|
||||
printk("YABLOKO\n\n");
|
||||
|
||||
printk("\n> ");
|
||||
while (1) {
|
||||
if (kbd_buf_size > 0 && kbd_buf[kbd_buf_size-1] == '\n') {
|
||||
if (!strncmp("halt\n", kbd_buf, kbd_buf_size)) {
|
||||
qemu_shutdown();
|
||||
} else if (!strncmp("work\n", kbd_buf, kbd_buf_size)) {
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
msleep(1000);
|
||||
printk(".");
|
||||
}
|
||||
} else if (!strncmp("run ", kbd_buf, 4)) {
|
||||
kbd_buf[kbd_buf_size-1] = '\0';
|
||||
const char* cmd = kbd_buf + 4;
|
||||
run_elf(cmd);
|
||||
} else if (!strncmp("graphtest", kbd_buf, 9)) {
|
||||
graphtest();
|
||||
} else {
|
||||
printk("unknown command, try: halt | run CMD");
|
||||
char input[100];
|
||||
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();
|
||||
} else if (cstr_equal(input, "work")) {
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
msleep(1000);
|
||||
printk(".");
|
||||
}
|
||||
kbd_buf_size = 0;
|
||||
printk("\n> ");
|
||||
} else if (cstr_equal(input, "graphtest")) {
|
||||
graphtest();
|
||||
} else if (cstr_starts_with(input, "run ")) {
|
||||
const char* cmd = input + 4;
|
||||
run_elf(cmd);
|
||||
} else {
|
||||
printk("as\n");
|
||||
printk("unknown command, try: halt | run CMD\n");
|
||||
}
|
||||
asm("hlt");
|
||||
}
|
||||
}
|
||||
|
||||
50
lib/string.c
50
lib/string.c
@ -1,18 +1,25 @@
|
||||
#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) {
|
||||
if (dst == src) return;
|
||||
if (dst > src && dst < src + size) { // s d
|
||||
// copy right-to-left
|
||||
for (; size != 0; size--) {
|
||||
dst[size - 1] = src[size - 1];
|
||||
}
|
||||
} else {
|
||||
// copy left-to-right
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
dst[i] = src[i];
|
||||
}
|
||||
}
|
||||
if (dst == src) return;
|
||||
if (dst > src && dst < src + size) { // s d
|
||||
// copy right-to-left
|
||||
for (; size != 0; size--) {
|
||||
dst[size - 1] = src[size - 1];
|
||||
}
|
||||
} else {
|
||||
// copy left-to-right
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
dst[i] = src[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int strncmp(const char* s1, const char* s2, size_t size) {
|
||||
@ -26,3 +33,22 @@ int strncmp(const char* s1, const char* s2, size_t size) {
|
||||
}
|
||||
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
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef unsigned size_t;
|
||||
|
||||
void memcpy(void*dst, const void *src, size_t size);
|
||||
void kmemmove(char* dst, char* src, 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