I think I reached kernel size limit, lol

This commit is contained in:
Андреев Григорий 2026-04-03 21:25:05 +03:00
parent 4ef561edf5
commit 79f4d25c27
7 changed files with 185 additions and 57 deletions

View File

@ -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.

View File

@ -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"); }

View File

@ -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;
} }

View File

@ -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();

View File

@ -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");
} }
} }

View File

@ -1,18 +1,25 @@
#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
// copy right-to-left // copy right-to-left
for (; size != 0; size--) { for (; size != 0; size--) {
dst[size - 1] = src[size - 1]; dst[size - 1] = src[size - 1];
} }
} else { } else {
// copy left-to-right // copy left-to-right
for (size_t i = 0; i < size; ++i) { for (size_t i = 0; i < size; ++i) {
dst[i] = src[i]; dst[i] = src[i];
} }
} }
} }
int strncmp(const char* s1, const char* s2, size_t size) { 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); 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;
}

View File

@ -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);