kernel settings file
This commit is contained in:
parent
cba9eec34b
commit
eae7442610
8 changed files with 179 additions and 17 deletions
31
doc/internal/settings.txt
Normal file
31
doc/internal/settings.txt
Normal file
|
@ -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
|
BIN
fs-skel/sys/settings.pls
Normal file
BIN
fs-skel/sys/settings.pls
Normal file
Binary file not shown.
2
makefile
2
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/serial.ko obj/kernel/task.ko obj/kernel/util.ko \
|
||||||
obj/kernel/window.ko obj/kernel/isrs.kao obj/kernel/kbd.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/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
|
mkdir -p out
|
||||||
ld -T src/kernel/elf-link.ld $^ -o obj/kernel.elf
|
ld -T src/kernel/elf-link.ld $^ -o obj/kernel.elf
|
||||||
objcopy -O binary obj/kernel.elf out/kernel.bin
|
objcopy -O binary obj/kernel.elf out/kernel.bin
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "settings.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
#include "pmap.h"
|
#include "pmap.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "kbd.h"
|
#include "kbd.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
#define SCANTAB_DIR "sys/scantabs"
|
#define SCANTAB_DIR "sys/scantabs/"
|
||||||
#define LAYOUT_HARDCODE_TMP "qwerty"
|
#define SCANTAB_DIR_LEN 13
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PS2_CMD = 0x64,
|
PS2_CMD = 0x64,
|
||||||
|
@ -45,14 +47,29 @@ enum {
|
||||||
ST_SKIP
|
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() {
|
void init_kbd() {
|
||||||
outb(PS2_CMD, PS2C_READ_CONFIG);
|
outb(PS2_CMD, PS2C_READ_CONFIG);
|
||||||
uint8_t config = inb(PS2_DATA);
|
uint8_t config = inb(PS2_DATA);
|
||||||
outb(PS2_CMD, PS2C_WRITE_CONFIG);
|
outb(PS2_CMD, PS2C_WRITE_CONFIG);
|
||||||
outb(PS2_DATA, config | PS2G_XT_COMPAT);
|
outb(PS2_DATA, config | PS2G_XT_COMPAT);
|
||||||
|
|
||||||
//TODO: get layout from some config file
|
uint32_t layout_len;
|
||||||
file_id_t stf = drives->get_file(drives, SCANTAB_DIR "/" LAYOUT_HARDCODE_TMP ".sct");
|
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);
|
fmcpy(&n_scantabs, drives, stf, 0, 4);
|
||||||
scantabs = allocate_kernel_pages((sizeof(struct scantab_info) * n_scantabs - 1) / 4096 + 1);
|
scantabs = allocate_kernel_pages((sizeof(struct scantab_info) * n_scantabs - 1) / 4096 + 1);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include <stdint.h>
|
#include "settings.h"
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
@ -17,6 +17,8 @@
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
#include "vbe.h"
|
#include "vbe.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
void _start_user_mode() __attribute__ ((noreturn));
|
void _start_user_mode() __attribute__ ((noreturn));
|
||||||
|
|
||||||
__attribute__ ((noreturn))
|
__attribute__ ((noreturn))
|
||||||
|
@ -25,7 +27,6 @@ void main() {
|
||||||
init_paging();
|
init_paging();
|
||||||
init_tasks();
|
init_tasks();
|
||||||
init_serial();
|
init_serial();
|
||||||
|
|
||||||
pci_init();
|
pci_init();
|
||||||
|
|
||||||
init_fat();
|
init_fat();
|
||||||
|
@ -37,10 +38,10 @@ void main() {
|
||||||
//other drive drivers
|
//other drive drivers
|
||||||
|
|
||||||
init_log();
|
init_log();
|
||||||
|
init_settings();
|
||||||
|
|
||||||
init_kbd();
|
init_kbd();
|
||||||
init_idt();
|
init_idt();
|
||||||
|
|
||||||
init_win();
|
init_win();
|
||||||
|
|
||||||
logf(LOG_INFO, "Kernel initialization done.");
|
logf(LOG_INFO, "Kernel initialization done.");
|
||||||
|
|
91
src/kernel/settings.c
Normal file
91
src/kernel/settings.c
Normal file
|
@ -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;
|
||||||
|
}
|
16
src/kernel/settings.h
Normal file
16
src/kernel/settings.h
Normal file
|
@ -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
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "settings.h"
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
|
@ -16,7 +17,7 @@
|
||||||
#define GSC(x, y) (x / 4 + y / 4 >= 256 ? 255 : x / 4 + y / 4)
|
#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 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
|
#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;
|
const uint32_t fb_len = VBE_MODE_INFO->width * VBE_MODE_INFO->height;
|
||||||
buffer_pages = (fb_len * sizeof(struct pixel) - 1) / 4096 + 1;
|
buffer_pages = (fb_len * sizeof(struct pixel) - 1) / 4096 + 1;
|
||||||
buffer = allocate_kernel_pages(buffer_pages);
|
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))))
|
#define MASK(offset, length) ((~((1 << offset) - 1)) - (offset + length == 32 ? 0 : (~((1 << (offset + length)) - 1))))
|
||||||
pix_clear_mask = ~(
|
pix_clear_mask = ~(
|
||||||
|
@ -116,14 +119,14 @@ static void paint_and_above(const struct window *w) {
|
||||||
for (uint16_t x = xs; x < xm; ++x)
|
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];
|
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 - 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 - 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, 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_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 - 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 - 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, 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_vt_line(i->xpos + i->width + 1, i->ypos, i->ypos + i->height, border_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
blit();
|
blit();
|
||||||
|
@ -296,6 +299,9 @@ static char *run_command;
|
||||||
static char *run_command_pass = "";
|
static char *run_command_pass = "";
|
||||||
|
|
||||||
void init_win() {
|
void init_win() {
|
||||||
|
if (!try_get_color_setting("wm-border-color", &border_color))
|
||||||
|
PANIC("could not load window border color setting.");
|
||||||
|
|
||||||
buffer = 0;
|
buffer = 0;
|
||||||
load_mode_params();
|
load_mode_params();
|
||||||
|
|
||||||
|
|
Reference in a new issue