diff options
-rw-r--r-- | README.md | 35 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | lib/Makefile | 1 | ||||
-rw-r--r-- | lib/libgfx/Makefile | 1 | ||||
-rw-r--r-- | lib/libgfx/include/libgfx/draw.h | 11 | ||||
-rw-r--r-- | lib/libgfx/include/libgfx/gfx.h | 11 | ||||
-rw-r--r-- | lib/liboda/Makefile | 29 | ||||
-rw-r--r-- | lib/liboda/include/liboda/oda.h | 89 | ||||
-rw-r--r-- | lib/liboda/include/liboda/odavar.h | 59 | ||||
-rw-r--r-- | lib/liboda/include/liboda/types.h | 40 | ||||
-rw-r--r-- | lib/liboda/src/oda.c | 77 | ||||
-rw-r--r-- | lib/liboda/src/window.c | 153 | ||||
-rw-r--r-- | share/docs/kernel/ctlfs.md | 125 | ||||
-rw-r--r-- | share/docs/lib/liboda.md | 191 | ||||
-rw-r--r-- | share/man/man1/osh.1 | 83 | ||||
-rw-r--r-- | sys/include/fs/ctlfs.h | 6 |
16 files changed, 891 insertions, 22 deletions
@@ -1,14 +1,22 @@ The Hyra Operating System ========================= -Welcome to the Hyra Operating System project! +Welcome to the Hyra Operating System project! Hyra is an experimental +operating system inspired by BSD and Plan 9 while being entirely written from scratch. +Hyra aims to rethink core fundamentals in modern operating system design in order to +create new and improved architectural ideas. + Project Goal: -------------- -The goal of this project is to redefine what modern operating systems are while taking inspiration from BSD. Hyra does not use -POSIX by default and instead uses the [OSMORA Uniform System Interface (OUSI)](https://osmora.org/oap/oap-0002). Hyra also does +The goal of this project is to redefine what modern operating systems are while taking inspiration from BSD. Hyra does not use CPIO for its initramfs like other operating systems typically would and instead uses the [OSMORA Archive Format (OMAR)](https://osmora.org/oap/oap-0005). +What Hyra is NOT: +-------------- +Hyra is *NOT* Linux, nor does extend or share any sources with any existing +operating systems as it is written entirely from scratch. Hyra is *NOT* intended as a "toy" project as it is aimed to be the used as the main operating system for internal OSMORA operations and infrastructure. + Getting Started: ---------------- To build Hyra you'll need to bootstrap the project which is essentially just fetching dependencies for the project. This can be done by running the bootstrap script within the project root: `./bootstrap`. @@ -31,7 +39,7 @@ password is also `root`. Programs: ---------------- -The Hyra userspace provides the user various programs that they can run, examples of +The Hyra userspace provides the user various programs that they can run. Examples of such programs include: - ``beep`` - Play a tone @@ -47,12 +55,29 @@ such programs include: - ``readcore`` - Read coredump files - ``oasm`` - OSMORA [OSMX64](https://github.com/sigsegv7/OSMX64) Assembler - ``oemu`` - OSMORA [OSMX64](https://github.com/sigsegv7/OSMX64) Emulator +- ``kstat`` - Read kernel statistics +- ``dmidump`` - Dump DMI/SMBios information And more! See ``usr.bin/*`` +Libraries: +---------------- +The Hyra userspace additionally provides the user various libraries that they can +link with. Examples of such libraries include: + +- ``libc`` - C library (link flag: ``-lc``) +- ``libgfx`` - Low-level graphics (link flag: ``-lgfx``) + +And more! See ``lib/*`` + Documentation: -------------- -Documentation will be in the form of comments throughout the codebase and can also be found in the share/ directory within the project root. +Documentation will be in the form of comments throughout the codebase and can also be found in: + +- ``share/man/*``: Man pages +- ``share/contrib``: Information on contributing +- ``share/docs/kernel``: Kernel documentation +- ``share/docs/lib``: Library documentation Hyra running on bare metal: -------------- diff --git a/configure.ac b/configure.ac index ecbeafe..6db3a09 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([Hyra], [2.4], [ian@osmora.org]) +AC_INIT([Hyra], [2.5], [ian@osmora.org]) TARGET="amd64" QEMU="qemu-system-x86_64" diff --git a/lib/Makefile b/lib/Makefile index 4ad104b..fc77815 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -7,3 +7,4 @@ ARGS = -I$(ROOT)/builddeps LDSCRIPT=$(LDSCRIPT) USRDIR=$(USRDIR) ROOT=$(ROOT) all: make -C libc/ $(ARGS) make -C libgfx/ $(ARGS) + make -C liboda/ $(ARGS) diff --git a/lib/libgfx/Makefile b/lib/libgfx/Makefile index 1f866ac..12fdd9a 100644 --- a/lib/libgfx/Makefile +++ b/lib/libgfx/Makefile @@ -4,7 +4,6 @@ CFILES = $(shell find src/ -name "*.c") OBJ = $(CFILES:.c=.o) all: headers $(OBJ) build/libgfx.a - echo "----------------------------------------" echo $(USRDIR) mv build/libgfx.a $(USRDIR)/lib/ cp -r include/ $(USRDIR)/include/ diff --git a/lib/libgfx/include/libgfx/draw.h b/lib/libgfx/include/libgfx/draw.h index 60d2b24..3bd013a 100644 --- a/lib/libgfx/include/libgfx/draw.h +++ b/lib/libgfx/include/libgfx/draw.h @@ -36,6 +36,17 @@ /* Shape types */ #define SHAPE_SQUARE 0x00000000 +/* Basic color defines */ +#define GFX_BLACK 0x000000 +#define GFX_RED 0xFF0000 +#define GFX_GREEN 0x00FF00 +#define GFX_BLUE 0x0000FF +#define GFX_WHITE 0xFFFFFF +#define GFX_PURPLE 0x800080 +#define GFX_YELLOW 0xFFFF00 +#define GFX_DARK 0x1D2021 +#define GFX_AQUA 0x427B58 + /* * Default shape initializer, something that * works and can be tweaked. The idea of this diff --git a/lib/libgfx/include/libgfx/gfx.h b/lib/libgfx/include/libgfx/gfx.h index 3468571..67a1006 100644 --- a/lib/libgfx/include/libgfx/gfx.h +++ b/lib/libgfx/include/libgfx/gfx.h @@ -48,17 +48,6 @@ typedef uint32_t pixel_t; typedef pixel_t color_t; /* - * Basic color defines - */ -#define GFX_BLACK 0x000000 -#define GFX_RED 0xFF0000 -#define GFX_GREEN 0x00FF00 -#define GFX_BLUE 0x0000FF -#define GFX_WHITE 0xFFFFFF -#define GFX_PURPLE 0x800080 -#define GFX_YELLOW 0xFFFF00 - -/* * Represents cartesian x/y values */ typedef uint32_t cartpos_t; diff --git a/lib/liboda/Makefile b/lib/liboda/Makefile new file mode 100644 index 0000000..5b4022c --- /dev/null +++ b/lib/liboda/Makefile @@ -0,0 +1,29 @@ +CFLAGS = -c -fno-stack-protector -nostdlib -static \ + -Iinclude/ -I$(USRDIR)/include/ +CFILES = $(shell find src/ -name "*.c") +OBJ = $(CFILES:.c=.o) + +all: headers $(OBJ) build/liboda.a + echo $(USRDIR) + mv build/liboda.a $(USRDIR)/lib/ + cp -r include/ $(USRDIR)/include/ + +build/liboda.a: + mkdir -p build/ + ar rcs build/liboda.a $(OBJ) + +%.o: %.c + $(CC) $(CFLAGS) -Iinclude/ $< -o $@ + +.PHONY: headers +headers: + cp -rf include/* $(USRDIR)/include/ + +.PHONY: +build/: + mkdir -p build/ + +.PHONY: clean +clean: + rm -f $(OBJ) + rm -rf build/ diff --git a/lib/liboda/include/liboda/oda.h b/lib/liboda/include/liboda/oda.h new file mode 100644 index 0000000..d807a50 --- /dev/null +++ b/lib/liboda/include/liboda/oda.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * 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. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * 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 OWNER 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 LIBODA_ODA_H +#define LIBODA_ODA_H 1 + +#include <sys/queue.h> +#include <stdint.h> +#include <stddef.h> +#include <liboda/types.h> +#include <libgfx/gfx.h> +#include <libgfx/draw.h> + +/* + * ODA representation of a window. + * + * @surface: Window surface descriptor + * @session: Session this window belongs to + */ +struct oda_window { + struct gfx_shape surface; + struct oda_state *session; + TAILQ_ENTRY(oda_window) link; +}; + +/* + * ODA session + * + * @winq: Window queue + * @gctx: Graphics context + * @cookie: State cookie (ODA_COOKIE) + */ +struct oda_state { + TAILQ_HEAD(, oda_window) winq; + struct gfx_ctx gctx; + uint32_t cookie; +}; + +/* + * ODA window attributes. Arguments to be + * passed to oda_window_new() + * + * @session: Current ODA session / state + * @parent: Window parent (NULL for root) + * @pg: Background color (0xRRGGBB) + * @x,y: Window position + * @w,h: Window width [w] and height [h] + */ +struct oda_wattr { + struct oda_state *session; + struct oda_window *parent; + odacolor_t bg; + odapos_t x, y; + odadimm_t w, h; +}; + +int oda_reqwin(struct oda_wattr *params, struct oda_window **res); +int oda_termwin(struct oda_state *state, struct oda_window *win); + +int oda_start_win(struct oda_state *state, struct oda_window *win); +int oda_init(struct oda_state *res); + +#endif /* !LIBODA_ODA_H */ diff --git a/lib/liboda/include/liboda/odavar.h b/lib/liboda/include/liboda/odavar.h new file mode 100644 index 0000000..d2dbe2e --- /dev/null +++ b/lib/liboda/include/liboda/odavar.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * 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. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * 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 OWNER 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 LIBODA_ODAVAR_H +#define LIBODA_ODAVAR_H + +#include <sys/param.h> +#include <sys/errno.h> +#include <liboda/oda.h> + +/* + * Default window attributes + */ +#define DEFAULT_WIN_HEIGHT 200 +#define DEFAULT_WIN_WIDTH 150 + +/* + * Verify that ODA structures have been properly + * initialized before usage to prevent undefined + * behaviour. + */ +#define ODA_COOKIE 0xFAFECAD + +/* + * Verify an ODA cookie - internal usage + */ +__always_inline static inline int +oda_cookie_verify(struct oda_state *state) +{ + return (state->cookie == ODA_COOKIE) ? 0 : -EFAULT; +} + +#endif /* !LIBODA_ODAVAR_H */ diff --git a/lib/liboda/include/liboda/types.h b/lib/liboda/include/liboda/types.h new file mode 100644 index 0000000..8b77aa7 --- /dev/null +++ b/lib/liboda/include/liboda/types.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * 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. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * 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 OWNER 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 LIBODA_TYPE_H +#define LIBODA_TYPE_H + +#include <stdint.h> + +typedef uint32_t odapos_t; /* X/Y positions */ +typedef uint32_t odapix_t; /* RGB pixel */ +typedef odapix_t odacolor_t; /* RGB color */ +typedef uint32_t odadimm_t; /* Dimensions */ + +#endif /* !LIBODA_TYPE_H */ diff --git a/lib/liboda/src/oda.c b/lib/liboda/src/oda.c new file mode 100644 index 0000000..0eef523 --- /dev/null +++ b/lib/liboda/src/oda.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * 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. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * 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 OWNER 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. + */ + +#include <sys/errno.h> +#include <stdio.h> +#include <libgfx/gfx.h> +#include <liboda/oda.h> +#include <liboda/odavar.h> + +#define oda_log(fmt, ...) printf("oda: " fmt, ##__VA_ARGS__) + +/* + * Initialize the OSMORA Display Architecture + * (ODA) library. + * + * @res: Initialized ODA state result + * + * Returns 0 on success, otherwise a less than + * zero value. + */ +int +oda_init(struct oda_state *res) +{ + int error; + + /* Ensure the argument is valid */ + if (res == NULL) { + return -EINVAL; + } + + /* + * If this state has already been initialized, + * assume programmer error / undefined behaviour + * and let them know. + */ + if (oda_cookie_verify(res) == 0) { + oda_log("oda_init: 'res' already initialized\n"); + return -EBUSY; + } + + /* Initialize the graphics context */ + error = gfx_init(&res->gctx); + if (error != 0) { + oda_log("oda_init: could not init graphics context\n"); + return error; + } + + TAILQ_INIT(&res->winq); + res->cookie = ODA_COOKIE; + return 0; +} diff --git a/lib/liboda/src/window.c b/lib/liboda/src/window.c new file mode 100644 index 0000000..876f89e --- /dev/null +++ b/lib/liboda/src/window.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * 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. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * 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 OWNER 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. + */ + +#include <sys/errno.h> +#include <stdlib.h> +#include <string.h> +#include <liboda/oda.h> +#include <liboda/odavar.h> +#include <liboda/types.h> +#include <libgfx/gfx.h> + +/* + * Request a window from the OSMORA Display + * Architecture (ODA). + * + * @params: Arguments + * @res: Resulting pointer for new window + * + * Returns 0 on success, otherwise a less than + * zero value. + */ +int +oda_reqwin(struct oda_wattr *params, struct oda_window **res) +{ + struct oda_window *wp; + struct gfx_shape *surf; + struct oda_state *session; + int error; + + if (params == NULL || res == NULL) { + return -EINVAL; + } + + /* Try to grab the current session */ + if ((session = params->session) == NULL) { + return -EIO; + } + + /* Verify that cookie! */ + if ((error = oda_cookie_verify(session)) != 0) { + return error; + } + + /* Allocate a new window */ + wp = malloc(sizeof(*wp)); + if (wp == NULL) { + return -ENOMEM; + } + + /* Initialize the window */ + memset(wp, 0, sizeof(*wp)); + wp->session = session; + TAILQ_INSERT_TAIL(&session->winq, wp, link); + + /* Fix up width/height params */ + if (params->w == 0) + params->w = DEFAULT_WIN_WIDTH; + if (params->h == 0) + params->h = DEFAULT_WIN_HEIGHT; + + /* Initialize the window surface */ + surf = &wp->surface; + surf->color = params->bg; + surf->x = params->x; + surf->y = params->y; + surf->width = params->w; + surf->height = params->h; + surf->type = SHAPE_SQUARE; + *res = wp; + return 0; +} + +/* + * Register a window into the current ODA state. + * Everytime a compositor requests a window, we + * must keep track of it. + * + * @state: ODA state pointer + * @win: Pointer of window to register + */ +int +oda_start_win(struct oda_state *state, struct oda_window *win) +{ + int error; + + if (state == NULL || win == NULL) { + return -EINVAL; + } + + /* Make sure the state is valid */ + if ((error = oda_cookie_verify(state)) != 0) { + return error; + } + + gfx_draw_shape(&state->gctx, &win->surface); + return 0; +} + +/* + * Terminate a running window + * + * @state: ODA state pointer + * @win: Win pointer + * + * Returns 0 on success, otherwise a less than + * zero value. + * + * TODO: Cleanup screen + */ +int +oda_termwin(struct oda_state *state, struct oda_window *win) +{ + int error; + + if (state == NULL || win == NULL) { + return -EINVAL; + } + + /* Validate the cookie */ + if ((error = oda_cookie_verify(state)) != 0) { + return error; + } + + TAILQ_REMOVE(&state->winq, win, link); + free(win); + return 0; +} diff --git a/share/docs/kernel/ctlfs.md b/share/docs/kernel/ctlfs.md new file mode 100644 index 0000000..3087f60 --- /dev/null +++ b/share/docs/kernel/ctlfs.md @@ -0,0 +1,125 @@ +# The Hyra control filesystem (ctlfs) + +Written by Ian M. Moffett + +## Rationale + +Historically, Operating Systems of the Unix family typically relied +on syscalls like ``ioctl()`` or similar to perform operations (e.g., making calls through a driver) +via some file descriptor. Let's say for example, one wanted to acquire the framebuffer +dimensions of a given framebuffer device. To start, they'd acquire a file descriptor +by calling ``open()`` or similar on it. Then they'd make their ``ioctl()`` call. + +```c +int fd = ...; + +ioctl(fd, IOCTL_FBINFO, &fb_info); +... +``` + +While this works fine and is relatively simple to use from the user's +perspective, it is very clunky when you pop the hood and peer into the +inner-workings of it within the kernel. The number of possible requests +that can be passed through a file descriptor can grow quite rapidly which +can require really large switch statements within the drivers that implement +an ``ioctl()`` interface. + +## Replacing ``ioctl()`` + +Hyra provides ctlfs, an abstract in-memory filesystem designed for +setting/getting various kernel / driver parameters and state via +the filesystem API. The control filesystem consists of several +instances of two fundamentals: "control nodes" and "control entries". + +### Control nodes + +Control nodes are simply directories within the ``/ctl`` root. For example, +console specific control files are in the ``/ctl/console`` node. + +### Control entries + +Control entries are simply files within specific control nodes. For example +console features may be find in the ``consfeat`` entry of the ``console`` node +(i.e., ``/ctl/console/consfeat``). + +See ``sys/include/sys/console.h`` and ``sys/fs/ctlfs.h`` for more +information. + +## The ctlfs API + +The Hyra kernel provides an API for subsystems and drivers +to create their own ctlfs entries and nodes. This may be found +in sys/include/fs/ctlfs.h + +### Control operations + +Each control entry must define their own set of +"control operations" described by the ``ctlops`` structure: + +```c +struct ctlops { + int(*read)(struct ctlfs_dev *cdp, struct sio_txn *sio); + int(*write)(struct ctlfs_dev *cdp, struct sio_txn *sio); + ... +}; +``` + +NOTE: Callbacks defined as ``NULL`` will be +ignored and unused. + +## "Meow World": Creating a ctlfs entry + +```c +#include <sys/types.h> +#include <sys/sio.h> +#include <fs/ctlfs.h> + +static const struct ctlops meow_ctl; + +/* + * Ctlfs read callback - this will be called + * when "/ctl/meow/hii" is read. + */ +static int +ctl_meow_read(struct ctlfs_dev *cdp, struct sio_txn *sio) +{ + char data[] = "Meow World!"" + + /* Clamp the input length */ + if (sio->len > sizeof(data)) { + sio->len = sizeof(data) + } + + /* End of the data? */ + if ((sio->offset + sio->len) > sizeof(data)) { + return 0; + } + + /* Copy the data and return the length */ + memcpy(sio->buf, &data[sio->offset], sio->len); + return sio->len; +} + +static int +foo_init(void) +{ + char ctlname[] = "meow"; + struct ctlfs_dev ctl; + + /* + * Here we create the "/ctl/meow" node. + */ + ctl.mode = 0444; + ctl.devname = devname; + ctlfs_create_node(devname, &ctl); + + ctl.ops = &fb_size_ctl; + ctlfs_create_entry("attr", &ctl); + return 0; +} + +static const struct ctlops meow_ctl = { + .read = ctl_meow_read, + .write = NULL, +}; +``` diff --git a/share/docs/lib/liboda.md b/share/docs/lib/liboda.md new file mode 100644 index 0000000..f526ca9 --- /dev/null +++ b/share/docs/lib/liboda.md @@ -0,0 +1,191 @@ +# The OSMORA Display Architecture (ODA) + +Written by Ian M. Moffett + +## Introduction + +The OSMORA Display Architecture (ODA) is a protocol describing how +a compositor should create and manage graphical windows. A graphical +session in Hyra consists of a compositor, window management system and +management of user input. + +There are many existing display architectures out there. Take for instace, the X11 +protocol. X11 for example, has the concept of an "X server" in which window managers +or certain graphical programs would connect to as a means of performing interprocess +communication (IPC). The idea is that X will service graphics related requests from +the window manager or compositor. + +While this works just fine, the highly centralized nature of X11 or similar protocols +may complicate the flexibility of the graphics stack. On the other hand with ODA, a +compositor links with the ODA library and becomes the server for window managers running +on the system. The idea of ODA is to minimize complexity while preserving flexibility. + +Additionally, the compositor should provide its own API for use by window management +software. + +## Scope + +This document serves to describe common OSMORA Display Architecture (ODA) concepts +as well as providing basic example C sources showcasing how compositors and window +managers may interface with the described APIs for various needs. + +## Terminology + +### OSMORA Display Architecture (ODA): + +OSMORA protocol defining common interfaces for C2W and +W2C interactions. + +### Compositor to window (C2W): + +Describes the direction of communication originating from +a compositor and directed towards a specific window: + +``COMPOSITOR -> WINDOW`` + +### Window to compositor (W2C): + +Describes the direction of communication originating from +a specific window to a compositor running on the system: + +``WINDOW -> COMPOSITOR`` + +## Architecture + +``` ++-------------+ +| LIBGFX | ++-------------+ + ^ + | linked with libgfx + V ++-------------+ +| COMPOSITOR | ++-------------+ <---+ signal + | | | | + | | | | c2w: <winop: e.g., close> + | | | | w2c: <winop to accept: e.g., close> + WIN WIN WIN <---+ +``` + +### C2W signal flow: + +``` +-- CLOSE SIGNAL EXAMPLE -- + +WINDOW RECEIVES CLOSE SIGNAL + | + ECHO BACK TO COMPOSITOR + | + YES ---+--- NO + | | + | V + | nothing happens + | + V + window is destroyed by compositor +``` + +## Libgfx + +The Hyra userspace includes ``libgfx`` which is a low-level graphics library aimed +to facilitate drawing on the screen and performing various graphical operations while +decoupling from the concept of compositors, windows and the ODA as a whole. In other words, +libgfx has no knowledge of anything outside of the framebuffer and itself. + +The following is an example of how one may draw a yellow square at +x/y (30,0): + +```c +#include <libgfx/gfx.h> /* Common routines/defs */ +#include <libgfx/draw.h> /* Drawing related routines/defs */ + +int +main(void) +{ + struct gfx_ctx ctx; + struct gfx_shape sh = GFX_SHAPE_DEFAULT; + int error; + + /* Set the x/y and color */ + sh.x = 30; + sh.y = 0; + sh.color = GFX_YELLOW + + error = gfx_init(&ctx); + if (error < 0) { + printf("gfx_init returned %d\n", error); + return error; + } + + /* Draw the square and cleanup */ + gfx_draw_shape(&ctx, &sh); + gfx_cleanup(&ctx); + return 0; +} +``` + +## Liboda + +The Hyra userspace includes the ``liboda`` library which includes various +interfaces conforming to the OSMORA Display Architecture (ODA). + +### Linking a compositor with liboda + +In order for an ODA compliant compositor to reference library +symbols for ``liboda``, it should use the following linker flags: + +``... -loda -logfx`` + +### ODA Session + +For the ODA library to keep track of state, it relies on an ``oda_state`` +structure defined in ``liboda/oda.h``. Additionally, in order for any ODA +library calls to be made, the compositor must initialize the library with +``oda_init()`` like in the following example: + +``` +#include <liboda/oda.h> + +struct oda_state state; +int error; + +/* Returns 0 on success */ +error = oda_init(&state); +... +``` + +Upon failure of ``oda_init()`` a negative POSIX errno value +is returned (see ``sys/errno.h``). + +### Using liboda to request windows + +A compositor may request windows from the ODA by using +``oda_reqwin()`` like in the following example: + +``` +#include <liboda/oda.h> + +... +struct oda_wattr wattr; +struct oda_state state; + +... + +wattr.session = &state; +wattr.parent = NULL; +wattr.bg = GFX_YELLOW; +wattr.x = 200; +wattr.y = 150; +wattr.w = 120; +wattr.h = 300; + +/* Returns 0 on success */ +error = oda_reqwin(&wattr, &win); +``` + +Arguments passed to ``oda_reqwin()`` are first stored in a ``struct oda_wattr`` +structure to minimize the number of parameters used in the function signature. + +Upon failure of ``oda_reqwin()`` a negative POSIX errno value +is returned (see ``sys/errno.h``). diff --git a/share/man/man1/osh.1 b/share/man/man1/osh.1 new file mode 100644 index 0000000..1b2744c --- /dev/null +++ b/share/man/man1/osh.1 @@ -0,0 +1,83 @@ +.\" Copyright (c) 2025 Ian Marco Moffett and the Osmora Team. +.\" All rights reserved. +.\" +.\" 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. +.\" 3. Neither the name of Hyra nor the names of its +.\" contributors may be used to endorse or promote products derived from +.\" this software without specific prior written permission. +.\" +.\" 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 OWNER 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. +.Dd Aug 2 2025 +.Dt OSH 1 +.Os HYRA +.Sh NAME +.Nm osh - OSMORA shell +.Sh SYNOPSIS +osh [optional file] + +.Sh DESCRIPTION + +OSH is a simple shell interpreter that is capable of executing commands +from the user via stdin or a shell script file passed as an argument. + +.Sh COMMENTS +OSH supports the use of comments (i.e., pieces of text ignored by the shell) +denoted by '@'. The following is an example of using comments: + +.Bd -literal +echo hello !! @ Echos the text "hello !!" +.Ed + +.Sh DEFINITIONS +OSH defines "control operators" as any character(s) reserved by OSH for +representing specific operations (e.g., background jobs, command repetition, etc): + +The +.Ft '&' +control operator is used after a command or binary path +in order to run the executable as a background job, allowing +the shell to continue immediately. Here is an example of running "sleep" in the background: +.Bd -literal +-- +@ +@ Usually this will hang the shell for 5 +@ seconds until sleep wakes up. However, +@ when we postpend '&', the shell executes +@ 'sleep' as a background job and continues +@ as usual. +@ +sleep 5 & +-- +.Ed + +The +.Ft '!!' +control operator is used to repeat the most recently used +command. This is simply written by itself like this: + +.Bd -literal +-- +echo "hewwo" @ Echo "hewwo" +!! @ Do it again... +-- +.Ed + +.Sh AUTHORS +.An Ian Moffett Aq Mt ian@osmora.org diff --git a/sys/include/fs/ctlfs.h b/sys/include/fs/ctlfs.h index 90f42f0..29ae358 100644 --- a/sys/include/fs/ctlfs.h +++ b/sys/include/fs/ctlfs.h @@ -42,12 +42,10 @@ struct ctlops { /* * Ctlfs op arguments * - * @devname: Device name. - * @major: Device major - * @minor: Device minor. - * @mode: Access flags. * @devname [1]: Device name (node name) * @ctlname: [1]: Control name (node entry name) + * @ops: Callbacks / fs hooks + * @mode: Access flags. */ struct ctlfs_dev { union { |