From eae7442610215e55ea350c65aab4ab3869111014 Mon Sep 17 00:00:00 2001 From: Benji Dial Date: Fri, 19 Feb 2021 22:24:08 -0500 Subject: kernel settings file --- doc/internal/settings.txt | 31 ++++++++++++++++ fs-skel/sys/settings.pls | Bin 0 -> 86 bytes makefile | 2 +- src/kernel/kbd.c | 25 +++++++++++-- src/kernel/main.c | 7 ++-- src/kernel/settings.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++ src/kernel/settings.h | 16 ++++++++ src/kernel/window.c | 24 +++++++----- 8 files changed, 179 insertions(+), 17 deletions(-) create mode 100644 doc/internal/settings.txt create mode 100644 fs-skel/sys/settings.pls create mode 100644 src/kernel/settings.c create mode 100644 src/kernel/settings.h diff --git a/doc/internal/settings.txt b/doc/internal/settings.txt new file mode 100644 index 0000000..f0ba6a8 --- /dev/null +++ b/doc/internal/settings.txt @@ -0,0 +1,31 @@ +header format: + dword: offset of main area start + dword: number of main area entries + dword: offset of name area start + dword: offset of data area start + +main area entry format: + dword: offset into name area of setting name + byte: setting name length + byte: setting type + 0x00: string + 0x01: color + others: reserved + word: reserved + qword: + if sz string: + dword: offset into data area of start + dword: length of string + if color: + byte: red value + byte: green value + byte: blue value + byte: reserved + dword: reserved + +currently used settings: + "kbd-layout", sz string: + the name of the scancode table for the keyboard driver to use. + if it is , the file at sys/scantabs/.sct is loaded. + "wm-border-color", color: + the color to use for window borders \ No newline at end of file diff --git a/fs-skel/sys/settings.pls b/fs-skel/sys/settings.pls new file mode 100644 index 0000000..c1f97a9 Binary files /dev/null and b/fs-skel/sys/settings.pls differ diff --git a/makefile b/makefile index fe212a5..17dc0ec 100644 --- a/makefile +++ b/makefile @@ -55,7 +55,7 @@ out/kernel.bin: obj/kernel/drive.ko obj/kernel/fat.ko obj/kernel/ide.ko \ obj/kernel/serial.ko obj/kernel/task.ko obj/kernel/util.ko \ obj/kernel/window.ko obj/kernel/isrs.kao obj/kernel/kbd.ko \ obj/kernel/pmap.ko obj/kernel/paging.ko obj/kernel/dump.ko \ - obj/kernel/cmos.ko + obj/kernel/cmos.ko obj/kernel/settings.ko mkdir -p out ld -T src/kernel/elf-link.ld $^ -o obj/kernel.elf objcopy -O binary obj/kernel.elf out/kernel.bin diff --git a/src/kernel/kbd.c b/src/kernel/kbd.c index c09684d..96d2069 100644 --- a/src/kernel/kbd.c +++ b/src/kernel/kbd.c @@ -1,14 +1,16 @@ #include +#include "settings.h" #include "window.h" #include "drive.h" #include "panic.h" #include "pmap.h" #include "util.h" #include "kbd.h" +#include "log.h" -#define SCANTAB_DIR "sys/scantabs" -#define LAYOUT_HARDCODE_TMP "qwerty" +#define SCANTAB_DIR "sys/scantabs/" +#define SCANTAB_DIR_LEN 13 enum { PS2_CMD = 0x64, @@ -45,14 +47,29 @@ enum { ST_SKIP }; +#define LAYOUT_NAME_MAX_LEN 31 +static char scantab_path[SCANTAB_DIR_LEN + LAYOUT_NAME_MAX_LEN + 5] = SCANTAB_DIR; + void init_kbd() { outb(PS2_CMD, PS2C_READ_CONFIG); uint8_t config = inb(PS2_DATA); outb(PS2_CMD, PS2C_WRITE_CONFIG); outb(PS2_DATA, config | PS2G_XT_COMPAT); - //TODO: get layout from some config file - file_id_t stf = drives->get_file(drives, SCANTAB_DIR "/" LAYOUT_HARDCODE_TMP ".sct"); + uint32_t layout_len; + if (!try_get_sz_setting("kbd-layout", scantab_path + SCANTAB_DIR_LEN, LAYOUT_NAME_MAX_LEN, &layout_len)) + PANIC("keyboard layout not found in settings file."); + if (layout_len == LAYOUT_NAME_MAX_LEN) + logf(LOG_WARN, "keyboard layout name potentially cropped."); + scantab_path[SCANTAB_DIR_LEN + layout_len] = '.'; + scantab_path[SCANTAB_DIR_LEN + layout_len + 1] = 's'; + scantab_path[SCANTAB_DIR_LEN + layout_len + 2] = 'c'; + scantab_path[SCANTAB_DIR_LEN + layout_len + 3] = 't'; + scantab_path[SCANTAB_DIR_LEN + layout_len + 4] = '\0'; + logf(LOG_INFO, "Using scantab file at \"%s\".", scantab_path); + file_id_t stf = drives->get_file(drives, scantab_path); + if (!stf) + PANIC("could not load scantab file."); fmcpy(&n_scantabs, drives, stf, 0, 4); scantabs = allocate_kernel_pages((sizeof(struct scantab_info) * n_scantabs - 1) / 4096 + 1); diff --git a/src/kernel/main.c b/src/kernel/main.c index 43778d4..7e49049 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,4 +1,4 @@ -#include +#include "settings.h" #include "paging.h" #include "serial.h" #include "window.h" @@ -17,6 +17,8 @@ #include "pci.h" #include "vbe.h" +#include + void _start_user_mode() __attribute__ ((noreturn)); __attribute__ ((noreturn)) @@ -25,7 +27,6 @@ void main() { init_paging(); init_tasks(); init_serial(); - pci_init(); init_fat(); @@ -37,10 +38,10 @@ void main() { //other drive drivers init_log(); + init_settings(); init_kbd(); init_idt(); - init_win(); logf(LOG_INFO, "Kernel initialization done."); diff --git a/src/kernel/settings.c b/src/kernel/settings.c new file mode 100644 index 0000000..699196b --- /dev/null +++ b/src/kernel/settings.c @@ -0,0 +1,91 @@ +#include "window.h" +#include "drive.h" +#include "panic.h" +#include "util.h" + +#include + +#define SETTINGS_FILE "sys/settings.pls" + +static struct { + uint32_t main_start; + uint32_t main_entries; + uint32_t names_start; + uint32_t data_start; +} settings_header; + +enum { + ST_SZ_STRING = 0x00, + ST_COLOR = 0x01 +}; + +struct main_entry { + uint32_t name_offset; + uint8_t name_len; + uint8_t type; + uint16_t pad; + union { + struct { + uint32_t data_offset; + uint32_t length; + } as_string; + struct pixel as_pixel; + }; +} __attribute__ ((__packed__)); + +static file_id_t fid; +static uint32_t main_end; + +void init_settings() { + fid = drives->get_file(drives, SETTINGS_FILE); + if (!fid) + PANIC("could not open settings file at \"" SETTINGS_FILE "\"."); + + fmcpy(&settings_header, drives, fid, 0, 16); + + main_end = settings_header.main_start + settings_header.main_entries * sizeof(struct main_entry); +} + +bool try_find_setting(const char *name, struct main_entry *entry_out) { + uint16_t name_len = 0; + while (name[name_len]) + if (++name_len == 256) + return false; + + for (uint32_t i = settings_header.main_start; i < main_end; i += sizeof(struct main_entry)) { + fmcpy(entry_out, drives, fid, i, sizeof(struct main_entry)); + if (entry_out->name_len != name_len) + continue; + char found_name[255]; + fmcpy(found_name, drives, fid, settings_header.names_start + entry_out->name_offset, name_len); + for (uint8_t j = 0; j < name_len; ++j) + if (found_name[j] != name[j]) + goto lc; + return true; + lc: + ; + } + + return false; +} + +bool try_get_sz_setting(const char *name, char *out, uint32_t max_len, uint32_t *len_out) { + struct main_entry entry; + if (!try_find_setting(name, &entry) || (entry.type != ST_SZ_STRING)) + return false; + + const uint32_t len = entry.as_string.length > max_len ? max_len : entry.as_string.length; + fmcpy(out, drives, fid, settings_header.data_start + entry.as_string.data_offset, len); + out[len] = '\0'; + *len_out = len; + return true; +} + +bool try_get_color_setting(const char *name, struct pixel *out) { + struct main_entry entry; + if (!try_find_setting(name, &entry) || (entry.type != ST_COLOR)) + return false; + + *out = entry.as_pixel; + return true; +} \ No newline at end of file diff --git a/src/kernel/settings.h b/src/kernel/settings.h new file mode 100644 index 0000000..f25d4df --- /dev/null +++ b/src/kernel/settings.h @@ -0,0 +1,16 @@ +#ifndef SETTINGS_H +#define SETTINGS_H + +#include "window.h" + +#include +#include + +void init_settings(); + +//lengths do not include null terminator. if setting value is too long, it is cropped. +bool try_get_sz_setting(const char *name, char *out, uint32_t max_len, uint32_t *len_out); + +bool try_get_color_setting(const char *name, struct pixel *out); + +#endif \ No newline at end of file diff --git a/src/kernel/window.c b/src/kernel/window.c index 4d700bf..79d718e 100644 --- a/src/kernel/window.c +++ b/src/kernel/window.c @@ -1,3 +1,4 @@ +#include "settings.h" #include "paging.h" #include "window.h" #include "drive.h" @@ -16,7 +17,7 @@ #define GSC(x, y) (x / 4 + y / 4 >= 256 ? 255 : x / 4 + y / 4) #define BACKGROUND(x, y) ((struct pixel){.r = GSC(x / 2, y / 3), .g = GSC(x, y), .b = GSC(x, y / 2)}) -#define BORDER_COLOR ((struct pixel){.r = 0x11, .g = 0x11, .b = 0x11}) +static struct pixel border_color; #define MOVE_BY 5 @@ -52,6 +53,8 @@ static void load_mode_params() { const uint32_t fb_len = VBE_MODE_INFO->width * VBE_MODE_INFO->height; buffer_pages = (fb_len * sizeof(struct pixel) - 1) / 4096 + 1; buffer = allocate_kernel_pages(buffer_pages); + if (!buffer) + PANIC("could not allocate intermediate framebuffer"); #define MASK(offset, length) ((~((1 << offset) - 1)) - (offset + length == 32 ? 0 : (~((1 << (offset + length)) - 1)))) pix_clear_mask = ~( @@ -116,14 +119,14 @@ static void paint_and_above(const struct window *w) { for (uint16_t x = xs; x < xm; ++x) buffer[((y + i->ypos) & 0xffff) * VBE_MODE_INFO->width + ((x + i->xpos) & 0xffff)] = i->pixel_buffer_pma[y * i->width + x]; - draw_hz_line(i->ypos - 2, i->xpos - 2, i->xpos + i->width + 2, BORDER_COLOR); - draw_hz_line(i->ypos - 1, i->xpos - 2, i->xpos + i->width + 2, BORDER_COLOR); - draw_hz_line(i->ypos + i->height, i->xpos - 2, i->xpos + i->width + 2, BORDER_COLOR); - draw_hz_line(i->ypos + i->height + 1, i->xpos - 2, i->xpos + i->width + 2, BORDER_COLOR); - draw_vt_line(i->xpos - 2, i->ypos, i->ypos + i->height, BORDER_COLOR); - draw_vt_line(i->xpos - 1, i->ypos, i->ypos + i->height, BORDER_COLOR); - draw_vt_line(i->xpos + i->width, i->ypos, i->ypos + i->height, BORDER_COLOR); - draw_vt_line(i->xpos + i->width + 1, i->ypos, i->ypos + i->height, BORDER_COLOR); + draw_hz_line(i->ypos - 2, i->xpos - 2, i->xpos + i->width + 2, border_color); + draw_hz_line(i->ypos - 1, i->xpos - 2, i->xpos + i->width + 2, border_color); + draw_hz_line(i->ypos + i->height, i->xpos - 2, i->xpos + i->width + 2, border_color); + draw_hz_line(i->ypos + i->height + 1, i->xpos - 2, i->xpos + i->width + 2, border_color); + draw_vt_line(i->xpos - 2, i->ypos, i->ypos + i->height, border_color); + draw_vt_line(i->xpos - 1, i->ypos, i->ypos + i->height, border_color); + draw_vt_line(i->xpos + i->width, i->ypos, i->ypos + i->height, border_color); + draw_vt_line(i->xpos + i->width + 1, i->ypos, i->ypos + i->height, border_color); } blit(); @@ -296,6 +299,9 @@ static char *run_command; static char *run_command_pass = ""; void init_win() { + if (!try_get_color_setting("wm-border-color", &border_color)) + PANIC("could not load window border color setting."); + buffer = 0; load_mode_params(); -- cgit v1.2.3