Minimal device system, implement terminal device and libterminal
All checks were successful
Build documentation / build-and-deploy (push) Successful in 55s

This commit is contained in:
2026-02-12 15:49:04 +01:00
parent 4ad1519e06
commit f07e920270
40 changed files with 4664 additions and 7 deletions

2
kernel/Flanterm/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*.d
*.o

22
kernel/Flanterm/LICENSE Normal file
View File

@@ -0,0 +1,22 @@
Copyright (C) 2022-2026 Mintsuki and contributors.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

43
kernel/Flanterm/README.md Normal file
View File

@@ -0,0 +1,43 @@
# Flanterm
Flanterm is a fast and reasonably complete terminal emulator with support for
multiple output backends. Included is a fast framebuffer backend.
### Quick usage
To quickly set up and use a framebuffer Flanterm instance, it is possible to
use the `flanterm_fb_init()` function as such:
```c
#include <flanterm.h>
#include <flanterm_backends/fb.h>
struct flanterm_context *ft_ctx = flanterm_fb_init(
NULL,
NULL,
framebuffer_ptr, width, height, pitch,
red_mask_size, red_mask_shift,
green_mask_size, green_mask_shift,
blue_mask_size, blue_mask_shift,
NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL, 0, 0, 1,
0, 0,
0
);
```
Where `framebuffer_ptr, width, height, pitch` and `{red,green,blue}_mask_{size,shift}`
represent the corresponding info about the framebuffer to use for this given instance.
The meaning of the other arguments can be found in `flanterm_backends/fb.h`.
To then print to the terminal instance, simply use the `flanterm_write()`
function on the given instance. For example:
```c
#include <flanterm.h>
const char msg[] = "Hello world\n";
flanterm_write(ft_ctx, msg, sizeof(msg));
```

5
kernel/Flanterm/src.mk Normal file
View File

@@ -0,0 +1,5 @@
c += Flanterm/src/flanterm.c \
Flanterm/src/flanterm_backends/fb.c
o += Flanterm/src/flanterm.o \
Flanterm/src/flanterm_backends/fb.o

1
kernel/Flanterm/src/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.o

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,74 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright (C) 2022-2026 Mintsuki and contributors.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FLANTERM_H
#define FLANTERM_H 1
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define FLANTERM_CB_DEC 10
#define FLANTERM_CB_BELL 20
#define FLANTERM_CB_PRIVATE_ID 30
#define FLANTERM_CB_STATUS_REPORT 40
#define FLANTERM_CB_POS_REPORT 50
#define FLANTERM_CB_KBD_LEDS 60
#define FLANTERM_CB_MODE 70
#define FLANTERM_CB_LINUX 80
#define FLANTERM_CB_OSC 90
#ifdef FLANTERM_IN_FLANTERM
#include "flanterm_private.h"
#else
struct flanterm_context;
#endif
void flanterm_write (struct flanterm_context* ctx, const char* buf, size_t count);
void flanterm_flush (struct flanterm_context* ctx);
void flanterm_full_refresh (struct flanterm_context* ctx);
void flanterm_deinit (struct flanterm_context* ctx, void (*_free) (void* ptr, size_t size));
void flanterm_get_dimensions (struct flanterm_context* ctx, size_t* cols, size_t* rows);
void flanterm_set_autoflush (struct flanterm_context* ctx, bool state);
void flanterm_set_callback (struct flanterm_context* ctx,
void (*callback) (struct flanterm_context*, uint64_t, uint64_t,
uint64_t, uint64_t));
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1 @@
*.o

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,76 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright (C) 2022-2026 Mintsuki and contributors.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FLANTERM_FB_H
#define FLANTERM_FB_H 1
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "../flanterm.h"
#ifdef FLANTERM_IN_FLANTERM
#include "fb_private.h"
#endif
#define FLANTERM_FB_ROTATE_0 0
#define FLANTERM_FB_ROTATE_90 1
#define FLANTERM_FB_ROTATE_180 2
#define FLANTERM_FB_ROTATE_270 3
struct flanterm_context* flanterm_fb_init (
/* If _malloc and _free are nulled, use the bump allocated instance (1 use only). */
void* (*_malloc) (size_t size), void (*_free) (void* ptr, size_t size), uint32_t* framebuffer,
size_t width, size_t height, size_t pitch, uint8_t red_mask_size, uint8_t red_mask_shift,
uint8_t green_mask_size, uint8_t green_mask_shift, uint8_t blue_mask_size,
uint8_t blue_mask_shift, uint32_t* canvas, /* If nulled, no canvas. */
uint32_t* ansi_colours, uint32_t* ansi_bright_colours, /* If nulled, default. */
uint32_t* default_bg, uint32_t* default_fg, /* If nulled, default. */
uint32_t* default_bg_bright, uint32_t* default_fg_bright, /* If nulled, default. */
/* If font is null, use default font and font_width and font_height ignored. */
void* font, size_t font_width, size_t font_height, size_t font_spacing,
/* If scale_x and scale_y are 0, automatically scale font based on resolution. */
size_t font_scale_x, size_t font_scale_y, size_t margin,
/* One of FLANTERM_FB_ROTATE_* values. */
int rotation);
void flanterm_fb_set_flush_callback (struct flanterm_context* ctx,
void (*flush_callback) (volatile void* address,
size_t length));
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,127 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright (C) 2022-2026 Mintsuki and contributors.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FLANTERM_FB_PRIVATE_H
#define FLANTERM_FB_PRIVATE_H 1
#ifndef FLANTERM_IN_FLANTERM
#error "Do not use fb_private.h. Use interfaces defined in fb.h only."
#endif
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define FLANTERM_FB_FONT_GLYPHS 256
struct flanterm_fb_char {
uint32_t c;
uint32_t fg;
uint32_t bg;
};
struct flanterm_fb_queue_item {
size_t x, y;
struct flanterm_fb_char c;
};
struct flanterm_fb_context {
struct flanterm_context term;
void (*plot_char) (struct flanterm_context* ctx, struct flanterm_fb_char* c, size_t x, size_t y);
void (*flush_callback) (volatile void* address, size_t length);
size_t font_width;
size_t font_height;
size_t glyph_width;
size_t glyph_height;
size_t font_scale_x;
size_t font_scale_y;
size_t offset_x, offset_y;
volatile uint32_t* framebuffer;
size_t pitch;
size_t width;
size_t height;
size_t phys_height;
size_t bpp;
uint8_t red_mask_size, red_mask_shift;
uint8_t green_mask_size, green_mask_shift;
uint8_t blue_mask_size, blue_mask_shift;
int rotation;
size_t font_bits_size;
uint8_t* font_bits;
size_t font_bool_size;
bool* font_bool;
uint32_t ansi_colours[8];
uint32_t ansi_bright_colours[8];
uint32_t default_fg, default_bg;
uint32_t default_fg_bright, default_bg_bright;
size_t canvas_size;
uint32_t* canvas;
size_t grid_size;
size_t queue_size;
size_t map_size;
struct flanterm_fb_char* grid;
struct flanterm_fb_queue_item* queue;
size_t queue_i;
struct flanterm_fb_queue_item** map;
uint32_t text_fg;
uint32_t text_bg;
size_t cursor_x;
size_t cursor_y;
uint32_t saved_state_text_fg;
uint32_t saved_state_text_bg;
size_t saved_state_cursor_x;
size_t saved_state_cursor_y;
size_t old_cursor_x;
size_t old_cursor_y;
};
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,134 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright (C) 2022-2026 Mintsuki and contributors.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FLANTERM_PRIVATE_H
#define FLANTERM_PRIVATE_H 1
#ifndef FLANTERM_IN_FLANTERM
#error "Do not use flanterm_private.h. Use interfaces defined in flanterm.h only."
#endif
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define FLANTERM_MAX_ESC_VALUES 16
struct flanterm_context {
/* internal use */
size_t tab_size;
bool autoflush;
bool cursor_enabled;
bool scroll_enabled;
bool wrap_enabled;
bool origin_mode;
bool control_sequence;
bool escape;
bool osc;
bool osc_escape;
size_t osc_buf_i;
uint8_t osc_buf[256];
bool rrr;
bool discard_next;
bool bold;
bool bg_bold;
bool reverse_video;
bool dec_private;
bool insert_mode;
bool csi_unhandled;
uint64_t code_point;
size_t unicode_remaining;
uint8_t g_select;
uint8_t charsets[2];
size_t current_charset;
size_t escape_offset;
size_t esc_values_i;
size_t saved_cursor_x;
size_t saved_cursor_y;
size_t current_primary;
size_t current_bg;
size_t scroll_top_margin;
size_t scroll_bottom_margin;
uint32_t esc_values[FLANTERM_MAX_ESC_VALUES];
uint8_t last_printed_char;
bool last_was_graphic;
bool saved_state_bold;
bool saved_state_bg_bold;
bool saved_state_reverse_video;
bool saved_state_origin_mode;
bool saved_state_wrap_enabled;
size_t saved_state_current_charset;
uint8_t saved_state_charsets[2];
size_t saved_state_current_primary;
size_t saved_state_current_bg;
/* to be set by backend */
size_t rows, cols;
void (*raw_putchar) (struct flanterm_context*, uint8_t c);
void (*clear) (struct flanterm_context*, bool move);
void (*set_cursor_pos) (struct flanterm_context*, size_t x, size_t y);
void (*get_cursor_pos) (struct flanterm_context*, size_t* x, size_t* y);
void (*set_text_fg) (struct flanterm_context*, size_t fg);
void (*set_text_bg) (struct flanterm_context*, size_t bg);
void (*set_text_fg_bright) (struct flanterm_context*, size_t fg);
void (*set_text_bg_bright) (struct flanterm_context*, size_t bg);
void (*set_text_fg_rgb) (struct flanterm_context*, uint32_t fg);
void (*set_text_bg_rgb) (struct flanterm_context*, uint32_t bg);
void (*set_text_fg_default) (struct flanterm_context*);
void (*set_text_bg_default) (struct flanterm_context*);
void (*set_text_fg_default_bright) (struct flanterm_context*);
void (*set_text_bg_default_bright) (struct flanterm_context*);
void (*move_character) (struct flanterm_context*, size_t new_x, size_t new_y, size_t old_x,
size_t old_y);
void (*scroll) (struct flanterm_context*);
void (*revscroll) (struct flanterm_context*);
void (*swap_palette) (struct flanterm_context*);
void (*save_state) (struct flanterm_context*);
void (*restore_state) (struct flanterm_context*);
void (*double_buffer_flush) (struct flanterm_context*);
void (*full_refresh) (struct flanterm_context*);
void (*deinit) (struct flanterm_context*, void (*) (void*, size_t));
/* to be set by client */
void (*callback) (struct flanterm_context*, uint64_t, uint64_t, uint64_t, uint64_t);
};
void flanterm_context_reinit (struct flanterm_context* ctx);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -6,6 +6,7 @@
#include <amd64/msr-index.h>
#include <amd64/msr.h>
#include <aux/compiler.h>
#include <device/device.h>
#include <fs/vfs.h>
#include <irq/irq.h>
#include <libk/std.h>
@@ -45,6 +46,7 @@ void bootmain (void) {
amd64_ioapic_init ();
amd64_hpet_init ();
devices_init ();
vfs_init ();
vfs_create_mountpoint ("ramdisk", VFS_RAMDISKFS);

1
kernel/device/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.o

72
kernel/device/device.c Normal file
View File

@@ -0,0 +1,72 @@
#include <device/device.h>
#include <device/terminal.h>
#include <libk/fieldlengthof.h>
#include <libk/rbtree.h>
#include <libk/std.h>
#include <libk/string.h>
#include <m/terminal_device.h>
#include <mm/liballoc.h>
#include <sync/spin_lock.h>
static struct rb_node_link* device_tree = NULL;
static spin_lock_t device_tree_lock;
struct device* device_create (int id, device_op_func_t* ops, size_t ops_len,
bool (*init) (void* arg), void (*fini) (void), void* arg) {
if (ops_len >= fieldlengthof (struct device, ops))
return NULL;
struct device* device = malloc (sizeof (*device));
if (device == NULL)
return NULL;
memset (device, 0, sizeof (*device));
device->id = id;
device->init = init;
device->fini = fini;
memcpy (device->ops, ops, ops_len * sizeof (device_op_func_t));
if (!device->init (arg)) {
free (device);
return NULL;
}
spin_lock (&device_tree_lock);
rbtree_insert (struct device, &device_tree, &device->device_tree_link, device_tree_link, id);
spin_unlock (&device_tree_lock);
return device;
}
void device_delete (struct device* device) {
spin_lock (&device_tree_lock);
spin_lock (&device->lock);
rbtree_delete (&device_tree, &device->device_tree_link);
spin_unlock (&device->lock);
spin_unlock (&device_tree_lock);
device->fini ();
}
struct device* device_find (int id) {
struct device* device = NULL;
spin_lock (&device_tree_lock);
rbtree_find (struct device, &device_tree, id, device, device_tree_link, id);
spin_unlock (&device_tree_lock);
return device;
}
void devices_init (void) {
{
device_op_func_t ops[] = {
[TERMINAL_PUTSTR] = &terminal_putstr,
};
device_create (1, ops, lengthof (ops), &terminal_init, &terminal_fini, NULL);
}
}

24
kernel/device/device.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef _KERNEL_DEVICE_DEVICE_H
#define _KERNEL_DEVICE_DEVICE_H
#include <libk/rbtree.h>
#include <sync/spin_lock.h>
typedef int (*device_op_func_t) (void* a1, void* a2, void* a3, void* a4);
struct device {
int id;
device_op_func_t ops[32];
spin_lock_t lock;
struct rb_node_link device_tree_link;
bool (*init) (void* arg);
void (*fini) (void);
};
struct device* device_create (int id, device_op_func_t* ops, size_t ops_len,
bool (*init) (void* arg), void (*fini) (void), void* arg);
struct device* device_find (int id);
void device_delete (struct device* device);
void devices_init (void);
#endif // _KERNEL_DEVICE_DEVICE_H

5
kernel/device/src.mk Normal file
View File

@@ -0,0 +1,5 @@
c += device/device.c \
device/terminal.c
o += device/device.o \
device/terminal.o

44
kernel/device/terminal.c Normal file
View File

@@ -0,0 +1,44 @@
#include <Flanterm/src/flanterm.h>
#include <Flanterm/src/flanterm_backends/fb.h>
#include <device/terminal.h>
#include <libk/std.h>
#include <limine/requests.h>
#include <m/status.h>
#include <mm/liballoc.h>
#include <sys/debug.h>
struct flanterm_context* ft_ctx;
void* ft_malloc (size_t n) { return malloc (n); }
void ft_free (void* ptr, size_t size) {
(void)size;
free (ptr);
}
bool terminal_init (void* arg) {
(void)arg;
struct limine_framebuffer_response* fb_r = limine_framebuffer_request.response;
struct limine_framebuffer* fb = fb_r->framebuffers[0];
ft_ctx = flanterm_fb_init (&ft_malloc, &ft_free, fb->address, fb->width, fb->height, fb->pitch,
fb->red_mask_size, fb->red_mask_shift, fb->green_mask_size,
fb->green_mask_shift, fb->blue_mask_size, fb->blue_mask_shift, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 1, 0, 0, 0, 0);
return true;
}
void terminal_fini (void) {}
int terminal_putstr (void* a1, void* a2, void* a3, void* a4) {
(void)a2, (void)a3, (void)a4;
char* string = (char*)a1;
size_t* len = (size_t*)a2;
flanterm_write (ft_ctx, string, *len);
return ST_OK;
}

8
kernel/device/terminal.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef _KERNEL_DEVICE_TERMINAL_H
#define _KERNEL_DEVICE_TERMINAL_H
bool terminal_init (void* arg);
void terminal_fini (void);
int terminal_putstr (void* a1, void* a2, void* a3, void* a4);
#endif // _KERNEL_DEVICE_TERMINAL_H

View File

@@ -0,0 +1,8 @@
#ifndef _KERNEL_LIBK_FIELDLENGTHOF_H
#define _KERNEL_LIBK_FIELDLENGTHOF_H
#include <libk/lengthof.h>
#define fieldlengthof(type, field) (lengthof (((type*)0)->field))
#endif // _KERNEL_LIBK_FIELDLENGTHOF_H

View File

@@ -8,3 +8,5 @@ include irq/src.mk
include proc/src.mk
include syscall/src.mk
include fs/src.mk
include device/src.mk
include Flanterm/src.mk

View File

@@ -1,5 +1,7 @@
#include <aux/compiler.h>
#include <device/device.h>
#include <libk/assert.h>
#include <libk/fieldlengthof.h>
#include <libk/std.h>
#include <limine/requests.h>
#include <m/status.h>
@@ -166,6 +168,55 @@ DEFINE_SYSCALL (sys_mutex_unlock) {
return SYSRESULT (ST_OK);
}
/* int device_do (int device_id, int cmd, void* a1, void* a2, void* a3, void* a4) */
DEFINE_SYSCALL (sys_device_do) {
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
int device_id = (int)a1;
int cmd = (int)a2;
uintptr_t ua1 = a3, ka1 = 0;
uintptr_t ua2 = a4, ka2 = 0;
uintptr_t ua3 = a5, ka3 = 0;
uintptr_t ua4 = a6, ka4 = 0;
uintptr_t out_paddr;
if (!(cmd >= 0 && cmd < (int)fieldlengthof (struct device, ops)))
return -ST_BAD_DEVICE_OP;
spin_lock (&proc->procgroup->lock);
out_paddr = mm_v2p (&proc->procgroup->pd, ua1);
if (out_paddr != 0)
ka1 = (uintptr_t)hhdm->offset + out_paddr;
out_paddr = mm_v2p (&proc->procgroup->pd, ua2);
if (out_paddr != 0)
ka2 = (uintptr_t)hhdm->offset + out_paddr;
out_paddr = mm_v2p (&proc->procgroup->pd, ua3);
if (out_paddr != 0)
ka3 = (uintptr_t)hhdm->offset + out_paddr;
out_paddr = mm_v2p (&proc->procgroup->pd, ua4);
if (out_paddr != 0)
ka4 = (uintptr_t)hhdm->offset + out_paddr;
spin_unlock (&proc->procgroup->lock);
struct device* device = device_find (device_id);
if (device == NULL)
return -ST_NOT_FOUND;
spin_lock (&device->lock);
int ret = device->ops[cmd]((void*)ka1, (void*)ka2, (void*)ka3, (void*)ka4);
spin_unlock (&device->lock);
return ret;
}
static syscall_handler_func_t handler_table[] = {
[SYS_QUIT] = &sys_quit,
[SYS_TEST] = &sys_test,
@@ -178,6 +229,7 @@ static syscall_handler_func_t handler_table[] = {
[SYS_MUTEX_DELETE] = &sys_mutex_delete,
[SYS_MUTEX_LOCK] = &sys_mutex_lock,
[SYS_MUTEX_UNLOCK] = &sys_mutex_unlock,
[SYS_DEVICE_DO] = &sys_device_do,
};
syscall_handler_func_t syscall_find_handler (int syscall_num) {