Working i386 paging and liballoc

This commit is contained in:
2025-12-07 00:53:33 +01:00
commit de5350010b
75 changed files with 6716 additions and 0 deletions

13
Makefile Normal file
View File

@ -0,0 +1,13 @@
include build/make.config
srctree := $(PWD)
all:
$(make) -C $(srctree)/kernel srctree=$(srctree) all
clean:
$(make) -C $(srctree)/kernel srctree=$(srctree) clean
include platform/make.$(platform)
.PHONY: all clean

45
build/make.config Normal file
View File

@ -0,0 +1,45 @@
cc := clang
make := make
objcopy := llvm-objcopy
platform ?= i386_pc
build ?= release
ifeq ($(platform),i386_pc)
clang_res_dir := $(shell $(cc) -print-resource-dir)
kernel_cflags := --target=i386-none-elf \
-nostdinc \
-nostdlib \
-ffreestanding \
-fno-builtin \
-std=c11 \
-pedantic \
-Wall \
-Wextra
ifeq ($(build),debug)
kernel_cflags += -O0 -g
endif
ifeq ($(build),release)
kernel_cflags += -Oz
endif
kernel_ldflags := -mcpu=i386 \
--target=i386-none-elf \
-nostdlib \
-ffreestanding \
-fno-builtin \
-fuse-ld=lld \
-flto \
-static \
-Wl,--build-id=none \
$(clang_res_dir)/lib/*/libclang_rt.builtins-i386.a
ifeq ($(build),debug)
kernel_ldflags += -g
endif
endif

21
kernel/Makefile Normal file
View File

@ -0,0 +1,21 @@
include $(srctree)/build/make.config
here := $(srctree)/kernel
include $(here)/make.src
all: $(srctree)/out/kernel.elf
$(srctree)/out/kernel.elf: $(o_files)
$(cc) $(kernel_ldflags) -o $@ $^
%.o: %.c
$(cc) $(kernel_cflags) -c -o $@ $<
%.o: %.S
$(cc) $(kernel_cflags) -c -o $@ $<
clean:
-rm $(srctree)/out/kernel.elf $(o_files)
.PHONY: all clean

56
kernel/config.h Normal file
View File

@ -0,0 +1,56 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _CONFIG_H
#define _CONFIG_H
/*****************************************************************************/
#define CFG_I386_PC_DEBUG_DISABLED 0
#define CFG_I386_PC_DEBUG_SERIAL 1
#define CFG_I386_PC_DEBUG_SERIAL_PORT 0x3F8
#define CFG_I386_PC_DEBUG_SERIAL_BUFFER_SIZE 2048
#define CFG_I386_PC_DEBUG CFG_I386_PC_DEBUG_SERIAL
#if CFG_I386_PC_DEBUG == CFG_I386_PC_DEBUG_SERIAL
#if !defined(__ASSEMBLER__)
#include <sys/serialdbg.h>
#define dbgf(fmt, ...) serialdbg_printf((fmt), ##__VA_ARGS__)
#endif
#endif
#define CFG_I386_PC_PMM_BLOCK_SIZE 0x1000
/*****************************************************************************/
#endif // _CONFIG_H

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

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

58
kernel/libk/bitmap.c Normal file
View File

@ -0,0 +1,58 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
#include <libk/types.h>
#include <libk/bitmap.h>
#include <libk/string.h>
void bitmap_init(struct bitmap *bm, byte_t *baseptr, usize_t bit_count) {
bm->baseptr = baseptr;
bm->bit_count = bit_count;
memset(bm->baseptr, 0, (bit_count + 7) / 8);
}
void bitmap_set(struct bitmap *bm, usize_t k) {
byte_t *byte = (byte_t *)((uptr_t)bm->baseptr + (k / BM_BITS_PER_BYTE));
*byte = (*byte | (1 << (k % BM_BITS_PER_BYTE)));
}
void bitmap_clear(struct bitmap *bm, usize_t k) {
byte_t *byte = (byte_t *)((uptr_t)bm->baseptr + (k / BM_BITS_PER_BYTE));
*byte = (*byte & ~(1 << (k % BM_BITS_PER_BYTE)));
}
bool_t bitmap_test(struct bitmap *bm, usize_t k) {
if (k >= bm->bit_count)
return 0;
byte_t byte = *(byte_t *)((uptr_t)bm->baseptr + (k / BM_BITS_PER_BYTE));
return byte & (1 << (k % BM_BITS_PER_BYTE));
}

49
kernel/libk/bitmap.h Normal file
View File

@ -0,0 +1,49 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _LIBK_BITMAP_H
#define _LIBK_BITMAP_H
#include <libk/types.h>
#define BM_BITS_PER_BYTE 8
struct bitmap {
byte_t *baseptr;
usize_t bit_count;
};
void bitmap_init(struct bitmap *bm, byte_t *baseptr, usize_t bit_count);
void bitmap_set(struct bitmap *bm, usize_t k);
void bitmap_clear(struct bitmap *bm, usize_t k);
bool_t bitmap_test(struct bitmap *bm, usize_t k);
#endif // _LIBK_BITMAP_H

39
kernel/libk/compiler.h Normal file
View File

@ -0,0 +1,39 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _COMPILER_H
#define _COMPILER_H
#define unused __attribute__((unused))
#define aligned(x) __attribute__((aligned((x))))
#define packed __attribute__((packed))
#endif // _COMPILER_H

124
kernel/libk/float.h Normal file
View File

@ -0,0 +1,124 @@
/* Copyright (C) 2022-2025 Mintsuki and contributors.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __FREESTND_C_HDRS_FLOAT_H
#define __FREESTND_C_HDRS_FLOAT_H 1
#undef FLT_ROUNDS
#define FLT_ROUNDS 1
#undef FLT_RADIX
#define FLT_RADIX __FLT_RADIX__
#undef FLT_MANT_DIG
#define FLT_MANT_DIG __FLT_MANT_DIG__
#undef DBL_MANT_DIG
#define DBL_MANT_DIG __DBL_MANT_DIG__
#undef LDBL_MANT_DIG
#define LDBL_MANT_DIG __LDBL_MANT_DIG__
#if (defined(__cplusplus) && __cplusplus >= 201103L) \
|| (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
#undef DECIMAL_DIG
#define DECIMAL_DIG __DECIMAL_DIG__
#undef FLT_EVAL_METHOD
#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
#endif
#undef FLT_DIG
#define FLT_DIG __FLT_DIG__
#undef DBL_DIG
#define DBL_DIG __DBL_DIG__
#undef LDBL_DIG
#define LDBL_DIG __LDBL_DIG__
#undef FLT_MIN_EXP
#define FLT_MIN_EXP __FLT_MIN_EXP__
#undef DBL_MIN_EXP
#define DBL_MIN_EXP __DBL_MIN_EXP__
#undef LDBL_MIN_EXP
#define LDBL_MIN_EXP __LDBL_MIN_EXP__
#undef FLT_MIN_10_EXP
#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__
#undef DBL_MIN_10_EXP
#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__
#undef LDBL_MIN_10_EXP
#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__
#undef FLT_MAX_EXP
#define FLT_MAX_EXP __FLT_MAX_EXP__
#undef DBL_MAX_EXP
#define DBL_MAX_EXP __DBL_MAX_EXP__
#undef LDBL_MAX_EXP
#define LDBL_MAX_EXP __LDBL_MAX_EXP__
#undef FLT_MAX_10_EXP
#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__
#undef DBL_MAX_10_EXP
#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
#undef LDBL_MAX_10_EXP
#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__
#undef FLT_MAX
#define FLT_MAX __FLT_MAX__
#undef DBL_MAX
#define DBL_MAX __DBL_MAX__
#undef LDBL_MAX
#define LDBL_MAX __LDBL_MAX__
#undef FLT_EPSILON
#define FLT_EPSILON __FLT_EPSILON__
#undef DBL_EPSILON
#define DBL_EPSILON __DBL_EPSILON__
#undef LDBL_EPSILON
#define LDBL_EPSILON __LDBL_EPSILON__
#undef FLT_MIN
#define FLT_MIN __FLT_MIN__
#undef DBL_MIN
#define DBL_MIN __DBL_MIN__
#undef LDBL_MIN
#define LDBL_MIN __LDBL_MIN__
#if (defined(__cplusplus) && __cplusplus >= 201703L) \
|| (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
#undef FLT_DECIMAL_DIG
#define FLT_DECIMAL_DIG __FLT_DECIMAL_DIG__
#undef DBL_DECIMAL_DIG
#define DBL_DECIMAL_DIG __DBL_DECIMAL_DIG__
#undef LDBL_DECIMAL_DIG
#define LDBL_DECIMAL_DIG __LDBL_DECIMAL_DIG__
#undef FLT_TRUE_MIN
#define FLT_TRUE_MIN __FLT_DENORM_MIN__
#undef DBL_TRUE_MIN
#define DBL_TRUE_MIN __DBL_DENORM_MIN__
#undef LDBL_TRUE_MIN
#define LDBL_TRUE_MIN __LDBL_DENORM_MIN__
#undef FLT_HAS_SUBNORM
#define FLT_HAS_SUBNORM __FLT_HAS_DENORM__
#undef DBL_HAS_SUBNORM
#define DBL_HAS_SUBNORM __DBL_HAS_DENORM__
#undef LDBL_HAS_SUBNORM
#define LDBL_HAS_SUBNORM __LDBL_HAS_DENORM__
#endif
#endif

45
kernel/libk/iso646.h Normal file
View File

@ -0,0 +1,45 @@
/* Copyright (C) 2022-2025 Mintsuki and contributors.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __FREESTND_C_HDRS_ISO646_H
#define __FREESTND_C_HDRS_ISO646_H 1
#ifndef __cplusplus
#undef and
#define and &&
#undef and_eq
#define and_eq &=
#undef bitand
#define bitand &
#undef bitor
#define bitor |
#undef compl
#define compl ~
#undef not
#define not !
#undef not_eq
#define not_eq !=
#undef or
#define or ||
#undef or_eq
#define or_eq |=
#undef xor
#define xor ^
#undef xor_eq
#define xor_eq ^=
#endif
#endif

147
kernel/libk/limits.h Normal file
View File

@ -0,0 +1,147 @@
/* Copyright (C) 2022-2025 Mintsuki and contributors.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __FREESTND_C_HDRS_LIMITS_H
#define __FREESTND_C_HDRS_LIMITS_H 1
#undef CHAR_BIT
#define CHAR_BIT __CHAR_BIT__
#ifndef MB_LEN_MAX
# define MB_LEN_MAX 1
#endif
#undef SCHAR_MAX
#define SCHAR_MAX __SCHAR_MAX__
#undef SCHAR_MIN
#define SCHAR_MIN (-SCHAR_MAX - 1)
#undef UCHAR_MAX
#if __SCHAR_MAX__ == __INT_MAX__
# define UCHAR_MAX (SCHAR_MAX * 2U + 1U)
#else
# define UCHAR_MAX (SCHAR_MAX * 2 + 1)
#endif
#ifdef __CHAR_UNSIGNED__
# undef CHAR_MAX
# define CHAR_MAX UCHAR_MAX
# undef CHAR_MIN
# if __SCHAR_MAX__ == __INT_MAX__
# define CHAR_MIN 0U
# else
# define CHAR_MIN 0
# endif
#else
# undef CHAR_MAX
# define CHAR_MAX SCHAR_MAX
# undef CHAR_MIN
# define CHAR_MIN SCHAR_MIN
#endif
#undef SHRT_MAX
#define SHRT_MAX __SHRT_MAX__
#undef SHRT_MIN
#define SHRT_MIN (-SHRT_MAX - 1)
#undef USHRT_MAX
#if __SHRT_MAX__ == __INT_MAX__
# define USHRT_MAX (SHRT_MAX * 2U + 1U)
#else
# define USHRT_MAX (SHRT_MAX * 2 + 1)
#endif
#undef INT_MAX
#define INT_MAX __INT_MAX__
#undef INT_MIN
#define INT_MIN (-INT_MAX - 1)
#undef UINT_MAX
#define UINT_MAX (INT_MAX * 2U + 1U)
#undef LONG_MAX
#define LONG_MAX __LONG_MAX__
#undef LONG_MIN
#define LONG_MIN (-LONG_MAX - 1L)
#undef ULONG_MAX
#define ULONG_MAX (LONG_MAX * 2UL + 1UL)
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#undef LLONG_MAX
#define LLONG_MAX __LONG_LONG_MAX__
#undef LLONG_MIN
#define LLONG_MIN (-LLONG_MAX - 1LL)
#undef ULLONG_MAX
#define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
#endif
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
#if defined(__clang__)
# undef CHAR_WIDTH
# define CHAR_WIDTH CHAR_BIT
# undef SCHAR_WIDTH
# define SCHAR_WIDTH CHAR_BIT
# undef UCHAR_WIDTH
# define UCHAR_WIDTH CHAR_BIT
#else
# undef CHAR_WIDTH
# define CHAR_WIDTH __SCHAR_WIDTH__
# undef SCHAR_WIDTH
# define SCHAR_WIDTH __SCHAR_WIDTH__
# undef UCHAR_WIDTH
# define UCHAR_WIDTH __SCHAR_WIDTH__
#endif
# undef SHRT_WIDTH
# define SHRT_WIDTH __SHRT_WIDTH__
# undef USHRT_WIDTH
# define USHRT_WIDTH __SHRT_WIDTH__
# undef INT_WIDTH
# define INT_WIDTH __INT_WIDTH__
# undef UINT_WIDTH
# define UINT_WIDTH __INT_WIDTH__
# undef LONG_WIDTH
# define LONG_WIDTH __LONG_WIDTH__
# undef ULONG_WIDTH
# define ULONG_WIDTH __LONG_WIDTH__
#if defined(__clang__)
# undef LLONG_WIDTH
# define LLONG_WIDTH __LLONG_WIDTH__
# undef ULLONG_WIDTH
# define ULLONG_WIDTH __LLONG_WIDTH__
#else
# undef LLONG_WIDTH
# define LLONG_WIDTH __LONG_LONG_WIDTH__
# undef ULLONG_WIDTH
# define ULLONG_WIDTH __LONG_LONG_WIDTH__
#endif
#undef BOOL_MAX
#define BOOL_MAX 1
#undef BOOL_WIDTH
#define BOOL_WIDTH 1
#ifdef __BITINT_MAXWIDTH__
# undef BITINT_MAXWIDTH
# define BITINT_MAXWIDTH __BITINT_MAXWIDTH__
#endif
#define __STDC_VERSION_LIMITS_H__ 202311L
#endif
#endif

215
kernel/libk/list.h Normal file
View File

@ -0,0 +1,215 @@
#ifndef _LIBK_LIST_H
#define _LIBK_LIST_H
#define DL_APPEND(head, new) \
do { \
if ((new) != NULL) { \
(new)->next = NULL; \
if ((head) != NULL) { \
typeof((head)) __tmp = (head); \
while (__tmp->next != NULL) { \
__tmp = __tmp->next; \
} \
__tmp->next = (new); \
(new)->prev = __tmp; \
} else { \
(new)->prev = NULL; \
(head) = (new); \
} \
} \
} while (0)
#define DL_PREPEND(head, new) \
do { \
if ((new) != NULL) { \
(new)->prev = NULL; \
(new)->next = (head); \
if ((head) != NULL) { \
(head)->prev = (new); \
} \
(head) = (new); \
} \
} while (0)
#define DL_REMOVE(head, ele) \
do { \
if ((ele) != NULL) { \
if ((ele)->prev != NULL) { \
(ele)->prev->next = (ele)->next; \
} else { \
(head) = (ele)->next; \
} \
if ((ele)->next != NULL) { \
(ele)->next->prev = (ele)->prev; \
} \
(ele)->next = NULL; \
(ele)->prev = NULL; \
} \
} while (0)
#define DL_FINDPROP(head, out, propname, propvalue) \
do { \
(out) = NULL; \
typeof((head)) __tmp = (head); \
while (__tmp) { \
if (__tmp->propname == (propvalue)) { \
(out) = __tmp; \
break; \
} \
__tmp = __tmp->next; \
} \
} while (0)
#define DL_FOREACH_SAFE(head, var, tmp) \
for (var = (head), tmp = (var ? var->next : NULL); \
var != NULL; \
var = tmp, tmp = (var ? var->next : NULL))
#define DL_FOREACH_SAFE_IDX(head, var, tmp, idx) \
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
var != NULL; \
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
#define DL_FOREACH_SAFE_IDX_LIMIT(head, var, tmp, idx, max) \
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
var != NULL && (idx) < (max); \
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
#define DL_BACK(head, out) \
do { \
(out) = NULL; \
if ((head) != NULL) { \
typeof((head)) __tmp = (head); \
while (__tmp->next != NULL) { \
__tmp = __tmp->next; \
} \
(out) = __tmp; \
} \
} while (0)
#define DL_FRONT(head, out) \
do { \
(out) = NULL; \
if ((head) != NULL) { \
typeof((head)) __tmp = (head); \
while (__tmp->prev != NULL) { \
__tmp = __tmp->prev; \
} \
(out) = __tmp; \
} \
} while (0)
#define DL_INSERT_AFTER(head, pos, new) \
do { \
if ((pos) != NULL && (new) != NULL) { \
(new)->prev = (pos); \
(new)->next = (pos)->next; \
if ((pos)->next != NULL) { \
(pos)->next->prev = (new); \
} \
(pos)->next = (new); \
} else if ((pos) == NULL && (head) == NULL) { \
(new)->prev = NULL; \
(new)->next = NULL; \
(head) = (new); \
} \
} while (0)
#define DL_INSERT_BEFORE(head, pos, new) \
do { \
if ((pos) != NULL && (new) != NULL) { \
(new)->next = (pos); \
(new)->prev = (pos)->prev; \
if ((pos)->prev != NULL) { \
(pos)->prev->next = (new); \
} else { \
(head) = (new); \
} \
(pos)->prev = (new); \
} else if ((pos) == NULL && (head) == NULL) { \
(new)->prev = NULL; \
(new)->next = NULL; \
(head) = (new); \
} \
} while (0)
#define LL_APPEND(head, new) \
do { \
if ((new) != NULL) { \
if ((head) != NULL) { \
typeof((head)) __tmp; \
(new)->next = NULL; \
__tmp = (head); \
while (__tmp->next != NULL) { \
__tmp = __tmp->next; \
} \
__tmp->next = (new); \
} else { \
(new)->next = NULL; \
(head) = (new); \
} \
} \
} while(0)
#define LL_REMOVE(head, ele) \
do { \
if ((head) != NULL && (ele) != NULL) { \
typeof((head)) __cur = (head); \
typeof((head)) __prev = NULL; \
while (__cur != NULL && __cur != (ele)) { \
__prev = __cur; \
__cur = __cur->next; \
} \
if (__cur == (ele)) { \
if (__prev != NULL) { \
__prev->next = __cur->next; \
} else { \
(head) = __cur->next; \
} \
(ele)->next = NULL; \
} \
} \
} while(0)
#define LL_FINDPROP(head, out, propname, propvalue) \
do { \
(out) = NULL; \
typeof((head)) __tmp = (head); \
while (__tmp) { \
if (__tmp->propname == (propvalue)) { \
(out) = __tmp; \
break; \
} \
__tmp = __tmp->next; \
} \
} while(0)
#define LL_FOREACH_SAFE(head, var, tmp) \
for (var = (head), tmp = (var ? var->next : NULL); \
var != NULL; \
var = tmp, tmp = (var ? var->next : NULL) \
)
#define LL_FOREACH_SAFE_IDX(head, var, tmp, idx) \
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
var != NULL; \
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
#define LL_FOREACH_SAFE_IDX_LIMIT(head, var, tmp, idx, max) \
for ((idx) = 0, var = (head), tmp = (var ? var->next : NULL); \
var != NULL && (idx) < (max); \
var = tmp, tmp = (var ? var->next : NULL), (idx)++)
#define LL_BACK(head, out) \
do { \
(out) = NULL; \
if ((head) != NULL) { \
typeof((head)) __tmp = (head); \
while (__tmp->next != NULL) { \
__tmp = __tmp->next; \
} \
(out) = __tmp; \
} \
} while(0)
#endif // _LIBK_LIST_H

14
kernel/libk/make.src Normal file
View File

@ -0,0 +1,14 @@
dir_libk1 := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
kernel_cflags += -isystem $(dir_libk1) \
-DPRINTF_INCLUDE_CONFIG_H=1
c_files += $(dir_libk1)/string.c \
$(dir_libk1)/printf.c \
$(dir_libk1)/putchar_.c \
$(dir_libk1)/bitmap.c
o_files += $(dir_libk1)/string.o \
$(dir_libk1)/printf.o \
$(dir_libk1)/putchar_.o \
$(dir_libk1)/bitmap.o

1651
kernel/libk/printf.c Normal file

File diff suppressed because it is too large Load Diff

242
kernel/libk/printf.h Normal file
View File

@ -0,0 +1,242 @@
/**
* @author (c) Eyal Rozenberg <eyalroz1@gmx.com>
* 2021-2024, Haifa, Palestine/Israel
* @author (c) Marco Paland (info@paland.com)
* 2014-2019, PALANDesign Hannover, Germany
*
* @note Others have made smaller contributions to this file: see the
* contributors page at https://github.com/eyalroz/printf/graphs/contributors
* or ask one of the authors.
*
* @brief Small stand-alone implementation of the printf family of functions
* (`(v)printf`, `(v)s(n)printf` etc., geared towards use on embedded systems
* with a very limited resources.
*
* @note the implementations are thread-safe; re-entrant; use no functions from
* the standard library; and do not dynamically allocate any memory.
*
* @license The MIT License (MIT)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef PRINTF_H_
#define PRINTF_H_
#ifdef PRINTF_INCLUDE_CONFIG_H
#include "printf_config.h"
#endif
#ifdef __cplusplus
# include <cstdarg>
# include <cstddef>
extern "C" {
#else
# include <libk/stdarg.h>
# include <libk/stddef.h>
#endif
#ifdef __GNUC__
# if ((__GNUC__ == 4 && __GNUC_MINOR__>= 4) || __GNUC__ > 4)
# define ATTR_PRINTF(one_based_format_index, first_arg) \
__attribute__((format(gnu_printf, (one_based_format_index), (first_arg))))
# else
# define ATTR_PRINTF(one_based_format_index, first_arg) \
__attribute__((format(printf, (one_based_format_index), (first_arg))))
# endif
# define ATTR_VPRINTF(one_based_format_index) \
ATTR_PRINTF((one_based_format_index), 0)
#else
# define ATTR_PRINTF(one_based_format_index, first_arg)
# define ATTR_VPRINTF(one_based_format_index)
#endif
#ifndef PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_SOFT
#define PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_SOFT 0
#endif
#ifndef PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_HARD
#define PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_HARD 0
#endif
#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_HARD
# define printf_ printf
# define sprintf_ sprintf
# define vsprintf_ vsprintf
# define snprintf_ snprintf
# define vsnprintf_ vsnprintf
# define vprintf_ vprintf
#endif
/*
* If you want to include this implementation file directly rather than
* link against it, this will let you control the functions' visibility,
* e.g. make them static so as not to clash with other objects also
* using them.
*/
#ifndef PRINTF_VISIBILITY
#define PRINTF_VISIBILITY
#endif
/**
* Prints/send a single character to some opaque output entity
*
* @note This function is not implemented by the library, only declared; you
* must provide an implementation if you wish to use the @ref printf / @ref
* vprintf function (and possibly for linking against the library, if your
* toolchain does not support discarding unused functions)
*
* @note The output could be as simple as a wrapper for the `write()` system
* call on a Unix-like * system, or even libc's @ref putchar , for replicating
* actual functionality of libc's @ref printf * function; but on an embedded
* system it may involve interaction with a special output device, like a UART,
* etc.
*
* @note in libc's @ref putchar, the parameter type is an int; this was intended
* to support the representation of either a proper character or EOF in a
* variable - but this is really not meaningful to pass into @ref putchar and is
* discouraged today. See further discussion in:
* @link https://stackoverflow.com/q/17452847/1593077
*
* @param c the single character to print
*/
PRINTF_VISIBILITY
void putchar_(char c);
/**
* An implementation of the C standard's printf/vprintf
*
* @note you must implement a @ref putchar_ function for using this function -
* it invokes @ref putchar_ * rather than directly performing any I/O (which
* insulates it from any dependence on the operating system * and external
* libraries).
*
* @param format A string specifying the format of the output, with %-marked
* specifiers of how to interpret additional arguments.
* @param arg Additional arguments to the function, one for each %-specifier in
* @p format
* @return The number of characters written into @p s, not counting the
* terminating null character
*/
/* @{ */
PRINTF_VISIBILITY
int printf_(const char* format, ...) ATTR_PRINTF(1, 2);
PRINTF_VISIBILITY
int vprintf_(const char* format, va_list arg) ATTR_VPRINTF(1);
/* @} */
/**
* An implementation of the C standard's sprintf/vsprintf
*
* @note For security considerations (the potential for exceeding the buffer
* bounds), please consider using the size-constrained variant, @ref snprintf /
* @ref vsnprintf, instead.
*
* @param s An array in which to store the formatted string. It must be large
* enough to fit the formatted output!
* @param format A string specifying the format of the output, with %-marked
* specifiers of how to interpret additional arguments
* @param arg Additional arguments to the function, one for each specifier in
* @p format
* @return The number of characters written into @p s, not counting the
* terminating null character
*/
/* @{ */
PRINTF_VISIBILITY
int sprintf_(char* s, const char* format, ...) ATTR_PRINTF(2, 3);
PRINTF_VISIBILITY
int vsprintf_(char* s, const char* format, va_list arg) ATTR_VPRINTF(2);
/* @} */
/**
* An implementation of the C standard's snprintf/vsnprintf
*
* @param s An array in which to store the formatted string. It must be large
* enough to fit either the entire formatted output, or at least @p n
* characters. Alternatively, it can be NULL, in which case nothing will
* be printed, and only the number of characters which _could_ have been
* printed is tallied and returned.
* @param n The maximum number of characters to write to the array, including
* a terminating null character
* @param format A string specifying the format of the output, with %-marked
* specifiers of how to interpret additional arguments.
* @param arg Additional arguments to the function, one for each specifier in
* @p format
* @return The number of characters that COULD have been written into @p s, not
* counting the terminating null character. A value equal or larger than
* @p n indicates truncation. Only when the returned value is non-negative
* and less than @p n, the null-terminated string has been fully and
* successfully printed.
*/
/* @{ */
PRINTF_VISIBILITY
int snprintf_(char* s, size_t count, const char* format, ...) ATTR_PRINTF(3, 4);
PRINTF_VISIBILITY
int vsnprintf_(char* s, size_t count, const char* format, va_list arg) ATTR_VPRINTF(3);
/* @} */
/**
* printf/vprintf with user-specified output function
*
* An alternative to @ref printf_, in which the output function is specified
* dynamically (rather than @ref putchar_ being used)
*
* @param out An output function which takes one character and a type-erased
* additional parameters
* @param extra_arg The type-erased argument to pass to the output function @p
* out with each call
* @param format A string specifying the format of the output, with %-marked
* specifiers of how to interpret additional arguments.
* @param arg Additional arguments to the function, one for each specifier in
* @p format
* @return The number of characters for which the output f unction was invoked,
* not counting the terminating null character
*
*/
PRINTF_VISIBILITY
int fctprintf(void (*out)(char c, void* extra_arg), void* extra_arg, const char* format, ...) ATTR_PRINTF(3, 4);
PRINTF_VISIBILITY
int vfctprintf(void (*out)(char c, void* extra_arg), void* extra_arg, const char* format, va_list arg) ATTR_VPRINTF(3);
#ifdef __cplusplus
} /* extern "C" */
#endif
#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_HARD
# undef printf_
# undef sprintf_
# undef vsprintf_
# undef snprintf_
# undef vsnprintf_
# undef vprintf_
#else
#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_SOFT
# define printf printf_
# define sprintf sprintf_
# define vsprintf vsprintf_
# define snprintf snprintf_
# define vsnprintf vsnprintf_
# define vprintf vprintf_
#endif
#endif
#endif /* PRINTF_H_ */

View File

@ -0,0 +1,37 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _LIBK_PRINTF_CONFIG_H
#define _LIBK_PRINTF_CONFIG_H
#define PRINTF_ALIAS_STANDARD_FUNCTION_NAMES_HARD 1
#endif // _LIBK_PRINTF_CONFIG_H

37
kernel/libk/putchar_.c Normal file
View File

@ -0,0 +1,37 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
#include <libk/compiler.h>
void putchar_(char unused c) {
}

36
kernel/libk/stdalign.h Normal file
View File

@ -0,0 +1,36 @@
/* Copyright (C) 2022-2025 Mintsuki and contributors.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __FREESTND_C_HDRS_STDALIGN_H
#define __FREESTND_C_HDRS_STDALIGN_H 1
#ifndef __cplusplus
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
/* These do not need to be defined for C23+ */
#else
# undef alignas
# define alignas _Alignas
# undef alignof
# define alignof _Alignof
# undef __alignof_is_defined
# define __alignof_is_defined 1
# undef __alignas_is_defined
# define __alignas_is_defined 1
#endif
#endif
#endif

39
kernel/libk/stdarg.h Normal file
View File

@ -0,0 +1,39 @@
/* Copyright (C) 2022-2025 Mintsuki and contributors.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __FREESTND_C_HDRS_STDARG_H
#define __FREESTND_C_HDRS_STDARG_H 1
typedef __builtin_va_list va_list;
#undef va_start
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
# define va_start(v, ...) __builtin_va_start(v, 0)
#else
# define va_start(v, l) __builtin_va_start(v, l)
#endif
#undef va_end
#define va_end(v) __builtin_va_end(v)
#undef va_arg
#define va_arg(v, l) __builtin_va_arg(v, l)
#if (defined(__cplusplus) && (__cplusplus >= 201103L)) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))
# undef va_copy
# define va_copy(d, s) __builtin_va_copy(d, s)
#endif
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
# define __STDC_VERSION_STDARG_H__ 202311L
#endif
#endif

100
kernel/libk/stdatomic.h Normal file
View File

@ -0,0 +1,100 @@
#ifndef _LIBK_STDATOMIC_H
#define _LIBK_STDATOMIC_H
#include <libk/types.h>
// modified version of: https://github.com/llvm/llvm-project/blob/main/clang/lib/Headers/stdatomic.h
typedef enum memory_order {
memory_order_relaxed = __ATOMIC_RELAXED,
memory_order_consume = __ATOMIC_CONSUME,
memory_order_acquire = __ATOMIC_ACQUIRE,
memory_order_release = __ATOMIC_RELEASE,
memory_order_acq_rel = __ATOMIC_ACQ_REL,
memory_order_seq_cst = __ATOMIC_SEQ_CST
} memory_order;
typedef _Atomic(_Bool) atomic_bool;
typedef _Atomic(char) atomic_char;
typedef _Atomic(signed char) atomic_schar;
typedef _Atomic(unsigned char) atomic_uchar;
typedef _Atomic(short) atomic_short;
typedef _Atomic(unsigned short) atomic_ushort;
typedef _Atomic(int) atomic_int;
typedef _Atomic(unsigned int) atomic_uint;
typedef _Atomic(long) atomic_long;
typedef _Atomic(unsigned long) atomic_ulong;
typedef _Atomic(long long) atomic_llong;
typedef _Atomic(unsigned long long) atomic_ullong;
typedef _Atomic(uint_least16_t) atomic_char16_t;
typedef _Atomic(uint_least32_t) atomic_char32_t;
typedef _Atomic(wchar_t) atomic_wchar_t;
typedef _Atomic(int_least8_t) atomic_int_least8_t;
typedef _Atomic(uint_least8_t) atomic_uint_least8_t;
typedef _Atomic(int_least16_t) atomic_int_least16_t;
typedef _Atomic(uint_least16_t) atomic_uint_least16_t;
typedef _Atomic(int_least32_t) atomic_int_least32_t;
typedef _Atomic(uint_least32_t) atomic_uint_least32_t;
typedef _Atomic(int_least64_t) atomic_int_least64_t;
typedef _Atomic(uint_least64_t) atomic_uint_least64_t;
typedef _Atomic(int_fast8_t) atomic_int_fast8_t;
typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t;
typedef _Atomic(int_fast16_t) atomic_int_fast16_t;
typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t;
typedef _Atomic(int_fast32_t) atomic_int_fast32_t;
typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t;
typedef _Atomic(int_fast64_t) atomic_int_fast64_t;
typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t;
typedef _Atomic(intptr_t) atomic_intptr_t;
typedef _Atomic(uintptr_t) atomic_uintptr_t;
typedef _Atomic(size_t) atomic_size_t;
typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t;
typedef _Atomic(intmax_t) atomic_intmax_t;
typedef _Atomic(uintmax_t) atomic_uintmax_t;
typedef _Atomic(usize_t) atomic_usize_t;
typedef _Atomic(isize_t) atomic_isize_t;
typedef _Atomic(uptr_t) atomic_uptr_t;
typedef _Atomic(iptr_t) atomic_iptr_t;
typedef _Atomic(void *) atomic_ptr_t;
typedef _Atomic(byte_t) atomic_byte_t;
typedef struct atomic_flag { atomic_bool _Value; } atomic_flag;
#define ATOMIC_FLAG_INIT ((atomic_flag){ 0 })
#define atomic_store(object, desired) __c11_atomic_store(object, desired, __ATOMIC_SEQ_CST)
#define atomic_store_explicit __c11_atomic_store
#define atomic_load(object) __c11_atomic_load(object, __ATOMIC_SEQ_CST)
#define atomic_load_explicit __c11_atomic_load
#define atomic_exchange(object, desired) __c11_atomic_exchange(object, desired, __ATOMIC_SEQ_CST)
#define atomic_exchange_explicit __c11_atomic_exchange
#define atomic_compare_exchange_strong(object, expected, desired) __c11_atomic_compare_exchange_strong(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define atomic_compare_exchange_strong_explicit __c11_atomic_compare_exchange_strong
#define atomic_compare_exchange_weak(object, expected, desired) __c11_atomic_compare_exchange_weak(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define atomic_compare_exchange_weak_explicit __c11_atomic_compare_exchange_weak
#define atomic_fetch_add(object, operand) __c11_atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_add_explicit __c11_atomic_fetch_add
#define atomic_fetch_sub(object, operand) __c11_atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_sub_explicit __c11_atomic_fetch_sub
#define atomic_fetch_or(object, operand) __c11_atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_or_explicit __c11_atomic_fetch_or
#define atomic_fetch_xor(object, operand) __c11_atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_xor_explicit __c11_atomic_fetch_xor
#define atomic_fetch_and(object, operand) __c11_atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_and_explicit __c11_atomic_fetch_and
#define atomic_flag_test_and_set(object) __c11_atomic_exchange(&(object)->_Value, 1, __ATOMIC_SEQ_CST)
#define atomic_flag_test_and_set_explicit(object, order) __c11_atomic_exchange(&(object)->_Value, 1, order)
#define atomic_flag_clear(object) __c11_atomic_store(&(object)->_Value, 0, __ATOMIC_SEQ_CST)
#define atomic_flag_clear_explicit(object, order) __c11_atomic_store(&(object)->_Value, 0, order)
#endif // _LIBK_STDATOMIC_H

37
kernel/libk/stdbool.h Normal file
View File

@ -0,0 +1,37 @@
/* Copyright (C) 2022-2025 Mintsuki and contributors.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __FREESTND_C_HDRS_STDBOOL_H
#define __FREESTND_C_HDRS_STDBOOL_H 1
#ifndef __cplusplus
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
/* These do not need to be defined for C23+ */
#else
# undef bool
# define bool _Bool
# undef true
# define true 1
# undef false
# define false 0
#endif
#endif
#undef __bool_true_false_are_defined
#define __bool_true_false_are_defined 1
#endif

51
kernel/libk/stddef.h Normal file
View File

@ -0,0 +1,51 @@
/* Copyright (C) 2022-2025 Mintsuki and contributors.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __FREESTND_C_HDRS_STDDEF_H
#define __FREESTND_C_HDRS_STDDEF_H 1
typedef __SIZE_TYPE__ size_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
#ifndef __cplusplus
typedef __WCHAR_TYPE__ wchar_t;
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
typedef typeof(nullptr) nullptr_t;
#endif
#endif
#ifdef __cplusplus
typedef decltype(nullptr) nullptr_t;
#endif
#undef NULL
#ifndef __cplusplus
# define NULL ((void *)0)
#else
# define NULL __null
#endif
#undef offsetof
#define offsetof(s, m) __builtin_offsetof(s, m)
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
# undef unreachable
# define unreachable() __builtin_unreachable()
# define __STDC_VERSION_STDDEF_H__ 202311L
#endif
#endif

375
kernel/libk/stdint.h Normal file
View File

@ -0,0 +1,375 @@
/* Copyright (C) 2022-2025 Mintsuki and contributors.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __FREESTND_C_HDRS_STDINT_H
#define __FREESTND_C_HDRS_STDINT_H 1
#ifdef __UINT8_TYPE__
typedef __UINT8_TYPE__ uint8_t;
#endif
#ifdef __UINT16_TYPE__
typedef __UINT16_TYPE__ uint16_t;
#endif
#ifdef __UINT32_TYPE__
typedef __UINT32_TYPE__ uint32_t;
#endif
#ifdef __UINT64_TYPE__
typedef __UINT64_TYPE__ uint64_t;
#endif
typedef __UINT_LEAST8_TYPE__ uint_least8_t;
typedef __UINT_LEAST16_TYPE__ uint_least16_t;
typedef __UINT_LEAST32_TYPE__ uint_least32_t;
typedef __UINT_LEAST64_TYPE__ uint_least64_t;
typedef __UINT_FAST8_TYPE__ uint_fast8_t;
typedef __UINT_FAST16_TYPE__ uint_fast16_t;
typedef __UINT_FAST32_TYPE__ uint_fast32_t;
typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#ifdef __INT8_TYPE__
typedef __INT8_TYPE__ int8_t;
#endif
#ifdef __INT16_TYPE__
typedef __INT16_TYPE__ int16_t;
#endif
#ifdef __INT32_TYPE__
typedef __INT32_TYPE__ int32_t;
#endif
#ifdef __INT64_TYPE__
typedef __INT64_TYPE__ int64_t;
#endif
typedef __INT_LEAST8_TYPE__ int_least8_t;
typedef __INT_LEAST16_TYPE__ int_least16_t;
typedef __INT_LEAST32_TYPE__ int_least32_t;
typedef __INT_LEAST64_TYPE__ int_least64_t;
typedef __INT_FAST8_TYPE__ int_fast8_t;
typedef __INT_FAST16_TYPE__ int_fast16_t;
typedef __INT_FAST32_TYPE__ int_fast32_t;
typedef __INT_FAST64_TYPE__ int_fast64_t;
#ifdef __UINTPTR_TYPE__
typedef __UINTPTR_TYPE__ uintptr_t;
#endif
#ifdef __INTPTR_TYPE__
typedef __INTPTR_TYPE__ intptr_t;
#endif
typedef __UINTMAX_TYPE__ uintmax_t;
typedef __INTMAX_TYPE__ intmax_t;
/* Clang and GCC have different mechanisms for INT32_C and friends. */
#ifdef __clang__
# ifndef __FREESTND_C_HDRS_C_JOIN
# define __FREESTND_C_HDRS_C_EXPAND_JOIN(x, suffix) x ## suffix
# define __FREESTND_C_HDRS_C_JOIN(x, suffix) __FREESTND_C_HDRS_C_EXPAND_JOIN(x, suffix)
# endif
# undef INT8_C
# define INT8_C(x) __FREESTND_C_HDRS_C_JOIN(x, __INT8_C_SUFFIX__)
# undef INT16_C
# define INT16_C(x) __FREESTND_C_HDRS_C_JOIN(x, __INT16_C_SUFFIX__)
# undef INT32_C
# define INT32_C(x) __FREESTND_C_HDRS_C_JOIN(x, __INT32_C_SUFFIX__)
# undef INT64_C
# define INT64_C(x) __FREESTND_C_HDRS_C_JOIN(x, __INT64_C_SUFFIX__)
# undef UINT8_C
# define UINT8_C(x) __FREESTND_C_HDRS_C_JOIN(x, __UINT8_C_SUFFIX__)
# undef UINT16_C
# define UINT16_C(x) __FREESTND_C_HDRS_C_JOIN(x, __UINT16_C_SUFFIX__)
# undef UINT32_C
# define UINT32_C(x) __FREESTND_C_HDRS_C_JOIN(x, __UINT32_C_SUFFIX__)
# undef UINT64_C
# define UINT64_C(x) __FREESTND_C_HDRS_C_JOIN(x, __UINT64_C_SUFFIX__)
# undef INTMAX_C
# define INTMAX_C(x) __FREESTND_C_HDRS_C_JOIN(x, __INTMAX_C_SUFFIX__)
# undef UINTMAX_C
# define UINTMAX_C(x) __FREESTND_C_HDRS_C_JOIN(x, __UINTMAX_C_SUFFIX__)
#else
# undef INT8_C
# define INT8_C(x) __INT8_C(x)
# undef INT16_C
# define INT16_C(x) __INT16_C(x)
# undef INT32_C
# define INT32_C(x) __INT32_C(x)
# undef INT64_C
# define INT64_C(x) __INT64_C(x)
# undef UINT8_C
# define UINT8_C(x) __UINT8_C(x)
# undef UINT16_C
# define UINT16_C(x) __UINT16_C(x)
# undef UINT32_C
# define UINT32_C(x) __UINT32_C(x)
# undef UINT64_C
# define UINT64_C(x) __UINT64_C(x)
# undef INTMAX_C
# define INTMAX_C(x) __INTMAX_C(x)
# undef UINTMAX_C
# define UINTMAX_C(x) __UINTMAX_C(x)
#endif
#ifdef __UINT8_MAX__
# undef UINT8_MAX
# define UINT8_MAX __UINT8_MAX__
#endif
#ifdef __UINT16_MAX__
# undef UINT16_MAX
# define UINT16_MAX __UINT16_MAX__
#endif
#ifdef __UINT32_MAX__
# undef UINT32_MAX
# define UINT32_MAX __UINT32_MAX__
#endif
#ifdef __UINT64_MAX__
# undef UINT64_MAX
# define UINT64_MAX __UINT64_MAX__
#endif
#ifdef __INT8_MAX__
# undef INT8_MAX
# define INT8_MAX __INT8_MAX__
#endif
#ifdef __INT16_MAX__
# undef INT16_MAX
# define INT16_MAX __INT16_MAX__
#endif
#ifdef __INT32_MAX__
# undef INT32_MAX
# define INT32_MAX __INT32_MAX__
#endif
#ifdef __INT64_MAX__
# undef INT64_MAX
# define INT64_MAX __INT64_MAX__
#endif
#ifdef __INT8_MAX__
# undef INT8_MIN
# define INT8_MIN (-INT8_MAX - 1)
#endif
#ifdef __INT16_MAX__
# undef INT16_MIN
# define INT16_MIN (-INT16_MAX - 1)
#endif
#ifdef __INT32_MAX__
# undef INT32_MIN
# define INT32_MIN (-INT32_MAX - 1)
#endif
#ifdef __INT64_MAX__
# undef INT64_MIN
# define INT64_MIN (-INT64_MAX - 1)
#endif
#undef UINT_LEAST8_MAX
#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__
#undef UINT_LEAST16_MAX
#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__
#undef UINT_LEAST32_MAX
#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__
#undef UINT_LEAST64_MAX
#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__
#undef INT_LEAST8_MAX
#define INT_LEAST8_MAX __INT_LEAST8_MAX__
#undef INT_LEAST16_MAX
#define INT_LEAST16_MAX __INT_LEAST16_MAX__
#undef INT_LEAST32_MAX
#define INT_LEAST32_MAX __INT_LEAST32_MAX__
#undef INT_LEAST64_MAX
#define INT_LEAST64_MAX __INT_LEAST64_MAX__
#undef INT_LEAST8_MIN
#define INT_LEAST8_MIN (-INT_LEAST8_MAX - 1)
#undef INT_LEAST16_MIN
#define INT_LEAST16_MIN (-INT_LEAST16_MAX - 1)
#undef INT_LEAST32_MIN
#define INT_LEAST32_MIN (-INT_LEAST32_MAX - 1)
#undef INT_LEAST64_MIN
#define INT_LEAST64_MIN (-INT_LEAST64_MAX - 1)
#undef UINT_FAST8_MAX
#define UINT_FAST8_MAX __UINT_FAST8_MAX__
#undef UINT_FAST16_MAX
#define UINT_FAST16_MAX __UINT_FAST16_MAX__
#undef UINT_FAST32_MAX
#define UINT_FAST32_MAX __UINT_FAST32_MAX__
#undef UINT_FAST64_MAX
#define UINT_FAST64_MAX __UINT_FAST64_MAX__
#undef INT_FAST8_MAX
#define INT_FAST8_MAX __INT_FAST8_MAX__
#undef INT_FAST16_MAX
#define INT_FAST16_MAX __INT_FAST16_MAX__
#undef INT_FAST32_MAX
#define INT_FAST32_MAX __INT_FAST32_MAX__
#undef INT_FAST64_MAX
#define INT_FAST64_MAX __INT_FAST64_MAX__
#undef INT_FAST8_MIN
#define INT_FAST8_MIN (-INT_FAST8_MAX - 1)
#undef INT_FAST16_MIN
#define INT_FAST16_MIN (-INT_FAST16_MAX - 1)
#undef INT_FAST32_MIN
#define INT_FAST32_MIN (-INT_FAST32_MAX - 1)
#undef INT_FAST64_MIN
#define INT_FAST64_MIN (-INT_FAST64_MAX - 1)
#ifdef __UINTPTR_MAX__
# undef UINTPTR_MAX
# define UINTPTR_MAX __UINTPTR_MAX__
#endif
#ifdef __INTPTR_MAX__
# undef INTPTR_MAX
# define INTPTR_MAX __INTPTR_MAX__
# undef INTPTR_MIN
# define INTPTR_MIN (-INTPTR_MAX - 1)
#endif
#undef UINTMAX_MAX
#define UINTMAX_MAX __UINTMAX_MAX__
#undef INTMAX_MAX
#define INTMAX_MAX __INTMAX_MAX__
#undef INTMAX_MIN
#define INTMAX_MIN (-INTMAX_MAX - 1)
#undef PTRDIFF_MAX
#define PTRDIFF_MAX __PTRDIFF_MAX__
#undef PTRDIFF_MIN
#define PTRDIFF_MIN (-PTRDIFF_MAX - 1)
#undef SIG_ATOMIC_MAX
#define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__
#undef SIG_ATOMIC_MIN
#define SIG_ATOMIC_MIN (-SIG_ATOMIC_MAX - 1)
#undef SIZE_MAX
#define SIZE_MAX __SIZE_MAX__
#undef WCHAR_MAX
#define WCHAR_MAX __WCHAR_MAX__
#undef WCHAR_MIN
#define WCHAR_MIN (-WCHAR_MAX - 1)
#undef WINT_MAX
#define WINT_MAX __WINT_MAX__
#undef WINT_MIN
#define WINT_MIN (-WINT_MAX - 1)
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
#ifdef __INT8_TYPE__
# undef INT8_WIDTH
# define INT8_WIDTH 8
#endif
#ifdef __UINT8_TYPE__
# undef UINT8_WIDTH
# define UINT8_WIDTH 8
#endif
#ifdef __INT16_TYPE__
# undef INT16_WIDTH
# define INT16_WIDTH 16
#endif
#ifdef __UINT16_TYPE__
# undef UINT16_WIDTH
# define UINT16_WIDTH 16
#endif
#ifdef __INT32_TYPE__
# undef INT32_WIDTH
# define INT32_WIDTH 32
#endif
#ifdef __UINT32_TYPE__
# undef UINT32_WIDTH
# define UINT32_WIDTH 32
#endif
#ifdef __INT64_TYPE__
# undef INT64_WIDTH
# define INT64_WIDTH 64
#endif
#ifdef __UINT64_TYPE__
# undef UINT64_WIDTH
# define UINT64_WIDTH 64
#endif
#undef INT_LEAST8_WIDTH
#define INT_LEAST8_WIDTH __INT_LEAST8_WIDTH__
#undef UINT_LEAST8_WIDTH
#define UINT_LEAST8_WIDTH __INT_LEAST8_WIDTH__
#undef INT_LEAST16_WIDTH
#define INT_LEAST16_WIDTH __INT_LEAST16_WIDTH__
#undef UINT_LEAST16_WIDTH
#define UINT_LEAST16_WIDTH __INT_LEAST16_WIDTH__
#undef INT_LEAST32_WIDTH
#define INT_LEAST32_WIDTH __INT_LEAST32_WIDTH__
#undef UINT_LEAST32_WIDTH
#define UINT_LEAST32_WIDTH __INT_LEAST32_WIDTH__
#undef INT_LEAST64_WIDTH
#define INT_LEAST64_WIDTH __INT_LEAST64_WIDTH__
#undef UINT_LEAST64_WIDTH
#define UINT_LEAST64_WIDTH __INT_LEAST64_WIDTH__
#undef INT_FAST8_WIDTH
#define INT_FAST8_WIDTH __INT_FAST8_WIDTH__
#undef UINT_FAST8_WIDTH
#define UINT_FAST8_WIDTH __INT_FAST8_WIDTH__
#undef INT_FAST16_WIDTH
#define INT_FAST16_WIDTH __INT_FAST16_WIDTH__
#undef UINT_FAST16_WIDTH
#define UINT_FAST16_WIDTH __INT_FAST16_WIDTH__
#undef INT_FAST32_WIDTH
#define INT_FAST32_WIDTH __INT_FAST32_WIDTH__
#undef UINT_FAST32_WIDTH
#define UINT_FAST32_WIDTH __INT_FAST32_WIDTH__
#undef INT_FAST64_WIDTH
#define INT_FAST64_WIDTH __INT_FAST64_WIDTH__
#undef UINT_FAST64_WIDTH
#define UINT_FAST64_WIDTH __INT_FAST64_WIDTH__
#ifdef __INTPTR_TYPE__
# undef INTPTR_WIDTH
# define INTPTR_WIDTH __INTPTR_WIDTH__
#endif
#ifdef __UINTPTR_TYPE__
# undef UINTPTR_WIDTH
# define UINTPTR_WIDTH __INTPTR_WIDTH__
#endif
#undef INTMAX_WIDTH
#define INTMAX_WIDTH __INTMAX_WIDTH__
#undef UINTMAX_WIDTH
#define UINTMAX_WIDTH __INTMAX_WIDTH__
#undef PTRDIFF_WIDTH
#define PTRDIFF_WIDTH __PTRDIFF_WIDTH__
#undef SIG_ATOMIC_WIDTH
#define SIG_ATOMIC_WIDTH __SIG_ATOMIC_WIDTH__
#undef SIZE_WIDTH
#define SIZE_WIDTH __SIZE_WIDTH__
#undef WCHAR_WIDTH
#define WCHAR_WIDTH __WCHAR_WIDTH__
#undef WINT_WIDTH
#define WINT_WIDTH __WINT_WIDTH__
#define __STDC_VERSION_STDINT_H__ 202311L
#endif
#endif

24
kernel/libk/stdnoreturn.h Normal file
View File

@ -0,0 +1,24 @@
/* Copyright (C) 2022-2025 Mintsuki and contributors.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __FREESTND_C_HDRS_STDNORETURN_H
#define __FREESTND_C_HDRS_STDNORETURN_H 1
#ifndef __cplusplus
#define noreturn _Noreturn
#endif
#endif

62
kernel/libk/string.c Normal file
View File

@ -0,0 +1,62 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
#include <libk/types.h>
#include <libk/string.h>
usize_t memset(void *dst, byte_t b, usize_t n) {
byte_t *dst1 = dst;
usize_t i;
for (i = 0; i < n; i++)
dst1[i] = b;
return i;
}
usize_t memcpy(void *dst, const void *src, usize_t n) {
byte_t *dst1 = dst;
const byte_t *src1 = src;
usize_t i;
for (i = 0; i < n; i++)
dst1[i] = src1[i];
return i;
}
// SOURCE: https://stackoverflow.com/a/48967408
void strncpy(char* dst, const char* src, usize_t n) {
usize_t i = 0;
while(i++ != n && (*dst++ = *src++));
}
usize_t strlen(const char *str) {
const char *s;
for (s = str; *s; ++s);
return (s - str);
}

44
kernel/libk/string.h Normal file
View File

@ -0,0 +1,44 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _LIBK_STRING_H
#define _LIBK_STRING_H
#include <libk/types.h>
usize_t memset(void *dst, byte_t b, usize_t n);
usize_t memcpy(void *dst, const void *src, usize_t n);
void strncpy(char* dst, const char* src, usize_t n);
usize_t strlen(const char *str);
#define zero(p) memset((p), 0, sizeof(*(p)))
#endif // _LIBK_STRING_H

42
kernel/libk/util.h Normal file
View File

@ -0,0 +1,42 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _LIBK_UTIL_H
#define _LIBK_UTIL_H
#define LEN(X) (sizeof((X))/sizeof((X)[0]))
#define ELEM_SIZE(X) (sizeof((X)[0]))
#define ALIGN_DOWN(x, a) ((x) & ~((a) - 1))
#define ALIGN_UP(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
#endif // _LIBK_UTIL_H

8
kernel/make.src Normal file
View File

@ -0,0 +1,8 @@
dir_kernel := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
kernel_cflags += -isystem $(dir_kernel)
include platform/$(platform)/make.src
include libk/make.src
include sync/make.src
include mm/make.src

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

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

89
kernel/mm/bba.c Normal file
View File

@ -0,0 +1,89 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
#include <libk/types.h>
#include <libk/bitmap.h>
#include <libk/string.h>
#include <libk/util.h>
#include <libk/compiler.h>
#include <sync/spinlock.h>
#include <mm/bba.h>
#include <config.h>
static struct bba bba;
static volatile byte_t bba_membuf[BBA_SIZE] aligned(4096);
static volatile byte_t bba_bm_membuf[BBA_BM_SIZE] aligned(4096);
void bba_init(void) {
memset((void *)&bba, 0, sizeof(bba));
bba.baseptr = (uptr_t)bba_membuf;
bitmap_init(&bba.bm, (byte_t *)bba_bm_membuf, BBA_SIZE / BBA_BLOCK_SIZE);
sl_init(&bba.sl, "bba");
dbgf("bba_init(): initialized BBA %zu blocks, %zu block size, total=%zu\n",
BBA_SIZE / BBA_BLOCK_SIZE, BBA_BLOCK_SIZE, sizeof(bba_membuf));
}
uptr_t bba_alloc(void) {
uptr_t ret = 0;
sl_lock(&bba.sl);
for (usize_t i = 0; i < bba.bm.bit_count; i++) {
if (!bitmap_test(&bba.bm, i)) {
ret = (bba.baseptr + i * BBA_BLOCK_SIZE);
bitmap_set(&bba.bm, i);
goto done;
}
}
done:
sl_unlock(&bba.sl);
return ret;
}
void bba_free(uptr_t addr) {
uptr_t aligned_addr = ALIGN_DOWN(addr, BBA_BLOCK_SIZE);
if (aligned_addr < bba.baseptr)
goto done;
if (aligned_addr >= bba.baseptr + bba.bm.bit_count * BBA_BLOCK_SIZE)
goto done;
usize_t bit = (usize_t)(aligned_addr - bba.baseptr) / BBA_BLOCK_SIZE;
sl_lock(&bba.sl);
bitmap_clear(&bba.bm, bit);
sl_unlock(&bba.sl);
done:
return;
}

54
kernel/mm/bba.h Normal file
View File

@ -0,0 +1,54 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _MM_BBA_H
#define _MM_BBA_H
#include <libk/types.h>
#include <libk/bitmap.h>
#include <sync/spinlock.h>
/* Bootstrap Bitmap Allocator */
#define BBA_BLOCK_SIZE (4096)
#define BBA_SIZE (BBA_BLOCK_SIZE * 128)
#define BBA_BM_SIZE (BBA_BLOCK_SIZE)
struct bba {
struct spinlock sl;
struct bitmap bm;
uptr_t baseptr;
};
void bba_init(void);
uptr_t bba_alloc(void);
void bba_free(uptr_t addr);
#endif // _MM_BBA_H

604
kernel/mm/liballoc.c Normal file
View File

@ -0,0 +1,604 @@
/* Porting: */
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-compare"
#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
#pragma clang diagnostic ignored "-Wself-assign"
#pragma clang optimize off
#endif
#include <libk/stdatomic.h>
#include <libk/types.h>
#include <sys/mm.h>
#include <mm/liballoc.h>
#include <mm/pmm.h>
#include <sync/spinlock.h>
#include <config.h>
struct spinlock liballoc_sl = { .flag = ATOMIC_FLAG_INIT, .name = "liballoc" };
uptr_t liballoc_memory_start = KERNEL_HEAP_START;
int liballoc_lock(void) {
sl_lock(&liballoc_sl);
return 0;
}
int liballoc_unlock(void) {
sl_unlock(&liballoc_sl);
return 0;
}
void *liballoc_alloc(int pages) {
#if defined(__i386__)
struct page_dir *pd = mm_get_kernel_pd();
sl_lock(&pd->sl);
uptr_t vaddr = liballoc_memory_start;
for (uptr_t page = vaddr; page < vaddr + PAGE_SIZE * pages; page += PAGE_SIZE) {
uptr_t phys = pmm_alloc();
mm_map_page(pd, page, phys, PF_WRITABLE | PF_PRESENT);
}
sl_unlock(&pd->sl);
return (void *)vaddr;
#else
#error "platform unimplemented"
#endif
}
int liballoc_free(void *ptr1, int pages) {
#if defined(__i386__)
struct page_dir *pd = mm_get_kernel_pd();
uptr_t ptr = ALIGN_DOWN((uptr_t)ptr1, 0x1000);
sl_lock(&pd->sl);
for (uptr_t page = ptr; page < ptr + PAGE_SIZE * pages; page += PAGE_SIZE) {
uptr_t phys = mm_translate(pd, page, 0);
mm_unmap_page(pd, page, 0);
pmm_free(phys);
}
sl_unlock(&pd->sl);
return 0;
#else
#error "platform unimplemented"
#endif
}
/** Durand's Ridiculously Amazing Super Duper Memory functions. */
//#define DEBUG
#define LIBALLOC_MAGIC 0xc001c0de
#define MAXCOMPLETE 5
#define MAXEXP 32
#define MINEXP 8
#define MODE_BEST 0
#define MODE_INSTANT 1
#define MODE MODE_BEST
#ifdef DEBUG
#include <stdio.h>
#endif
struct boundary_tag* l_freePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
int l_completePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
#ifdef DEBUG
unsigned int l_allocated = 0; //< The real amount of memory allocated.
unsigned int l_inuse = 0; //< The amount of memory in use (malloc'ed).
#endif
static int l_initialized = 0; //< Flag to indicate initialization.
static int l_pageSize = 4096; //< Individual page size
static int l_pageCount = 16; //< Minimum number of pages to allocate.
// *********** HELPER FUNCTIONS *******************************
/** Returns the exponent required to manage 'size' amount of memory.
*
* Returns n where 2^n <= size < 2^(n+1)
*/
static inline int getexp( unsigned int size )
{
if ( size < (1<<MINEXP) )
{
#ifdef DEBUG
printf("getexp returns -1 for %i less than MINEXP\n", size );
#endif
return -1; // Smaller than the quantum.
}
int shift = MINEXP;
while ( shift < MAXEXP )
{
if ( (1<<shift) > size ) break;
shift += 1;
}
#ifdef DEBUG
printf("getexp returns %i (%i bytes) for %i size\n", shift - 1, (1<<(shift -1)), size );
#endif
return shift - 1;
}
static void* liballoc_memset(void* s, int c, size_t n)
{
int i;
for ( i = 0; i < n ; i++)
((char*)s)[i] = c;
return s;
}
static void* liballoc_memcpy(void* s1, const void* s2, size_t n)
{
char *cdest;
char *csrc;
unsigned int *ldest = (unsigned int*)s1;
unsigned int *lsrc = (unsigned int*)s2;
while ( n >= sizeof(unsigned int) )
{
*ldest++ = *lsrc++;
n -= sizeof(unsigned int);
}
cdest = (char*)ldest;
csrc = (char*)lsrc;
while ( n > 0 )
{
*cdest++ = *csrc++;
n -= 1;
}
return s1;
}
#ifdef DEBUG
static void dump_array()
{
int i = 0;
struct boundary_tag *tag = NULL;
printf("------ Free pages array ---------\n");
printf("System memory allocated: %i\n", l_allocated );
printf("Memory in used (malloc'ed): %i\n", l_inuse );
for ( i = 0; i < MAXEXP; i++ )
{
printf("%.2i(%i): ",i, l_completePages[i] );
tag = l_freePages[ i ];
while ( tag != NULL )
{
if ( tag->split_left != NULL ) printf("*");
printf("%i", tag->real_size );
if ( tag->split_right != NULL ) printf("*");
printf(" ");
tag = tag->next;
}
printf("\n");
}
printf("'*' denotes a split to the left/right of a tag\n");
fflush( stdout );
}
#endif
static inline void insert_tag( struct boundary_tag *tag, int index )
{
int realIndex;
if ( index < 0 )
{
realIndex = getexp( tag->real_size - sizeof(struct boundary_tag) );
if ( realIndex < MINEXP ) realIndex = MINEXP;
}
else
realIndex = index;
tag->index = realIndex;
if ( l_freePages[ realIndex ] != NULL )
{
l_freePages[ realIndex ]->prev = tag;
tag->next = l_freePages[ realIndex ];
}
l_freePages[ realIndex ] = tag;
}
static inline void remove_tag( struct boundary_tag *tag )
{
if ( l_freePages[ tag->index ] == tag ) l_freePages[ tag->index ] = tag->next;
if ( tag->prev != NULL ) tag->prev->next = tag->next;
if ( tag->next != NULL ) tag->next->prev = tag->prev;
tag->next = NULL;
tag->prev = NULL;
tag->index = -1;
}
static inline struct boundary_tag* melt_left( struct boundary_tag *tag )
{
struct boundary_tag *left = tag->split_left;
left->real_size += tag->real_size;
left->split_right = tag->split_right;
if ( tag->split_right != NULL ) tag->split_right->split_left = left;
return left;
}
static inline struct boundary_tag* absorb_right( struct boundary_tag *tag )
{
struct boundary_tag *right = tag->split_right;
remove_tag( right ); // Remove right from free pages.
tag->real_size += right->real_size;
tag->split_right = right->split_right;
if ( right->split_right != NULL )
right->split_right->split_left = tag;
return tag;
}
static inline struct boundary_tag* split_tag( struct boundary_tag* tag )
{
unsigned int remainder = tag->real_size - sizeof(struct boundary_tag) - tag->size;
struct boundary_tag *new_tag =
(struct boundary_tag*)((unsigned int)tag + sizeof(struct boundary_tag) + tag->size);
new_tag->magic = LIBALLOC_MAGIC;
new_tag->real_size = remainder;
new_tag->next = NULL;
new_tag->prev = NULL;
new_tag->split_left = tag;
new_tag->split_right = tag->split_right;
if (new_tag->split_right != NULL) new_tag->split_right->split_left = new_tag;
tag->split_right = new_tag;
tag->real_size -= new_tag->real_size;
insert_tag( new_tag, -1 );
return new_tag;
}
// ***************************************************************
static struct boundary_tag* allocate_new_tag( unsigned int size )
{
unsigned int pages;
unsigned int usage;
struct boundary_tag *tag;
// This is how much space is required.
usage = size + sizeof(struct boundary_tag);
// Perfect amount of space
pages = usage / l_pageSize;
if ( (usage % l_pageSize) != 0 ) pages += 1;
// Make sure it's >= the minimum size.
if ( pages < l_pageCount ) pages = l_pageCount;
tag = (struct boundary_tag*)liballoc_alloc( pages );
if ( tag == NULL ) return NULL; // uh oh, we ran out of memory.
tag->magic = LIBALLOC_MAGIC;
tag->size = size;
tag->real_size = pages * l_pageSize;
tag->index = -1;
tag->next = NULL;
tag->prev = NULL;
tag->split_left = NULL;
tag->split_right = NULL;
#ifdef DEBUG
printf("Resource allocated %x of %i pages (%i bytes) for %i size.\n", tag, pages, pages * l_pageSize, size );
l_allocated += pages * l_pageSize;
printf("Total memory usage = %i KB\n", (int)((l_allocated / (1024))) );
#endif
return tag;
}
void *malloc(size_t size)
{
int index;
void *ptr;
struct boundary_tag *tag = NULL;
liballoc_lock();
if ( l_initialized == 0 )
{
#ifdef DEBUG
printf("%s\n","liballoc initializing.");
#endif
for ( index = 0; index < MAXEXP; index++ )
{
l_freePages[index] = NULL;
l_completePages[index] = 0;
}
l_initialized = 1;
}
index = getexp( size ) + MODE;
if ( index < MINEXP ) index = MINEXP;
// Find one big enough.
tag = l_freePages[ index ]; // Start at the front of the list.
while ( tag != NULL )
{
// If there's enough space in this tag.
if ( (tag->real_size - sizeof(struct boundary_tag))
>= (size + sizeof(struct boundary_tag) ) )
{
#ifdef DEBUG
printf("Tag search found %i >= %i\n",(tag->real_size - sizeof(struct boundary_tag)), (size + sizeof(struct boundary_tag) ) );
#endif
break;
}
tag = tag->next;
}
// No page found. Make one.
if ( tag == NULL )
{
if ( (tag = allocate_new_tag( size )) == NULL )
{
liballoc_unlock();
return NULL;
}
index = getexp( tag->real_size - sizeof(struct boundary_tag) );
}
else
{
remove_tag( tag );
if ( (tag->split_left == NULL) && (tag->split_right == NULL) )
l_completePages[ index ] -= 1;
}
// We have a free page. Remove it from the free pages list.
tag->size = size;
// Removed... see if we can re-use the excess space.
#ifdef DEBUG
printf("Found tag with %i bytes available (requested %i bytes, leaving %i), which has exponent: %i (%i bytes)\n", tag->real_size - sizeof(struct boundary_tag), size, tag->real_size - size - sizeof(struct boundary_tag), index, 1<<index );
#endif
unsigned int remainder = tag->real_size - size - sizeof( struct boundary_tag ) * 2; // Support a new tag + remainder
if ( ((int)(remainder) > 0) /*&& ( (tag->real_size - remainder) >= (1<<MINEXP))*/ )
{
int childIndex = getexp( remainder );
if ( childIndex >= 0 )
{
#ifdef DEBUG
printf("Seems to be splittable: %i >= 2^%i .. %i\n", remainder, childIndex, (1<<childIndex) );
#endif
struct boundary_tag *new_tag = split_tag( tag );
new_tag = new_tag; // Get around the compiler warning about unused variables.
#ifdef DEBUG
printf("Old tag has become %i bytes, new tag is now %i bytes (%i exp)\n", tag->real_size, new_tag->real_size, new_tag->index );
#endif
}
}
ptr = (void*)((unsigned int)tag + sizeof( struct boundary_tag ) );
#ifdef DEBUG
l_inuse += size;
printf("malloc: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024 );
dump_array();
#endif
liballoc_unlock();
return ptr;
}
void free(void *ptr)
{
int index;
struct boundary_tag *tag;
if ( ptr == NULL ) return;
liballoc_lock();
tag = (struct boundary_tag*)((unsigned int)ptr - sizeof( struct boundary_tag ));
if ( tag->magic != LIBALLOC_MAGIC )
{
liballoc_unlock(); // release the lock
return;
}
#ifdef DEBUG
l_inuse -= tag->size;
printf("free: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024 );
#endif
// MELT LEFT...
while ( (tag->split_left != NULL) && (tag->split_left->index >= 0) )
{
#ifdef DEBUG
printf("Melting tag left into available memory. Left was %i, becomes %i (%i)\n", tag->split_left->real_size, tag->split_left->real_size + tag->real_size, tag->split_left->real_size );
#endif
tag = melt_left( tag );
remove_tag( tag );
}
// MELT RIGHT...
while ( (tag->split_right != NULL) && (tag->split_right->index >= 0) )
{
#ifdef DEBUG
printf("Melting tag right into available memory. This was was %i, becomes %i (%i)\n", tag->real_size, tag->split_right->real_size + tag->real_size, tag->split_right->real_size );
#endif
tag = absorb_right( tag );
}
// Where is it going back to?
index = getexp( tag->real_size - sizeof(struct boundary_tag) );
if ( index < MINEXP ) index = MINEXP;
// A whole, empty block?
if ( (tag->split_left == NULL) && (tag->split_right == NULL) )
{
if ( l_completePages[ index ] == MAXCOMPLETE )
{
// Too many standing by to keep. Free this one.
unsigned int pages = tag->real_size / l_pageSize;
if ( (tag->real_size % l_pageSize) != 0 ) pages += 1;
if ( pages < l_pageCount ) pages = l_pageCount;
liballoc_free( tag, pages );
#ifdef DEBUG
l_allocated -= pages * l_pageSize;
printf("Resource freeing %x of %i pages\n", tag, pages );
dump_array();
#endif
liballoc_unlock();
return;
}
l_completePages[ index ] += 1; // Increase the count of complete pages.
}
// ..........
insert_tag( tag, index );
#ifdef DEBUG
printf("Returning tag with %i bytes (requested %i bytes), which has exponent: %i\n", tag->real_size, tag->size, index );
dump_array();
#endif
liballoc_unlock();
}
void* calloc(size_t nobj, size_t size)
{
int real_size;
void *p;
real_size = nobj * size;
p = malloc( real_size );
liballoc_memset( p, 0, real_size );
return p;
}
void* realloc(void *p, size_t size)
{
void *ptr;
struct boundary_tag *tag;
int real_size;
if ( size == 0 )
{
free( p );
return NULL;
}
if ( p == NULL ) return malloc( size );
if ( liballoc_lock != NULL ) liballoc_lock(); // lockit
tag = (struct boundary_tag*)((unsigned int)p - sizeof( struct boundary_tag ));
real_size = tag->size;
if ( liballoc_unlock != NULL ) liballoc_unlock();
if ( real_size > size ) real_size = size;
ptr = malloc( size );
liballoc_memcpy( ptr, p, real_size );
free( p );
return ptr;
}

99
kernel/mm/liballoc.h Normal file
View File

@ -0,0 +1,99 @@
#ifndef _LIBALLOC_H
#define _LIBALLOC_H
// If we are told to not define our own size_t, then we
// skip the define.
#ifndef _ALLOC_SKIP_DEFINE
#ifndef _HAVE_SIZE_T
#define _HAVE_SIZE_T
typedef unsigned int size_t;
#endif
#ifndef NULL
#define NULL 0
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** This is a boundary tag which is prepended to the
* page or section of a page which we have allocated. It is
* used to identify valid memory blocks that the
* application is trying to free.
*/
struct boundary_tag
{
unsigned int magic; //< It's a kind of ...
unsigned int size; //< Requested size.
unsigned int real_size; //< Actual size.
int index; //< Location in the page table.
struct boundary_tag *split_left; //< Linked-list info for broken pages.
struct boundary_tag *split_right; //< The same.
struct boundary_tag *next; //< Linked list info.
struct boundary_tag *prev; //< Linked list info.
};
/** This function is supposed to lock the memory data structures. It
* could be as simple as disabling interrupts or acquiring a spinlock.
* It's up to you to decide.
*
* \return 0 if the lock was acquired successfully. Anything else is
* failure.
*/
extern int liballoc_lock();
/** This function unlocks what was previously locked by the liballoc_lock
* function. If it disabled interrupts, it enables interrupts. If it
* had acquiried a spinlock, it releases the spinlock. etc.
*
* \return 0 if the lock was successfully released.
*/
extern int liballoc_unlock();
/** This is the hook into the local system which allocates pages. It
* accepts an integer parameter which is the number of pages
* required. The page size was set up in the liballoc_init function.
*
* \return NULL if the pages were not allocated.
* \return A pointer to the allocated memory.
*/
extern void* liballoc_alloc(int);
/** This frees previously allocated memory. The void* parameter passed
* to the function is the exact same value returned from a previous
* liballoc_alloc call.
*
* The integer value is the number of pages to free.
*
* \return 0 if the memory was successfully freed.
*/
extern int liballoc_free(void*,int);
void *malloc(size_t); //< The standard function.
void *realloc(void *, size_t); //< The standard function.
void *calloc(size_t, size_t); //< The standard function.
void free(void *); //< The standard function.
#ifdef __cplusplus
}
#endif
#endif

9
kernel/mm/make.src Normal file
View File

@ -0,0 +1,9 @@
dir_mm1 := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
c_files += $(dir_mm1)/pmm.c \
$(dir_mm1)/bba.c \
$(dir_mm1)/liballoc.c
o_files += $(dir_mm1)/pmm.o \
$(dir_mm1)/bba.o \
$(dir_mm1)/liballoc.o

87
kernel/mm/pmm.c Normal file
View File

@ -0,0 +1,87 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
#include <libk/types.h>
#include <libk/bitmap.h>
#include <libk/string.h>
#include <libk/util.h>
#include <sync/spinlock.h>
#include <mm/pmm.h>
#include <config.h>
static struct pmm pmm;
void pmm_init(uptr_t baseptr, uptr_t bm_baseptr, usize_t block_count, usize_t block_size) {
zero(&pmm);
pmm.block_size = block_size;
pmm.baseptr = baseptr;
bitmap_init(&pmm.bm, (byte_t *)bm_baseptr, block_count);
sl_init(&pmm.sl, "pmm");
dbgf("pmm_init(): initialized PMM %zu blocks, %zu block size, total=%zu\n",
block_count, block_size, block_count * block_size);
}
uptr_t pmm_alloc(void) {
uptr_t ret = 0;
sl_lock(&pmm.sl);
for (usize_t i = 0; i < pmm.bm.bit_count; i++) {
if (!bitmap_test(&pmm.bm, i)) {
ret = (pmm.baseptr + i * pmm.block_size);
bitmap_set(&pmm.bm, i);
goto done;
}
}
done:
sl_unlock(&pmm.sl);
return ret;
}
void pmm_free(uptr_t addr) {
uptr_t aligned_addr = ALIGN_DOWN(addr, pmm.block_size);
if (aligned_addr < pmm.baseptr)
goto done;
if (aligned_addr >= pmm.baseptr + pmm.bm.bit_count * pmm.block_size)
goto done;
usize_t bit = (usize_t)(aligned_addr - pmm.baseptr) / pmm.block_size;
sl_lock(&pmm.sl);
bitmap_clear(&pmm.bm, bit);
sl_unlock(&pmm.sl);
done:
return;
}

50
kernel/mm/pmm.h Normal file
View File

@ -0,0 +1,50 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _MM_PMM_H
#define _MM_PMM_H
#include <libk/types.h>
#include <libk/bitmap.h>
#include <sync/spinlock.h>
struct pmm {
struct spinlock sl;
struct bitmap bm;
usize_t block_size;
uptr_t baseptr;
};
void pmm_init(uptr_t baseptr, uptr_t bm_baseptr, usize_t block_count, usize_t block_size);
uptr_t pmm_alloc(void);
void pmm_free(uptr_t addr);
#endif // _MM_PMM_H

View File

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

View File

@ -0,0 +1,95 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
#define F_MEMALIGN (1<<0)
#define F_MEMINFO (1<<1)
#define FLAGS (F_MEMALIGN | F_MEMINFO)
#define MAGIC (0x1BADB002)
#define CHECKSUM (-(MAGIC + FLAGS))
#define VIRT_BASE 0xC0000000
.section .multiboot, "aw"
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
.section .bss
.align 16
__stack_bottom:
.skip 16384
__stack_top:
.section .boot, "ax"
.global _start
_start:
movl $(__init_pd - VIRT_BASE), %ecx
movl %ecx, %cr3
movl %cr4, %ecx
orl $0x10, %ecx
movl %ecx, %cr4
movl %cr0, %ecx
orl $0x80000000, %ecx
movl %ecx, %cr0
movl $__kernel_higherhalf, %ecx
jmp *%ecx
.section .text, "ax"
__kernel_higherhalf:
mov $__stack_top, %esp
push %ebx
xorl %ebp, %ebp
call bootmain
1:
hlt
jmp 1b
.section .data
.align 4096
.global __init_pd
__init_pd:
.long 0b10000011
.rept 768-1
.long 0
.endr
.long (0 << 22) | 0b10000011
.long (1 << 22) | 0b10000011
.long (2 << 22) | 0b10000011
.long (3 << 22) | 0b10000011
.rept 256-4
.long 0
.endr

View File

@ -0,0 +1,103 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
#include <libk/types.h>
#include <libk/util.h>
#include <libk/string.h>
#include <sys/cpu.h>
#include <sys/multiboot.h>
#include <sys/serialdbg.h>
#include <sys/mm.h>
#include <mm/pmm.h>
#include <mm/bba.h>
#include <mm/liballoc.h>
#include <config.h>
extern byte_t __kernel_end;
static void dump_multiboot_header(void) {
struct multiboot *mb = multiboot_get();
dbgf("multiboot=%p\n", mb);
dbgf("multiboot sanity dump:\n");
dbgf("flags=%08x, mem_low=%08x, mem_up=%08x\n",
mb->flags, mb->mem_low, mb->mem_up);
}
static void pmm_init1(void) {
struct multiboot *mb = multiboot_get();
dbgf("__kernel_end=%p, %p\n", &__kernel_end, (uptr_t)&__kernel_end - VIRT_BASE);
usize_t usable_ram_bytes = mb->mem_up * 1024;
dbgf("usable ram = %zu\n", usable_ram_bytes);
uptr_t ram_start = ALIGN_UP((uptr_t)&__kernel_end - VIRT_BASE, 0x1000);
uptr_t ram_end = ALIGN_DOWN(0x100000 + usable_ram_bytes, 0x1000);
usize_t block_size = CFG_I386_PC_PMM_BLOCK_SIZE;
usize_t block_count = (ram_end - ram_start) / block_size;
usize_t pmm_bm_bytes = ALIGN_UP((block_count + 7) / 8, block_size);
uptr_t pmm_bm_baseptr = ram_start;
uptr_t pmm_baseptr = ram_start + pmm_bm_bytes;
usize_t remaining_blocks = (ram_end - pmm_baseptr) / block_size;
dbgf("ram_start=%p, pmm_bm_baseptr=%p, pmm_baseptr=%p\n",
ram_start, pmm_bm_baseptr, pmm_baseptr);
pmm_init(pmm_baseptr, pmm_bm_baseptr, remaining_blocks, block_size);
}
void bootmain(void *mbootptr) {
multiboot_set((struct multiboot *)VIRT(mbootptr));
cpu_init();
#if CFG_I386_PC_DEBUG == CFG_I386_PC_DEBUG_SERIAL
serialdbg_init();
dbgf("dbgf() test...\n");
#endif
dump_multiboot_header();
pmm_init1();
bba_init();
mm_init();
char *string = malloc(12);
memset(string, 0, 12);
strncpy(string, "Hello world", 12);
dbgf("string = %s\n", string);
free(string);
for (;;);
}

View File

@ -0,0 +1,8 @@
dir_boot := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
c_files += $(dir_boot)/bootmain.c
S_files += $(dir_boot)/_start.S
o_files += $(dir_boot)/bootmain.o \
$(dir_boot)/_start.o

View File

View File

@ -0,0 +1,48 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _TYPES_H
#define _TYPES_H
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
typedef uint32_t usize_t;
typedef int32_t isize_t;
typedef uintptr_t uptr_t;
typedef intptr_t iptr_t;
typedef void * ptr_t;
typedef bool bool_t;
typedef uint8_t byte_t;
typedef int err_t;
#endif // _TYPES_H

View File

@ -0,0 +1,68 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
VIRT_BASE = 0xC0000000;
SECTIONS {
. = 0x00100000;
.multiboot ALIGN(4K): {
*(.multiboot)
}
.boot ALIGN(4K) : {
*(.boot)
}
. += VIRT_BASE;
.text ALIGN(4K) : AT(ADDR(.text) - VIRT_BASE) {
*(.text)
}
.rodata ALIGN(4K) : AT(ADDR(.rodata) - VIRT_BASE) {
*(.rodata)
}
.data ALIGN(4K) : AT(ADDR(.data) - VIRT_BASE) {
*(.data)
}
.bss ALIGN(4K) : AT(ADDR(.bss) - VIRT_BASE) {
*(.bss)
}
__kernel_end = .;
}

View File

@ -0,0 +1,8 @@
dir_i386_pc := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
kernel_ldflags += -T$(dir_i386_pc)/link.ld
kernel_cflags += -isystem $(dir_i386_pc)
include $(dir_i386_pc)/boot/make.src
include $(dir_i386_pc)/libk/make.src
include $(dir_i386_pc)/sys/make.src

View File

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

View File

@ -0,0 +1,198 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
#include <libk/types.h>
#include <libk/util.h>
#include <libk/string.h>
#include <libk/stdatomic.h>
#include <sys/cpu.h>
#include <sys/gdt_flush.h>
#include <sys/tss_flush.h>
#include <sys/idt_flush.h>
#include <sys/isr.h>
#include <sys/pic.h>
static volatile struct gdt_entry gdt[6];
static volatile struct gdt_ptr gdtptr;
static volatile struct tss tss;
static volatile struct idt_entry idt[0x100];
static volatile struct idt_ptr idtptr;
static struct { volatile uint32_t eflags; atomic_int nesting; } intr_state =
{ .eflags = 0, .nesting = 0 };
static void gdt_make_entry(int index, uint32_t base, uint32_t limit,
uint8_t access, uint8_t gran) {
gdt[index].base_low = (base & 0xFFFF);
gdt[index].base_mid = (base >> 16) & 0xFF;
gdt[index].base_up = (base >> 24) & 0xFF;
gdt[index].limit_low = (limit & 0xFFFF);
gdt[index].gran = ((limit >> 16) & 0x0F);
gdt[index].gran |= (gran & 0xF0);
gdt[index].access = access;
}
static void gdt_init(void) {
gdtptr.limit = ELEM_SIZE(gdt) * LEN(gdt) - 1;
gdtptr.base = (uint32_t)&gdt;
gdt_make_entry(0, 0, 0, 0, 0);
gdt_make_entry(1, 0, 0xFFFFF, 0x9A, 0xCF);
gdt_make_entry(2, 0, 0xFFFFF, 0x92, 0xCF);
gdt_make_entry(3, 0, 0xFFFFF, 0xFA, 0xCF);
gdt_make_entry(4, 0, 0xFFFFF, 0xF2, 0xCF);
gdt_flush((ptr_t)&gdtptr);
}
static void tss_init(void) {
uint32_t base = (uint32_t)&tss;
gdt_make_entry(5, base, base + sizeof(struct tss), 0xE9, 0);
memset((void *)&tss, 0, sizeof(tss));
uptr_t sp;
__asm__ volatile("mov %%esp, %0" : "=r"(sp));
tss.ss0 = 0x10;
tss.esp0 = (uint32_t)sp;
tss.cs = 0x08 | 0x3;
tss.ds = 0x10 | 0x3;
tss.es = 0x10 | 0x3;
tss.fs = 0x10 | 0x3;
tss.fs = 0x10 | 0x3;
tss.ss = 0x10 | 0x3;
tss_flush();
}
static void idt_make_entry(int index, uint32_t base, uint32_t sel, uint8_t flags) {
volatile struct idt_entry *ent = &idt[index];
ent->base_low = (base & 0xFFFF);
ent->base_up = ((base >> 16) & 0xFFFF);
ent->always0 = 0;
ent->sel = sel;
ent->flags = flags | 0x60;
}
void idt_init(void) {
memset((void *)idt, 0, sizeof(idt));
idtptr.base = (uint32_t)idt;
idtptr.limit = sizeof(idt) - 1;
idt_make_entry(0, (uint32_t)&except0, 0x08, 0x8E);
idt_make_entry(1, (uint32_t)&except1, 0x08, 0x8E);
idt_make_entry(2, (uint32_t)&except2, 0x08, 0x8E);
idt_make_entry(3, (uint32_t)&except3, 0x08, 0x8E);
idt_make_entry(4, (uint32_t)&except4, 0x08, 0x8E);
idt_make_entry(5, (uint32_t)&except5, 0x08, 0x8E);
idt_make_entry(6, (uint32_t)&except6, 0x08, 0x8E);
idt_make_entry(7, (uint32_t)&except7, 0x08, 0x8E);
idt_make_entry(8, (uint32_t)&except8, 0x08, 0x8E);
idt_make_entry(9, (uint32_t)&except9, 0x08, 0x8E);
idt_make_entry(10, (uint32_t)&except10, 0x08, 0x8E);
idt_make_entry(11, (uint32_t)&except11, 0x08, 0x8E);
idt_make_entry(12, (uint32_t)&except12, 0x08, 0x8E);
idt_make_entry(13, (uint32_t)&except13, 0x08, 0x8E);
idt_make_entry(14, (uint32_t)&except14, 0x08, 0x8E);
idt_make_entry(15, (uint32_t)&except15, 0x08, 0x8E);
idt_make_entry(16, (uint32_t)&except16, 0x08, 0x8E);
idt_make_entry(17, (uint32_t)&except17, 0x08, 0x8E);
idt_make_entry(18, (uint32_t)&except18, 0x08, 0x8E);
idt_make_entry(19, (uint32_t)&except19, 0x08, 0x8E);
idt_make_entry(20, (uint32_t)&except20, 0x08, 0x8E);
idt_make_entry(21, (uint32_t)&except21, 0x08, 0x8E);
idt_make_entry(22, (uint32_t)&except22, 0x08, 0x8E);
idt_make_entry(23, (uint32_t)&except23, 0x08, 0x8E);
idt_make_entry(24, (uint32_t)&except24, 0x08, 0x8E);
idt_make_entry(25, (uint32_t)&except25, 0x08, 0x8E);
idt_make_entry(26, (uint32_t)&except26, 0x08, 0x8E);
idt_make_entry(27, (uint32_t)&except27, 0x08, 0x8E);
idt_make_entry(28, (uint32_t)&except28, 0x08, 0x8E);
idt_make_entry(29, (uint32_t)&except29, 0x08, 0x8E);
idt_make_entry(30, (uint32_t)&except30, 0x08, 0x8E);
idt_make_entry(31, (uint32_t)&except31, 0x08, 0x8E);
idt_make_entry(32, (uint32_t)&irq0, 0x08, 0x8E);
idt_make_entry(33, (uint32_t)&irq1, 0x08, 0x8E);
idt_make_entry(34, (uint32_t)&irq2, 0x08, 0x8E);
idt_make_entry(35, (uint32_t)&irq3, 0x08, 0x8E);
idt_make_entry(36, (uint32_t)&irq4, 0x08, 0x8E);
idt_make_entry(37, (uint32_t)&irq5, 0x08, 0x8E);
idt_make_entry(38, (uint32_t)&irq6, 0x08, 0x8E);
idt_make_entry(39, (uint32_t)&irq7, 0x08, 0x8E);
idt_make_entry(40, (uint32_t)&irq8, 0x08, 0x8E);
idt_make_entry(41, (uint32_t)&irq9, 0x08, 0x8E);
idt_make_entry(42, (uint32_t)&irq10, 0x08, 0x8E);
idt_make_entry(43, (uint32_t)&irq11, 0x08, 0x8E);
idt_make_entry(44, (uint32_t)&irq12, 0x08, 0x8E);
idt_make_entry(45, (uint32_t)&irq13, 0x08, 0x8E);
idt_make_entry(46, (uint32_t)&irq14, 0x08, 0x8E);
idt_make_entry(47, (uint32_t)&irq15, 0x08, 0x8E);
idt_make_entry(128, (uint32_t)&except128, 0x08, 0xEE);
idt_flush((ptr_t)&idtptr);
}
void cpu_init(void) {
gdt_init();
tss_init();
pic_init();
idt_init();
}
static uint32_t intr_save1(void) {
uint32_t eflags;
__asm__ volatile ("pushfl; cli; popl %0;" : "=r"(eflags) :: "memory", "cc");
return eflags;
}
static void intr_restore1(uint32_t eflags) {
if (eflags & (1 << 9)) {
__asm__ volatile("sti" ::: "memory", "cc");
}
}
void intr_save(void) {
int prev = atomic_fetch_add_explicit(&intr_state.nesting, 1, memory_order_acq_rel);
if (prev == 0) {
intr_state.eflags = intr_save1();
}
}
void intr_restore(void) {
int prev = atomic_fetch_sub_explicit(&intr_state.nesting, 1, memory_order_acq_rel);
if (prev == 1) {
intr_restore1(intr_state.eflags);
}
}
void cpu_relax(void) {
__asm__ volatile("pause");
}

View File

@ -0,0 +1,93 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _SYS_CPU_H
#define _SYS_CPU_H
#include <libk/types.h>
#include <libk/compiler.h>
struct gdt_entry {
uint16_t limit_low;
uint16_t base_low;
uint8_t base_mid;
uint8_t access;
uint8_t gran;
uint8_t base_up;
} packed;
struct gdt_ptr {
uint16_t limit;
uint32_t base;
} packed;
struct tss {
uint32_t link;
uint32_t esp0, ss0;
uint32_t esp1, ss1;
uint32_t esp2, ss2;
uint32_t cr3;
uint32_t eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;
uint32_t es, cs, ss, ds, fs, gs;
uint32_t ldt;
uint16_t trap;
uint16_t iomap;
} packed;
struct idt_entry {
uint16_t base_low;
uint16_t sel;
uint8_t always0;
uint8_t flags;
uint16_t base_up;
} packed;
struct idt_ptr {
uint16_t limit;
uint32_t base;
} packed;
struct trapframe {
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
uint32_t ds;
uint32_t cr3;
uint32_t trapno;
uint32_t ec;
uint32_t eip, cs, eflags, uesp, uss;
} packed;
void cpu_init(void);
void intr_save(void);
void intr_restore(void);
void cpu_relax(void);
#endif // _SYS_CPU_H

View File

@ -0,0 +1,46 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
.section .text
.global gdt_flush
.type gdt_flush, @function
gdt_flush:
mov 4(%esp), %eax
lgdt (%eax)
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
ljmp $0x08, $1f
1:
ret

View File

@ -0,0 +1,39 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _SYS_GDT_FLUSH_H
#define _SYS_GDT_FLUSH_H
#include <libk/types.h>
void gdt_flush(ptr_t gdtptr);
#endif // _SYS_GDT_FLUSH_H

View File

@ -0,0 +1,38 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
.section .text
.global halt
.type halt, @function
halt:
cli
hlt
jmp halt

View File

@ -0,0 +1,37 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _SYS_HALT_H
#define _SYS_HALT_H
void halt(void);
#endif // _SYS_HALT_H

View File

@ -0,0 +1,39 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
.section .text
.global idt_flush
.type idt_flush, @function
idt_flush:
mov 4(%esp), %eax
lidt (%eax)
sti
ret

View File

@ -0,0 +1,39 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _SYS_IDT_FLUSH_H
#define _SYS_IDT_FLUSH_H
#include <libk/types.h>
void idt_flush(ptr_t idtptr);
#endif // _SYS_IDT_FLUSH_H

View File

@ -0,0 +1,85 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
#include <libk/types.h>
#include <sys/ioport.h>
uint8_t ioport_in8(uint16_t port) {
uint8_t r;
__asm__ volatile("inb %1, %0" : "=a"(r) : "dN"(port));
return r;
}
void ioport_out8(uint16_t port, uint8_t value) {
__asm__ volatile("outb %1, %0" :: "dN"(port), "a"(value));
}
uint16_t ioport_in16(uint16_t port) {
uint16_t r;
__asm__ volatile("in %%dx, %%ax" : "=a"(r) : "d"(port));
return r;
}
void ioport_out16(uint16_t port, uint16_t value) {
__asm__ volatile("out %%ax, %%dx" :: "a"(value), "d"(port));
}
uint32_t ioport_in32(uint16_t port) {
uint32_t r;
__asm__ volatile("inl %%dx, %%eax" : "=a"(r) : "d"(port));
return r;
}
void ioport_out32(uint16_t port, uint32_t value) {
__asm__ volatile("outl %%eax, %%dx" :: "d"(port), "a"(value));
}
void ioport_ins16(uint16_t port, void *addr, int cnt) {
__asm__ volatile(
"cld; rep insw"
: "+D"(addr), "+c"(cnt)
: "d"(port)
: "memory", "cc"
);
}
void ioport_outs16(uint16_t port, const void *addr, int cnt) {
__asm__ volatile(
"cld; rep outsw"
: "+S"(addr), "+c"(cnt)
: "d"(port)
: "memory", "cc"
);
}
void ioport_wait(void) {
ioport_out8(0x80, 0);
}

View File

@ -0,0 +1,48 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _SYS_IOPORT_H
#define _SYS_IOPORT_H
#include <libk/types.h>
uint8_t ioport_in8(uint16_t port);
void ioport_out8(uint16_t port, uint8_t value);
uint16_t ioport_in16(uint16_t port);
void ioport_out16(uint16_t port, uint16_t value);
uint32_t ioport_in32(uint16_t port);
void ioport_out32(uint16_t port, uint32_t value);
void ioport_ins16(uint16_t port, void *addr, int cnt);
void ioport_outs16(uint16_t port, const void *addr, int cnt);
void ioport_wait(void);
#endif // _SYS_IOPORT_H

View File

@ -0,0 +1,182 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
.extern except_fini
.extern irq_fini
.section .text
#define EXCEPT_NOERR(exc) \
.global except ## exc; \
.type except ## exc, @function; \
except ## exc:; \
cli; \
push $0; \
push $exc; \
jmp temp_except_hndlr;
#define EXCEPT_ERR(exc) \
.global except ## exc; \
.type except ## exc, @function; \
except ## exc:; \
cli; \
push $exc; \
jmp temp_except_hndlr;
EXCEPT_NOERR(0)
EXCEPT_NOERR(1)
EXCEPT_NOERR(2)
EXCEPT_NOERR(3)
EXCEPT_NOERR(4)
EXCEPT_NOERR(5)
EXCEPT_NOERR(6)
EXCEPT_NOERR(7)
EXCEPT_ERR(8)
EXCEPT_NOERR(9)
EXCEPT_ERR(10)
EXCEPT_ERR(11)
EXCEPT_ERR(12)
EXCEPT_ERR(13)
EXCEPT_ERR(14)
EXCEPT_NOERR(15)
EXCEPT_NOERR(16)
EXCEPT_NOERR(17)
EXCEPT_NOERR(18)
EXCEPT_NOERR(19)
EXCEPT_NOERR(20)
EXCEPT_NOERR(21)
EXCEPT_NOERR(22)
EXCEPT_NOERR(23)
EXCEPT_NOERR(24)
EXCEPT_NOERR(25)
EXCEPT_NOERR(26)
EXCEPT_NOERR(27)
EXCEPT_NOERR(28)
EXCEPT_NOERR(29)
EXCEPT_NOERR(30)
EXCEPT_NOERR(31)
EXCEPT_NOERR(128)
temp_except_hndlr:
pushal /* push eax, ecx, edx, ebx, esp, ebp, esi, edi (8*4) */
xorl %eax, %eax
mov %ds, %ax
push %eax /* save ds (4) */
/* load kernel DS */
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %cr3, %ecx
push %ecx
/* save frame (4) */
push %esp
call except_fini
add $0x04, %esp
/* restore DS */
pop %ebx
mov %bx, %ds
mov %bx, %es
mov %bx, %fs
mov %bx, %gs
/* rebalance */
popal
add $0x8, %esp
sti
iret
#define IRQ(irq1) \
.global irq ## irq1; \
.type irq ## irq1, @function; \
irq ## irq1:; \
cli; \
push $0; \
push $irq1; \
jmp temp_irq_hndlr;
IRQ(0)
IRQ(1)
IRQ(2)
IRQ(3)
IRQ(4)
IRQ(5)
IRQ(6)
IRQ(7)
IRQ(8)
IRQ(9)
IRQ(10)
IRQ(11)
IRQ(12)
IRQ(13)
IRQ(14)
IRQ(15)
temp_irq_hndlr:
pushal /* push eax, ecx, edx, ebx, esp, ebp, esi, edi (8*4) */
xorl %eax, %eax
mov %ds, %ax
push %eax /* save ds (4) */
/* load kernel DS */
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %cr3, %ecx
push %ecx
/* save frame (4) */
push %esp
call irq_fini
add $0x04, %esp
/* restore DS */
pop %ebx
mov %bx, %ds
mov %bx, %es
mov %bx, %fs
mov %bx, %gs
/* rebalance */
popal
add $0x8, %esp
sti
iret

View File

@ -0,0 +1,86 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _SYS_ISR_H
#define _SYS_ISR_H
void except0(void);
void except1(void);
void except2(void);
void except3(void);
void except4(void);
void except5(void);
void except6(void);
void except7(void);
void except8(void);
void except9(void);
void except10(void);
void except11(void);
void except12(void);
void except13(void);
void except14(void);
void except15(void);
void except16(void);
void except17(void);
void except18(void);
void except19(void);
void except20(void);
void except21(void);
void except22(void);
void except23(void);
void except24(void);
void except25(void);
void except26(void);
void except27(void);
void except28(void);
void except29(void);
void except30(void);
void except31(void);
void except128(void);
void irq0(void);
void irq1(void);
void irq2(void);
void irq3(void);
void irq4(void);
void irq5(void);
void irq6(void);
void irq7(void);
void irq8(void);
void irq9(void);
void irq10(void);
void irq11(void);
void irq12(void);
void irq13(void);
void irq14(void);
void irq15(void);
#endif // _SYS_ISR_H

View File

@ -0,0 +1,54 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
#include <libk/types.h>
#include <sys/cpu.h>
#include <sys/serialdbg.h>
#include <sys/halt.h>
#include <config.h>
void except_fini(struct trapframe *tf) {
dbgf("EXCEPTION %u\n", tf->trapno);
/* dbgf("trapframe:\n"); */
/* dbgf("ds =%08x, edi=%08x, esi=%08x, ebp=%08x\n", */
/* tf->ds, tf->edi, tf->esi, tf->ebp); */
/* dbgf("esp=%08x, ebx=%08x, edx=%08x, ecx=%08x\n", */
/* tf->esp, tf->ebx, tf->edx, tf->ecx); */
/* dbgf("trp=%08x, erc=%08x, eip=%08x, cs =%08x\n", */
/* tf->trapno, tf->ec, tf->eip, tf->cs); */
/* dbgf("efl=%08x, usp=%08x, uss=%08x, cr3=%08x\n", */
/* tf->eflags, tf->uesp, tf->uss, tf->cr3); */
halt();
}
void irq_fini(struct trapframe *tf) {
dbgf("IRQ %u\n", tf->trapno);
}

View File

@ -0,0 +1,28 @@
dir_sys := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
c_files += $(dir_sys)/cpu.c \
$(dir_sys)/multiboot.c \
$(dir_sys)/serialdbg.c \
$(dir_sys)/ioport.c \
$(dir_sys)/isr1.c \
$(dir_sys)/pic.c \
$(dir_sys)/mm.c
S_files += $(dir_sys)/gdt_flush.S \
$(dir_sys)/tss_flush.S \
$(dir_sys)/idt_flush.S \
$(dir_sys)/isr.S \
$(dir_sys)/halt.S
o_files += $(dir_sys)/cpu.o \
$(dir_sys)/multiboot.o \
$(dir_sys)/gdt_flush.o \
$(dir_sys)/tss_flush.o \
$(dir_sys)/idt_flush.o \
$(dir_sys)/isr.o \
$(dir_sys)/serialdbg.o \
$(dir_sys)/ioport.o \
$(dir_sys)/isr1.o \
$(dir_sys)/halt.o \
$(dir_sys)/pic.o \
$(dir_sys)/mm.o

View File

@ -0,0 +1,158 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
#include <libk/util.h>
#include <libk/types.h>
#include <libk/string.h>
#include <sys/mm.h>
#include <sync/spinlock.h>
#include <mm/bba.h>
#include <mm/pmm.h>
#include <config.h>
#define PD_INDEX(va) (((va) >> 22) & 0x3FF)
#define PT_INDEX(va) (((va) >> 12) & 0x3FF)
extern char __init_pd;
static struct page_dir *init_pd;
struct page_dir *mm_get_kernel_pd(void) { return init_pd; }
static struct page_dir *mm_alloc_pd(void) {
struct page_dir *pd = (struct page_dir *)bba_alloc();
memset(pd, 0, sizeof(*pd));
sl_init(&pd->sl, "pd");
pd->pd = (volatile uint32_t *)bba_alloc();
return pd;
}
static struct page_dir *mm_alloc_existing_pd(uptr_t ptr) {
struct page_dir *pd = (struct page_dir *)bba_alloc();
memset(pd, 0, sizeof(*pd));
sl_init(&pd->sl, "pd");
pd->pd = (volatile uint32_t *)ptr;
return pd;
}
void mm_map_page(struct page_dir *pd, uptr_t vaddr, uptr_t paddr, uint32_t flags) {
if (!(flags & PF_PRESENT))
return;
if (flags & PF_LOCK)
sl_lock(&pd->sl);
uint32_t pd_idx = PD_INDEX(vaddr);
uint32_t pt_idx = PT_INDEX(vaddr);
volatile uint32_t *pt;
if (!(pd->pd[pd_idx] & PF_PRESENT)) {
pt = (volatile uint32_t *)bba_alloc();
if (pt == 0) {
if (flags & PF_LOCK)
sl_unlock(&pd->sl);
dbgf("mm_map_page(): run out of BBA memory to alloc a PD\n");
return;
}
for (usize_t i = 0; i < PAGE_SIZE/sizeof(uint32_t); i++)
pt[i] = 0;
uptr_t phys_pt = (uptr_t)pt - VIRT_BASE;
pd->pd[pd_idx] = phys_pt | PF_PRESENT | PF_WRITABLE;
} else {
uptr_t pt_phys = pd->pd[pd_idx] & ~(PAGE_SIZE - 1);
pt = (volatile uint32_t *)(pt_phys + VIRT_BASE);
}
pt[pt_idx] = (paddr & ~(PAGE_SIZE - 1)) | (flags & ~PF_LOCK);
if (flags & PF_LOCK)
sl_unlock(&pd->sl);
}
void mm_unmap_page(struct page_dir *pd, uptr_t vaddr, uint32_t flags) {
if (flags & PF_LOCK)
sl_lock(&pd->sl);
uint32_t pd_idx = PD_INDEX(vaddr);
uint32_t pt_idx = PT_INDEX(vaddr);
volatile uint32_t *pt;
if (!(pd->pd[pd_idx] & PF_PRESENT)) {
if (flags & PF_LOCK)
sl_unlock(&pd->sl);
return;
} else {
uptr_t pt_phys = pd->pd[pd_idx] & ~(PAGE_SIZE - 1);
pt = (volatile uint32_t *)(pt_phys + VIRT_BASE);
}
pt[pt_idx] &= ~PF_PRESENT;
__asm__ volatile ("invlpg (%0)" :: "r"(vaddr) : "memory");
if (flags & PF_LOCK)
sl_unlock(&pd->sl);
}
uptr_t mm_translate(struct page_dir *pd, uptr_t vaddr, uint32_t flags) {
if (flags & PF_LOCK)
sl_lock(&pd->sl);
uint32_t pd_idx = PD_INDEX(vaddr);
uint32_t pt_idx = PT_INDEX(vaddr);
volatile uint32_t *pt;
uptr_t paddr = 0;
if (!(pd->pd[pd_idx] & PF_PRESENT))
goto done;
uptr_t pt_phys = pd->pd[pd_idx] & ~(PAGE_SIZE - 1);
pt = (volatile uint32_t *)(pt_phys + VIRT_BASE);
if (!(pt[pt_idx] & PF_PRESENT))
goto done;
paddr = (pt[pt_idx] & ~(PAGE_SIZE - 1)) | (vaddr & (PAGE_SIZE - 1));
done:
if (flags & PF_LOCK)
sl_unlock(&pd->sl);
return paddr;
}
void mm_load_pd(struct page_dir *pd) {
uptr_t phys = (uptr_t)pd->pd - VIRT_BASE;
__asm__ volatile ("movl %0, %%cr3" :: "r"(phys));
}
void mm_init(void) {
init_pd = mm_alloc_existing_pd((uptr_t)&__init_pd);
}

View File

@ -0,0 +1,67 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _SYS_MM_H
#define _SYS_MM_H
#include <libk/util.h>
#include <libk/types.h>
#include <libk/compiler.h>
#include <sync/spinlock.h>
#define VIRT_BASE 0xC0000000
#define VIRT(x) (((uptr_t)(x)) + VIRT_BASE)
#define PAGE_SIZE 0x1000
#define PF_PRESENT (1<<0)
#define PF_WRITABLE (1<<1)
#define PF_USER (1<<2)
#define PF_LOCK (1<<31) /* Special flag for internal usage that doesn't exist in x86.
I use this here, because when (un)mapping an entire page range
it would be inefficient to constantly (un)lock. */
#define KERNEL_HEAP_START 0xF0000000
struct page_dir {
volatile uint32_t *pd;
struct spinlock sl;
};
void mm_init(void);
void mm_map_page(struct page_dir *pd, uptr_t vaddr, uptr_t paddr, uint32_t flags);
void mm_unmap_page(struct page_dir *pd, uptr_t vaddr, uint32_t flags);
uptr_t mm_translate(struct page_dir *pd, uptr_t vaddr, uint32_t flags);
void mm_load_pd(struct page_dir *pd);
struct page_dir *mm_get_kernel_pd(void);
#endif // _SYS_MM_H

View File

@ -0,0 +1,42 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
#include <sys/multiboot.h>
struct multiboot *mb;
void multiboot_set(struct multiboot *mb1) {
mb = mb1;
}
struct multiboot *multiboot_get(void) {
return mb;
}

View File

@ -0,0 +1,48 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _SYS_MULTIBOOT_H
#define _SYS_MULTIBOOT_H
#include <libk/types.h>
#include <libk/compiler.h>
struct multiboot {
uint32_t flags;
uint32_t mem_low;
uint32_t mem_up;
uint32_t boot_dev;
} packed;
void multiboot_set(struct multiboot *mb);
struct multiboot *multiboot_get(void);
#endif // _SYS_MULTIBOOT_H

View File

@ -0,0 +1,84 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
#include <sys/pic.h>
#include <sys/ioport.h>
#define PIC1 0x20
#define PIC2 0xA0
#define PIC1_CMD PIC1
#define PIC1_DATA (PIC1 + 1)
#define PIC2_CMD PIC2
#define PIC2_DATA (PIC2 + 1)
#define ICW1_ICW4 0x01
#define ICW1_SINGLE 0x02
#define ICW1_INTVL4 0x04
#define ICW1_LEVEL 0x08
#define ICW1_INIT 0x10
#define ICW4_8086 0x01
#define ICW4_AUTO 0x02
#define ICW4_BUFSLAVE 0x08
#define ICW4_BUFMASER 0x0C
#define ICW4_SFNM 0x10
#define CASCADE_IRQ 2
void pic_init(void) {
// remap & disable
ioport_out8(PIC1_CMD, ICW1_INIT | ICW1_ICW4);
ioport_wait();
ioport_out8(PIC2_CMD, ICW1_INIT | ICW1_ICW4);
ioport_wait();
ioport_out8(PIC1_DATA, 4);
ioport_wait();
ioport_out8(PIC2_DATA, 2);
ioport_wait();
ioport_out8(PIC1_DATA, 1<<CASCADE_IRQ);
ioport_wait();
ioport_out8(PIC2_DATA, 2);
ioport_wait();
ioport_out8(PIC1_DATA, ICW4_8086);
ioport_wait();
ioport_out8(PIC2_DATA, ICW4_8086);
ioport_wait();
ioport_out8(PIC1_DATA, 0xFF);
ioport_out8(PIC2_DATA, 0xFF);
}

View File

@ -0,0 +1,37 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _SYS_PIC_H
#define _SYS_PIC_H
void pic_init(void);
#endif // _SYS_PIC_H

View File

@ -0,0 +1,76 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
#include <libk/types.h>
#include <libk/string.h>
#include <libk/stdarg.h>
#include <libk/printf.h>
#include <sys/serialdbg.h>
#include <sys/ioport.h>
#include <config.h>
static uint8_t serialdbg_tx_empty(void) {
return ioport_in8(CFG_I386_PC_DEBUG_SERIAL_PORT + 5) & 0x20;
}
static void serialdbg_writechr(char x) {
while (!serialdbg_tx_empty());
ioport_out8(CFG_I386_PC_DEBUG_SERIAL_PORT, (uint8_t)x);
}
void serialdbg_printf(const char *fmt, ...) {
char buffer[CFG_I386_PC_DEBUG_SERIAL_BUFFER_SIZE];
memset(buffer, 0, sizeof(buffer));
va_list ap;
va_start(ap, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, ap);
va_end(ap);
buffer[sizeof(buffer) - 1] = '\0';
const char *p = buffer;
while (*p) {
serialdbg_writechr(*p);
p++;
}
}
void serialdbg_init(void) {
ioport_out8(CFG_I386_PC_DEBUG_SERIAL_PORT + 1, 0x00);
ioport_out8(CFG_I386_PC_DEBUG_SERIAL_PORT + 3, 0x80);
ioport_out8(CFG_I386_PC_DEBUG_SERIAL_PORT + 0, 0x03);
ioport_out8(CFG_I386_PC_DEBUG_SERIAL_PORT + 1, 0x00);
ioport_out8(CFG_I386_PC_DEBUG_SERIAL_PORT + 3, 0x03);
ioport_out8(CFG_I386_PC_DEBUG_SERIAL_PORT + 2, 0xC7);
ioport_out8(CFG_I386_PC_DEBUG_SERIAL_PORT + 4, 0x0B);
}

View File

@ -0,0 +1,40 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _SYS_SERIALDBG_H
#define _SYS_SERIALDBG_H
#include <libk/types.h>
void serialdbg_init(void);
void serialdbg_printf(const char *fmt, ...);
#endif // _SYS_SERIALDBG_H

View File

@ -0,0 +1,38 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
.section .text
.global tss_flush
.type tss_flush, @function
tss_flush:
mov $0x28, %ax
ltr %ax
ret

View File

@ -0,0 +1,37 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _SYS_TSS_FLUSH_H
#define _SYS_TSS_FLUSH_H
void tss_flush(void);
#endif // _SYS_TSS_FLUSH_H

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

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

5
kernel/sync/make.src Normal file
View File

@ -0,0 +1,5 @@
dir_sync1 := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
c_files += $(dir_sync1)/spinlock.c
o_files += $(dir_sync1)/spinlock.o

57
kernel/sync/spinlock.c Normal file
View File

@ -0,0 +1,57 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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.
*/
#include <libk/stdatomic.h>
#include <libk/string.h>
#include <sync/spinlock.h>
#include <sys/cpu.h>
void sl_init(struct spinlock *sl, const char *name) {
if (strlen(name) > SPINLOCK_NAME_MAX) {
return;
}
strncpy(sl->name, name, SPINLOCK_NAME_MAX);
sl->flag = ATOMIC_FLAG_INIT;
}
void sl_lock(struct spinlock *sl) {
intr_save();
while (atomic_flag_test_and_set_explicit(&sl->flag, memory_order_acquire)) {
cpu_relax();
}
}
void sl_unlock(struct spinlock *sl) {
atomic_flag_clear_explicit(&sl->flag, memory_order_release);
intr_restore();
}

48
kernel/sync/spinlock.h Normal file
View File

@ -0,0 +1,48 @@
/*
Copyright 2025 Kamil Kowalczyk
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 the copyright holder 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
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 _SYNC_SPINLOCK_H
#define _SYNC_SPINLOCK_H
#include <libk/stdatomic.h>
#define SPINLOCK_NAME_MAX 32
struct spinlock {
atomic_flag flag;
char name[SPINLOCK_NAME_MAX];
};
void sl_init(struct spinlock *sl, const char *name);
void sl_lock(struct spinlock *sl);
void sl_unlock(struct spinlock *sl);
#endif // _SYNC_SPINLOCK_H

View File

@ -0,0 +1,6 @@
set timeout=15
set default=0
menuentry "mop3" {
multiboot /boot/kernel.elf
}

23
platform/make.i386_pc Normal file
View File

@ -0,0 +1,23 @@
$(srctree)/out/i386_pc/mop3.iso: $(srctree)/out/kernel.elf
rm -rf $(srctree)/out/i386_pc/tmp
mkdir -p $(srctree)/out/i386_pc/tmp
mkdir -p $(srctree)/out/i386_pc/tmp/iso/boot/grub
cp $(srctree)/out/kernel.elf $(srctree)/out/i386_pc/tmp/iso/boot
cp $(srctree)/platform/i386_pc/grub.cfg $(srctree)/out/i386_pc/tmp/iso/boot/grub
grub-mkrescue -o $(srctree)/out/i386_pc/mop3.iso $(srctree)/out/i386_pc/tmp/iso
QEMU_EXTRA ?=
QEMU_OPTS := -M pc \
-cdrom $(srctree)/out/i386_pc/mop3.iso \
-serial mon:stdio \
$(QEMU_EXTRA)
ifeq ($(debug),1)
QEMU_OPTS += -gdb tcp::5557 -S
endif
i386_pc_qemu: $(srctree)/out/i386_pc/mop3.iso
qemu-system-i386 $(QEMU_OPTS)
.PHONY: i386_pc_qemu