summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenji Dial <benji6283@gmail.com>2021-02-19 22:24:08 -0500
committerBenji Dial <benji6283@gmail.com>2021-02-19 22:24:08 -0500
commiteae7442610215e55ea350c65aab4ab3869111014 (patch)
tree601aa476e52a5e3bb3b352df7e781d3aa11c090b
parentcba9eec34b205c760f16f7171b58bfc906723b72 (diff)
downloadportland-os-eae7442610215e55ea350c65aab4ab3869111014.tar.gz
kernel settings file
-rw-r--r--doc/internal/settings.txt31
-rw-r--r--fs-skel/sys/settings.plsbin0 -> 86 bytes
-rw-r--r--makefile2
-rw-r--r--src/kernel/kbd.c25
-rw-r--r--src/kernel/main.c7
-rw-r--r--src/kernel/settings.c91
-rw-r--r--src/kernel/settings.h16
-rw-r--r--src/kernel/window.c24
8 files changed, 179 insertions, 17 deletions
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 <layout>, the file at sys/scantabs/<layout>.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
--- /dev/null
+++ b/fs-skel/sys/settings.pls
Binary files 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 <stdint.h>
+#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 <stdint.h>
+#include "settings.h"
#include "paging.h"
#include "serial.h"
#include "window.h"
@@ -17,6 +17,8 @@
#include "pci.h"
#include "vbe.h"
+#include <stdint.h>
+
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 <stdint.h>
+
+#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 <stdbool.h>
+#include <stdint.h>
+
+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();