Merge branch 'master' into multiboot2-bindings

This commit is contained in:
Alex Kotov 2022-12-22 22:47:21 +04:00
commit 114faecb18
Signed by: kotovalexarian
GPG Key ID: 553C0EBBEB5D5F08
56 changed files with 844 additions and 784 deletions

View File

@ -12,7 +12,7 @@ main_freebsd_task:
- pip install --user Jinja2 PyYAML
main_build_script:
- ./autogen.sh
- ./configure --enable-debug --enable-fixtures --enable-checks-all CFLAGS='-O3'
- ./configure --enable-fixtures --enable-checks-all CFLAGS='-O3'
- make
- sudo make install
main_test_script:
@ -32,7 +32,7 @@ mruby_freebsd_task:
- unzip mruby-3.1.0.zip
main_build_script:
- ./autogen.sh
- ./configure --enable-debug CFLAGS='-O3'
- ./configure CFLAGS='-O3'
- make
- sudo make install
mruby_test_script:
@ -56,7 +56,7 @@ ruby_freebsd_task:
- sudo make install
main_build_script:
- ./autogen.sh
- ./configure --enable-debug --enable-fixtures CFLAGS='-O3'
- ./configure --enable-fixtures CFLAGS='-O3'
- make
- sudo make install
ruby_build_script:
@ -78,7 +78,7 @@ rust_freebsd_task:
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
main_build_script:
- ./autogen.sh
- ./configure --enable-debug CFLAGS='-O3'
- ./configure CFLAGS='-O3'
- make
- sudo make install
rust_test_script:

View File

@ -24,7 +24,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
debug: ['--disable-debug', '--enable-debug']
assert: ['--disable-assert', '--enable-assert']
cc: ['gcc', 'clang', 'tcc']
opt: ['', '-O0', '-O3']
steps:
@ -34,7 +34,7 @@ jobs:
- name: autogen
run: ./autogen.sh
- name: configure
run: ./configure ${{matrix.debug}} --enable-fixtures --enable-checks --enable-checks-pthreads --enable-checks-python CC='${{matrix.cc}}' CFLAGS='${{matrix.opt}}'
run: ./configure ${{matrix.assert}} --enable-fixtures --enable-checks --enable-checks-pthreads --enable-checks-python CC='${{matrix.cc}}' CFLAGS='${{matrix.opt}}'
- name: make
run: make
- name: check
@ -94,12 +94,13 @@ jobs:
- without: 'ntoa'
dependencies: '--without-printf --without-units'
- without: 'printf'
- without: 'memmap'
steps:
- uses: actions/checkout@v2
- name: autogen
run: ./autogen.sh
- name: configure
run: ./configure --enable-debug --enable-checks --enable-checks-pthreads --enable-checks-python --without-${{matrix.packages.without}} ${{matrix.packages.dependencies}}
run: ./configure --enable-checks --enable-checks-pthreads --enable-checks-python --without-${{matrix.packages.without}} ${{matrix.packages.dependencies}}
- name: make
run: make
- name: check
@ -111,7 +112,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
debug: ['--disable-debug', '--enable-debug']
assert: ['--disable-assert', '--enable-assert']
steps:
- uses: actions/checkout@v2
- name: apt update
@ -121,7 +122,7 @@ jobs:
- name: autogen
run: ./autogen.sh
- name: configure
run: ./configure --host='i386-elf' ${{matrix.debug}} --enable-freestanding --with-libc CC="$(which i686-linux-gnu-gcc)"
run: ./configure --host='i386-elf' ${{matrix.assert}} --enable-freestanding --with-libc CC="$(which i686-linux-gnu-gcc)"
- name: make
run: make
@ -138,7 +139,7 @@ jobs:
- name: extract
run: tar -xzf "libkernaux-$(cat VERSION).tar.gz"
- name: configure
run: cd "libkernaux-$(cat VERSION)" && ./configure --enable-debug --enable-checks --enable-checks-pthreads --enable-checks-python
run: cd "libkernaux-$(cat VERSION)" && ./configure --enable-checks --enable-checks-pthreads --enable-checks-python
- name: make
run: cd "libkernaux-$(cat VERSION)" && make
- name: check

View File

@ -13,7 +13,7 @@ jobs:
MRUBY_YAML_USE_SYSTEM_LIBRARY: x
strategy:
matrix:
debug: ['--disable-debug', '--enable-debug']
assert: ['--disable-assert', '--enable-assert']
packages:
- configure: ''
- configure: '--without-all'
@ -30,7 +30,7 @@ jobs:
- name: autogen
run: ./autogen.sh
- name: configure
run: ./configure ${{matrix.debug}} ${{matrix.packages.configure}} CFLAGS='-O3'
run: ./configure ${{matrix.assert}} ${{matrix.packages.configure}} CFLAGS='-O3'
- name: make
run: make
- name: install

View File

@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
debug: ['--disable-debug', '--enable-debug']
assert: ['--disable-assert', '--enable-assert']
packages:
- configure: ''
- configure: '--without-all'
@ -28,7 +28,7 @@ jobs:
- name: autogen
run: ./autogen.sh
- name: configure
run: ./configure --enable-fixtures ${{matrix.debug}} ${{matrix.packages.configure}} CFLAGS='-O3'
run: ./configure --enable-fixtures ${{matrix.assert}} ${{matrix.packages.configure}} CFLAGS='-O3'
- name: make
run: make
- name: install

View File

@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
debug: ['--disable-debug', '--enable-debug']
assert: ['--disable-assert', '--enable-assert']
packages:
- configure: ''
- configure: '--without-all'
@ -27,7 +27,7 @@ jobs:
- name: autogen
run: ./autogen.sh
- name: configure
run: ./configure ${{matrix.debug}} ${{matrix.packages.configure}} CFLAGS='-O3'
run: ./configure ${{matrix.assert}} ${{matrix.packages.configure}} CFLAGS='-O3'
- name: make
run: make
- name: install

View File

@ -31,7 +31,7 @@ tasks:
- build: |
cd libkernaux
./autogen.sh
./configure --enable-debug --enable-fixtures --enable-checks-all CFLAGS='-O3'
./configure --enable-fixtures --enable-checks-all CFLAGS='-O3'
make
doas make install
- test: |

View File

@ -25,6 +25,13 @@ The following statements are recommendations, but highly encouraged:
* Write tests
* Keep lines less than 80 characters long for better experience on split screen
### Things to review periodically
* `git grep -i fixme`
* `git grep -i todo`
* `git grep -i cppcheck-suppress`
* `git grep -i rubocop:disable`
### Programming mistakes
* Always check documentation, manuals and specifications
@ -62,13 +69,6 @@ Avoid stupid errors with:
* Default case in switch statements
* Braces (curly brackets) around code blocks
### Things to review periodically
* `git grep -i fixme`
* `git grep -i todo`
* `git grep -i cppcheck-suppress`
* `git grep -i rubocop:disable`
C language
@ -101,6 +101,11 @@ Use **cppcheck**.
* Name public (*defined in the headers*) methods with the prefix `KernAux_` and
with the prefix of the type name (example: `KernAux_FooBar_car_cdr`).
* Use postfix `size` for a byte size.
* Use postfix `slen` for C string length without terminating `\0` character
(size - 1).
* Use postfix `count` for a number of elements in an array.
* Create `typedef`s with the names of related `struct`s. Use this name with a
prefix `struct` to declare the data itself, withoth the prefix to declare
a pointer or an array:

View File

@ -1,3 +1,15 @@
2022-12-22 Alex Kotov <kotovalexarian@gmail.com>
* include/kernaux/memmap.h: Complete rewrite
2022-12-21 Alex Kotov <kotovalexarian@gmail.com>
* configure.ac: Rename feature "--(enable|disable)-debug" to
"--(enable|disable)-assert"
* include/: Definition "KERNAUX_DEBUG" has been removed
* include/kernaux/runtime.h: New header
* include/kernaux/assert.h: Removed header
2022-12-19 Alex Kotov <kotovalexarian@gmail.com>
* src/multiboot2/*_print.c: Print Multiboot 2 ELF section headers

View File

@ -2,7 +2,7 @@ include $(top_srcdir)/make/shared.am
include $(top_srcdir)/make/checks.am
ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = autogen.sh CONTRIBUTING.md sha256sums.txt
EXTRA_DIST = autogen.sh CONTRIBUTING.md sha256sums.txt src/assert.h
SUBDIRS = include
@ -35,10 +35,10 @@ lib_LTLIBRARIES = libkernaux.la
libkernaux_la_LDFLAGS = -version-info @PACKAGE_VERSION_SO@
libkernaux_la_LIBADD =
libkernaux_la_SOURCES = \
src/assert.c \
src/generic/display.c \
src/generic/malloc.c \
src/generic/mutex.c
src/generic/mutex.c \
src/runtime.c
########
# libc #
@ -97,6 +97,7 @@ libkernaux_la_SOURCES += \
src/multiboot2/header_helpers.c \
src/multiboot2/header_is_valid.c \
src/multiboot2/header_print.c \
src/multiboot2/info_convert.c \
src/multiboot2/info_enums.c \
src/multiboot2/info_helpers.c \
src/multiboot2/info_is_valid.c \

View File

@ -40,15 +40,13 @@ zero). Work-in-progress APIs can change at any time.
* Basic features
* [Feature macros](/include/kernaux/version.h.in) (*work in progress*)
* [Runtime environment](/include/kernaux/runtime.h) (*non-breaking since* **?.?.?**)
* [Macros](/include/kernaux/macro.h) (*non-breaking since* **0.6.0**)
* [Example: packing](/examples/macro_packing.c)
* [Example: BITS](/examples/macro_bits.c)
* [Example: CAST\_\*](/examples/macro_cast.c);
* [Example: CONTAINER\_OF](/examples/macro_container_of.c)
* [Example: STATIC\_TEST\*](/examples/macro_static_test.c)
* [Assertions](/include/kernaux/assert.h) (*non-breaking since* **0.4.0**)
* [Example: Assert](/examples/assert.c)
* [Example: Panic](/examples/panic.c)
* Stack trace *(planned)*
* Generic types
* [Display](/include/kernaux/generic/display.h) (*non-breaking since* **?.?.?**)
@ -71,7 +69,7 @@ zero). Work-in-progress APIs can change at any time.
* Utilities
* [Measurement units utils](/include/kernaux/units.h) (*work in progress*)
* [Example: To human](/examples/units_human.c)
* [Memory map](/include/kernaux/memmap.h) (*non-breaking since* **0.4.0**)
* [Memory map](/include/kernaux/memmap.h) (*non-breaking since* **?.?.?**)
* [Example](/examples/memmap.c)
* [printf format parser](/include/kernaux/printf_fmt.h) (*non-breaking since* **0.6.0**)
* [Example](/examples/printf_fmt.c)
@ -100,7 +98,6 @@ zero). Work-in-progress APIs can change at any time.
`#define` the following C preprocessor macros before including `<kernaux.h>` and
`<kernaux/*.h>` files. They have effect on your code, not the library code.
* `KERNAUX_DEBUG` - enable assertions.
* `KERNAUX_ACCESS_PRIVATE` - disable access modifier "private". Don't do this!
* `KERNAUX_ACCESS_PROTECTED` - disable access modifier "protected". Only do this
in a file where you implement an inherited type.
@ -110,12 +107,12 @@ zero). Work-in-progress APIs can change at any time.
### Global variables
```c
// in <kernaux/assert.h>
// in <kernaux/runtime.h>
void (*kernaux_assert_cb)(const char *file, int line, const char *msg)
```
Assertion callback. It's better to always set it to some function which always
interrupts the execution, even when debugging is disabled. It may for example
interrupts the execution, even when assertions are disabled. It may for example
call `abort()` in hosted environment, raise an exception in Ruby, panic in Rust
or power off the machine in freestanding environment. It may also log the error
location and message.
@ -153,7 +150,7 @@ stable options.
#### Features
* `--(enable|disable)-debug` - debugging
* `--(enable|disable)-assert` - assertions
* `--(enable|disable)-float` - floating-point arithmetic
* `--(enable|disable)-werror` - fail on warning (`CFLAGS+='-Werror'`)

View File

@ -22,7 +22,7 @@ AC_CANONICAL_HOST
AC_CONFIG_MACRO_DIRS([m4])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/assert.c])
AC_CONFIG_SRCDIR([src/runtime.c])
AC_CONFIG_FILES([
Makefile
examples/Makefile
@ -48,7 +48,7 @@ AC_SUBST([PACKAGE_VERSION_SO], m4_normalize(m4_include([VERSION_SO])))
###############
dnl Features (enabled by default)
AC_ARG_ENABLE([debug], AS_HELP_STRING([--disable-debug], [disable debugging]))
AC_ARG_ENABLE([assert], AS_HELP_STRING([--disable-assert], [disable assertions]))
AC_ARG_ENABLE([float], AS_HELP_STRING([--disable-float], [disable floating-point arithmetic]))
AC_ARG_ENABLE([werror], AS_HELP_STRING([--disable-werror], [disable -Werror]))
@ -134,7 +134,7 @@ AS_IF([test "$with_all" = no], do_without_all)
##################
dnl Features (enabled by default)
AS_IF([test "$enable_debug" = no ], [enable_debug=no], [enable_debug=yes])
AS_IF([test "$enable_assert" = no ], [enable_assert=no], [enable_assert=yes])
AS_IF([test "$enable_float" = no ], [enable_float=no], [enable_float=yes])
AS_IF([test "$enable_werror" = no ], [enable_werror=no], [enable_werror=yes])
@ -200,7 +200,7 @@ dnl Architecture (additional)
AM_CONDITIONAL([ASM_X86], [test "$host_cpu" = i386 -o "$host_cpu" = x86_64])
dnl Features (enabled by default)
AM_CONDITIONAL([ENABLE_DEBUG], [test "$enable_debug" = yes])
AM_CONDITIONAL([ENABLE_ASSERT], [test "$enable_assert" = yes])
AM_CONDITIONAL([ENABLE_FLOAT], [test "$enable_float" = yes])
AM_CONDITIONAL([ENABLE_WERROR], [test "$enable_werror" = yes])
@ -252,7 +252,7 @@ AS_IF([test "$host_cpu" = i386], [AC_DEFINE([ASM_X86],
AS_IF([test "$host_cpu" = x86_64], [AC_DEFINE([ASM_X86], [1], [architecture is x86])])
dnl Features (enabled by default)
AS_IF([test "$enable_debug" = yes], [AC_DEFINE([ENABLE_DEBUG], [1], [enabled debugging])])
AS_IF([test "$enable_assert" = yes], [AC_DEFINE([ENABLE_ASSERT], [1], [enabled assertions])])
AS_IF([test "$enable_float" = yes], [AC_DEFINE([ENABLE_FLOAT], [1], [enabled floating-point arithmetic])])
AS_IF([test "$enable_werror" = yes], [AC_DEFINE([ENABLE_WERROR], [1], [enabled -Werror])])
@ -289,9 +289,6 @@ dnl Packages (virtual)
AS_IF([test "$with_arch_i386" = yes], [AC_DEFINE([WITH_ARCH_X86], [1], [with architecture x86])])
AS_IF([test "$with_arch_x86_64" = yes], [AC_DEFINE([WITH_ARCH_X86], [1], [with architecture x86])])
dnl Additional
AS_IF([test "$enable_debug" = yes], [AC_DEFINE([KERNAUX_DEBUG], [1], [enabled debugging])])
##########################

2
examples/.gitignore vendored
View File

@ -1,4 +1,3 @@
/assert
/cmdline
/generic_display
/generic_malloc
@ -11,7 +10,6 @@
/memmap
/multiboot2_header_macro
/ntoa
/panic
/pfa
/printf_file
/printf_file_va

View File

@ -3,14 +3,6 @@ include $(top_srcdir)/make/shared.am
TESTS =
noinst_PROGRAMS = $(TESTS)
##########
# assert #
##########
TESTS += assert
assert_LDADD = $(top_builddir)/libkernaux.la
assert_SOURCES = assert.c
###########
# cmdline #
###########
@ -117,14 +109,6 @@ ntoa_LDADD = $(top_builddir)/libkernaux.la
ntoa_SOURCES = main.c ntoa.c
endif
#########
# panic #
#########
TESTS += panic
panic_LDADD = $(top_builddir)/libkernaux.la
panic_SOURCES = panic.c
#######
# pfa #
#######

View File

@ -1,53 +0,0 @@
#define KERNAUX_DEBUG
#include <kernaux/assert.h>
#include <assert.h>
#include <stddef.h>
#include <string.h>
static unsigned int count = 0;
static const char *last_file = NULL;
static int last_line = 0;
static const char *last_str = NULL;
static void assert_cb(
const char *const file,
const int line,
const char *const str
) {
++count;
last_file = file;
last_line = line;
last_str = str;
}
int main()
{
kernaux_assert_cb = assert_cb;
// cppcheck-suppress duplicateExpression
KERNAUX_ASSERT(1 == 1);
assert(count == 0);
assert(last_file == NULL);
assert(last_line == 0);
assert(last_str == NULL);
// cppcheck-suppress duplicateExpression
KERNAUX_ASSERT(1 != 1);
assert(count == 1);
assert(strcmp(last_file, __FILE__) == 0);
assert(last_line == __LINE__ - 4);
assert(strcmp(last_str, "1 != 1") == 0);
// cppcheck-suppress staticStringCompare
KERNAUX_ASSERT(strcmp("qwe", "rty") == 0);
assert(count == 2);
assert(strcmp(last_file, __FILE__) == 0);
assert(last_line == __LINE__ - 4);
assert(strcmp(last_str, "strcmp(\"qwe\", \"rty\") == 0") == 0);
return 0;
}

View File

@ -2,7 +2,7 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include <kernaux/runtime.h>
#include <stdio.h>
#include <stdlib.h>

View File

@ -1,45 +1,60 @@
#define KERNAUX_ACCESS_PROTECTED
#include <kernaux/free_list.h>
#include <kernaux/generic/display.h>
#include <kernaux/macro.h>
#include <kernaux/memmap.h>
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#define SIZE_256MiB ( 256 * 1024 * 1024)
#define SIZE_512MiB ( 512 * 1024 * 1024)
#define SIZE_1GiB (1024 * 1024 * 1024)
static char malloc_memory[8192];
static void my_putc(void *const display KERNAUX_UNUSED, const char c)
{
putchar(c);
}
static void my_vprintf(
void *const display KERNAUX_UNUSED,
const char *const format,
va_list va
) {
vprintf(format, va);
}
static const struct KernAux_Display display = {
.putc = my_putc,
.vprintf = my_vprintf,
};
void example_main()
{
KernAux_MemMap memmap = { KernAux_MemMap_create(SIZE_1GiB) };
struct KernAux_FreeList malloc = KernAux_FreeList_create(NULL);
KernAux_FreeList_add_zone(&malloc, malloc_memory, sizeof(malloc_memory));
assert(KernAux_MemMap_add_entry(memmap, true, NULL, 0, SIZE_256MiB));
assert(KernAux_MemMap_add_entry(memmap, false, "foo", SIZE_256MiB, SIZE_256MiB));
assert(KernAux_MemMap_add_entry(memmap, true, "bar", SIZE_512MiB, SIZE_512MiB));
KernAux_Memmap_Builder memmap_builder =
KernAux_Memmap_Builder_new(&malloc.malloc);
assert(memmap_builder);
assert(KernAux_MemMap_finish(memmap));
assert(KernAux_Memmap_Builder_add(memmap_builder, NULL, 0x0, 654336, "available"));
assert(KernAux_Memmap_Builder_add(memmap_builder, NULL, 0x9fc00, 1024, "reserved"));
assert(KernAux_Memmap_Builder_add(memmap_builder, NULL, 0xf0000, 65536, "reserved"));
KernAux_Memmap_Node kernel_node =
KernAux_Memmap_Builder_add (memmap_builder, NULL, 0x100000, 133038080, "available");
assert(kernel_node);
assert(KernAux_Memmap_Builder_add(memmap_builder, NULL, 0x7fe0000, 131072, "reserved"));
assert(KernAux_Memmap_Builder_add(memmap_builder, NULL, 0xfffc0000, 262144, "reserved"));
// You can get the entry by it's index:
assert( KernAux_MemMap_entry_by_index(memmap, 0)->is_available == true);
assert(strcmp(KernAux_MemMap_entry_by_index(memmap, 0)->tag, "") == 0);
assert( KernAux_MemMap_entry_by_index(memmap, 0)->start == 0);
assert( KernAux_MemMap_entry_by_index(memmap, 0)->size == SIZE_256MiB);
assert( KernAux_MemMap_entry_by_index(memmap, 0)->end == SIZE_256MiB - 1);
assert( KernAux_MemMap_entry_by_index(memmap, 0)->limit == SIZE_256MiB);
assert(KernAux_Memmap_Builder_add(memmap_builder, kernel_node, 0x400000, 8192, "kernel code"));
assert(KernAux_Memmap_Builder_add(memmap_builder, kernel_node, 0x402000, 4096, "kernel data"));
// You can get the entry by it's start address:
assert( KernAux_MemMap_entry_by_start(memmap, SIZE_256MiB)->is_available == false);
assert(strcmp(KernAux_MemMap_entry_by_start(memmap, SIZE_256MiB)->tag, "foo") == 0);
assert( KernAux_MemMap_entry_by_start(memmap, SIZE_256MiB)->start == SIZE_256MiB);
assert( KernAux_MemMap_entry_by_start(memmap, SIZE_256MiB)->size == SIZE_256MiB);
assert( KernAux_MemMap_entry_by_start(memmap, SIZE_256MiB)->end == SIZE_512MiB - 1);
assert( KernAux_MemMap_entry_by_start(memmap, SIZE_256MiB)->limit == SIZE_512MiB);
KernAux_Memmap memmap =
KernAux_Memmap_Builder_finish_and_free(memmap_builder);
assert(memmap);
// You can get the entry by any address inside it:
assert( KernAux_MemMap_entry_by_addr(memmap, SIZE_512MiB )->is_available == true);
assert(strcmp(KernAux_MemMap_entry_by_addr(memmap, SIZE_512MiB + 1 )->tag, "bar") == 0);
assert( KernAux_MemMap_entry_by_addr(memmap, SIZE_512MiB + SIZE_256MiB)->start == SIZE_512MiB);
assert( KernAux_MemMap_entry_by_addr(memmap, SIZE_1GiB - 3 )->size == SIZE_512MiB);
assert( KernAux_MemMap_entry_by_addr(memmap, SIZE_1GiB - 2 )->end == SIZE_1GiB - 1);
assert( KernAux_MemMap_entry_by_addr(memmap, SIZE_1GiB - 1 )->limit == SIZE_1GiB);
KernAux_Memmap_print(memmap, &display);
KERNAUX_MEMMAP_FREE(memmap);
}

View File

@ -1,48 +0,0 @@
#define KERNAUX_DEBUG
#include <kernaux/assert.h>
#include <assert.h>
#include <stddef.h>
#include <string.h>
static unsigned int count = 0;
static const char *last_file = NULL;
static int last_line = 0;
static const char *last_str = NULL;
static void assert_cb(
const char *const file,
const int line,
const char *const str
) {
++count;
last_file = file;
last_line = line;
last_str = str;
}
int main()
{
KERNAUX_PANIC("foo");
assert(count == 0);
assert(last_file == NULL);
assert(last_line == 0);
assert(last_str == NULL);
kernaux_assert_cb = assert_cb;
KERNAUX_PANIC("bar");
assert(count == 1);
assert(strcmp(last_file, __FILE__) == 0);
assert(last_line == __LINE__ - 4);
assert(strcmp(last_str, "bar") == 0);
KERNAUX_PANIC("car");
assert(count == 2);
assert(strcmp(last_file, __FILE__) == 0);
assert(last_line == __LINE__ - 4);
assert(strcmp(last_str, "car") == 0);
}

View File

@ -2,7 +2,7 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include <kernaux/runtime.h>
#include <assert.h>
#include <stdio.h>

View File

@ -53,37 +53,37 @@ Multiboot 2 info tag {
[0]: {
u64 base_addr: 0x0
u64 length: 654336
u32 type: 1
u32 type: 1 (available)
u32 reserved: 0x0
}
[1]: {
u64 base_addr: 0x9fc00
u64 length: 1024
u32 type: 2
u32 type: 2 (reserved)
u32 reserved: 0x0
}
[2]: {
u64 base_addr: 0xf0000
u64 length: 65536
u32 type: 2
u32 type: 2 (reserved)
u32 reserved: 0x0
}
[3]: {
u64 base_addr: 0x100000
u64 length: 133038080
u32 type: 1
u32 type: 1 (available)
u32 reserved: 0x0
}
[4]: {
u64 base_addr: 0x7fe0000
u64 length: 131072
u32 type: 2
u32 type: 2 (reserved)
u32 reserved: 0x0
}
[5]: {
u64 base_addr: 0xfffc0000
u64 length: 262144
u32 type: 2
u32 type: 2 (reserved)
u32 reserved: 0x0
}
]

View File

@ -48,37 +48,37 @@ Multiboot 2 info tag {
[0]: {
u64 base_addr: 0x0
u64 length: 654336
u32 type: 1
u32 type: 1 (available)
u32 reserved: 0x0
}
[1]: {
u64 base_addr: 0x9fc00
u64 length: 1024
u32 type: 2
u32 type: 2 (reserved)
u32 reserved: 0x0
}
[2]: {
u64 base_addr: 0xf0000
u64 length: 65536
u32 type: 2
u32 type: 2 (reserved)
u32 reserved: 0x0
}
[3]: {
u64 base_addr: 0x100000
u64 length: 133038080
u32 type: 1
u32 type: 1 (available)
u32 reserved: 0x0
}
[4]: {
u64 base_addr: 0x7fe0000
u64 length: 131072
u32 type: 2
u32 type: 2 (reserved)
u32 reserved: 0x0
}
[5]: {
u64 base_addr: 0xfffc0000
u64 length: 262144
u32 type: 2
u32 type: 2 (reserved)
u32 reserved: 0x0
}
]

View File

@ -9,7 +9,6 @@ nobase_include_HEADERS = \
kernaux/asm/riscv64.h \
kernaux/asm/x86_64.h \
kernaux/asm/x86.h \
kernaux/assert.h \
kernaux/cmdline.h \
kernaux/elf.h \
kernaux/free_list.h \
@ -35,5 +34,6 @@ nobase_include_HEADERS = \
kernaux/pfa.h \
kernaux/printf.h \
kernaux/printf_fmt.h \
kernaux/runtime.h \
kernaux/units.h \
kernaux/version.h

View File

@ -6,7 +6,6 @@
#include <kernaux/arch/i386.h>
#include <kernaux/arch/riscv64.h>
#include <kernaux/arch/x86_64.h>
#include <kernaux/assert.h>
#include <kernaux/cmdline.h>
#include <kernaux/elf.h>
#include <kernaux/free_list.h>
@ -21,5 +20,6 @@
#include <kernaux/pfa.h>
#include <kernaux/printf.h>
#include <kernaux/printf_fmt.h>
#include <kernaux/runtime.h>
#include <kernaux/units.h>
#include <kernaux/version.h>

View File

@ -5,55 +5,60 @@
extern "C" {
#endif
#include <kernaux/generic/display.h>
#include <kernaux/generic/malloc.h>
#include <kernaux/macro.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#define KERNAUX_MEMMAP_ENTRIES_MAX 100
#define KERNAUX_MEMMAP_FREE(memmap) do { \
KernAux_Memmap_free(memmap); \
memmap = NULL; \
} while (0)
#define KERNAUX_MEMMAP_ENTRY_TAG_SLEN_MAX 24
#define KERNAUX_MEMMAP_ENTRY_TAG_SIZE_MAX (KERNAUX_MEMMAP_ENTRY_TAG_SLEN_MAX + 1)
/*********
* Types *
*********/
typedef const struct KernAux_MemMap_Entry {
bool is_available;
char tag[KERNAUX_MEMMAP_ENTRY_TAG_SIZE_MAX];
size_t start, size, end, limit;
} *KernAux_MemMap_Entry;
typedef const struct KernAux_Memmap_Node {
uint64_t mem_start, mem_end, mem_size;
const char *tag;
const struct KernAux_Memmap_Node *next, *children;
} *KernAux_Memmap_Node;
typedef struct KernAux_MemMap {
bool KERNAUX_PRIVATE_FIELD(is_finished);
size_t KERNAUX_PRIVATE_FIELD(memory_size);
size_t KERNAUX_PRIVATE_FIELD(entries_count);
struct KernAux_MemMap_Entry KERNAUX_PRIVATE_FIELD(entries)[KERNAUX_MEMMAP_ENTRIES_MAX];
} KernAux_MemMap[1];
typedef const struct KernAux_Memmap {
KernAux_Memmap_Node root_node;
struct KernAux_MemMap KernAux_MemMap_create(size_t memory_size);
void KernAux_MemMap_init(KernAux_MemMap memmap, size_t memory_size);
KernAux_Malloc KERNAUX_PRIVATE_FIELD(malloc);
} *KernAux_Memmap;
/// @warning Must only be called with NOT finished memmap, otherwise panics.
bool KernAux_MemMap_add_entry(
KernAux_MemMap memmap,
bool is_available,
const char *tag,
size_t start,
size_t size
typedef struct KernAux_Memmap_Builder {
KernAux_Memmap KERNAUX_PRIVATE_FIELD(memmap);
} *KernAux_Memmap_Builder;
/*************
* Functions *
*************/
KernAux_Memmap_Builder
KernAux_Memmap_Builder_new(KernAux_Malloc malloc);
KernAux_Memmap_Node
KernAux_Memmap_Builder_add(
KernAux_Memmap_Builder builder,
KernAux_Memmap_Node parent_node,
uint64_t mem_start,
uint64_t mem_size,
const char *tag
);
/// @warning Must only be called with NOT finished memmap, otherwise panics.
bool KernAux_MemMap_finish(KernAux_MemMap memmap);
KernAux_Memmap
KernAux_Memmap_Builder_finish_and_free(KernAux_Memmap_Builder builder);
/// @warning Must only be called with finished memmap, otherwise panics.
KernAux_MemMap_Entry
KernAux_MemMap_entry_by_index(KernAux_MemMap memmap, size_t index);
/// @warning Must only be called with finished memmap, otherwise panics.
KernAux_MemMap_Entry
KernAux_MemMap_entry_by_start(KernAux_MemMap memmap, size_t start);
/// @warning Must only be called with finished memmap, otherwise panics.
KernAux_MemMap_Entry
KernAux_MemMap_entry_by_addr(KernAux_MemMap memmap, size_t addr);
void KernAux_Memmap_free(KernAux_Memmap memmap);
void KernAux_Memmap_print(KernAux_Memmap memmap, KernAux_Display display);
#ifdef __cplusplus
}

View File

@ -5,8 +5,10 @@
extern "C" {
#endif
#include <kernaux/macro.h>
#include <kernaux/generic/display.h>
#include <kernaux/generic/malloc.h>
#include <kernaux/macro.h>
#include <kernaux/memmap.h>
#include <kernaux/multiboot2/header_macro.h>
#include <stdint.h>
@ -559,6 +561,15 @@ KERNAUX_STATIC_TEST_STRUCT_SIZE(
#include <kernaux/multiboot2/header_print.h>
#include <kernaux/multiboot2/info_print.h>
/*******************
* Other functions *
*******************/
KernAux_Memmap_Builder KernAux_Multiboot2_Info_to_memmap_builder(
const struct KernAux_Multiboot2_Info *multiboot2_info,
KernAux_Malloc malloc
);
#ifdef __cplusplus
}
#endif

View File

@ -32,7 +32,15 @@ extern "C" {
#define KERNAUX_MULTIBOOT2_ITAG_EFI_64BIT_IMAGE_HANDLE_PTR 20
#define KERNAUX_MULTIBOOT2_ITAG_IMAGE_LOAD_BASE_PHYS_ADDR 21
#define KERNAUX_MULTIBOOT2_MEMMAP_AVAILABLE 1
#define KERNAUX_MULTIBOOT2_MEMMAP_RESERVED 2
#define KERNAUX_MULTIBOOT2_MEMMAP_ACPI_RECLAIMABLE 3
#define KERNAUX_MULTIBOOT2_MEMMAP_NVS 4
#define KERNAUX_MULTIBOOT2_MEMMAP_BADRAM 5
const char *KernAux_Multiboot2_ITag_to_str(uint32_t tag_type);
const char*
KernAux_Multiboot2_ITag_MemoryMap_EntryBase_Type_to_str(uint32_t type);
#ifdef __cplusplus
}

18
include/kernaux/runtime.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef KERNAUX_INCLUDED_RUNTIME
#define KERNAUX_INCLUDED_RUNTIME
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*KernAux_Assert_Cb)(const char *file, int line, const char *msg);
extern KernAux_Assert_Cb kernaux_assert_cb;
void kernaux_assert_do(const char *file, int line, const char *msg);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -2,8 +2,9 @@
#include "config.h"
#endif
#include "../../assert.h"
#include <kernaux/arch/i386.h>
#include <kernaux/assert.h>
#include <string.h>
@ -15,7 +16,7 @@ void KernAux_Arch_I386_IDTE_init_intr(
const uint16_t cs_selector,
const uint8_t dpl
) {
KERNAUX_ASSERT(idte);
KERNAUX_NOTNULL(idte);
memset(idte, 0, sizeof(*idte));
KernAux_Arch_I386_IDTE_set_offset(idte, offset);
@ -28,7 +29,7 @@ void KernAux_Arch_I386_IDTE_init_task(
const uint16_t tss_selector,
const uint8_t dpl
) {
KERNAUX_ASSERT(idte);
KERNAUX_NOTNULL(idte);
memset(idte, 0, sizeof(*idte));
idte->selector = tss_selector;
@ -41,7 +42,7 @@ void KernAux_Arch_I386_IDTE_init_trap(
const uint16_t cs_selector,
const uint8_t dpl
) {
KERNAUX_ASSERT(idte);
KERNAUX_NOTNULL(idte);
memset(idte, 0, sizeof(*idte));
KernAux_Arch_I386_IDTE_set_offset(idte, offset);
@ -51,14 +52,14 @@ void KernAux_Arch_I386_IDTE_init_trap(
uint32_t KernAux_Arch_I386_IDTE_offset(const KernAux_Arch_I386_IDTE idte)
{
KERNAUX_ASSERT(idte);
KERNAUX_NOTNULL(idte);
return (idte->offset_high << 16) | idte->offset_low;
}
uint8_t KernAux_Arch_I386_IDTE_dpl(const KernAux_Arch_I386_IDTE idte)
{
KERNAUX_ASSERT(idte);
KERNAUX_NOTNULL(idte);
return 3 & (idte->flags >> 5);
}
@ -67,7 +68,7 @@ void KernAux_Arch_I386_IDTE_set_offset(
const KernAux_Arch_I386_IDTE idte,
const uint32_t offset
) {
KERNAUX_ASSERT(idte);
KERNAUX_NOTNULL(idte);
idte->offset_low = 0xffffu & offset;
idte->offset_high = 0xffffu & (offset >> 16);

View File

@ -1,11 +1,9 @@
#ifndef KERNAUX_INCLUDED_ASSERT
#define KERNAUX_INCLUDED_ASSERT
#ifdef __cplusplus
extern "C" {
#endif
#include <kernaux/runtime.h>
#ifdef KERNAUX_DEBUG
#ifdef ENABLE_ASSERT
#define KERNAUX_PANIC(msg) (kernaux_assert_do(__FILE__, __LINE__, msg))
#define KERNAUX_ASSERT(cond) ((cond) ? (void)0 : KERNAUX_PANIC(#cond))
#else
@ -13,12 +11,6 @@ extern "C" {
#define KERNAUX_ASSERT(cond) ((void)0)
#endif
void kernaux_assert_do(const char *file, int line, const char *msg);
extern void (*kernaux_assert_cb)(const char *file, int line, const char *msg);
#ifdef __cplusplus
}
#endif
#define KERNAUX_NOTNULL(cond) KERNAUX_ASSERT(cond)
#endif

View File

@ -2,7 +2,8 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "assert.h"
#include <kernaux/cmdline.h>
#include <kernaux/macro.h>
@ -58,10 +59,10 @@ bool kernaux_cmdline(
const size_t arg_count_max,
const size_t buffer_size
) {
KERNAUX_ASSERT(cmdline);
KERNAUX_ASSERT(error_msg);
KERNAUX_NOTNULL(cmdline);
KERNAUX_NOTNULL(error_msg);
KERNAUX_ASSERT(argc);
KERNAUX_ASSERT(argv);
KERNAUX_NOTNULL(argv);
KERNAUX_ASSERT(arg_count_max > 0);
KERNAUX_ASSERT(buffer_size > 0);
@ -100,8 +101,8 @@ bool kernaux_cmdline_common(
const size_t arg_count_max,
const size_t buffer_size
) {
KERNAUX_ASSERT(cmdline);
KERNAUX_ASSERT(error_msg);
KERNAUX_NOTNULL(cmdline);
KERNAUX_NOTNULL(error_msg);
KERNAUX_ASSERT(argc);
(void)arg_idxs;

View File

@ -9,7 +9,8 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "assert.h"
#include <kernaux/free_list.h>
#include <kernaux/generic/malloc.h>
#include <kernaux/generic/mutex.h>
@ -69,7 +70,7 @@ void KernAux_FreeList_init(
const KernAux_FreeList free_list,
const KernAux_Mutex mutex
) {
KERNAUX_ASSERT(free_list);
KERNAUX_NOTNULL(free_list);
free_list->malloc.calloc = NULL;
free_list->malloc.free = KernAux_FreeList_free;
@ -84,8 +85,8 @@ void KernAux_FreeList_add_zone(
void *const ptr,
const size_t size
) {
KERNAUX_ASSERT(free_list);
KERNAUX_ASSERT(ptr);
KERNAUX_NOTNULL(free_list);
KERNAUX_NOTNULL(ptr);
KERNAUX_ASSERT(size >= MIN_ZONE_SIZE);
LOCK(free_list);
@ -126,8 +127,8 @@ block_found:
void KernAux_FreeList_free(void *const malloc, void *const ptr)
{
const KernAux_FreeList free_list = malloc;
KERNAUX_ASSERT(free_list);
KERNAUX_ASSERT(ptr);
KERNAUX_NOTNULL(free_list);
KERNAUX_NOTNULL(ptr);
LOCK(free_list);
@ -164,7 +165,7 @@ block_added:
void *KernAux_FreeList_malloc(void *const malloc, size_t size)
{
const KernAux_FreeList free_list = malloc;
KERNAUX_ASSERT(free_list);
KERNAUX_NOTNULL(free_list);
KERNAUX_ASSERT(size);
LOCK(free_list);
@ -220,8 +221,8 @@ void *KernAux_FreeList_realloc(
const size_t new_size
) {
const KernAux_FreeList free_list = malloc;
KERNAUX_ASSERT(free_list);
KERNAUX_ASSERT(old_ptr);
KERNAUX_NOTNULL(free_list);
KERNAUX_NOTNULL(old_ptr);
KERNAUX_ASSERT(new_size);
LOCK(free_list);
@ -243,7 +244,7 @@ void *KernAux_FreeList_realloc(
void KernAux_FreeList_defrag(const KernAux_FreeList free_list)
{
KERNAUX_ASSERT(free_list);
KERNAUX_NOTNULL(free_list);
for (
KernAux_FreeList_Node item_node = free_list->head;
@ -267,8 +268,8 @@ void KernAux_FreeList_insert(
const KernAux_FreeList_Node prev,
const KernAux_FreeList_Node next
) {
KERNAUX_ASSERT(free_list);
KERNAUX_ASSERT(node);
KERNAUX_NOTNULL(free_list);
KERNAUX_NOTNULL(node);
KERNAUX_ASSERT(node != prev);
KERNAUX_ASSERT(node != next);
KERNAUX_ASSERT(!prev || prev->next == next);
@ -285,8 +286,8 @@ void KernAux_FreeList_remove(
const KernAux_FreeList free_list,
const KernAux_FreeList_Node node
) {
KERNAUX_ASSERT(free_list);
KERNAUX_ASSERT(node);
KERNAUX_NOTNULL(free_list);
KERNAUX_NOTNULL(node);
KERNAUX_ASSERT(!node->next || node->next->prev == node);
KERNAUX_ASSERT(!node->prev || node->prev->next == node);

View File

@ -2,7 +2,8 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "../assert.h"
#include <kernaux/generic/display.h>
#include <stdarg.h>
@ -10,7 +11,7 @@
void KernAux_Display_putc(const KernAux_Display display, const char c)
{
KERNAUX_ASSERT(display);
KERNAUX_NOTNULL(display);
KERNAUX_ASSERT(display->putc);
// Inherited implementation
@ -19,7 +20,7 @@ void KernAux_Display_putc(const KernAux_Display display, const char c)
void KernAux_Display_print(const KernAux_Display display, const char *const s)
{
KERNAUX_ASSERT(display);
KERNAUX_NOTNULL(display);
KERNAUX_ASSERT(display->putc);
// Default implementation
@ -28,7 +29,7 @@ void KernAux_Display_print(const KernAux_Display display, const char *const s)
void KernAux_Display_println(const KernAux_Display display, const char *const s)
{
KERNAUX_ASSERT(display);
KERNAUX_NOTNULL(display);
KERNAUX_ASSERT(display->putc);
// Default implementation
@ -41,7 +42,7 @@ void KernAux_Display_write(
const char *const data,
const size_t size
) {
KERNAUX_ASSERT(display);
KERNAUX_NOTNULL(display);
KERNAUX_ASSERT(display->putc);
// Default implementation
@ -53,7 +54,7 @@ void KernAux_Display_writeln(
const char *const data,
const size_t size
) {
KERNAUX_ASSERT(display);
KERNAUX_NOTNULL(display);
KERNAUX_ASSERT(display->putc);
// Default implementation
@ -66,7 +67,7 @@ void KernAux_Display_printf(
const char *const format,
...
) {
KERNAUX_ASSERT(display);
KERNAUX_NOTNULL(display);
// Default implementation
va_list va;
@ -80,7 +81,7 @@ void KernAux_Display_printlnf(
const char *const format,
...
) {
KERNAUX_ASSERT(display);
KERNAUX_NOTNULL(display);
// Default implementation
va_list va;
@ -94,7 +95,7 @@ void KernAux_Display_vprintf(
const char *const format,
va_list va
) {
KERNAUX_ASSERT(display);
KERNAUX_NOTNULL(display);
KERNAUX_ASSERT(display->vprintf);
// Inherited implementation
@ -106,7 +107,7 @@ void KernAux_Display_vprintlnf(
const char *const format,
va_list va
) {
KERNAUX_ASSERT(display);
KERNAUX_NOTNULL(display);
KERNAUX_ASSERT(display->putc);
// Default implementation

View File

@ -2,7 +2,8 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "../assert.h"
#include <kernaux/generic/malloc.h>
#include <stddef.h>
@ -10,7 +11,7 @@
void *KernAux_Malloc_calloc(KernAux_Malloc malloc, size_t nmemb, size_t size)
{
KERNAUX_ASSERT(malloc);
KERNAUX_NOTNULL(malloc);
// Common implementation
const size_t total_size = nmemb * size;
@ -28,7 +29,7 @@ void *KernAux_Malloc_calloc(KernAux_Malloc malloc, size_t nmemb, size_t size)
void KernAux_Malloc_free(KernAux_Malloc malloc, void *ptr)
{
KERNAUX_ASSERT(malloc);
KERNAUX_NOTNULL(malloc);
KERNAUX_ASSERT(malloc->free);
// Common implementation
@ -40,7 +41,7 @@ void KernAux_Malloc_free(KernAux_Malloc malloc, void *ptr)
void *KernAux_Malloc_malloc(KernAux_Malloc malloc, size_t size)
{
KERNAUX_ASSERT(malloc);
KERNAUX_NOTNULL(malloc);
KERNAUX_ASSERT(malloc->malloc);
// Common implementation
@ -52,7 +53,7 @@ void *KernAux_Malloc_malloc(KernAux_Malloc malloc, size_t size)
void *KernAux_Malloc_realloc(KernAux_Malloc malloc, void *ptr, size_t size)
{
KERNAUX_ASSERT(malloc);
KERNAUX_NOTNULL(malloc);
KERNAUX_ASSERT(malloc->realloc);
// Common implementation

View File

@ -2,12 +2,13 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "../assert.h"
#include <kernaux/generic/mutex.h>
void KernAux_Mutex_lock(const KernAux_Mutex mutex)
{
KERNAUX_ASSERT(mutex);
KERNAUX_NOTNULL(mutex);
KERNAUX_ASSERT(mutex->lock);
mutex->lock((void*)mutex);
@ -15,7 +16,7 @@ void KernAux_Mutex_lock(const KernAux_Mutex mutex)
void KernAux_Mutex_unlock(const KernAux_Mutex mutex)
{
KERNAUX_ASSERT(mutex);
KERNAUX_NOTNULL(mutex);
KERNAUX_ASSERT(mutex->unlock);
mutex->unlock((void*)mutex);

View File

@ -2,7 +2,8 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "assert.h"
#include <kernaux/mbr.h>
#include <stdbool.h>
@ -10,14 +11,14 @@
bool KernAux_Mbr_is_valid(const struct KernAux_Mbr *const mbr)
{
KERNAUX_ASSERT(mbr);
KERNAUX_NOTNULL(mbr);
return KernAux_Mbr_Info_is_valid(&mbr->info);
}
bool KernAux_Mbr_Info_is_valid(const struct KernAux_Mbr_Info *const mbr_info)
{
KERNAUX_ASSERT(mbr_info);
KERNAUX_NOTNULL(mbr_info);
if (mbr_info->magic != KERNAUX_MBR_MAGIC) return false;
@ -32,7 +33,7 @@ bool KernAux_Mbr_Info_is_valid(const struct KernAux_Mbr_Info *const mbr_info)
bool KernAux_Mbr_Entry_is_valid(const struct KernAux_Mbr_Entry *const mbr_entry)
{
KERNAUX_ASSERT(mbr_entry);
KERNAUX_NOTNULL(mbr_entry);
// TODO: implement this
(void)mbr_entry;

View File

@ -2,7 +2,11 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "assert.h"
#include <kernaux/generic/display.h>
#include <kernaux/generic/malloc.h>
#include <kernaux/macro.h>
#include <kernaux/memmap.h>
#include <stdbool.h>
@ -10,144 +14,245 @@
#include <stdint.h>
#include <string.h>
#define MEMMAP (*memmap)
static void free_node(KernAux_Malloc malloc, struct KernAux_Memmap_Node *node);
static void print_nodes(
KernAux_Memmap_Node node,
KernAux_Display display,
unsigned indentation
);
struct KernAux_MemMap KernAux_MemMap_create(const size_t memory_size)
KernAux_Memmap_Builder
KernAux_Memmap_Builder_new(const KernAux_Malloc malloc)
{
struct KernAux_MemMap memmap;
KernAux_MemMap_init(&memmap, memory_size);
KERNAUX_NOTNULL(malloc);
struct KernAux_Memmap_Builder *const builder =
KernAux_Malloc_malloc(malloc, sizeof(*builder));
if (!builder) {
return NULL;
}
struct KernAux_Memmap *const memmap =
KernAux_Malloc_malloc(malloc, sizeof(*memmap));
if (!memmap) {
KernAux_Malloc_free(malloc, builder);
return NULL;
}
struct KernAux_Memmap_Node *const root_node =
KernAux_Malloc_malloc(malloc, sizeof(*root_node));
if (!root_node) {
KernAux_Malloc_free(malloc, memmap);
KernAux_Malloc_free(malloc, builder);
return NULL;
}
*root_node = (struct KernAux_Memmap_Node){
.mem_start = 0x0,
.mem_end = 0xffffffffffffffff, // 2**64 - 1
.mem_size = 0xffffffffffffffff, // 2**64 - 1
.tag = NULL,
.next = NULL,
.children = NULL,
};
*memmap = (struct KernAux_Memmap){
.malloc = malloc,
.root_node = root_node,
};
*builder = (struct KernAux_Memmap_Builder){
.memmap = memmap,
};
return builder;
}
KernAux_Memmap_Node KernAux_Memmap_Builder_add(
const KernAux_Memmap_Builder builder,
KernAux_Memmap_Node parent_node,
const uint64_t mem_start,
const uint64_t mem_size,
const char *tag
) {
KERNAUX_NOTNULL(builder);
KERNAUX_ASSERT(builder->memmap);
KERNAUX_ASSERT(builder->memmap->root_node);
KERNAUX_ASSERT(builder->memmap->malloc);
if (mem_size == 0) goto fail;
char *tag_copy = NULL;
if (tag) {
tag_copy =
KernAux_Malloc_malloc(builder->memmap->malloc, strlen(tag) + 1);
if (!tag_copy) goto fail;
strcpy(tag_copy, tag);
}
struct KernAux_Memmap_Node *const new_node =
KernAux_Malloc_malloc(builder->memmap->malloc, sizeof(*new_node));
if (!new_node) goto fail_after_tag;
new_node->mem_start = mem_start;
new_node->mem_size = mem_size;
new_node->mem_end = mem_start + mem_size - 1;
new_node->tag = tag_copy;
if (!parent_node) {
parent_node = (struct KernAux_Memmap_Node*)builder->memmap->root_node;
}
if (new_node->mem_start < parent_node->mem_start ||
new_node->mem_end > parent_node->mem_end)
{
goto fail_after_new_node;
}
if (parent_node->children) {
for (
struct KernAux_Memmap_Node *curr_node =
(struct KernAux_Memmap_Node*)parent_node->children;
curr_node;
curr_node = (struct KernAux_Memmap_Node*)curr_node->next
) {
if (!curr_node->next ||
curr_node->next->mem_start > new_node->mem_start)
{
if (new_node->next &&
new_node->mem_end >= new_node->next->mem_start)
{
goto fail_after_new_node;
}
new_node->next = curr_node->next;
curr_node->next = new_node;
break;
}
}
} else {
new_node->next = NULL;
((struct KernAux_Memmap_Node*)parent_node)->children = new_node;
}
return new_node;
fail_after_new_node:
KernAux_Malloc_free(builder->memmap->malloc, new_node);
fail_after_tag:
if (tag_copy) KernAux_Malloc_free(builder->memmap->malloc, tag_copy);
fail:
return NULL;
}
KernAux_Memmap
KernAux_Memmap_Builder_finish_and_free(const KernAux_Memmap_Builder builder)
{
KERNAUX_NOTNULL(builder);
KERNAUX_ASSERT(builder->memmap);
KERNAUX_ASSERT(builder->memmap->root_node);
KERNAUX_ASSERT(builder->memmap->malloc);
KernAux_Memmap memmap = builder->memmap;
builder->memmap = NULL;
KernAux_Malloc_free(memmap->malloc, builder);
return memmap;
}
void KernAux_MemMap_init(KernAux_MemMap memmap, const size_t memory_size)
void KernAux_Memmap_free(const KernAux_Memmap memmap)
{
MEMMAP.is_finished = false;
MEMMAP.memory_size = memory_size;
MEMMAP.entries_count = 0;
memset(MEMMAP.entries, 0, sizeof(MEMMAP.entries));
KERNAUX_NOTNULL(memmap);
KERNAUX_ASSERT(memmap->root_node);
KERNAUX_ASSERT(memmap->malloc);
KERNAUX_ASSERT(memmap->root_node->next == NULL);
free_node(memmap->malloc, (struct KernAux_Memmap_Node*)memmap->root_node);
KernAux_Malloc malloc = memmap->malloc;
((struct KernAux_Memmap*)memmap)->root_node = NULL;
((struct KernAux_Memmap*)memmap)->malloc = NULL;
KernAux_Malloc_free(malloc, (void*)memmap);
}
bool KernAux_MemMap_add_entry(
KernAux_MemMap memmap,
const bool is_available,
const char *const tag,
const size_t start,
const size_t size
void KernAux_Memmap_print(
const KernAux_Memmap memmap,
const KernAux_Display display
) {
if (MEMMAP.is_finished) {
KERNAUX_PANIC("memmap is finished");
return false;
}
KERNAUX_NOTNULL(memmap);
KERNAUX_ASSERT(memmap->root_node);
KERNAUX_ASSERT(memmap->malloc);
KERNAUX_ASSERT(memmap->root_node->next == NULL);
if (MEMMAP.entries_count >= KERNAUX_MEMMAP_ENTRIES_MAX) return false;
if (SIZE_MAX - start < size) return false;
if (size == 0) return false;
const size_t index = MEMMAP.entries_count++;
memset(&MEMMAP.entries[index], 0, sizeof(MEMMAP.entries[index]));
MEMMAP.entries[index].is_available = is_available;
MEMMAP.entries[index].start = start;
MEMMAP.entries[index].size = size;
MEMMAP.entries[index].end = start + size - 1;
MEMMAP.entries[index].limit = start + size;
if (tag) {
strncpy(
MEMMAP.entries[index].tag,
tag,
KERNAUX_MEMMAP_ENTRY_TAG_SLEN_MAX
);
}
return true;
print_nodes(memmap->root_node, display, 0);
}
bool KernAux_MemMap_finish(KernAux_MemMap memmap)
{
if (MEMMAP.is_finished) {
KERNAUX_PANIC("memmap is finished");
return false;
void free_node(
const KernAux_Malloc malloc,
struct KernAux_Memmap_Node *const node
) {
KERNAUX_NOTNULL(malloc);
KERNAUX_NOTNULL(node);
for (
struct KernAux_Memmap_Node *child_node =
(struct KernAux_Memmap_Node*)node->children;
child_node;
child_node = (struct KernAux_Memmap_Node*)child_node->next
) {
free_node(malloc, child_node);
}
if ((MEMMAP.entries_count == 0 && MEMMAP.memory_size != 0) ||
MEMMAP.entries_count > KERNAUX_MEMMAP_ENTRIES_MAX ||
MEMMAP.entries[0].start != 0 ||
MEMMAP.entries[MEMMAP.entries_count - 1].limit != MEMMAP.memory_size)
{
return false;
}
if (node->tag) KernAux_Malloc_free(malloc, (void*)node->tag);
KernAux_Malloc_free(malloc, node);
}
// At first, let's validate the individual entries.
for (size_t index = 0; index < MEMMAP.entries_count; ++index) {
if (SIZE_MAX - MEMMAP.entries[index].start <
MEMMAP.entries[index].size
||
MEMMAP.entries[index].end !=
MEMMAP.entries[index].start + MEMMAP.entries[index].size - 1
||
MEMMAP.entries[index].limit !=
MEMMAP.entries[index].start + MEMMAP.entries[index].size)
{
return false;
#define PRINT(s) do { KernAux_Display_print (display, s); } while (0)
#define PRINTLN(s) do { KernAux_Display_println(display, s); } while (0)
#define PRINTLNF(format, ...) \
do { KernAux_Display_printlnf(display, format, __VA_ARGS__); } while (0)
#define INDENT do { \
for (unsigned index = 0; index < indentation; ++index) PRINT(" "); \
} while (0)
void print_nodes(
KernAux_Memmap_Node node,
const KernAux_Display display,
const unsigned indentation
) {
for (; node; node = node->next) {
INDENT;
PRINTLN("{");
KERNAUX_CAST_CONST(unsigned long long, mem_start, node->mem_start);
KERNAUX_CAST_CONST(unsigned long long, mem_size, node->mem_size);
KERNAUX_CAST_CONST(unsigned long long, mem_end, node->mem_end);
INDENT;
PRINTLNF(" u64 mem_start: 0x%llx", mem_start);
INDENT;
PRINTLNF(" u64 mem_size: %llu", mem_size);
INDENT;
PRINTLNF(" u64 mem_end: 0x%llx", mem_end);
INDENT;
if (node->tag) {
PRINTLNF(" char* tag: \"%s\"", node->tag);
} else {
PRINTLN(" char* tag: NULL");
}
}
// TODO: Next, let's sort the entries.
// Finally, let's validate that the entries fit each other properly.
for (size_t index = 1; index < MEMMAP.entries_count; ++index) {
if (MEMMAP.entries[index - 1].limit != MEMMAP.entries[index].start) {
return false;
if (node->children) {
INDENT;
PRINTLN(" struct* children: [");
print_nodes(node->children, display, indentation + 2);
INDENT;
PRINTLN(" ]");
} else {
INDENT;
PRINTLN(" struct* children: []");
}
}
return MEMMAP.is_finished = true;
}
KernAux_MemMap_Entry
KernAux_MemMap_entry_by_index(KernAux_MemMap memmap, const size_t index)
{
if (!MEMMAP.is_finished) {
KERNAUX_PANIC("memmap is not finished");
return NULL;
}
if (index >= MEMMAP.entries_count) return NULL;
return &MEMMAP.entries[index];
}
KernAux_MemMap_Entry
KernAux_MemMap_entry_by_start(KernAux_MemMap memmap, const size_t start)
{
if (!MEMMAP.is_finished) {
KERNAUX_PANIC("memmap is not finished");
return NULL;
}
for (size_t index = 0; index < MEMMAP.entries_count; ++index) {
if (MEMMAP.entries[index].start == start) return &MEMMAP.entries[index];
}
return NULL;
}
KernAux_MemMap_Entry
KernAux_MemMap_entry_by_addr(KernAux_MemMap memmap, const size_t addr)
{
if (!MEMMAP.is_finished) {
KERNAUX_PANIC("memmap is not finished");
return NULL;
}
for (size_t index = 0; index < MEMMAP.entries_count; ++index) {
if (addr >= MEMMAP.entries[index].start &&
addr <= MEMMAP.entries[index].end)
{
return &MEMMAP.entries[index];
}
}
return NULL;
INDENT;
PRINTLN("}");
}
}

View File

@ -2,7 +2,8 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "../assert.h"
#include <kernaux/multiboot2.h>
#include <stddef.h>
@ -13,7 +14,7 @@ const struct KernAux_Multiboot2_HTagBase
const struct KernAux_Multiboot2_Header *const multiboot2_header,
const uint16_t tag_type
) {
KERNAUX_ASSERT(multiboot2_header);
KERNAUX_NOTNULL(multiboot2_header);
const struct KernAux_Multiboot2_HTagBase *tag_base =
(struct KernAux_Multiboot2_HTagBase*)
@ -38,8 +39,8 @@ const struct KernAux_Multiboot2_HTagBase
const uint16_t tag_type,
const struct KernAux_Multiboot2_HTagBase *const after_tag
) {
KERNAUX_ASSERT(multiboot2_header);
KERNAUX_ASSERT(after_tag);
KERNAUX_NOTNULL(multiboot2_header);
KERNAUX_NOTNULL(after_tag);
const struct KernAux_Multiboot2_HTagBase *tag_base =
(struct KernAux_Multiboot2_HTagBase*)

View File

@ -2,7 +2,8 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "../assert.h"
#include <kernaux/multiboot2.h>
#include <stdbool.h>
@ -12,7 +13,7 @@
bool KernAux_Multiboot2_Header_is_valid(
const struct KernAux_Multiboot2_Header *const multiboot2_header
) {
KERNAUX_ASSERT(multiboot2_header);
KERNAUX_NOTNULL(multiboot2_header);
if (multiboot2_header->magic != KERNAUX_MULTIBOOT2_HEADER_MAGIC) {
return false;
@ -86,7 +87,7 @@ bool KernAux_Multiboot2_Header_is_valid(
bool KernAux_Multiboot2_HTagBase_is_valid(
const struct KernAux_Multiboot2_HTagBase *tag_base
) {
KERNAUX_ASSERT(tag_base);
KERNAUX_NOTNULL(tag_base);
switch (tag_base->type) {
case KERNAUX_MULTIBOOT2_HTAG_NONE:
@ -141,7 +142,7 @@ bool KernAux_Multiboot2_HTagBase_is_valid(
bool KernAux_Multiboot2_HTag_None_is_valid(
const struct KernAux_Multiboot2_HTag_None *tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_NONE &&
tag->base.size == 8
@ -151,7 +152,7 @@ bool KernAux_Multiboot2_HTag_None_is_valid(
bool KernAux_Multiboot2_HTag_InfoReq_is_valid(
const struct KernAux_Multiboot2_HTag_InfoReq *tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_INFO_REQ &&
tag->base.size > 8 &&
@ -162,7 +163,7 @@ bool KernAux_Multiboot2_HTag_InfoReq_is_valid(
bool KernAux_Multiboot2_HTag_Addr_is_valid(
const struct KernAux_Multiboot2_HTag_Addr *tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_ADDR &&
tag->base.size == 24
@ -172,7 +173,7 @@ bool KernAux_Multiboot2_HTag_Addr_is_valid(
bool KernAux_Multiboot2_HTag_EntryAddr_is_valid(
const struct KernAux_Multiboot2_HTag_EntryAddr *tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_ENTRY_ADDR &&
tag->base.size == 12
@ -182,7 +183,7 @@ bool KernAux_Multiboot2_HTag_EntryAddr_is_valid(
bool KernAux_Multiboot2_HTag_Flags_is_valid(
const struct KernAux_Multiboot2_HTag_Flags *tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_FLAGS &&
tag->base.size == 12
@ -192,7 +193,7 @@ bool KernAux_Multiboot2_HTag_Flags_is_valid(
bool KernAux_Multiboot2_HTag_Framebuffer_is_valid(
const struct KernAux_Multiboot2_HTag_Framebuffer *tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_FRAMEBUFFER &&
tag->base.size == 20
@ -202,7 +203,7 @@ bool KernAux_Multiboot2_HTag_Framebuffer_is_valid(
bool KernAux_Multiboot2_HTag_ModuleAlign_is_valid(
const struct KernAux_Multiboot2_HTag_ModuleAlign *tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_MODULE_ALIGN &&
tag->base.size == 8
@ -212,7 +213,7 @@ bool KernAux_Multiboot2_HTag_ModuleAlign_is_valid(
bool KernAux_Multiboot2_HTag_EFIBootServices_is_valid(
const struct KernAux_Multiboot2_HTag_EFIBootServices *tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_EFI_BOOT_SERVICES &&
tag->base.size == 8
@ -222,7 +223,7 @@ bool KernAux_Multiboot2_HTag_EFIBootServices_is_valid(
bool KernAux_Multiboot2_HTag_EFII386EntryAddr_is_valid(
const struct KernAux_Multiboot2_HTag_EFII386EntryAddr *tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_EFI_I386_ENTRY_ADDR &&
tag->base.size == 12
@ -232,7 +233,7 @@ bool KernAux_Multiboot2_HTag_EFII386EntryAddr_is_valid(
bool KernAux_Multiboot2_HTag_EFIAmd64EntryAddr_is_valid(
const struct KernAux_Multiboot2_HTag_EFIAmd64EntryAddr *tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_EFI_AMD64_ENTRY_ADDR &&
tag->base.size == 12
@ -242,7 +243,7 @@ bool KernAux_Multiboot2_HTag_EFIAmd64EntryAddr_is_valid(
bool KernAux_Multiboot2_HTag_RelocatableHeader_is_valid(
const struct KernAux_Multiboot2_HTag_RelocatableHeader *tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
if (!(
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_RELOCATABLE_HEADER &&

View File

@ -2,7 +2,8 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "../assert.h"
#include <kernaux/generic/display.h>
#include <kernaux/macro.h>
#include <kernaux/multiboot2.h>
@ -20,8 +21,8 @@
do { KernAux_Display_printlnf(display, format, __VA_ARGS__); } while (0)
#define HEADER(Type) do { \
KERNAUX_ASSERT(tag); \
KERNAUX_ASSERT(display); \
KERNAUX_NOTNULL(tag); \
KERNAUX_NOTNULL(display); \
\
if (!KernAux_Multiboot2_HTag_##Type##_is_valid(tag)) { \
PRINTLN("Multiboot 2 header tag // invalid!"); \
@ -100,8 +101,8 @@ void KernAux_Multiboot2_Header_print(
const struct KernAux_Multiboot2_Header *const multiboot2_header,
const KernAux_Display display
) {
KERNAUX_ASSERT(multiboot2_header);
KERNAUX_ASSERT(display);
KERNAUX_NOTNULL(multiboot2_header);
KERNAUX_NOTNULL(display);
KERNAUX_CAST_CONST(unsigned long, magic, multiboot2_header->magic);
KERNAUX_CAST_CONST(unsigned long, arch, multiboot2_header->arch);
@ -136,8 +137,8 @@ void KernAux_Multiboot2_HTagBase_print(
const struct KernAux_Multiboot2_HTagBase *const tag_base,
const KernAux_Display display
) {
KERNAUX_ASSERT(tag_base);
KERNAUX_ASSERT(display);
KERNAUX_NOTNULL(tag_base);
KERNAUX_NOTNULL(display);
switch (tag_base->type) {
case KERNAUX_MULTIBOOT2_HTAG_NONE:

View File

@ -0,0 +1,71 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "../assert.h"
#include <kernaux/generic/malloc.h>
#include <kernaux/macro.h>
#include <kernaux/memmap.h>
#include <kernaux/multiboot2.h>
#include <stddef.h>
#ifdef WITH_MEMMAP
KernAux_Memmap_Builder KernAux_Multiboot2_Info_to_memmap_builder(
const struct KernAux_Multiboot2_Info *const multiboot2_info,
const KernAux_Malloc malloc
) {
KERNAUX_NOTNULL(multiboot2_info);
KERNAUX_NOTNULL(malloc);
if (!KernAux_Multiboot2_Info_is_valid(multiboot2_info)) return NULL;
const struct KernAux_Multiboot2_ITag_MemoryMap *const memory_map_tag =
(const struct KernAux_Multiboot2_ITag_MemoryMap*)
KernAux_Multiboot2_Info_first_tag_with_type(
multiboot2_info,
KERNAUX_MULTIBOOT2_ITAG_MEMORY_MAP
);
if (!memory_map_tag) return NULL;
const void *const data = KERNAUX_MULTIBOOT2_DATA(memory_map_tag);
size_t data_size = memory_map_tag->base.size - sizeof(*memory_map_tag);
const void *const data_end = ((const char*)data) + data_size;
if (memory_map_tag->entry_size <
sizeof(struct KernAux_Multiboot2_ITag_MemoryMap_EntryBase))
{
return NULL;
}
KernAux_Memmap_Builder builder =
KernAux_Memmap_Builder_new(malloc);
if (!builder) return NULL;
for (
const struct KernAux_Multiboot2_ITag_MemoryMap_EntryBase *entry = data;
(const char*)entry < (const char*)data_end;
entry =
(const struct KernAux_Multiboot2_ITag_MemoryMap_EntryBase*)
(((const char*)entry) + memory_map_tag->entry_size)
) {
const void *const node = KernAux_Memmap_Builder_add(
builder,
NULL,
entry->base_addr,
entry->length,
KernAux_Multiboot2_ITag_MemoryMap_EntryBase_Type_to_str(
entry->type
)
);
if (!node) {
KernAux_Memmap_Builder_finish_and_free(builder);
return NULL;
}
}
return builder;
}
#endif

View File

@ -58,3 +58,22 @@ const char *KernAux_Multiboot2_ITag_to_str(const uint32_t tag_type)
return NULL;
}
}
const char*
KernAux_Multiboot2_ITag_MemoryMap_EntryBase_Type_to_str(const uint32_t type)
{
switch (type) {
case KERNAUX_MULTIBOOT2_MEMMAP_AVAILABLE:
return "available";
case KERNAUX_MULTIBOOT2_MEMMAP_RESERVED:
return "reserved";
case KERNAUX_MULTIBOOT2_MEMMAP_ACPI_RECLAIMABLE:
return "ACPI reclaimable";
case KERNAUX_MULTIBOOT2_MEMMAP_NVS:
return "ACPI Non-Volatile Storage";
case KERNAUX_MULTIBOOT2_MEMMAP_BADRAM:
return "bad RAM";
default:
return NULL;
}
}

View File

@ -2,7 +2,8 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "../assert.h"
#include <kernaux/multiboot2.h>
#include <stddef.h>
@ -13,7 +14,7 @@ const struct KernAux_Multiboot2_ITagBase
const struct KernAux_Multiboot2_Info *const multiboot2_info,
const uint32_t tag_type
) {
KERNAUX_ASSERT(multiboot2_info);
KERNAUX_NOTNULL(multiboot2_info);
const struct KernAux_Multiboot2_ITagBase *tag_base =
(struct KernAux_Multiboot2_ITagBase*)
@ -38,8 +39,8 @@ const struct KernAux_Multiboot2_ITagBase
const uint32_t tag_type,
const struct KernAux_Multiboot2_ITagBase *const after_tag
) {
KERNAUX_ASSERT(multiboot2_info);
KERNAUX_ASSERT(after_tag);
KERNAUX_NOTNULL(multiboot2_info);
KERNAUX_NOTNULL(after_tag);
const struct KernAux_Multiboot2_ITagBase *tag_base =
(struct KernAux_Multiboot2_ITagBase*)
@ -63,7 +64,7 @@ const struct KernAux_Multiboot2_ITagBase
const char *KernAux_Multiboot2_Info_boot_cmd_line(
const struct KernAux_Multiboot2_Info *const multiboot2_info
) {
KERNAUX_ASSERT(multiboot2_info);
KERNAUX_NOTNULL(multiboot2_info);
const struct KernAux_Multiboot2_ITag_BootCmdLine *const tag =
(struct KernAux_Multiboot2_ITag_BootCmdLine*)

View File

@ -2,7 +2,8 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "../assert.h"
#include <kernaux/multiboot2.h>
#include <stdbool.h>
@ -12,7 +13,7 @@
bool KernAux_Multiboot2_Info_is_valid(
const struct KernAux_Multiboot2_Info *const multiboot2_info
) {
KERNAUX_ASSERT(multiboot2_info);
KERNAUX_NOTNULL(multiboot2_info);
if (multiboot2_info->total_size <
sizeof(struct KernAux_Multiboot2_Info) +
@ -67,7 +68,7 @@ bool KernAux_Multiboot2_Info_is_valid(
bool KernAux_Multiboot2_ITagBase_is_valid(
const struct KernAux_Multiboot2_ITagBase *const tag_base
) {
KERNAUX_ASSERT(tag_base);
KERNAUX_NOTNULL(tag_base);
switch (tag_base->type) {
case KERNAUX_MULTIBOOT2_ITAG_NONE:
@ -167,7 +168,7 @@ bool KernAux_Multiboot2_ITagBase_is_valid(
bool KernAux_Multiboot2_ITag_None_is_valid(
const struct KernAux_Multiboot2_ITag_None *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_NONE &&
tag->base.size == 8
@ -177,7 +178,7 @@ bool KernAux_Multiboot2_ITag_None_is_valid(
bool KernAux_Multiboot2_ITag_BootCmdLine_is_valid(
const struct KernAux_Multiboot2_ITag_BootCmdLine *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
size_t index = 1;
@ -198,7 +199,7 @@ bool KernAux_Multiboot2_ITag_BootCmdLine_is_valid(
bool KernAux_Multiboot2_ITag_BootLoaderName_is_valid(
const struct KernAux_Multiboot2_ITag_BootLoaderName *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
size_t index = 1;
@ -219,7 +220,7 @@ bool KernAux_Multiboot2_ITag_BootLoaderName_is_valid(
bool KernAux_Multiboot2_ITag_Module_is_valid(
const struct KernAux_Multiboot2_ITag_Module *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
size_t index = 1;
@ -241,7 +242,7 @@ bool KernAux_Multiboot2_ITag_Module_is_valid(
bool KernAux_Multiboot2_ITag_BasicMemoryInfo_is_valid(
const struct KernAux_Multiboot2_ITag_BasicMemoryInfo *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_BASIC_MEMORY_INFO &&
tag->base.size == 16
@ -251,7 +252,7 @@ bool KernAux_Multiboot2_ITag_BasicMemoryInfo_is_valid(
bool KernAux_Multiboot2_ITag_BIOSBootDevice_is_valid(
const struct KernAux_Multiboot2_ITag_BIOSBootDevice *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE &&
tag->base.size == 20
@ -261,7 +262,7 @@ bool KernAux_Multiboot2_ITag_BIOSBootDevice_is_valid(
bool KernAux_Multiboot2_ITag_MemoryMap_is_valid(
const struct KernAux_Multiboot2_ITag_MemoryMap *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_MEMORY_MAP &&
tag->base.size >= 16 &&
@ -274,7 +275,7 @@ bool KernAux_Multiboot2_ITag_MemoryMap_is_valid(
bool KernAux_Multiboot2_ITag_VBEInfo_is_valid(
const struct KernAux_Multiboot2_ITag_VBEInfo *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_VBE_INFO &&
tag->base.size == 784
@ -284,7 +285,7 @@ bool KernAux_Multiboot2_ITag_VBEInfo_is_valid(
bool KernAux_Multiboot2_ITag_FramebufferInfo_is_valid(
const struct KernAux_Multiboot2_ITag_FramebufferInfo *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_FRAMEBUFFER_INFO &&
tag->base.size >= 32
@ -294,7 +295,7 @@ bool KernAux_Multiboot2_ITag_FramebufferInfo_is_valid(
bool KernAux_Multiboot2_ITag_ELFSymbols_is_valid(
const struct KernAux_Multiboot2_ITag_ELFSymbols *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_ELF_SYMBOLS &&
tag->base.size >= 20 &&
@ -308,7 +309,7 @@ bool KernAux_Multiboot2_ITag_ELFSymbols_is_valid(
bool KernAux_Multiboot2_ITag_APMTable_is_valid(
const struct KernAux_Multiboot2_ITag_APMTable *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_APM_TABLE &&
tag->base.size == 28
@ -318,7 +319,7 @@ bool KernAux_Multiboot2_ITag_APMTable_is_valid(
bool KernAux_Multiboot2_ITag_EFI32bitSystemTablePtr_is_valid(
const struct KernAux_Multiboot2_ITag_EFI32bitSystemTablePtr *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_EFI_32BIT_SYSTEM_TABLE_PTR &&
tag->base.size == 12
@ -328,7 +329,7 @@ bool KernAux_Multiboot2_ITag_EFI32bitSystemTablePtr_is_valid(
bool KernAux_Multiboot2_ITag_EFI64bitSystemTablePtr_is_valid(
const struct KernAux_Multiboot2_ITag_EFI64bitSystemTablePtr *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_EFI_64BIT_SYSTEM_TABLE_PTR &&
tag->base.size == 16
@ -338,7 +339,7 @@ bool KernAux_Multiboot2_ITag_EFI64bitSystemTablePtr_is_valid(
bool KernAux_Multiboot2_ITag_SMBIOSTables_is_valid(
const struct KernAux_Multiboot2_ITag_SMBIOSTables *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_SMBIOS_TABLES &&
tag->base.size >= 16
@ -348,7 +349,7 @@ bool KernAux_Multiboot2_ITag_SMBIOSTables_is_valid(
bool KernAux_Multiboot2_ITag_ACPIOldRSDP_is_valid(
const struct KernAux_Multiboot2_ITag_ACPIOldRSDP *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_ACPI_OLD_RSDP &&
tag->base.size >= 8
@ -358,7 +359,7 @@ bool KernAux_Multiboot2_ITag_ACPIOldRSDP_is_valid(
bool KernAux_Multiboot2_ITag_ACPINewRSDP_is_valid(
const struct KernAux_Multiboot2_ITag_ACPINewRSDP *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_ACPI_NEW_RSDP &&
tag->base.size >= 8
@ -368,7 +369,7 @@ bool KernAux_Multiboot2_ITag_ACPINewRSDP_is_valid(
bool KernAux_Multiboot2_ITag_NetworkingInfo_is_valid(
const struct KernAux_Multiboot2_ITag_NetworkingInfo *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_NETWORKING_INFO &&
tag->base.size >= 8
@ -378,7 +379,7 @@ bool KernAux_Multiboot2_ITag_NetworkingInfo_is_valid(
bool KernAux_Multiboot2_ITag_EFIMemoryMap_is_valid(
const struct KernAux_Multiboot2_ITag_EFIMemoryMap *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_EFI_MEMORY_MAP &&
tag->base.size >= 16
@ -388,7 +389,7 @@ bool KernAux_Multiboot2_ITag_EFIMemoryMap_is_valid(
bool KernAux_Multiboot2_ITag_EFIBootServicesNotTerminated_is_valid(
const struct KernAux_Multiboot2_ITag_EFIBootServicesNotTerminated *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type ==
KERNAUX_MULTIBOOT2_ITAG_EFI_BOOT_SERVICES_NOT_TERMINATED &&
@ -399,7 +400,7 @@ bool KernAux_Multiboot2_ITag_EFIBootServicesNotTerminated_is_valid(
bool KernAux_Multiboot2_ITag_EFI32bitImageHandlePtr_is_valid(
const struct KernAux_Multiboot2_ITag_EFI32bitImageHandlePtr *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_EFI_32BIT_IMAGE_HANDLE_PTR &&
tag->base.size == 12
@ -409,7 +410,7 @@ bool KernAux_Multiboot2_ITag_EFI32bitImageHandlePtr_is_valid(
bool KernAux_Multiboot2_ITag_EFI64bitImageHandlePtr_is_valid(
const struct KernAux_Multiboot2_ITag_EFI64bitImageHandlePtr *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_EFI_64BIT_IMAGE_HANDLE_PTR &&
tag->base.size == 16
@ -419,7 +420,7 @@ bool KernAux_Multiboot2_ITag_EFI64bitImageHandlePtr_is_valid(
bool KernAux_Multiboot2_ITag_ImageLoadBasePhysAddr_is_valid(
const struct KernAux_Multiboot2_ITag_ImageLoadBasePhysAddr *const tag
) {
KERNAUX_ASSERT(tag);
KERNAUX_NOTNULL(tag);
return (
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_IMAGE_LOAD_BASE_PHYS_ADDR &&
tag->base.size == 12

View File

@ -2,7 +2,8 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "../assert.h"
#include <kernaux/elf.h>
#include <kernaux/generic/display.h>
#include <kernaux/macro.h>
@ -21,8 +22,8 @@
do { KernAux_Display_printlnf(display, format, __VA_ARGS__); } while (0)
#define HEADER(Type) do { \
KERNAUX_ASSERT(tag); \
KERNAUX_ASSERT(display); \
KERNAUX_NOTNULL(tag); \
KERNAUX_NOTNULL(display); \
\
if (!KernAux_Multiboot2_ITag_##Type##_is_valid(tag)) { \
PRINTLN("Multiboot 2 info tag // invalid!"); \
@ -83,8 +84,8 @@ void KernAux_Multiboot2_Info_print(
const struct KernAux_Multiboot2_Info *const multiboot2_info,
const KernAux_Display display
) {
KERNAUX_ASSERT(multiboot2_info);
KERNAUX_ASSERT(display);
KERNAUX_NOTNULL(multiboot2_info);
KERNAUX_NOTNULL(display);
KERNAUX_CAST_CONST(unsigned long, total_size, multiboot2_info->total_size);
KERNAUX_CAST_CONST(unsigned long, reserved, multiboot2_info->reserved);
@ -112,8 +113,8 @@ void KernAux_Multiboot2_ITagBase_print(
const struct KernAux_Multiboot2_ITagBase *const tag_base,
const KernAux_Display display
) {
KERNAUX_ASSERT(tag_base);
KERNAUX_ASSERT(display);
KERNAUX_NOTNULL(tag_base);
KERNAUX_NOTNULL(display);
switch (tag_base->type) {
case KERNAUX_MULTIBOOT2_ITAG_NONE:
@ -377,7 +378,12 @@ void KernAux_Multiboot2_ITag_MemoryMap_print(
PRINTLNF(" [%zu]: {", index);
PRINTLNF(" u64 base_addr: 0x%llx", base_addr);
PRINTLNF(" u64 length: %llu", length);
PRINTLNF(" u32 type: %lu", type);
PRINTLNF(" u32 type: %lu (%s)",
type,
KernAux_Multiboot2_ITag_MemoryMap_EntryBase_Type_to_str(
entries[index].type
)
);
PRINTLNF(" u32 reserved: 0x%lx", reserved);
PRINTLN (" }");
}

View File

@ -2,14 +2,15 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "assert.h"
#include <kernaux/ntoa.h>
#include <stddef.h>
char *kernaux_utoa(uint64_t value, char *buffer, int base, const char *prefix)
{
KERNAUX_ASSERT(buffer);
KERNAUX_NOTNULL(buffer);
// Protect caller from invalid state in case of future assertions
// cppcheck-suppress ctunullpointer

View File

@ -2,7 +2,8 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "assert.h"
#include <kernaux/macro.h>
#include <kernaux/pfa.h>
@ -41,14 +42,14 @@ static void KernAux_PFA_mark(
void KernAux_PFA_initialize(const KernAux_PFA pfa)
{
KERNAUX_ASSERT(pfa);
KERNAUX_NOTNULL(pfa);
// cppcheck-suppress ctunullpointer
memset(pfa->flags, 0, sizeof(pfa->flags));
}
bool KernAux_PFA_is_available(const KernAux_PFA pfa, const size_t page_addr)
{
KERNAUX_ASSERT(pfa);
KERNAUX_NOTNULL(pfa);
KERNAUX_ASSERT(page_addr % KERNAUX_PFA_PAGE_SIZE == 0);
// cppcheck-suppress ctunullpointer
@ -77,7 +78,7 @@ void KernAux_PFA_mark(
size_t start,
size_t end
) {
KERNAUX_ASSERT(pfa);
KERNAUX_NOTNULL(pfa);
KERNAUX_ASSERT(start < end);
const size_t start_rem = start % KERNAUX_PFA_PAGE_SIZE;
@ -105,7 +106,7 @@ void KernAux_PFA_mark(
size_t KernAux_PFA_alloc_pages(const KernAux_PFA pfa, size_t mem_size)
{
KERNAUX_ASSERT(pfa);
KERNAUX_NOTNULL(pfa);
const size_t mem_rem = mem_size % KERNAUX_PFA_PAGE_SIZE;
@ -144,7 +145,7 @@ void KernAux_PFA_free_pages(
const size_t page_addr,
size_t mem_size
) {
KERNAUX_ASSERT(pfa);
KERNAUX_NOTNULL(pfa);
KERNAUX_ASSERT(page_addr % KERNAUX_PFA_PAGE_SIZE == 0);
const size_t mem_rem = mem_size % KERNAUX_PFA_PAGE_SIZE;

View File

@ -13,7 +13,8 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "assert.h"
#include <kernaux/printf.h>
#include <kernaux/printf_fmt.h>
@ -70,8 +71,8 @@ static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d
int kernaux_fprintf(void (*out)(char, void*), void *data, const char* format, ...)
{
KERNAUX_ASSERT(out);
KERNAUX_ASSERT(format);
KERNAUX_NOTNULL(out);
KERNAUX_NOTNULL(format);
va_list va;
va_start(va, format);
@ -83,8 +84,8 @@ int kernaux_fprintf(void (*out)(char, void*), void *data, const char* format, ..
int kernaux_vfprintf(void (*out)(char, void*), void *data, const char* format, va_list va)
{
KERNAUX_ASSERT(out);
KERNAUX_ASSERT(format);
KERNAUX_NOTNULL(out);
KERNAUX_NOTNULL(format);
const out_fct_wrap_type out_fct_wrap = { out, data };
return _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va);
@ -92,8 +93,8 @@ int kernaux_vfprintf(void (*out)(char, void*), void *data, const char* format, v
int kernaux_snprintf(char* buffer, size_t count, const char* format, ...)
{
KERNAUX_ASSERT(buffer);
KERNAUX_ASSERT(format);
KERNAUX_NOTNULL(buffer);
KERNAUX_NOTNULL(format);
va_list va;
va_start(va, format);
@ -104,16 +105,16 @@ int kernaux_snprintf(char* buffer, size_t count, const char* format, ...)
int kernaux_vsnprintf(char* buffer, size_t count, const char* format, va_list va)
{
KERNAUX_ASSERT(buffer);
KERNAUX_ASSERT(format);
KERNAUX_NOTNULL(buffer);
KERNAUX_NOTNULL(format);
return _vsnprintf(_out_buffer, buffer, count, format, va);
}
int kernaux_sprintf(char* buffer, const char* format, ...)
{
KERNAUX_ASSERT(buffer);
KERNAUX_ASSERT(format);
KERNAUX_NOTNULL(buffer);
KERNAUX_NOTNULL(format);
va_list va;
va_start(va, format);
@ -128,7 +129,7 @@ int kernaux_sprintf(char* buffer, const char* format, ...)
int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va)
{
KERNAUX_ASSERT(format);
KERNAUX_NOTNULL(format);
size_t idx = 0u;

View File

@ -9,7 +9,8 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "assert.h"
#include <kernaux/printf_fmt.h>
#include <ctype.h>
@ -35,7 +36,7 @@ static unsigned int _atoi(const char** str);
struct KernAux_PrintfFmt_Spec KernAux_PrintfFmt_Spec_create_out(
const char **const format
) {
KERNAUX_ASSERT(format);
KERNAUX_NOTNULL(format);
const struct KernAux_PrintfFmt_Spec spec =
KernAux_PrintfFmt_Spec_create(*format);
@ -47,8 +48,8 @@ struct KernAux_PrintfFmt_Spec KernAux_PrintfFmt_Spec_create_out_new(
const char *const format,
const char **const new_format
) {
KERNAUX_ASSERT(format);
KERNAUX_ASSERT(new_format);
KERNAUX_NOTNULL(format);
KERNAUX_NOTNULL(new_format);
*new_format = NULL;
const struct KernAux_PrintfFmt_Spec spec =
@ -59,7 +60,7 @@ struct KernAux_PrintfFmt_Spec KernAux_PrintfFmt_Spec_create_out_new(
struct KernAux_PrintfFmt_Spec KernAux_PrintfFmt_Spec_create(const char *format)
{
KERNAUX_ASSERT(format);
KERNAUX_NOTNULL(format);
struct KernAux_PrintfFmt_Spec spec;
@ -87,7 +88,7 @@ struct KernAux_PrintfFmt_Spec KernAux_PrintfFmt_Spec_create(const char *format)
void KernAux_PrintfFmt_Spec_set_width(const Spec spec, const int width)
{
KERNAUX_ASSERT(spec);
KERNAUX_NOTNULL(spec);
if (width < 0) {
spec->flags |= KERNAUX_PRINTF_FMT_FLAGS_LEFT; // reverse padding
@ -99,7 +100,7 @@ void KernAux_PrintfFmt_Spec_set_width(const Spec spec, const int width)
void KernAux_PrintfFmt_Spec_set_precision(const Spec spec, const int precision)
{
KERNAUX_ASSERT(spec);
KERNAUX_NOTNULL(spec);
spec->precision = precision > 0 ? (unsigned int)precision : 0u;
}
@ -110,8 +111,8 @@ void KernAux_PrintfFmt_Spec_set_precision(const Spec spec, const int precision)
void parse_flags(const Spec spec, const char **const format)
{
KERNAUX_ASSERT(spec);
KERNAUX_ASSERT(format);
KERNAUX_NOTNULL(spec);
KERNAUX_NOTNULL(format);
KERNAUX_ASSERT(*format);
bool running = true;
@ -144,8 +145,8 @@ void parse_flags(const Spec spec, const char **const format)
void parse_width(const Spec spec, const char **const format)
{
KERNAUX_ASSERT(spec);
KERNAUX_ASSERT(format);
KERNAUX_NOTNULL(spec);
KERNAUX_NOTNULL(format);
KERNAUX_ASSERT(*format);
if (isdigit(**format)) {
@ -161,8 +162,8 @@ void parse_width(const Spec spec, const char **const format)
void parse_precision(const Spec spec, const char **const format)
{
KERNAUX_ASSERT(spec);
KERNAUX_ASSERT(format);
KERNAUX_NOTNULL(spec);
KERNAUX_NOTNULL(format);
KERNAUX_ASSERT(*format);
if (**format == '.') {
@ -184,8 +185,8 @@ void parse_precision(const Spec spec, const char **const format)
void parse_length(const Spec spec, const char **const format)
{
KERNAUX_ASSERT(spec);
KERNAUX_ASSERT(format);
KERNAUX_NOTNULL(spec);
KERNAUX_NOTNULL(format);
KERNAUX_ASSERT(*format);
switch (**format) {
@ -236,8 +237,8 @@ void parse_length(const Spec spec, const char **const format)
void parse_type(const Spec spec, const char **const format)
{
KERNAUX_ASSERT(spec);
KERNAUX_ASSERT(format);
KERNAUX_NOTNULL(spec);
KERNAUX_NOTNULL(format);
KERNAUX_ASSERT(*format);
switch (**format) {

View File

@ -2,11 +2,11 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include <kernaux/runtime.h>
#include <stddef.h>
void (*kernaux_assert_cb)(const char *file, int line, const char *msg) = NULL;
KernAux_Assert_Cb kernaux_assert_cb = NULL;
void kernaux_assert_do(
const char *const file,

View File

@ -2,7 +2,8 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include "assert.h"
#include <kernaux/ntoa.h>
#include <kernaux/units.h>
@ -16,7 +17,7 @@ bool kernaux_units_human_raw(
char *const buffer,
const size_t buffer_size
) {
KERNAUX_ASSERT(buffer);
KERNAUX_NOTNULL(buffer);
KERNAUX_ASSERT(buffer_size > 0);
char tmp_buffer[TMP_BUFFER_SIZE];
@ -56,7 +57,7 @@ bool kernaux_units_human_dec(
char *const buffer,
const size_t buffer_size
) {
KERNAUX_ASSERT(buffer);
KERNAUX_NOTNULL(buffer);
KERNAUX_ASSERT(buffer_size > 0);
char tmp_buffer[TMP_BUFFER_SIZE];

2
tests/.gitignore vendored
View File

@ -11,12 +11,12 @@
/test_elf
/test_free_list
/test_mbr
/test_memmap
/test_multiboot2_common_packing
/test_multiboot2_header_helpers
/test_multiboot2_header_print
/test_multiboot2_header_print.c
/test_multiboot2_header_validation
/test_multiboot2_info_convert_memmap
/test_multiboot2_info_helpers
/test_multiboot2_info_print
/test_multiboot2_info_print.c

View File

@ -168,18 +168,6 @@ test_mbr_SOURCES = \
test_mbr.c
endif
###############
# test_memmap #
###############
if WITH_MEMMAP
TESTS += test_memmap
test_memmap_LDADD = $(top_builddir)/libkernaux.la
test_memmap_SOURCES = \
main.c \
test_memmap.c
endif
##################################
# test_multiboot2_common_packing #
##################################
@ -241,6 +229,22 @@ test_multiboot2_header_validation_SOURCES = \
../fixtures/multiboot2_header_example2.h
endif
#######################################
# test_multiboot2_info_convert_memmap #
#######################################
if WITH_MULTIBOOT2
if WITH_MEMMAP
TESTS += test_multiboot2_info_convert_memmap
test_multiboot2_info_convert_memmap_LDADD = $(top_builddir)/libkernaux.la
test_multiboot2_info_convert_memmap_SOURCES = \
main.c \
test_multiboot2_info_convert_memmap.c \
../fixtures/multiboot2_header_example2.h \
../fixtures/multiboot2_info_example2.h
endif
endif
################################
# test_multiboot2_info_helpers #
################################
@ -304,7 +308,7 @@ endif
# test_ntoa_assert #
####################
if ENABLE_DEBUG
if ENABLE_ASSERT
if WITH_NTOA
TESTS += test_ntoa_assert
test_ntoa_assert_LDADD = $(top_builddir)/libkernaux.la
@ -330,7 +334,7 @@ endif
# test_pfa_assert #
###################
if ENABLE_DEBUG
if ENABLE_ASSERT
if WITH_PFA
TESTS += test_pfa_assert
test_pfa_assert_LDADD = $(top_builddir)/libkernaux.la

View File

@ -2,7 +2,7 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include <kernaux/runtime.h>
#include <stdio.h>
#include <stdlib.h>

View File

@ -1,233 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define KERNAUX_ACCESS_PRIVATE
#include <kernaux/assert.h>
#include <kernaux/macro.h>
#include <kernaux/memmap.h>
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
static KernAux_MemMap memmap;
static unsigned int assert_count_exp = 0;
static unsigned int assert_count_ctr = 0;
static const char *assert_last_file = NULL;
static void assert_cb(
const char *const file,
const int line KERNAUX_UNUSED,
const char *const msg KERNAUX_UNUSED
) {
++assert_count_ctr;
assert_last_file = file;
}
static void before_assert()
{
assert(assert_count_ctr == assert_count_exp);
}
static void expect_assert()
{
#ifdef ENABLE_DEBUG
// cppcheck-suppress assignmentInAssert
assert(assert_count_ctr == ++assert_count_exp);
assert(strstr(assert_last_file, "src/memmap.c") != NULL);
assert_last_file = NULL;
#else
assert(assert_count_ctr == 0);
assert(assert_last_file == NULL);
#endif
}
#define MEMSET memset(memmap, 0xff, sizeof(memmap))
#define MEMMAP (*memmap)
void test_main()
{
kernaux_assert_cb = assert_cb;
{
MEMSET;
KernAux_MemMap_init(memmap, 0);
assert(MEMMAP.is_finished == false);
assert(MEMMAP.memory_size == 0);
assert(MEMMAP.entries_count == 0);
assert(KernAux_MemMap_finish(memmap));
assert(MEMMAP.is_finished);
assert(MEMMAP.memory_size == 0);
assert(MEMMAP.entries_count == 0);
assert(KernAux_MemMap_entry_by_index(memmap, 0) == NULL);
before_assert();
assert(!KernAux_MemMap_finish(memmap));
expect_assert();
}
{
MEMSET;
KernAux_MemMap_init(memmap, 0);
assert(MEMMAP.is_finished == false);
assert(MEMMAP.memory_size == 0);
assert(MEMMAP.entries_count == 0);
assert(!KernAux_MemMap_add_entry(memmap, false, NULL, 0, 0));
assert(MEMMAP.is_finished == false);
assert(MEMMAP.memory_size == 0);
assert(MEMMAP.entries_count == 0);
assert(KernAux_MemMap_finish(memmap));
assert(MEMMAP.is_finished);
assert(MEMMAP.memory_size == 0);
assert(MEMMAP.entries_count == 0);
assert(KernAux_MemMap_entry_by_index(memmap, 0) == NULL);
}
{
MEMSET;
KernAux_MemMap_init(memmap, 1);
assert(MEMMAP.is_finished == false);
assert(MEMMAP.memory_size == 1);
assert(MEMMAP.entries_count == 0);
assert(KernAux_MemMap_add_entry(memmap, false, NULL, 0, 1));
assert(MEMMAP.is_finished == false);
assert(MEMMAP.memory_size == 1);
assert(MEMMAP.entries_count == 1);
assert(KernAux_MemMap_finish(memmap));
assert(MEMMAP.is_finished);
assert(MEMMAP.memory_size == 1);
assert(MEMMAP.entries_count == 1);
assert(MEMMAP.entries[0].is_available == false);
assert(MEMMAP.entries[0].tag[0] == '\0');
assert(MEMMAP.entries[0].start == 0);
assert(MEMMAP.entries[0].size == 1);
assert(MEMMAP.entries[0].end == 0);
assert(MEMMAP.entries[0].limit == 1);
assert(KernAux_MemMap_entry_by_index(memmap, 0) == &MEMMAP.entries[0]);
}
{
MEMSET;
KernAux_MemMap_init(memmap, 2);
assert(MEMMAP.is_finished == false);
assert(MEMMAP.memory_size == 2);
assert(MEMMAP.entries_count == 0);
assert(KernAux_MemMap_add_entry(memmap, false, NULL, 0, 2));
assert(MEMMAP.is_finished == false);
assert(MEMMAP.memory_size == 2);
assert(MEMMAP.entries_count == 1);
assert(KernAux_MemMap_finish(memmap));
assert(MEMMAP.is_finished);
assert(MEMMAP.memory_size == 2);
assert(MEMMAP.entries_count == 1);
assert(MEMMAP.entries[0].is_available == false);
assert(MEMMAP.entries[0].tag[0] == '\0');
assert(MEMMAP.entries[0].start == 0);
assert(MEMMAP.entries[0].size == 2);
assert(MEMMAP.entries[0].end == 1);
assert(MEMMAP.entries[0].limit == 2);
assert(KernAux_MemMap_entry_by_index(memmap, 0) == &MEMMAP.entries[0]);
}
{
MEMSET;
KernAux_MemMap_init(memmap, 1);
assert(MEMMAP.is_finished == false);
assert(MEMMAP.memory_size == 1);
assert(MEMMAP.entries_count == 0);
assert(KernAux_MemMap_add_entry(memmap, false, NULL, 0, 2));
assert(MEMMAP.is_finished == false);
assert(MEMMAP.memory_size == 1);
assert(MEMMAP.entries_count == 1);
assert(!KernAux_MemMap_finish(memmap));
assert(MEMMAP.is_finished == false);
assert(MEMMAP.memory_size == 1);
assert(MEMMAP.entries_count == 1);
assert(MEMMAP.entries[0].is_available == false);
assert(MEMMAP.entries[0].tag[0] == '\0');
assert(MEMMAP.entries[0].start == 0);
assert(MEMMAP.entries[0].size == 2);
assert(MEMMAP.entries[0].end == 1);
assert(MEMMAP.entries[0].limit == 2);
before_assert();
assert(KernAux_MemMap_entry_by_index(memmap, 0) == NULL);
expect_assert();
}
{
MEMSET;
KernAux_MemMap_init(memmap, 2);
assert(MEMMAP.is_finished == false);
assert(MEMMAP.memory_size == 2);
assert(MEMMAP.entries_count == 0);
assert(KernAux_MemMap_add_entry(memmap, false, NULL, 0, 1));
assert(MEMMAP.is_finished == false);
assert(MEMMAP.memory_size == 2);
assert(MEMMAP.entries_count == 1);
assert(KernAux_MemMap_add_entry(memmap, false, NULL, 1, 1));
assert(MEMMAP.is_finished == false);
assert(MEMMAP.memory_size == 2);
assert(MEMMAP.entries_count == 2);
assert(KernAux_MemMap_finish(memmap));
assert(MEMMAP.is_finished);
assert(MEMMAP.memory_size == 2);
assert(MEMMAP.entries_count == 2);
assert(MEMMAP.entries[0].is_available == false);
assert(MEMMAP.entries[0].tag[0] == '\0');
assert(MEMMAP.entries[0].start == 0);
assert(MEMMAP.entries[0].size == 1);
assert(MEMMAP.entries[0].end == 0);
assert(MEMMAP.entries[0].limit == 1);
assert(MEMMAP.entries[1].is_available == false);
assert(MEMMAP.entries[1].tag[0] == '\0');
assert(MEMMAP.entries[1].start == 1);
assert(MEMMAP.entries[1].size == 1);
assert(MEMMAP.entries[1].end == 1);
assert(MEMMAP.entries[1].limit == 2);
assert(KernAux_MemMap_entry_by_index(memmap, 0) == &MEMMAP.entries[0]);
assert(KernAux_MemMap_entry_by_index(memmap, 1) == &MEMMAP.entries[1]);
}
assert(assert_count_ctr == assert_count_exp);
}

View File

@ -0,0 +1,128 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <kernaux/free_list.h>
#include <kernaux/memmap.h>
#include <kernaux/multiboot2.h>
#include <assert.h>
#include <stddef.h>
#include <string.h>
#include "../fixtures/multiboot2_info_example0.h"
#include "../fixtures/multiboot2_info_example1.h"
#include "../fixtures/multiboot2_info_example2.h"
static char buffer[4096];
static void test_examples_1_and_2(KernAux_Memmap_Node node);
void test_main()
{
struct KernAux_FreeList malloc = KernAux_FreeList_create(NULL);
KernAux_FreeList_add_zone(&malloc, buffer, sizeof(buffer));
{
const KernAux_Memmap_Builder builder =
KernAux_Multiboot2_Info_to_memmap_builder(
&multiboot2_info_example0.multiboot2_info,
&malloc.malloc
);
assert(builder == NULL);
}
{
const KernAux_Memmap_Builder builder =
KernAux_Multiboot2_Info_to_memmap_builder(
(const struct KernAux_Multiboot2_Info*)
&multiboot2_info_example1,
&malloc.malloc
);
assert(builder);
const KernAux_Memmap memmap =
KernAux_Memmap_Builder_finish_and_free(builder);
assert(memmap);
test_examples_1_and_2(memmap->root_node);
KernAux_Memmap_free(memmap);
}
{
const KernAux_Memmap_Builder builder =
KernAux_Multiboot2_Info_to_memmap_builder(
&multiboot2_info_example2.multiboot2_info,
&malloc.malloc
);
assert(builder);
const KernAux_Memmap memmap =
KernAux_Memmap_Builder_finish_and_free(builder);
assert(memmap);
test_examples_1_and_2(memmap->root_node);
KernAux_Memmap_free(memmap);
}
}
void test_examples_1_and_2(KernAux_Memmap_Node node)
{
assert(node);
assert(node->mem_start == 0x0);
assert(node->mem_size == 0xffffffffffffffff);
assert(node->mem_end == 0xffffffffffffffff);
assert(node->tag == NULL);
assert(node->next == NULL);
node = node->children;
assert(node);
assert(node->mem_start == 0x0);
assert(node->mem_size == 654336);
assert(node->mem_end == 0x9fbff);
assert(strcmp(node->tag, "available") == 0);
assert(node->children == NULL);
node = node->next;
assert(node);
assert(node->mem_start == 0x9fc00);
assert(node->mem_size == 1024);
assert(node->mem_end == 0x9ffff);
assert(strcmp(node->tag, "reserved") == 0);
assert(node->children == NULL);
node = node->next;
assert(node);
assert(node->mem_start == 0xf0000);
assert(node->mem_size == 65536);
assert(node->mem_end == 0xfffff);
assert(strcmp(node->tag, "reserved") == 0);
assert(node->children == NULL);
node = node->next;
assert(node);
assert(node->mem_start == 0x100000);
assert(node->mem_size == 133038080);
assert(node->mem_end == 0x7fdffff);
assert(strcmp(node->tag, "available") == 0);
assert(node->children == NULL);
node = node->next;
assert(node);
assert(node->mem_start == 0x7fe0000);
assert(node->mem_size == 131072);
assert(node->mem_end == 0x7ffffff);
assert(strcmp(node->tag, "reserved") == 0);
assert(node->children == NULL);
node = node->next;
assert(node);
assert(node->mem_start == 0xfffc0000);
assert(node->mem_size == 262144);
assert(node->mem_end == 0xffffffff);
assert(strcmp(node->tag, "reserved") == 0);
assert(node->children == NULL);
node = node->next;
assert(node == NULL);
}

View File

@ -2,8 +2,8 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include <kernaux/ntoa.h>
#include <kernaux/runtime.h>
#include <assert.h>
#include <setjmp.h>

View File

@ -2,9 +2,9 @@
#include "config.h"
#endif
#include <kernaux/assert.h>
#include <kernaux/macro.h>
#include <kernaux/pfa.h>
#include <kernaux/runtime.h>
#include <assert.h>
#include <setjmp.h>