mirror of https://github.com/tailix/libkernaux.git
Compare commits
6 Commits
8bee6b424a
...
c1bf030159
Author | SHA1 | Date |
---|---|---|
Alex Kotov | c1bf030159 | |
Alex Kotov | 18f3c70c1b | |
Alex Kotov | be761bd9f7 | |
Alex Kotov | 0d8bdec847 | |
Alex Kotov | f3f34e9057 | |
Alex Kotov | 187475826e |
|
@ -8,10 +8,11 @@ main_freebsd_task:
|
||||||
name: Main (FreeBSD)
|
name: Main (FreeBSD)
|
||||||
only_if: $CIRRUS_BRANCH == 'master' || $CIRRUS_BASE_BRANCH == 'master'
|
only_if: $CIRRUS_BRANCH == 'master' || $CIRRUS_BASE_BRANCH == 'master'
|
||||||
dependencies_script:
|
dependencies_script:
|
||||||
- pkg install --yes autoconf automake libtool
|
- pkg install --yes autoconf automake cppcheck libtool libyaml py39-pip py39-wheel python3
|
||||||
|
- pip install --user Jinja2 PyYAML
|
||||||
main_build_script:
|
main_build_script:
|
||||||
- ./autogen.sh
|
- ./autogen.sh
|
||||||
- ./configure --enable-debug --enable-checks --enable-checks-pthreads CFLAGS='-O3'
|
- ./configure --enable-debug --enable-checks-all CFLAGS='-O3'
|
||||||
- make
|
- make
|
||||||
- sudo make install
|
- sudo make install
|
||||||
main_test_script:
|
main_test_script:
|
||||||
|
|
|
@ -76,7 +76,7 @@ jobs:
|
||||||
- name: autogen
|
- name: autogen
|
||||||
run: ./autogen.sh
|
run: ./autogen.sh
|
||||||
- name: configure
|
- name: configure
|
||||||
run: ./configure --host='${{matrix.cross.arch}}-unknown-elf' --enable-checks --enable-checks-pthreads --enable-checks-python AR='${{matrix.cross.cprefix}}ar' CC='${{matrix.cross.cprefix}}gcc' LD='${{matrix.cross.cprefix}}ld' RANLIB='${{matrix.cross.cprefix}}ranlib'
|
run: ./configure --host='${{matrix.cross.arch}}-unknown-elf' --enable-checks --enable-checks-pthreads --enable-checks-python CC='${{matrix.cross.cprefix}}gcc'
|
||||||
- name: make
|
- name: make
|
||||||
run: make
|
run: make
|
||||||
- name: check
|
- name: check
|
||||||
|
@ -121,7 +121,7 @@ jobs:
|
||||||
- name: autogen
|
- name: autogen
|
||||||
run: ./autogen.sh
|
run: ./autogen.sh
|
||||||
- name: configure
|
- name: configure
|
||||||
run: ./configure --host='i386-elf' ${{matrix.debug}} --enable-freestanding --with-libc AR="$(which i686-linux-gnu-ar)" CC="$(which i686-linux-gnu-gcc)" LD="$(which i686-linux-gnu-ld)" RANLIB="$(which i686-linux-gnu-ranlib)"
|
run: ./configure --host='i386-elf' ${{matrix.debug}} --enable-freestanding --with-libc CC="$(which i686-linux-gnu-gcc)"
|
||||||
- name: make
|
- name: make
|
||||||
run: make
|
run: make
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,8 @@ jobs:
|
||||||
run: make
|
run: make
|
||||||
- name: install
|
- name: install
|
||||||
run: sudo make install
|
run: sudo make install
|
||||||
|
- name: ldconfig
|
||||||
|
run: sudo ldconfig
|
||||||
- working-directory: vendor/mruby
|
- working-directory: vendor/mruby
|
||||||
name: test
|
name: test
|
||||||
run: MRUBY_CONFIG=../../bindings/mruby/build_config.rb rake test
|
run: MRUBY_CONFIG=../../bindings/mruby/build_config.rb rake test
|
||||||
|
|
|
@ -33,6 +33,8 @@ jobs:
|
||||||
run: make
|
run: make
|
||||||
- name: install
|
- name: install
|
||||||
run: sudo make install
|
run: sudo make install
|
||||||
|
- name: ldconfig
|
||||||
|
run: sudo ldconfig
|
||||||
- working-directory: bindings/ruby
|
- working-directory: bindings/ruby
|
||||||
name: setup
|
name: setup
|
||||||
run: ./bin/setup
|
run: ./bin/setup
|
||||||
|
|
|
@ -32,6 +32,8 @@ jobs:
|
||||||
run: make
|
run: make
|
||||||
- name: install
|
- name: install
|
||||||
run: sudo make install
|
run: sudo make install
|
||||||
|
- name: ldconfig
|
||||||
|
run: sudo ldconfig
|
||||||
- working-directory: bindings/rust
|
- working-directory: bindings/rust
|
||||||
name: test
|
name: test
|
||||||
run: cargo test ${{matrix.packages.cargo}}
|
run: cargo test ${{matrix.packages.cargo}}
|
||||||
|
|
|
@ -57,6 +57,15 @@
|
||||||
/libtool
|
/libtool
|
||||||
/stamp-h1
|
/stamp-h1
|
||||||
|
|
||||||
|
# Temporary
|
||||||
|
/confcache
|
||||||
|
/confdefs.h
|
||||||
|
/confinc.mk
|
||||||
|
/confmf.BSD
|
||||||
|
/confmf.GNU
|
||||||
|
/conftest.c
|
||||||
|
/conftest.err
|
||||||
|
|
||||||
/examples/test-suite.log
|
/examples/test-suite.log
|
||||||
/examples/*.log
|
/examples/*.log
|
||||||
/examples/*.trs
|
/examples/*.trs
|
||||||
|
@ -97,8 +106,10 @@
|
||||||
/examples/printf_str_va
|
/examples/printf_str_va
|
||||||
/examples/units_human
|
/examples/units_human
|
||||||
|
|
||||||
|
/tests/multiboot2_header_print0
|
||||||
/tests/multiboot2_header_print1
|
/tests/multiboot2_header_print1
|
||||||
/tests/multiboot2_header_print2
|
/tests/multiboot2_header_print2
|
||||||
|
/tests/multiboot2_info_print0
|
||||||
/tests/multiboot2_info_print1
|
/tests/multiboot2_info_print1
|
||||||
/tests/multiboot2_info_print2
|
/tests/multiboot2_info_print2
|
||||||
/tests/test_arch_i386
|
/tests/test_arch_i386
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
# We use sourcehut CI (https://builds.sr.ht) to test on OpenBSD.
|
||||||
|
# For GNU/Linux CI see GitHub Actions.
|
||||||
|
|
||||||
|
image: openbsd/7.2
|
||||||
|
arch: amd64
|
||||||
|
sources:
|
||||||
|
- https://github.com/tailix/libkernaux.git
|
||||||
|
packages:
|
||||||
|
- autoconf-2.71
|
||||||
|
- automake-1.16.5
|
||||||
|
- cppcheck
|
||||||
|
- libyaml
|
||||||
|
- m4
|
||||||
|
- py3-pip
|
||||||
|
- py3-wheel
|
||||||
|
- python3
|
||||||
|
- wget
|
||||||
|
environment:
|
||||||
|
AUTOCONF_VERSION: '2.71'
|
||||||
|
AUTOMAKE_VERSION: '1.16'
|
||||||
|
tasks:
|
||||||
|
- libtool: |
|
||||||
|
wget https://ftpmirror.gnu.org/libtool/libtool-2.4.7.tar.gz
|
||||||
|
tar -xzf libtool-2.4.7.tar.gz
|
||||||
|
cd libtool-2.4.7
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
doas make install
|
||||||
|
- dependencies: |
|
||||||
|
pip3 install --user Jinja2 PyYAML
|
||||||
|
- build: |
|
||||||
|
cd libkernaux
|
||||||
|
./autogen.sh
|
||||||
|
./configure --enable-debug --enable-checks-all CFLAGS='-O3'
|
||||||
|
make
|
||||||
|
doas make install
|
||||||
|
- test: |
|
||||||
|
cd libkernaux
|
||||||
|
make check
|
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
||||||
|
2022-12-16 Alex Kotov <kotovalexarian@gmail.com>
|
||||||
|
|
||||||
|
* configure.ac: Feature "--with[out]-multiboot2" has been added
|
||||||
|
* include/kernaux/multiboot2.h: Has been made stable
|
||||||
|
|
||||||
|
2022-12-14 Alex Kotov <kotovalexarian@gmail.com>
|
||||||
|
|
||||||
|
* configure.ac: Enable shared library
|
||||||
|
|
||||||
|
2022-12-13 Alex Kotov <kotovalexarian@gmail.com>
|
||||||
|
|
||||||
|
* tests/Makefile.am: Fix FreeBSD builds
|
||||||
|
|
||||||
2022-12-12 Alex Kotov <kotovalexarian@gmail.com>
|
2022-12-12 Alex Kotov <kotovalexarian@gmail.com>
|
||||||
|
|
||||||
* examples/Makefile.am: Fix builds without pthreads
|
* examples/Makefile.am: Fix builds without pthreads
|
||||||
|
|
|
@ -28,6 +28,7 @@ lib_LTLIBRARIES = libkernaux.la
|
||||||
# Required files #
|
# Required files #
|
||||||
##################
|
##################
|
||||||
|
|
||||||
|
libkernaux_la_LDFLAGS = -version-info @PACKAGE_VERSION_SO@
|
||||||
libkernaux_la_LIBADD =
|
libkernaux_la_LIBADD =
|
||||||
libkernaux_la_SOURCES = \
|
libkernaux_la_SOURCES = \
|
||||||
src/assert.c \
|
src/assert.c \
|
||||||
|
@ -92,7 +93,6 @@ libkernaux_la_SOURCES += \
|
||||||
src/multiboot2/header_helpers.c \
|
src/multiboot2/header_helpers.c \
|
||||||
src/multiboot2/header_is_valid.c \
|
src/multiboot2/header_is_valid.c \
|
||||||
src/multiboot2/header_print.c \
|
src/multiboot2/header_print.c \
|
||||||
src/multiboot2/info_convert.c \
|
|
||||||
src/multiboot2/info_helpers.c \
|
src/multiboot2/info_helpers.c \
|
||||||
src/multiboot2/info_is_valid.c \
|
src/multiboot2/info_is_valid.c \
|
||||||
src/multiboot2/info_print.c
|
src/multiboot2/info_print.c
|
||||||
|
|
12
README.md
12
README.md
|
@ -66,7 +66,7 @@ zero). Work-in-progress APIs can change at any time.
|
||||||
* Data formats
|
* Data formats
|
||||||
* [ELF](/include/kernaux/elf.h) (*work in progress*)
|
* [ELF](/include/kernaux/elf.h) (*work in progress*)
|
||||||
* [MBR](/include/kernaux/mbr.h) (*work in progress*)
|
* [MBR](/include/kernaux/mbr.h) (*work in progress*)
|
||||||
* [Multiboot 2 (GRUB 2)](/include/kernaux/multiboot2.h.in) (*work in progress*)
|
* [Multiboot 2 (GRUB 2)](/include/kernaux/multiboot2.h.in) (*non-breaking since* **?.?.?**)
|
||||||
* [Example: header macros](/examples/multiboot2_header_macro.c)
|
* [Example: header macros](/examples/multiboot2_header_macro.c)
|
||||||
* Utilities
|
* Utilities
|
||||||
* [Measurement units utils](/include/kernaux/units.h) (*work in progress*)
|
* [Measurement units utils](/include/kernaux/units.h) (*work in progress*)
|
||||||
|
@ -169,6 +169,7 @@ explicitly included, use `--without-all`.
|
||||||
* `--with[out]-cmdline` - command line parser
|
* `--with[out]-cmdline` - command line parser
|
||||||
* `--with[out]-free-list` - free list memory allocator
|
* `--with[out]-free-list` - free list memory allocator
|
||||||
* `--with[out]-memmap` - memory map
|
* `--with[out]-memmap` - memory map
|
||||||
|
* `--with[out]-multiboot2` - Multiboot 2 utils
|
||||||
* `--with[out]-ntoa` - itoa/ftoa
|
* `--with[out]-ntoa` - itoa/ftoa
|
||||||
* `--with[out]-printf` - printf
|
* `--with[out]-printf` - printf
|
||||||
|
|
||||||
|
@ -184,6 +185,7 @@ Tips
|
||||||
./configure
|
./configure
|
||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
|
sudo ldconfig # on GNU/Linux
|
||||||
```
|
```
|
||||||
|
|
||||||
This is just a usual library. You can use most of it's APIs in hosted
|
This is just a usual library. You can use most of it's APIs in hosted
|
||||||
|
@ -210,13 +212,15 @@ without it in `$PATH`:
|
||||||
```
|
```
|
||||||
./configure \
|
./configure \
|
||||||
--host='i386-elf' \
|
--host='i386-elf' \
|
||||||
|
--disable-shared \
|
||||||
--enable-freestanding \
|
--enable-freestanding \
|
||||||
--with-libc \
|
--with-libc \
|
||||||
AR="$(which i386-elf-ar)" \
|
CC="$(which i386-elf-gcc)"
|
||||||
CC="$(which i386-elf-gcc)" \
|
|
||||||
RANLIB="$(which i386-elf-ranlib)"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The variables include `AR`, `AS`, `CC`, `CCAS`, `LD`, `NM`, `OBJDUMP`, `RANLIB`,
|
||||||
|
`STRIP`. See the generated `config.log` for more information.
|
||||||
|
|
||||||
To install into specific directory use full path: `DESTDIR="$(pwd)/dest" make
|
To install into specific directory use full path: `DESTDIR="$(pwd)/dest" make
|
||||||
install` instead of `DESTDIR=dest make install`.
|
install` instead of `DESTDIR=dest make install`.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
0:0:0
|
|
@ -27,7 +27,11 @@ Metrics/BlockLength:
|
||||||
|
|
||||||
Metrics/BlockNesting:
|
Metrics/BlockNesting:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'test/printf.rb'
|
- 'test/sprintf.rb'
|
||||||
|
|
||||||
|
Performance/CollectionLiteralInLoop:
|
||||||
|
Exclude:
|
||||||
|
- 'test/**/*.rb'
|
||||||
|
|
||||||
Security/Eval:
|
Security/Eval:
|
||||||
Exclude:
|
Exclude:
|
||||||
|
|
|
@ -2,4 +2,5 @@ MRuby::Build.new do |conf|
|
||||||
conf.toolchain
|
conf.toolchain
|
||||||
conf.enable_test
|
conf.enable_test
|
||||||
conf.gem '.'
|
conf.gem '.'
|
||||||
|
conf.gem core: 'mruby-bin-mirb'
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,24 +7,6 @@ module KernAux
|
||||||
raise AssertError, "#{file}:#{line}:#{msg}"
|
raise AssertError, "#{file}:#{line}:#{msg}"
|
||||||
}
|
}
|
||||||
|
|
||||||
SPRINTF1_BUFFER_SIZE = 10_000
|
|
||||||
|
|
||||||
if Version.with_printf?
|
|
||||||
def self.sprintf(*args)
|
|
||||||
args.map do |arg|
|
|
||||||
if arg.is_a? Array
|
|
||||||
sprintf1(*arg)
|
|
||||||
else
|
|
||||||
arg
|
|
||||||
end
|
|
||||||
end.join.freeze
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.sprintf1(format, *args)
|
|
||||||
snprintf1(SPRINTF1_BUFFER_SIZE, format, *args).first
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Error < RuntimeError; end
|
class Error < RuntimeError; end
|
||||||
class AssertError < Error; end
|
class AssertError < Error; end
|
||||||
class CmdlineError < Error; end
|
class CmdlineError < Error; end
|
||||||
|
|
|
@ -1,155 +1,147 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
#include "dynarg.h"
|
#include "dynarg.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <mruby/array.h>
|
#include <mruby/array.h>
|
||||||
#include <mruby/error.h>
|
#include <mruby/error.h>
|
||||||
#include <mruby/presym.h>
|
#include <mruby/presym.h>
|
||||||
#include <mruby/string.h>
|
#include <mruby/string.h>
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 4096
|
||||||
|
|
||||||
#ifdef KERNAUX_VERSION_WITH_PRINTF
|
#ifdef KERNAUX_VERSION_WITH_PRINTF
|
||||||
|
|
||||||
struct snprintf1_userdata {
|
static mrb_value rb_KernAux_sprintf(mrb_state *mrb, mrb_value self);
|
||||||
const struct KernAux_PrintfFmt_Spec *spec;
|
|
||||||
const struct DynArg *dynarg;
|
|
||||||
mrb_int size;
|
|
||||||
const char *format;
|
|
||||||
char *str;
|
|
||||||
};
|
|
||||||
|
|
||||||
static mrb_value rb_KernAux_snprintf1(mrb_state *mrb, mrb_value self);
|
|
||||||
|
|
||||||
static mrb_value snprintf1_protect(mrb_state *mrb, void *userdata);
|
|
||||||
|
|
||||||
void init_printf(mrb_state *const mrb)
|
void init_printf(mrb_state *const mrb)
|
||||||
{
|
{
|
||||||
struct RClass *const rb_KernAux = mrb_module_get_id(mrb, MRB_SYM(KernAux));
|
struct RClass *const rb_KernAux = mrb_module_get_id(mrb, MRB_SYM(KernAux));
|
||||||
|
|
||||||
mrb_define_class_method(mrb, rb_KernAux, "snprintf1", rb_KernAux_snprintf1,
|
mrb_define_class_method(mrb, rb_KernAux, "sprintf", rb_KernAux_sprintf,
|
||||||
MRB_ARGS_REQ(2) | MRB_ARGS_OPT(2));
|
MRB_ARGS_REQ(1) | MRB_ARGS_REST());
|
||||||
}
|
}
|
||||||
|
|
||||||
mrb_value rb_KernAux_snprintf1(mrb_state *const mrb, mrb_value self)
|
#define TAKE_ARG \
|
||||||
|
if (arg_index >= argc) { \
|
||||||
|
mrb_raise(mrb, E_ARGUMENT_ERROR, "too few arguments"); \
|
||||||
|
} \
|
||||||
|
mrb_value arg_rb = args[arg_index++]; \
|
||||||
|
do {} while (0)
|
||||||
|
|
||||||
|
mrb_value rb_KernAux_sprintf(mrb_state *const mrb, mrb_value self)
|
||||||
{
|
{
|
||||||
mrb_int size = 0;
|
// FIXME: const
|
||||||
const char *format = NULL;
|
char *format;
|
||||||
mrb_value rest[3];
|
mrb_value *args;
|
||||||
mrb_bool rest_given[3];
|
mrb_int argc;
|
||||||
|
mrb_get_args(mrb, "z*", &format, &args, &argc);
|
||||||
mrb_get_args(
|
|
||||||
mrb,
|
|
||||||
"iz|o?o?o?",
|
|
||||||
&size,
|
|
||||||
&format,
|
|
||||||
&rest[0], &rest_given[0],
|
|
||||||
&rest[1], &rest_given[1],
|
|
||||||
&rest[2], &rest_given[2]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (size < 0) mrb_raise(mrb, E_RANGE_ERROR, "expected non-negative size");
|
|
||||||
|
|
||||||
const char *fmt = format;
|
|
||||||
|
|
||||||
while (*fmt && *fmt != '%') ++fmt;
|
|
||||||
if (*(fmt++) != '%') mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format");
|
|
||||||
|
|
||||||
struct KernAux_PrintfFmt_Spec spec = KernAux_PrintfFmt_Spec_create_out(&fmt);
|
|
||||||
|
|
||||||
while (*fmt) {
|
|
||||||
if (*(fmt++) == '%') mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format");
|
|
||||||
}
|
|
||||||
|
|
||||||
int argc = 0;
|
|
||||||
for (int i = 0; i < 3; ++i) if (rest_given[i]) ++argc;
|
|
||||||
|
|
||||||
int arg_index = 0;
|
int arg_index = 0;
|
||||||
if (spec.set_width && argc > arg_index) {
|
mrb_value result = mrb_str_new_lit(mrb, "");
|
||||||
KernAux_PrintfFmt_Spec_set_width(&spec, mrb_integer(rest[arg_index++]));
|
|
||||||
}
|
|
||||||
if (spec.set_precision && argc > arg_index) {
|
|
||||||
KernAux_PrintfFmt_Spec_set_precision(&spec, mrb_integer(rest[arg_index++]));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DynArg dynarg = DynArg_create();
|
while (*format) {
|
||||||
if (argc > arg_index) {
|
if (*format != '%') {
|
||||||
mrb_value arg_rb = rest[arg_index];
|
mrb_str_cat(mrb, result, format, 1);
|
||||||
|
++format;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: unnecessary
|
||||||
|
const char *const old_format = format;
|
||||||
|
++format;
|
||||||
|
struct KernAux_PrintfFmt_Spec spec =
|
||||||
|
// FIXME: no type cast
|
||||||
|
KernAux_PrintfFmt_Spec_create_out((const char**)&format);
|
||||||
|
|
||||||
|
if (spec.set_width) {
|
||||||
|
TAKE_ARG;
|
||||||
|
KernAux_PrintfFmt_Spec_set_width(&spec, mrb_integer(arg_rb));
|
||||||
|
}
|
||||||
|
if (spec.set_precision) {
|
||||||
|
TAKE_ARG;
|
||||||
|
KernAux_PrintfFmt_Spec_set_precision(&spec, mrb_integer(arg_rb));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DynArg dynarg = DynArg_create();
|
||||||
|
|
||||||
if (spec.type == KERNAUX_PRINTF_FMT_TYPE_INT) {
|
if (spec.type == KERNAUX_PRINTF_FMT_TYPE_INT) {
|
||||||
|
TAKE_ARG;
|
||||||
|
mrb_ensure_int_type(mrb, arg_rb);
|
||||||
DynArg_use_long_long(&dynarg, mrb_integer(arg_rb));
|
DynArg_use_long_long(&dynarg, mrb_integer(arg_rb));
|
||||||
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_UINT) {
|
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_UINT) {
|
||||||
mrb_int arg = mrb_integer(arg_rb);
|
TAKE_ARG;
|
||||||
if (arg < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "expected non-negative argument");
|
mrb_ensure_int_type(mrb, arg_rb);
|
||||||
DynArg_use_unsigned_long_long(&dynarg, arg);
|
DynArg_use_unsigned_long_long(&dynarg, mrb_integer(arg_rb));
|
||||||
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_FLOAT ||
|
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_FLOAT ||
|
||||||
spec.type == KERNAUX_PRINTF_FMT_TYPE_EXP)
|
spec.type == KERNAUX_PRINTF_FMT_TYPE_EXP)
|
||||||
{
|
{
|
||||||
DynArg_use_double(&dynarg, mrb_as_float(mrb, arg_rb));
|
TAKE_ARG;
|
||||||
|
mrb_ensure_float_type(mrb, arg_rb);
|
||||||
|
DynArg_use_double(&dynarg, mrb_float(arg_rb));
|
||||||
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_CHAR) {
|
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_CHAR) {
|
||||||
DynArg_use_char(&dynarg, *RSTRING_CSTR(mrb, arg_rb));
|
TAKE_ARG;
|
||||||
|
mrb_ensure_string_type(mrb, arg_rb);
|
||||||
|
DynArg_use_char(&dynarg, *RSTRING_PTR(arg_rb));
|
||||||
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_STR) {
|
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_STR) {
|
||||||
|
TAKE_ARG;
|
||||||
|
mrb_ensure_string_type(mrb, arg_rb);
|
||||||
DynArg_use_str(&dynarg, RSTRING_CSTR(mrb, arg_rb));
|
DynArg_use_str(&dynarg, RSTRING_CSTR(mrb, arg_rb));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
char *const str = malloc(size);
|
char buffer[BUFFER_SIZE];
|
||||||
if (!str) mrb_raise(mrb, mrb_exc_get_id(mrb, MRB_ERROR_SYM(NoMemoryError)), "snprintf1 buffer malloc");
|
int slen;
|
||||||
|
|
||||||
struct snprintf1_userdata userdata = {
|
// FIXME: it's a hack
|
||||||
.spec = &spec,
|
// TODO: convert printf format spec to string
|
||||||
.dynarg = &dynarg,
|
const char tmp = *format;
|
||||||
.size = size,
|
*format = '\0';
|
||||||
.format = format,
|
|
||||||
.str = str,
|
|
||||||
};
|
|
||||||
mrb_bool error;
|
|
||||||
mrb_value result = mrb_protect_error(mrb, snprintf1_protect, &userdata, &error);
|
|
||||||
|
|
||||||
free(str);
|
if (spec.set_width) {
|
||||||
|
if (spec.set_precision) {
|
||||||
if (error) {
|
if (dynarg.use_dbl) {
|
||||||
mrb_exc_raise(mrb, result);
|
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||||
} else {
|
spec.width, spec.precision,
|
||||||
return result;
|
dynarg.dbl);
|
||||||
}
|
} else {
|
||||||
}
|
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||||
|
spec.width, spec.precision,
|
||||||
mrb_value snprintf1_protect(mrb_state *const mrb, void *const userdata_raw)
|
dynarg.arg);
|
||||||
{
|
}
|
||||||
const struct snprintf1_userdata *const userdata = userdata_raw;
|
} else {
|
||||||
|
if (dynarg.use_dbl) {
|
||||||
int slen;
|
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||||
if (userdata->spec->set_width) {
|
spec.width, dynarg.dbl);
|
||||||
if (userdata->spec->set_precision) {
|
} else {
|
||||||
slen = userdata->dynarg->use_dbl
|
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||||
? kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->spec->width, userdata->spec->precision, userdata->dynarg->dbl)
|
spec.width, dynarg.arg);
|
||||||
: kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->spec->width, userdata->spec->precision, userdata->dynarg->arg);
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
slen = userdata->dynarg->use_dbl
|
if (spec.set_precision) {
|
||||||
? kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->spec->width, userdata->dynarg->dbl)
|
if (dynarg.use_dbl) {
|
||||||
: kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->spec->width, userdata->dynarg->arg);
|
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||||
}
|
spec.precision, dynarg.dbl);
|
||||||
} else {
|
} else {
|
||||||
if (userdata->spec->set_precision) {
|
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||||
slen = userdata->dynarg->use_dbl
|
spec.precision, dynarg.arg);
|
||||||
? kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->spec->precision, userdata->dynarg->dbl)
|
}
|
||||||
: kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->spec->precision, userdata->dynarg->arg);
|
} else {
|
||||||
} else {
|
if (dynarg.use_dbl) {
|
||||||
slen = userdata->dynarg->use_dbl
|
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format, dynarg.dbl);
|
||||||
? kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->dynarg->dbl)
|
} else {
|
||||||
: kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->dynarg->arg);
|
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format, dynarg.arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*format = tmp;
|
||||||
|
mrb_str_cat(mrb, result, buffer, slen);
|
||||||
}
|
}
|
||||||
|
|
||||||
mrb_value output_rb =
|
if (arg_index < argc) {
|
||||||
mrb_obj_freeze(mrb, mrb_str_cat_cstr(mrb, mrb_str_new_lit(mrb, ""), userdata->str));
|
mrb_raise(mrb, E_ARGUMENT_ERROR, "too many arguments");
|
||||||
|
}
|
||||||
|
|
||||||
mrb_value values[2];
|
return mrb_obj_freeze(mrb, result);
|
||||||
values[0] = output_rb;
|
|
||||||
values[1] = mrb_fixnum_value(slen);
|
|
||||||
return mrb_obj_freeze(mrb, mrb_ary_new_from_values(mrb, 2, values));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // KERNAUX_VERSION_WITH_PRINTF
|
#endif // KERNAUX_VERSION_WITH_PRINTF
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
if KernAux::Version.with_printf?
|
|
||||||
assert 'KernAux.sprintf' do
|
|
||||||
assert 'integers' do
|
|
||||||
assert_equal 'i:0', KernAux.sprintf('i:', ['%i', 0])
|
|
||||||
assert_equal 'u:0', KernAux.sprintf('u:', ['%u', 0])
|
|
||||||
assert_equal 'i:1', KernAux.sprintf('i:', ['%i', 1])
|
|
||||||
assert_equal 'u:1', KernAux.sprintf('u:', ['%u', 1])
|
|
||||||
assert_equal 'i:10', KernAux.sprintf('i:', ['%i', 10])
|
|
||||||
assert_equal 'u:10', KernAux.sprintf('u:', ['%u', 10])
|
|
||||||
assert_equal 'i:100', KernAux.sprintf('i:', ['%i', 100])
|
|
||||||
assert_equal 'u:100', KernAux.sprintf('u:', ['%u', 100])
|
|
||||||
assert_equal 'i:1000', KernAux.sprintf('i:', ['%i', 1000])
|
|
||||||
assert_equal 'u:1000', KernAux.sprintf('u:', ['%u', 1000])
|
|
||||||
assert_equal 'i:10000', KernAux.sprintf('i:', ['%i', 10_000])
|
|
||||||
assert_equal 'u:10000', KernAux.sprintf('u:', ['%u', 10_000])
|
|
||||||
assert_equal 'i:100000', KernAux.sprintf('i:', ['%i', 100_000])
|
|
||||||
assert_equal 'u:100000', KernAux.sprintf('u:', ['%u', 100_000])
|
|
||||||
assert_equal 'i:1000000', KernAux.sprintf('i:', ['%i', 1_000_000])
|
|
||||||
assert_equal 'u:1000000', KernAux.sprintf('u:', ['%u', 1_000_000])
|
|
||||||
assert_equal 'i:10000000', KernAux.sprintf('i:', ['%i', 10_000_000])
|
|
||||||
assert_equal 'u:10000000', KernAux.sprintf('u:', ['%u', 10_000_000])
|
|
||||||
assert_equal 'i:100000000', KernAux.sprintf('i:', ['%i', 10**8])
|
|
||||||
assert_equal 'u:100000000', KernAux.sprintf('u:', ['%u', 10**8])
|
|
||||||
assert_equal 'i:1000000000', KernAux.sprintf('i:', ['%i', 10**9])
|
|
||||||
assert_equal 'u:1000000000', KernAux.sprintf('u:', ['%u', 10**9])
|
|
||||||
assert_equal 'i:2147483647', KernAux.sprintf('i:', ['%i', 2**31 - 1])
|
|
||||||
assert_equal 'u:2147483647', KernAux.sprintf('u:', ['%u', 2**31 - 1])
|
|
||||||
end
|
|
||||||
|
|
||||||
# TODO: test with different boxing
|
|
||||||
# assert 'integer overflows' do
|
|
||||||
# assert_equal 'i:-2147483648', KernAux.sprintf('i:', ['%i', 2**31])
|
|
||||||
# assert_equal 'u: 2147483648', KernAux.sprintf('u: ', ['%u', 2**31])
|
|
||||||
# assert_equal 'i:-2147483647', KernAux.sprintf('i:', ['%i', 2**31 + 1])
|
|
||||||
# assert_equal 'u: 2147483649', KernAux.sprintf('u: ', ['%u', 2**31 + 1])
|
|
||||||
# assert_equal 'i:-1', KernAux.sprintf('i:', ['%i', 2**32 - 1])
|
|
||||||
# assert_equal 'u: 4294967295', KernAux.sprintf('u: ', ['%u', 2**32 - 1])
|
|
||||||
# assert_equal 'i: 0', KernAux.sprintf('i: ', ['%i', 2**32])
|
|
||||||
# assert_equal 'u: 0', KernAux.sprintf('u: ', ['%u', 2**32])
|
|
||||||
# end
|
|
||||||
|
|
||||||
[
|
|
||||||
['', 'using regular tests'],
|
|
||||||
['_orig', 'using original tests'],
|
|
||||||
].each do |(suffix, description)|
|
|
||||||
assert description do
|
|
||||||
printf_yml =
|
|
||||||
File.expand_path("../../../../common/printf#{suffix}.yml", __FILE__)
|
|
||||||
|
|
||||||
YAML.load(File.read(printf_yml)).each do |test|
|
|
||||||
expected = test['result']
|
|
||||||
|
|
||||||
args = test['args'].map do |arg|
|
|
||||||
if arg.is_a? String
|
|
||||||
arg
|
|
||||||
else
|
|
||||||
arg.map do |item|
|
|
||||||
if item.is_a? Array
|
|
||||||
if item.length == 1
|
|
||||||
item[0]
|
|
||||||
elsif item[0] == 'long long'
|
|
||||||
item[1]
|
|
||||||
else
|
|
||||||
raise "Unknown format: #{args.inspect}"
|
|
||||||
end
|
|
||||||
elsif item.is_a?(Float) && item.round == item
|
|
||||||
item.round
|
|
||||||
else
|
|
||||||
item
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assert "transforms #{args.inspect} to #{expected.inspect}" do
|
|
||||||
assert_equal expected, KernAux.sprintf(*args)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
if KernAux::Version.with_printf?
|
||||||
|
assert 'KernAux.sprintf' do
|
||||||
|
assert 'integers' do
|
||||||
|
assert_equal 'i:0', KernAux.sprintf('i:%i', 0)
|
||||||
|
assert_equal 'u:0', KernAux.sprintf('u:%u', 0)
|
||||||
|
assert_equal 'i:1', KernAux.sprintf('i:%i', 1)
|
||||||
|
assert_equal 'u:1', KernAux.sprintf('u:%u', 1)
|
||||||
|
assert_equal 'i:10', KernAux.sprintf('i:%i', 10)
|
||||||
|
assert_equal 'u:10', KernAux.sprintf('u:%u', 10)
|
||||||
|
assert_equal 'i:100', KernAux.sprintf('i:%i', 100)
|
||||||
|
assert_equal 'u:100', KernAux.sprintf('u:%u', 100)
|
||||||
|
assert_equal 'i:1000', KernAux.sprintf('i:%i', 1000)
|
||||||
|
assert_equal 'u:1000', KernAux.sprintf('u:%u', 1000)
|
||||||
|
assert_equal 'i:10000', KernAux.sprintf('i:%i', 10_000)
|
||||||
|
assert_equal 'u:10000', KernAux.sprintf('u:%u', 10_000)
|
||||||
|
assert_equal 'i:100000', KernAux.sprintf('i:%i', 100_000)
|
||||||
|
assert_equal 'u:100000', KernAux.sprintf('u:%u', 100_000)
|
||||||
|
assert_equal 'i:1000000', KernAux.sprintf('i:%i', 1_000_000)
|
||||||
|
assert_equal 'u:1000000', KernAux.sprintf('u:%u', 1_000_000)
|
||||||
|
assert_equal 'i:10000000', KernAux.sprintf('i:%i', 10_000_000)
|
||||||
|
assert_equal 'u:10000000', KernAux.sprintf('u:%u', 10_000_000)
|
||||||
|
assert_equal 'i:100000000', KernAux.sprintf('i:%i', 10**8)
|
||||||
|
assert_equal 'u:100000000', KernAux.sprintf('u:%u', 10**8)
|
||||||
|
assert_equal 'i:1000000000', KernAux.sprintf('i:%i', 10**9)
|
||||||
|
assert_equal 'u:1000000000', KernAux.sprintf('u:%u', 10**9)
|
||||||
|
assert_equal 'i:2147483647', KernAux.sprintf('i:%i', 2**31 - 1)
|
||||||
|
assert_equal 'u:2147483647', KernAux.sprintf('u:%u', 2**31 - 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO: test with different boxing
|
||||||
|
# assert 'integer overflows' do
|
||||||
|
# assert_equal 'i:-2147483648', KernAux.sprintf('i:%i', 2**31)
|
||||||
|
# assert_equal 'u: 2147483648', KernAux.sprintf('u: %u', 2**31)
|
||||||
|
# assert_equal 'i:-2147483647', KernAux.sprintf('i:%i', 2**31 + 1)
|
||||||
|
# assert_equal 'u: 2147483649', KernAux.sprintf('u: %u', 2**31 + 1)
|
||||||
|
# assert_equal 'i:-1', KernAux.sprintf('i:%i', 2**32 - 1)
|
||||||
|
# assert_equal 'u: 4294967295', KernAux.sprintf('u: %u', 2**32 - 1)
|
||||||
|
# assert_equal 'i: 0', KernAux.sprintf('i: %i', 2**32)
|
||||||
|
# assert_equal 'u: 0', KernAux.sprintf('u: %u', 2**32)
|
||||||
|
# end
|
||||||
|
|
||||||
|
assert 'when there are too many arguments' do
|
||||||
|
[
|
||||||
|
['Hello!', 'World!'],
|
||||||
|
['Hello, %s!', 'World', 'Alex'],
|
||||||
|
].each do |args|
|
||||||
|
assert_raise ArgumentError, 'too many arguments' do
|
||||||
|
KernAux.sprintf(*args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert 'when there are too few arguments' do
|
||||||
|
[
|
||||||
|
[],
|
||||||
|
['Hello, %s!'],
|
||||||
|
['Hello, %*s!', 20],
|
||||||
|
['Hello, %.*s!', 20],
|
||||||
|
['Hello, %*.*s!', 20, 20],
|
||||||
|
].each do |args|
|
||||||
|
assert_raise ArgumentError, 'too few arguments' do
|
||||||
|
KernAux.sprintf(*args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
[
|
||||||
|
['', 'using regular tests'],
|
||||||
|
['_orig', 'using original tests'],
|
||||||
|
].each do |(suffix, description)|
|
||||||
|
assert description do
|
||||||
|
printf_yml =
|
||||||
|
File.expand_path("../../../../common/printf#{suffix}.yml", __FILE__)
|
||||||
|
|
||||||
|
YAML.load(File.read(printf_yml)).each do |test|
|
||||||
|
expected = test['result']
|
||||||
|
|
||||||
|
format = ''
|
||||||
|
args = []
|
||||||
|
|
||||||
|
test['args'].each do |arg|
|
||||||
|
if arg.is_a? String
|
||||||
|
format += arg
|
||||||
|
else
|
||||||
|
format += arg[0]
|
||||||
|
is_int_format = %w[i d u x X o b].any? { |s| arg[0].include? s }
|
||||||
|
arg[1..].each do |item|
|
||||||
|
if item.is_a? Array
|
||||||
|
if item.length == 1
|
||||||
|
args << item[0]
|
||||||
|
elsif item[0] == 'long long'
|
||||||
|
args << item[1]
|
||||||
|
else
|
||||||
|
raise "Unknown format: #{args.inspect}"
|
||||||
|
end
|
||||||
|
elsif is_int_format && item.is_a?(Float)
|
||||||
|
args << item.round
|
||||||
|
else
|
||||||
|
args << item
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert "transforms (#{format.inspect}, #{args.inspect[1...-1]}) " \
|
||||||
|
"to #{expected.inspect}" do
|
||||||
|
assert_equal expected, KernAux.sprintf(format, *args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,208 +1,140 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
#include "dynarg.h"
|
#include "dynarg.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
#define BUFFER_SIZE 4096
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#ifdef KERNAUX_VERSION_WITH_PRINTF
|
#ifdef KERNAUX_VERSION_WITH_PRINTF
|
||||||
|
|
||||||
/*************
|
/**
|
||||||
* ::KernAux *
|
* Typical `printf`.
|
||||||
*************/
|
*
|
||||||
|
* @param format [String] format string
|
||||||
static VALUE rb_KernAux_snprintf1(int argc, const VALUE *argv, VALUE self);
|
* @return [String] formatted output
|
||||||
|
*
|
||||||
static VALUE rb_KernAux_snprintf1_PROTECT(VALUE userdata);
|
* @example
|
||||||
|
* KernAux.sprintf 'foo%*scar%d', 5, 'bar', 123
|
||||||
/************************
|
* #=> "foo barcar123"
|
||||||
* ::KernAux::Snprintf1 *
|
*/
|
||||||
************************/
|
static VALUE rb_KernAux_sprintf(int argc, VALUE *argv, VALUE self);
|
||||||
|
|
||||||
static VALUE rb_KernAux_Snprintf1 = Qnil;
|
|
||||||
|
|
||||||
static size_t rb_KernAux_Snprintf1_DSIZE(const void *ptr);
|
|
||||||
|
|
||||||
const rb_data_type_t rb_KernAux_Snprintf1_DTYPE = {
|
|
||||||
.wrap_struct_name = "KernAux::Snprintf1",
|
|
||||||
.parent = NULL,
|
|
||||||
.data = NULL,
|
|
||||||
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
|
||||||
.function = {
|
|
||||||
.dfree = RUBY_DEFAULT_FREE,
|
|
||||||
.dsize = rb_KernAux_Snprintf1_DSIZE,
|
|
||||||
.dmark = NULL,
|
|
||||||
.dcompact = NULL,
|
|
||||||
.reserved = { 0 },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rb_KernAux_Snprintf1_DATA {
|
|
||||||
const struct KernAux_PrintfFmt_Spec *spec;
|
|
||||||
const struct DynArg *dynarg;
|
|
||||||
int size;
|
|
||||||
const char *format;
|
|
||||||
char *str;
|
|
||||||
};
|
|
||||||
|
|
||||||
/********
|
|
||||||
* Main *
|
|
||||||
********/
|
|
||||||
|
|
||||||
void init_printf()
|
void init_printf()
|
||||||
{
|
{
|
||||||
rb_gc_register_mark_object(
|
rb_define_singleton_method(rb_KernAux, "sprintf", rb_KernAux_sprintf, -1);
|
||||||
rb_KernAux_Snprintf1 =
|
|
||||||
// @api private
|
|
||||||
rb_define_class_under(rb_KernAux, "Snprintf1", rb_cObject));
|
|
||||||
rb_funcall(rb_KernAux, rb_intern("private_constant"), 1, ID2SYM(rb_intern("Snprintf1")));
|
|
||||||
|
|
||||||
rb_define_singleton_method(rb_KernAux, "snprintf1",
|
|
||||||
rb_KernAux_snprintf1, -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************
|
#define TAKE_ARG \
|
||||||
* ::KernAux *
|
if (arg_index >= argc) rb_raise(rb_eArgError, "too few arguments"); \
|
||||||
*************/
|
VALUE arg_rb = argv[arg_index++]; \
|
||||||
|
do {} while (0)
|
||||||
|
|
||||||
VALUE rb_KernAux_snprintf1(
|
VALUE rb_KernAux_sprintf(const int argc, VALUE *const argv, VALUE self)
|
||||||
const int argc,
|
{
|
||||||
const VALUE *const argv_rb,
|
if (argc == 0) rb_raise(rb_eArgError, "too few arguments");
|
||||||
const VALUE self KERNAUX_UNUSED
|
|
||||||
) {
|
|
||||||
if (argc < 2 || argc > 5) rb_raise(rb_eArgError, "expected 2, 3, 4 or 5 args");
|
|
||||||
|
|
||||||
const VALUE size_rb = argv_rb[0];
|
// FIXME: const
|
||||||
VALUE format_rb = argv_rb[1];
|
char *format = StringValueCStr(argv[0]);
|
||||||
|
int arg_index = 1;
|
||||||
|
VALUE result = rb_str_new_literal("");
|
||||||
|
|
||||||
const int size = NUM2INT(size_rb);
|
while (*format) {
|
||||||
const char *const format = StringValueCStr(format_rb);
|
if (*format != '%') {
|
||||||
|
rb_str_cat(result, format, 1);
|
||||||
|
++format;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (size < 0) rb_raise(rb_eRangeError, "expected non-negative size");
|
// FIXME: unnecessary
|
||||||
|
const char *const old_format = format;
|
||||||
|
++format;
|
||||||
|
struct KernAux_PrintfFmt_Spec spec =
|
||||||
|
// FIXME: no type cast
|
||||||
|
KernAux_PrintfFmt_Spec_create_out((const char**)&format);
|
||||||
|
|
||||||
const char *fmt = format;
|
if (spec.set_width) {
|
||||||
|
TAKE_ARG;
|
||||||
|
KernAux_PrintfFmt_Spec_set_width(&spec, NUM2INT(arg_rb));
|
||||||
|
}
|
||||||
|
if (spec.set_precision) {
|
||||||
|
TAKE_ARG;
|
||||||
|
KernAux_PrintfFmt_Spec_set_precision(&spec, NUM2INT(arg_rb));
|
||||||
|
}
|
||||||
|
|
||||||
while (*fmt && *fmt != '%') ++fmt;
|
struct DynArg dynarg = DynArg_create();
|
||||||
if (*(fmt++) != '%') rb_raise(rb_eArgError, "invalid format");
|
|
||||||
|
|
||||||
struct KernAux_PrintfFmt_Spec spec = KernAux_PrintfFmt_Spec_create_out(&fmt);
|
|
||||||
|
|
||||||
while (*fmt) {
|
|
||||||
if (*(fmt++) == '%') rb_raise(rb_eArgError, "invalid format");
|
|
||||||
}
|
|
||||||
|
|
||||||
int arg_index = 2;
|
|
||||||
if (spec.set_width && argc > arg_index) {
|
|
||||||
KernAux_PrintfFmt_Spec_set_width(&spec, NUM2INT(argv_rb[arg_index++]));
|
|
||||||
}
|
|
||||||
if (spec.set_precision && argc > arg_index) {
|
|
||||||
KernAux_PrintfFmt_Spec_set_precision(&spec, NUM2INT(argv_rb[arg_index++]));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DynArg dynarg = DynArg_create();
|
|
||||||
if (argc > arg_index) {
|
|
||||||
VALUE arg_rb = argv_rb[arg_index];
|
|
||||||
|
|
||||||
if (spec.type == KERNAUX_PRINTF_FMT_TYPE_INT) {
|
if (spec.type == KERNAUX_PRINTF_FMT_TYPE_INT) {
|
||||||
|
TAKE_ARG;
|
||||||
DynArg_use_long_long(&dynarg, NUM2LL(arg_rb));
|
DynArg_use_long_long(&dynarg, NUM2LL(arg_rb));
|
||||||
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_UINT) {
|
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_UINT) {
|
||||||
|
TAKE_ARG;
|
||||||
DynArg_use_unsigned_long_long(&dynarg, NUM2ULL(arg_rb));
|
DynArg_use_unsigned_long_long(&dynarg, NUM2ULL(arg_rb));
|
||||||
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_FLOAT ||
|
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_FLOAT ||
|
||||||
spec.type == KERNAUX_PRINTF_FMT_TYPE_EXP)
|
spec.type == KERNAUX_PRINTF_FMT_TYPE_EXP)
|
||||||
{
|
{
|
||||||
|
TAKE_ARG;
|
||||||
DynArg_use_double(&dynarg, NUM2DBL(arg_rb));
|
DynArg_use_double(&dynarg, NUM2DBL(arg_rb));
|
||||||
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_CHAR) {
|
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_CHAR) {
|
||||||
|
TAKE_ARG;
|
||||||
Check_Type(arg_rb, T_STRING);
|
Check_Type(arg_rb, T_STRING);
|
||||||
DynArg_use_char(&dynarg, *StringValuePtr(arg_rb));
|
DynArg_use_char(&dynarg, *StringValuePtr(arg_rb));
|
||||||
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_STR) {
|
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_STR) {
|
||||||
|
TAKE_ARG;
|
||||||
Check_Type(arg_rb, T_STRING);
|
Check_Type(arg_rb, T_STRING);
|
||||||
DynArg_use_str(&dynarg, StringValueCStr(arg_rb));
|
DynArg_use_str(&dynarg, StringValueCStr(arg_rb));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
char *const str = malloc(size);
|
char buffer[BUFFER_SIZE];
|
||||||
if (!str) rb_raise(rb_eNoMemError, "snprintf1 buffer malloc");
|
int slen;
|
||||||
|
|
||||||
struct rb_KernAux_Snprintf1_DATA *userdata;
|
// FIXME: it's a hack
|
||||||
VALUE userdata_rb = TypedData_Make_Struct(
|
// TODO: convert printf format spec to string
|
||||||
rb_KernAux_Snprintf1,
|
const char tmp = *format;
|
||||||
struct rb_KernAux_Snprintf1_DATA,
|
*format = '\0';
|
||||||
&rb_KernAux_Snprintf1_DTYPE,
|
|
||||||
userdata
|
|
||||||
);
|
|
||||||
if (NIL_P(userdata_rb) || userdata == NULL) {
|
|
||||||
free(str);
|
|
||||||
rb_raise(rb_eNoMemError, "snprintf1 userdata alloc");
|
|
||||||
}
|
|
||||||
|
|
||||||
userdata->spec = &spec;
|
if (spec.set_width) {
|
||||||
userdata->dynarg = &dynarg;
|
if (spec.set_precision) {
|
||||||
userdata->size = size;
|
if (dynarg.use_dbl) {
|
||||||
userdata->format = format;
|
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||||
userdata->str = str;
|
spec.width, spec.precision,
|
||||||
|
dynarg.dbl);
|
||||||
int state = 0;
|
} else {
|
||||||
VALUE result =
|
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||||
rb_protect(rb_KernAux_snprintf1_PROTECT, userdata_rb, &state);
|
spec.width, spec.precision,
|
||||||
|
dynarg.arg);
|
||||||
free(str);
|
}
|
||||||
|
} else {
|
||||||
if (state == 0) {
|
if (dynarg.use_dbl) {
|
||||||
return result;
|
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||||
} else {
|
spec.width, dynarg.dbl);
|
||||||
rb_jump_tag(state);
|
} else {
|
||||||
}
|
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||||
}
|
spec.width, dynarg.arg);
|
||||||
|
}
|
||||||
VALUE rb_KernAux_snprintf1_PROTECT(VALUE userdata_rb)
|
}
|
||||||
{
|
|
||||||
const struct rb_KernAux_Snprintf1_DATA *userdata = NULL;
|
|
||||||
TypedData_Get_Struct(
|
|
||||||
userdata_rb,
|
|
||||||
struct rb_KernAux_Snprintf1_DATA,
|
|
||||||
&rb_KernAux_Snprintf1_DTYPE,
|
|
||||||
userdata
|
|
||||||
);
|
|
||||||
|
|
||||||
int slen;
|
|
||||||
if (userdata->spec->set_width) {
|
|
||||||
if (userdata->spec->set_precision) {
|
|
||||||
slen = userdata->dynarg->use_dbl
|
|
||||||
? kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->spec->width, userdata->spec->precision, userdata->dynarg->dbl)
|
|
||||||
: kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->spec->width, userdata->spec->precision, userdata->dynarg->arg);
|
|
||||||
} else {
|
} else {
|
||||||
slen = userdata->dynarg->use_dbl
|
if (spec.set_precision) {
|
||||||
? kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->spec->width, userdata->dynarg->dbl)
|
if (dynarg.use_dbl) {
|
||||||
: kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->spec->width, userdata->dynarg->arg);
|
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||||
}
|
spec.precision, dynarg.dbl);
|
||||||
} else {
|
} else {
|
||||||
if (userdata->spec->set_precision) {
|
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||||
slen = userdata->dynarg->use_dbl
|
spec.precision, dynarg.arg);
|
||||||
? kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->spec->precision, userdata->dynarg->dbl)
|
}
|
||||||
: kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->spec->precision, userdata->dynarg->arg);
|
} else {
|
||||||
} else {
|
if (dynarg.use_dbl) {
|
||||||
slen = userdata->dynarg->use_dbl
|
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format, dynarg.dbl);
|
||||||
? kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->dynarg->dbl)
|
} else {
|
||||||
: kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->dynarg->arg);
|
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format, dynarg.arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*format = tmp;
|
||||||
|
rb_str_cat(result, buffer, slen);
|
||||||
}
|
}
|
||||||
|
|
||||||
const VALUE output_rb =
|
if (arg_index < argc) rb_raise(rb_eArgError, "too many arguments");
|
||||||
rb_funcall(rb_str_new2(userdata->str), rb_intern_freeze, 0);
|
|
||||||
|
|
||||||
const VALUE result_rb = rb_ary_new2(2);
|
return rb_funcall(result, rb_intern_freeze, 0);
|
||||||
rb_ary_push(result_rb, output_rb);
|
|
||||||
rb_ary_push(result_rb, INT2NUM(slen));
|
|
||||||
return rb_funcall(result_rb, rb_intern_freeze, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* ::KernAux::Snprintf1 *
|
|
||||||
************************/
|
|
||||||
|
|
||||||
size_t rb_KernAux_Snprintf1_DSIZE(const void *const ptr)
|
|
||||||
{
|
|
||||||
return sizeof(struct rb_KernAux_Snprintf1_DATA);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // KERNAUX_VERSION_WITH_PRINTF
|
#endif // KERNAUX_VERSION_WITH_PRINTF
|
||||||
|
|
|
@ -17,4 +17,3 @@ require_relative 'kernaux/assert'
|
||||||
require_relative 'kernaux/cmdline'
|
require_relative 'kernaux/cmdline'
|
||||||
require_relative 'kernaux/errors'
|
require_relative 'kernaux/errors'
|
||||||
require_relative 'kernaux/ntoa'
|
require_relative 'kernaux/ntoa'
|
||||||
require_relative 'kernaux/printf'
|
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# rubocop:disable Style/Documentation
|
|
||||||
begin; end
|
|
||||||
|
|
||||||
module KernAux
|
|
||||||
# Buffer size for {.sprintf1}.
|
|
||||||
# @todo Make it dynamic.
|
|
||||||
SPRINTF1_BUFFER_SIZE = 10_000
|
|
||||||
|
|
||||||
# @!scope class
|
|
||||||
|
|
||||||
# @!parse [ruby]
|
|
||||||
|
|
||||||
if Version.with_printf?
|
|
||||||
##
|
|
||||||
# Typical `printf`.
|
|
||||||
#
|
|
||||||
# @param args [Array<String,
|
|
||||||
# Array<(String, Object)>,
|
|
||||||
# Array<(String, Integer, Object)>>]
|
|
||||||
# @return [String] formatted output
|
|
||||||
#
|
|
||||||
# @example
|
|
||||||
# KernAux.sprintf 'foo', ['%*s', 5, 'bar'], 'car', ['%d', 123]
|
|
||||||
# #=> "foo barcar123"
|
|
||||||
#
|
|
||||||
def self.sprintf(*args)
|
|
||||||
args.map do |arg|
|
|
||||||
if arg.is_a? Array
|
|
||||||
sprintf1(*arg)
|
|
||||||
else
|
|
||||||
arg
|
|
||||||
end
|
|
||||||
end.join.freeze
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# `printf` for single formatting parameter.
|
|
||||||
#
|
|
||||||
# @param format [String] formatting string
|
|
||||||
# @return [String] formatted output
|
|
||||||
#
|
|
||||||
# @see .sprintf Multiple formatting parameters
|
|
||||||
#
|
|
||||||
# @example
|
|
||||||
# KernAux.sprintf1 '%%' #=> "%"
|
|
||||||
# KernAux.sprintf1 '%s', 'foo' #=> "foo"
|
|
||||||
# KernAux.sprintf1 '%5s', 'foo' #=> " foo"
|
|
||||||
# KernAux.sprintf1 '%*s', 5, 'foo' #=> " foo"
|
|
||||||
#
|
|
||||||
def self.sprintf1(format, *args)
|
|
||||||
snprintf1(SPRINTF1_BUFFER_SIZE, format, *args).first
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# @!method snprintf1(buffer_size, format, ...)
|
|
||||||
# `printf` for single formatting parameter with manual buffer size.
|
|
||||||
#
|
|
||||||
# @param buffer_size [Integer] buffer size (including terminating null
|
|
||||||
# character)
|
|
||||||
# @param format [String] formatting string
|
|
||||||
# @return [Array<(String, Integer)>] formatted output and it's size
|
|
||||||
#
|
|
||||||
# @see .sprintf1 Automatic buffer size
|
|
||||||
##
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# rubocop:enable Style/Documentation
|
|
|
@ -1,280 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
KernAux::Version.with_printf? and RSpec.describe KernAux, '.snprintf1' do
|
|
||||||
let(:size) { 10_000 }
|
|
||||||
|
|
||||||
context 'with 0 arguments' do
|
|
||||||
specify do
|
|
||||||
expect { described_class.snprintf1 }.to \
|
|
||||||
raise_error ArgumentError, 'expected 2, 3, 4 or 5 args'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with 1 argument' do
|
|
||||||
specify do
|
|
||||||
expect { described_class.snprintf1 size }.to \
|
|
||||||
raise_error ArgumentError, 'expected 2, 3, 4 or 5 args'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with 6 arguments' do
|
|
||||||
specify do
|
|
||||||
expect do
|
|
||||||
described_class.snprintf1 size, '%*.*s', 20, 10, 'foo', 'bar'
|
|
||||||
end.to \
|
|
||||||
raise_error ArgumentError, 'expected 2, 3, 4 or 5 args'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with 2 arguments' do
|
|
||||||
subject(:snprintf1) { described_class.snprintf1 size, format }
|
|
||||||
|
|
||||||
let(:format) { '%%' }
|
|
||||||
|
|
||||||
it { is_expected.to be_instance_of Array }
|
|
||||||
it { is_expected.to be_frozen }
|
|
||||||
it { is_expected.to all be_frozen }
|
|
||||||
|
|
||||||
specify { expect(snprintf1.size).to equal 2 }
|
|
||||||
specify { expect(snprintf1[0]).to be_instance_of String }
|
|
||||||
specify { expect(snprintf1[1]).to be_instance_of Integer }
|
|
||||||
specify { expect(snprintf1[0]).to eq '%' }
|
|
||||||
specify { expect(snprintf1[1]).to eq 1 }
|
|
||||||
|
|
||||||
context 'with leading and trailing spaces' do
|
|
||||||
let(:format) { ' %% ' }
|
|
||||||
|
|
||||||
specify { expect(snprintf1[0]).to eq ' % ' }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with "%s" format' do
|
|
||||||
let(:format) { '%s' }
|
|
||||||
|
|
||||||
specify { expect(snprintf1[0]).to eq '' }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when size has invalid type' do
|
|
||||||
let(:size) { '10000' }
|
|
||||||
|
|
||||||
specify { expect { snprintf1 }.to raise_error TypeError }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when size is negative' do
|
|
||||||
let(:size) { -1 }
|
|
||||||
|
|
||||||
specify do
|
|
||||||
expect { snprintf1 }.to \
|
|
||||||
raise_error RangeError, 'expected non-negative size'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when format doesn\'t include "%" char' do
|
|
||||||
let(:format) { 'foo' }
|
|
||||||
|
|
||||||
specify do
|
|
||||||
expect { snprintf1 }.to raise_error ArgumentError, 'invalid format'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when format includes more than two "%" chars' do
|
|
||||||
let(:format) { '%%%' }
|
|
||||||
|
|
||||||
specify do
|
|
||||||
expect { snprintf1 }.to raise_error ArgumentError, 'invalid format'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with 3 arguments' do
|
|
||||||
subject(:snprintf1) { described_class.snprintf1 size, format, arg }
|
|
||||||
|
|
||||||
let(:format) { '%s' }
|
|
||||||
let(:arg) { 'Hello, World!' }
|
|
||||||
|
|
||||||
it { is_expected.to be_instance_of Array }
|
|
||||||
it { is_expected.to be_frozen }
|
|
||||||
it { is_expected.to all be_frozen }
|
|
||||||
|
|
||||||
specify { expect(snprintf1.size).to equal 2 }
|
|
||||||
specify { expect(snprintf1[0]).to be_instance_of String }
|
|
||||||
specify { expect(snprintf1[1]).to be_instance_of Integer }
|
|
||||||
specify { expect(snprintf1[0]).to eq arg }
|
|
||||||
specify { expect(snprintf1[1]).to eq arg.size }
|
|
||||||
|
|
||||||
context 'with leading and trailing spaces' do
|
|
||||||
let(:format) { ' %s ' }
|
|
||||||
|
|
||||||
specify { expect(snprintf1[0]).to eq " #{arg} " }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with "%%" format' do
|
|
||||||
let(:format) { '%%' }
|
|
||||||
|
|
||||||
specify { expect(snprintf1[0]).to eq '%' }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when size has invalid type' do
|
|
||||||
let(:size) { '10000' }
|
|
||||||
|
|
||||||
specify { expect { snprintf1 }.to raise_error TypeError }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when size is negative' do
|
|
||||||
let(:size) { -1 }
|
|
||||||
|
|
||||||
specify do
|
|
||||||
expect { snprintf1 }.to \
|
|
||||||
raise_error RangeError, 'expected non-negative size'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when format doesn\'t include "%" char' do
|
|
||||||
let(:format) { 'foo' }
|
|
||||||
|
|
||||||
specify do
|
|
||||||
expect { snprintf1 }.to raise_error ArgumentError, 'invalid format'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when format includes more than two "%" chars' do
|
|
||||||
let(:format) { '%%%' }
|
|
||||||
|
|
||||||
specify do
|
|
||||||
expect { snprintf1 }.to raise_error ArgumentError, 'invalid format'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with 4 arguments' do
|
|
||||||
subject(:snprintf1) { described_class.snprintf1 size, format, width, arg }
|
|
||||||
|
|
||||||
let(:format) { '%*s' }
|
|
||||||
let(:width) { 20 }
|
|
||||||
let(:arg) { 'Hello, World!' }
|
|
||||||
|
|
||||||
it { is_expected.to be_instance_of Array }
|
|
||||||
it { is_expected.to be_frozen }
|
|
||||||
it { is_expected.to all be_frozen }
|
|
||||||
|
|
||||||
specify { expect(snprintf1.size).to equal 2 }
|
|
||||||
specify { expect(snprintf1[0]).to be_instance_of String }
|
|
||||||
specify { expect(snprintf1[1]).to be_instance_of Integer }
|
|
||||||
specify { expect(snprintf1[0]).to eq arg.rjust(width, ' ') }
|
|
||||||
specify { expect(snprintf1[1]).to eq width }
|
|
||||||
|
|
||||||
context 'with leading and trailing spaces' do
|
|
||||||
let(:format) { ' %*s ' }
|
|
||||||
|
|
||||||
specify { expect(snprintf1[0]).to eq " #{arg.rjust(width, ' ')} " }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with "%*%" format' do
|
|
||||||
let(:format) { '%*%' }
|
|
||||||
|
|
||||||
specify { expect(snprintf1[0]).to eq '%' }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when size has invalid type' do
|
|
||||||
let(:size) { '10000' }
|
|
||||||
|
|
||||||
specify { expect { snprintf1 }.to raise_error TypeError }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when size is negative' do
|
|
||||||
let(:size) { -1 }
|
|
||||||
|
|
||||||
specify do
|
|
||||||
expect { snprintf1 }.to \
|
|
||||||
raise_error RangeError, 'expected non-negative size'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when format doesn\'t include "%" char' do
|
|
||||||
let(:format) { 'foo' }
|
|
||||||
|
|
||||||
specify do
|
|
||||||
expect { snprintf1 }.to raise_error ArgumentError, 'invalid format'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when format includes more than two "%" chars' do
|
|
||||||
let(:format) { '%%%' }
|
|
||||||
|
|
||||||
specify do
|
|
||||||
expect { snprintf1 }.to raise_error ArgumentError, 'invalid format'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with 5 arguments' do
|
|
||||||
subject :snprintf1 do
|
|
||||||
described_class.snprintf1 size, format, width, precision, arg
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:format) { '%*.*f' }
|
|
||||||
let(:width) { 20 }
|
|
||||||
let(:precision) { 3 }
|
|
||||||
let(:arg) { 123.456789 }
|
|
||||||
|
|
||||||
it { is_expected.to be_instance_of Array }
|
|
||||||
it { is_expected.to be_frozen }
|
|
||||||
it { is_expected.to all be_frozen }
|
|
||||||
|
|
||||||
specify { expect(snprintf1.size).to equal 2 }
|
|
||||||
specify { expect(snprintf1[0]).to be_instance_of String }
|
|
||||||
specify { expect(snprintf1[1]).to be_instance_of Integer }
|
|
||||||
specify { expect(snprintf1[1]).to eq width }
|
|
||||||
|
|
||||||
specify do
|
|
||||||
expect(snprintf1[0]).to eq arg.round(precision).to_s.rjust(width, ' ')
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with leading and trailing spaces' do
|
|
||||||
let(:format) { ' %*.*f ' }
|
|
||||||
|
|
||||||
specify do
|
|
||||||
expect(snprintf1[0]).to \
|
|
||||||
eq " #{arg.round(precision).to_s.rjust(width, ' ')} "
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with "%*.*%" format' do
|
|
||||||
let(:format) { '%*.*%' }
|
|
||||||
|
|
||||||
specify { expect(snprintf1[0]).to eq '%' }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when size has invalid type' do
|
|
||||||
let(:size) { '10000' }
|
|
||||||
|
|
||||||
specify { expect { snprintf1 }.to raise_error TypeError }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when size is negative' do
|
|
||||||
let(:size) { -1 }
|
|
||||||
|
|
||||||
specify do
|
|
||||||
expect { snprintf1 }.to \
|
|
||||||
raise_error RangeError, 'expected non-negative size'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when format doesn\'t include "%" char' do
|
|
||||||
let(:format) { 'foo' }
|
|
||||||
|
|
||||||
specify do
|
|
||||||
expect { snprintf1 }.to raise_error ArgumentError, 'invalid format'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when format includes more than two "%" chars' do
|
|
||||||
let(:format) { '%%%' }
|
|
||||||
|
|
||||||
specify do
|
|
||||||
expect { snprintf1 }.to raise_error ArgumentError, 'invalid format'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,26 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
KernAux::Version.with_printf? and RSpec.describe KernAux, '.sprintf1' do
|
|
||||||
context 'with 1 argument' do
|
|
||||||
subject(:sprintf1) { described_class.sprintf1 format }
|
|
||||||
|
|
||||||
let(:format) { '%%' }
|
|
||||||
|
|
||||||
it { is_expected.to be_instance_of String }
|
|
||||||
it { is_expected.to be_frozen }
|
|
||||||
it { is_expected.to eq described_class.snprintf1(1000, format).first }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with 2 argument' do
|
|
||||||
subject(:sprintf1) { described_class.sprintf1 format, arg }
|
|
||||||
|
|
||||||
let(:format) { '%s' }
|
|
||||||
let(:arg) { 'Hello, World!' }
|
|
||||||
|
|
||||||
it { is_expected.to be_instance_of String }
|
|
||||||
it { is_expected.to be_frozen }
|
|
||||||
it { is_expected.to eq described_class.snprintf1(100, format, arg).first }
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,59 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
KernAux::Version.with_printf? and RSpec.describe KernAux, '.sprintf' do
|
|
||||||
subject :sprintf do
|
|
||||||
described_class.sprintf 'Hello, ', ['%s', 'World'], '!'
|
|
||||||
end
|
|
||||||
|
|
||||||
it { is_expected.to be_instance_of String }
|
|
||||||
it { is_expected.to be_frozen }
|
|
||||||
it { is_expected.to eq 'Hello, World!' }
|
|
||||||
|
|
||||||
context 'for empty string value' do
|
|
||||||
subject(:sprintf) { described_class.sprintf ['Hello testing%s'] }
|
|
||||||
|
|
||||||
it { is_expected.to eq 'Hello testing' }
|
|
||||||
end
|
|
||||||
|
|
||||||
[
|
|
||||||
['', 'using regular tests'],
|
|
||||||
['_orig', 'using original tests'],
|
|
||||||
].each do |(suffix, description)|
|
|
||||||
context description do
|
|
||||||
printf_yml = File.expand_path(
|
|
||||||
"../../../../../../common/printf#{suffix}.yml",
|
|
||||||
__dir__,
|
|
||||||
)
|
|
||||||
|
|
||||||
YAML.safe_load_file(printf_yml).each do |test|
|
|
||||||
expected = test['result']
|
|
||||||
|
|
||||||
args = test['args'].map do |arg|
|
|
||||||
if arg.is_a? String
|
|
||||||
arg
|
|
||||||
else
|
|
||||||
arg.map do |item|
|
|
||||||
if item.is_a? Array
|
|
||||||
if item.length == 1
|
|
||||||
item[0]
|
|
||||||
elsif item[0] == 'long long'
|
|
||||||
item[1]
|
|
||||||
else
|
|
||||||
raise "Unknown format: #{args.inspect}"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
item
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it "transforms #{args.inspect} to #{expected.inspect}" do
|
|
||||||
expect(described_class.sprintf(*args)).to eq expected
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
KernAux::Version.with_printf? and RSpec.describe KernAux, '.sprintf' do
|
||||||
|
subject :sprintf do
|
||||||
|
described_class.sprintf 'Hello, %s!', 'World'
|
||||||
|
end
|
||||||
|
|
||||||
|
it { is_expected.to be_instance_of String }
|
||||||
|
it { is_expected.to be_frozen }
|
||||||
|
it { is_expected.to eq 'Hello, World!' }
|
||||||
|
|
||||||
|
context 'when there are too many arguments' do
|
||||||
|
[
|
||||||
|
['Hello!', 'World!'],
|
||||||
|
['Hello, %s!', 'World', 'Alex'],
|
||||||
|
].each do |args|
|
||||||
|
it "raises on #{args.inspect}" do
|
||||||
|
expect { described_class.sprintf(*args) }.to \
|
||||||
|
raise_error ArgumentError, 'too many arguments'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when there are too few arguments' do
|
||||||
|
[
|
||||||
|
[],
|
||||||
|
['Hello, %s!'],
|
||||||
|
['Hello, %*s!', 20],
|
||||||
|
['Hello, %.*s!', 20],
|
||||||
|
['Hello, %*.*s!', 20, 20],
|
||||||
|
].each do |args|
|
||||||
|
it "raises on #{args.inspect}" do
|
||||||
|
expect { described_class.sprintf(*args) }.to \
|
||||||
|
raise_error ArgumentError, 'too few arguments'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
[
|
||||||
|
['', 'using regular tests'],
|
||||||
|
['_orig', 'using original tests'],
|
||||||
|
].each do |(suffix, description)|
|
||||||
|
context description do
|
||||||
|
printf_yml = File.expand_path(
|
||||||
|
"../../../../../common/printf#{suffix}.yml",
|
||||||
|
__dir__,
|
||||||
|
)
|
||||||
|
|
||||||
|
YAML.safe_load_file(printf_yml).each do |test|
|
||||||
|
expected = test['result']
|
||||||
|
|
||||||
|
format = ''
|
||||||
|
args = []
|
||||||
|
|
||||||
|
test['args'].each do |arg|
|
||||||
|
if arg.is_a? String
|
||||||
|
format += arg
|
||||||
|
else
|
||||||
|
format += arg[0]
|
||||||
|
arg[1..].each do |item|
|
||||||
|
if item.is_a? Array
|
||||||
|
if item.length == 1
|
||||||
|
args << item[0]
|
||||||
|
elsif item[0] == 'long long'
|
||||||
|
args << item[1]
|
||||||
|
else
|
||||||
|
raise "Unknown format: #{args.inspect}"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
args << item
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "transforms (#{format.inspect}, #{args.inspect[1...-1]}) " \
|
||||||
|
"to #{expected.inspect}" do
|
||||||
|
expect(described_class.sprintf(format, *args)).to eq expected
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
12
configure.ac
12
configure.ac
|
@ -35,6 +35,8 @@ AC_CONFIG_FILES([
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE([1.16 subdir-objects])
|
AM_INIT_AUTOMAKE([1.16 subdir-objects])
|
||||||
|
|
||||||
|
AC_SUBST([PACKAGE_VERSION_SO], m4_normalize(m4_include([VERSION_SO])))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###############
|
###############
|
||||||
|
@ -67,7 +69,7 @@ AC_ARG_WITH( [elf], AS_HELP_STRING([--without-elf], [wit
|
||||||
AC_ARG_WITH( [free-list], AS_HELP_STRING([--without-free-list], [without free list memory allocator]))
|
AC_ARG_WITH( [free-list], AS_HELP_STRING([--without-free-list], [without free list memory allocator]))
|
||||||
AC_ARG_WITH( [mbr], AS_HELP_STRING([--without-mbr], [without MBR utils]))
|
AC_ARG_WITH( [mbr], AS_HELP_STRING([--without-mbr], [without MBR utils]))
|
||||||
AC_ARG_WITH( [memmap], AS_HELP_STRING([--without-memmap], [without memory map]))
|
AC_ARG_WITH( [memmap], AS_HELP_STRING([--without-memmap], [without memory map]))
|
||||||
AC_ARG_WITH( [multiboot2], AS_HELP_STRING([--without-multiboot2], [without Multiboot 2 information parser]))
|
AC_ARG_WITH( [multiboot2], AS_HELP_STRING([--without-multiboot2], [without Multiboot 2 utils]))
|
||||||
AC_ARG_WITH( [ntoa], AS_HELP_STRING([--without-ntoa], [without itoa/ftoa]))
|
AC_ARG_WITH( [ntoa], AS_HELP_STRING([--without-ntoa], [without itoa/ftoa]))
|
||||||
AC_ARG_WITH( [pfa], AS_HELP_STRING([--without-pfa], [without Page Frame Allocator]))
|
AC_ARG_WITH( [pfa], AS_HELP_STRING([--without-pfa], [without Page Frame Allocator]))
|
||||||
AC_ARG_WITH( [printf], AS_HELP_STRING([--without-printf], [without printf]))
|
AC_ARG_WITH( [printf], AS_HELP_STRING([--without-printf], [without printf]))
|
||||||
|
@ -263,7 +265,7 @@ AS_IF([test "$with_elf" = yes], [AC_DEFINE([WITH_ELF],
|
||||||
AS_IF([test "$with_free_list" = yes], [AC_DEFINE([WITH_FREE_LIST], [1], [with free list memory allocator])])
|
AS_IF([test "$with_free_list" = yes], [AC_DEFINE([WITH_FREE_LIST], [1], [with free list memory allocator])])
|
||||||
AS_IF([test "$with_mbr" = yes], [AC_DEFINE([WITH_MBR], [1], [with MBR utils])])
|
AS_IF([test "$with_mbr" = yes], [AC_DEFINE([WITH_MBR], [1], [with MBR utils])])
|
||||||
AS_IF([test "$with_memmap" = yes], [AC_DEFINE([WITH_MEMMAP], [1], [with memory map])])
|
AS_IF([test "$with_memmap" = yes], [AC_DEFINE([WITH_MEMMAP], [1], [with memory map])])
|
||||||
AS_IF([test "$with_multiboot2" = yes], [AC_DEFINE([WITH_MULTIBOOT2], [1], [with Multiboot 2 information parser])])
|
AS_IF([test "$with_multiboot2" = yes], [AC_DEFINE([WITH_MULTIBOOT2], [1], [with Multiboot 2 utils])])
|
||||||
AS_IF([test "$with_ntoa" = yes], [AC_DEFINE([WITH_NTOA], [1], [with ntoa])])
|
AS_IF([test "$with_ntoa" = yes], [AC_DEFINE([WITH_NTOA], [1], [with ntoa])])
|
||||||
AS_IF([test "$with_pfa" = yes], [AC_DEFINE([WITH_PFA], [1], [with Page Frame Allocator])])
|
AS_IF([test "$with_pfa" = yes], [AC_DEFINE([WITH_PFA], [1], [with Page Frame Allocator])])
|
||||||
AS_IF([test "$with_printf" = yes], [AC_DEFINE([WITH_PRINTF], [1], [with printf])])
|
AS_IF([test "$with_printf" = yes], [AC_DEFINE([WITH_PRINTF], [1], [with printf])])
|
||||||
|
@ -319,10 +321,8 @@ AS_IF([test "$enable_freestanding" = yes],
|
||||||
##############
|
##############
|
||||||
|
|
||||||
AC_LANG([C])
|
AC_LANG([C])
|
||||||
|
|
||||||
AM_PROG_AR
|
|
||||||
AM_PROG_AS
|
AM_PROG_AS
|
||||||
AC_PROG_CC
|
|
||||||
AC_C_INLINE
|
AC_C_INLINE
|
||||||
|
|
||||||
AC_HEADER_STDBOOL
|
AC_HEADER_STDBOOL
|
||||||
|
@ -380,7 +380,7 @@ AS_IF([test "$enable_checks_python" = yes -a "$enable_checks" = yes -a "$PYTHON_
|
||||||
# Initialize Libtool #
|
# Initialize Libtool #
|
||||||
######################
|
######################
|
||||||
|
|
||||||
LT_INIT([disable-shared])
|
LT_INIT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ multiboot2_header = {
|
||||||
.magic = KERNAUX_MULTIBOOT2_HEADER_MAGIC,
|
.magic = KERNAUX_MULTIBOOT2_HEADER_MAGIC,
|
||||||
.arch = KERNAUX_MULTIBOOT2_HEADER_ARCH_I386,
|
.arch = KERNAUX_MULTIBOOT2_HEADER_ARCH_I386,
|
||||||
.total_size = sizeof(multiboot2_header),
|
.total_size = sizeof(multiboot2_header),
|
||||||
|
// This macro helps to calculate the checksum.
|
||||||
.checksum = KERNAUX_MULTIBOOT2_HEADER_CHECKSUM(
|
.checksum = KERNAUX_MULTIBOOT2_HEADER_CHECKSUM(
|
||||||
KERNAUX_MULTIBOOT2_HEADER_ARCH_I386,
|
KERNAUX_MULTIBOOT2_HEADER_ARCH_I386,
|
||||||
sizeof(multiboot2_header)
|
sizeof(multiboot2_header)
|
||||||
|
|
|
@ -1,31 +1,37 @@
|
||||||
nobase_include_HEADERS = \
|
nobase_include_HEADERS = \
|
||||||
kernaux.h \
|
kernaux.h \
|
||||||
kernaux/arch/i386.h \
|
kernaux/arch/i386.h \
|
||||||
kernaux/arch/i386-idt.h \
|
kernaux/arch/i386-idt.h \
|
||||||
kernaux/arch/riscv64.h \
|
kernaux/arch/riscv64.h \
|
||||||
kernaux/arch/x86_64.h \
|
kernaux/arch/x86_64.h \
|
||||||
kernaux/arch/x86.h \
|
kernaux/arch/x86.h \
|
||||||
kernaux/asm/i386.h \
|
kernaux/asm/i386.h \
|
||||||
kernaux/asm/riscv64.h \
|
kernaux/asm/riscv64.h \
|
||||||
kernaux/asm/x86_64.h \
|
kernaux/asm/x86_64.h \
|
||||||
kernaux/asm/x86.h \
|
kernaux/asm/x86.h \
|
||||||
kernaux/assert.h \
|
kernaux/assert.h \
|
||||||
kernaux/cmdline.h \
|
kernaux/cmdline.h \
|
||||||
kernaux/elf.h \
|
kernaux/elf.h \
|
||||||
kernaux/free_list.h \
|
kernaux/free_list.h \
|
||||||
kernaux/generic/display.h \
|
kernaux/generic/display.h \
|
||||||
kernaux/generic/malloc.h \
|
kernaux/generic/malloc.h \
|
||||||
kernaux/generic/mutex.h \
|
kernaux/generic/mutex.h \
|
||||||
kernaux/macro.h \
|
kernaux/macro.h \
|
||||||
kernaux/macro/packing_end.run \
|
kernaux/macro/packing_end.run \
|
||||||
kernaux/macro/packing_start.run \
|
kernaux/macro/packing_start.run \
|
||||||
kernaux/mbr.h \
|
kernaux/mbr.h \
|
||||||
kernaux/memmap.h \
|
kernaux/memmap.h \
|
||||||
kernaux/multiboot2.h \
|
kernaux/multiboot2.h \
|
||||||
kernaux/multiboot2/header_macro.h \
|
kernaux/multiboot2/header_helpers.h \
|
||||||
kernaux/ntoa.h \
|
kernaux/multiboot2/header_is_valid.h \
|
||||||
kernaux/pfa.h \
|
kernaux/multiboot2/header_macro.h \
|
||||||
kernaux/printf.h \
|
kernaux/multiboot2/header_print.h \
|
||||||
kernaux/printf_fmt.h \
|
kernaux/multiboot2/info_helpers.h \
|
||||||
kernaux/units.h \
|
kernaux/multiboot2/info_is_valid.h \
|
||||||
|
kernaux/multiboot2/info_print.h \
|
||||||
|
kernaux/ntoa.h \
|
||||||
|
kernaux/pfa.h \
|
||||||
|
kernaux/printf.h \
|
||||||
|
kernaux/printf_fmt.h \
|
||||||
|
kernaux/units.h \
|
||||||
kernaux/version.h
|
kernaux/version.h
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include <kernaux/mbr.h>
|
#include <kernaux/mbr.h>
|
||||||
#include <kernaux/memmap.h>
|
#include <kernaux/memmap.h>
|
||||||
#include <kernaux/multiboot2.h>
|
#include <kernaux/multiboot2.h>
|
||||||
#include <kernaux/multiboot2/header_macro.h>
|
|
||||||
#include <kernaux/ntoa.h>
|
#include <kernaux/ntoa.h>
|
||||||
#include <kernaux/pfa.h>
|
#include <kernaux/pfa.h>
|
||||||
#include <kernaux/printf.h>
|
#include <kernaux/printf.h>
|
||||||
|
|
|
@ -7,7 +7,6 @@ extern "C" {
|
||||||
|
|
||||||
#include <kernaux/macro.h>
|
#include <kernaux/macro.h>
|
||||||
#include <kernaux/generic/display.h>
|
#include <kernaux/generic/display.h>
|
||||||
#include <kernaux/memmap.h>
|
|
||||||
#include <kernaux/multiboot2/header_macro.h>
|
#include <kernaux/multiboot2/header_macro.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -24,13 +23,6 @@ extern "C" {
|
||||||
// @see https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html#Basic-tags-structure
|
// @see https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html#Basic-tags-structure
|
||||||
#define KERNAUX_MULTIBOOT2_TAG_ALIGN 8
|
#define KERNAUX_MULTIBOOT2_TAG_ALIGN 8
|
||||||
|
|
||||||
#define KERNAUX_MULTIBOOT2_HEADER_CHECKSUM(arch, total_size) \
|
|
||||||
((uint32_t)(-( \
|
|
||||||
((uint32_t)KERNAUX_MULTIBOOT2_HEADER_MAGIC) + \
|
|
||||||
((uint32_t)(arch)) + \
|
|
||||||
((uint32_t)(total_size)) \
|
|
||||||
)))
|
|
||||||
|
|
||||||
#define KERNAUX_MULTIBOOT2_DATA(ptr) (((uint8_t*)(ptr)) + sizeof(*(ptr)))
|
#define KERNAUX_MULTIBOOT2_DATA(ptr) (((uint8_t*)(ptr)) + sizeof(*(ptr)))
|
||||||
|
|
||||||
#define KERNAUX_MULTIBOOT2_HTAG_NEXT(tag_base) \
|
#define KERNAUX_MULTIBOOT2_HTAG_NEXT(tag_base) \
|
||||||
|
@ -97,7 +89,7 @@ KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_Multiboot2_HTagBase, 8);
|
||||||
|
|
||||||
struct KernAux_Multiboot2_Info {
|
struct KernAux_Multiboot2_Info {
|
||||||
uint32_t total_size;
|
uint32_t total_size;
|
||||||
uint32_t reserved1;
|
uint32_t reserved;
|
||||||
}
|
}
|
||||||
KERNAUX_PACKED;
|
KERNAUX_PACKED;
|
||||||
|
|
||||||
|
@ -154,7 +146,7 @@ struct KernAux_Multiboot2_ITag_MemoryMap_EntryBase {
|
||||||
uint64_t base_addr;
|
uint64_t base_addr;
|
||||||
uint64_t length;
|
uint64_t length;
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint32_t reserved1;
|
uint32_t reserved;
|
||||||
}
|
}
|
||||||
KERNAUX_PACKED;
|
KERNAUX_PACKED;
|
||||||
|
|
||||||
|
@ -177,6 +169,8 @@ struct KernAux_Multiboot2_HTag_InfoReq {
|
||||||
// type = 1
|
// type = 1
|
||||||
// size > 8
|
// size > 8
|
||||||
struct KernAux_Multiboot2_HTagBase base;
|
struct KernAux_Multiboot2_HTagBase base;
|
||||||
|
|
||||||
|
// DATA: uint32_t mbi_tag_types[]
|
||||||
}
|
}
|
||||||
KERNAUX_PACKED;
|
KERNAUX_PACKED;
|
||||||
|
|
||||||
|
@ -302,6 +296,8 @@ struct KernAux_Multiboot2_ITag_BootCmdLine {
|
||||||
// type = 1
|
// type = 1
|
||||||
// size > 8
|
// size > 8
|
||||||
struct KernAux_Multiboot2_ITagBase base;
|
struct KernAux_Multiboot2_ITagBase base;
|
||||||
|
|
||||||
|
// DATA: char cmdline[]
|
||||||
}
|
}
|
||||||
KERNAUX_PACKED;
|
KERNAUX_PACKED;
|
||||||
|
|
||||||
|
@ -311,6 +307,8 @@ struct KernAux_Multiboot2_ITag_BootLoaderName {
|
||||||
// type = 2
|
// type = 2
|
||||||
// size > 8
|
// size > 8
|
||||||
struct KernAux_Multiboot2_ITagBase base;
|
struct KernAux_Multiboot2_ITagBase base;
|
||||||
|
|
||||||
|
// DATA: char name[]
|
||||||
}
|
}
|
||||||
KERNAUX_PACKED;
|
KERNAUX_PACKED;
|
||||||
|
|
||||||
|
@ -323,6 +321,8 @@ struct KernAux_Multiboot2_ITag_Module {
|
||||||
|
|
||||||
uint32_t mod_start;
|
uint32_t mod_start;
|
||||||
uint32_t mod_end;
|
uint32_t mod_end;
|
||||||
|
|
||||||
|
// DATA: char cmdline[]
|
||||||
}
|
}
|
||||||
KERNAUX_PACKED;
|
KERNAUX_PACKED;
|
||||||
|
|
||||||
|
@ -345,7 +345,7 @@ struct KernAux_Multiboot2_ITag_BIOSBootDevice {
|
||||||
// size = 20
|
// size = 20
|
||||||
struct KernAux_Multiboot2_ITagBase base;
|
struct KernAux_Multiboot2_ITagBase base;
|
||||||
|
|
||||||
uint32_t bios_dev;
|
uint32_t biosdev;
|
||||||
uint32_t partition;
|
uint32_t partition;
|
||||||
uint32_t sub_partition;
|
uint32_t sub_partition;
|
||||||
}
|
}
|
||||||
|
@ -360,6 +360,8 @@ struct KernAux_Multiboot2_ITag_MemoryMap {
|
||||||
|
|
||||||
uint32_t entry_size;
|
uint32_t entry_size;
|
||||||
uint32_t entry_version;
|
uint32_t entry_version;
|
||||||
|
|
||||||
|
// DATA: varies(entry_size) KernAux_Multiboot2_ITag_MemoryMap_EntryBase entries[]
|
||||||
}
|
}
|
||||||
KERNAUX_PACKED;
|
KERNAUX_PACKED;
|
||||||
|
|
||||||
|
@ -383,7 +385,7 @@ KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_Multiboot2_ITag_VBEInfo, 784);
|
||||||
|
|
||||||
struct KernAux_Multiboot2_ITag_FramebufferInfo {
|
struct KernAux_Multiboot2_ITag_FramebufferInfo {
|
||||||
// type = 8
|
// type = 8
|
||||||
// size > 31
|
// size > 32
|
||||||
struct KernAux_Multiboot2_ITagBase base;
|
struct KernAux_Multiboot2_ITagBase base;
|
||||||
|
|
||||||
uint64_t framebuffer_addr;
|
uint64_t framebuffer_addr;
|
||||||
|
@ -392,25 +394,37 @@ struct KernAux_Multiboot2_ITag_FramebufferInfo {
|
||||||
uint32_t framebuffer_height;
|
uint32_t framebuffer_height;
|
||||||
uint8_t framebuffer_bpp;
|
uint8_t framebuffer_bpp;
|
||||||
uint8_t framebuffer_type;
|
uint8_t framebuffer_type;
|
||||||
uint8_t reserved1;
|
|
||||||
|
// WARNING: GRUB 2 and Limine don't follow the spec, so we do not too!
|
||||||
|
// Multiboot 2: https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html#Framebuffer-info
|
||||||
|
// GRUB 2: https://github.com/rhboot/grub2/blob/7259d55ffcf124e32eafb61aa381f9856e98a708/include/multiboot2.h#L288
|
||||||
|
// Limine: https://github.com/limine-bootloader/limine/blob/1aba6b3aeb72ac55b177132ca75ea8adfbcb78aa/common/protos/multiboot2.h#L292
|
||||||
|
uint16_t reserved;
|
||||||
|
|
||||||
|
// DATA: varies color_info[]
|
||||||
}
|
}
|
||||||
KERNAUX_PACKED;
|
KERNAUX_PACKED;
|
||||||
|
|
||||||
KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_Multiboot2_ITag_FramebufferInfo, 31);
|
KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_Multiboot2_ITag_FramebufferInfo, 32);
|
||||||
|
|
||||||
|
// WARNING: GRUB 2 and Limine don't follow the spec, so we do not too!
|
||||||
|
// Multiboot 2: https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html#ELF_002dSymbols
|
||||||
|
// GRUB 2: https://github.com/rhboot/grub2/blob/7259d55ffcf124e32eafb61aa381f9856e98a708/include/multiboot2.h#L314-L322
|
||||||
|
// Limine: https://github.com/limine-bootloader/limine/blob/1aba6b3aeb72ac55b177132ca75ea8adfbcb78aa/common/protos/multiboot2.h#L318-L326
|
||||||
struct KernAux_Multiboot2_ITag_ELFSymbols {
|
struct KernAux_Multiboot2_ITag_ELFSymbols {
|
||||||
// type = 9
|
// type = 9
|
||||||
// size > 16
|
// size > 20
|
||||||
struct KernAux_Multiboot2_ITagBase base;
|
struct KernAux_Multiboot2_ITagBase base;
|
||||||
|
|
||||||
uint16_t num;
|
uint32_t num;
|
||||||
uint16_t ent_size;
|
uint32_t entsize;
|
||||||
uint16_t shndx;
|
uint32_t shndx;
|
||||||
uint16_t reserved1;
|
|
||||||
|
// DATA: varies section_headers[]
|
||||||
}
|
}
|
||||||
KERNAUX_PACKED;
|
KERNAUX_PACKED;
|
||||||
|
|
||||||
KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_Multiboot2_ITag_ELFSymbols, 16);
|
KERNAUX_STATIC_TEST_STRUCT_SIZE(KernAux_Multiboot2_ITag_ELFSymbols, 20);
|
||||||
|
|
||||||
struct KernAux_Multiboot2_ITag_APMTable {
|
struct KernAux_Multiboot2_ITag_APMTable {
|
||||||
// type = 10
|
// type = 10
|
||||||
|
@ -460,7 +474,9 @@ struct KernAux_Multiboot2_ITag_SMBIOSTables {
|
||||||
|
|
||||||
uint8_t major;
|
uint8_t major;
|
||||||
uint8_t minor;
|
uint8_t minor;
|
||||||
uint8_t reserved1[6];
|
uint8_t reserved[6];
|
||||||
|
|
||||||
|
// TODO: DATA?
|
||||||
}
|
}
|
||||||
KERNAUX_PACKED;
|
KERNAUX_PACKED;
|
||||||
|
|
||||||
|
@ -470,6 +486,8 @@ struct KernAux_Multiboot2_ITag_ACPIOldRSDP {
|
||||||
// type = 14
|
// type = 14
|
||||||
// size > 8
|
// size > 8
|
||||||
struct KernAux_Multiboot2_ITagBase base;
|
struct KernAux_Multiboot2_ITagBase base;
|
||||||
|
|
||||||
|
// TODO: DATA?
|
||||||
}
|
}
|
||||||
KERNAUX_PACKED;
|
KERNAUX_PACKED;
|
||||||
|
|
||||||
|
@ -479,6 +497,8 @@ struct KernAux_Multiboot2_ITag_ACPINewRSDP {
|
||||||
// type = 15
|
// type = 15
|
||||||
// size > 8
|
// size > 8
|
||||||
struct KernAux_Multiboot2_ITagBase base;
|
struct KernAux_Multiboot2_ITagBase base;
|
||||||
|
|
||||||
|
// TODO: DATA?
|
||||||
}
|
}
|
||||||
KERNAUX_PACKED;
|
KERNAUX_PACKED;
|
||||||
|
|
||||||
|
@ -488,6 +508,8 @@ struct KernAux_Multiboot2_ITag_NetworkingInfo {
|
||||||
// type = 16
|
// type = 16
|
||||||
// size > 8
|
// size > 8
|
||||||
struct KernAux_Multiboot2_ITagBase base;
|
struct KernAux_Multiboot2_ITagBase base;
|
||||||
|
|
||||||
|
// TODO: DATA?
|
||||||
}
|
}
|
||||||
KERNAUX_PACKED;
|
KERNAUX_PACKED;
|
||||||
|
|
||||||
|
@ -500,6 +522,8 @@ struct KernAux_Multiboot2_ITag_EFIMemoryMap {
|
||||||
|
|
||||||
uint32_t descriptor_size;
|
uint32_t descriptor_size;
|
||||||
uint32_t descriptor_version;
|
uint32_t descriptor_version;
|
||||||
|
|
||||||
|
// TODO: DATA?
|
||||||
}
|
}
|
||||||
KERNAUX_PACKED;
|
KERNAUX_PACKED;
|
||||||
|
|
||||||
|
@ -581,256 +605,26 @@ const char *KernAux_Multiboot2_HTag_RelocatableHeader_Preference_to_str(
|
||||||
enum KernAux_Multiboot2_HTag_RelocatableHeader_Preference pref
|
enum KernAux_Multiboot2_HTag_RelocatableHeader_Preference pref
|
||||||
);
|
);
|
||||||
|
|
||||||
/************************************
|
/********************
|
||||||
* Information conversion functions *
|
* Helper functions *
|
||||||
************************************/
|
********************/
|
||||||
|
|
||||||
bool KernAux_Multiboot2_Info_to_memmap(
|
#include <kernaux/multiboot2/header_helpers.h>
|
||||||
const struct KernAux_Multiboot2_Info *multiboot2_info,
|
#include <kernaux/multiboot2/info_helpers.h>
|
||||||
KernAux_MemMap memmap
|
|
||||||
);
|
|
||||||
|
|
||||||
/***************************
|
/************************
|
||||||
* Header helper functions *
|
* Validation functions *
|
||||||
***************************/
|
************************/
|
||||||
|
|
||||||
const struct KernAux_Multiboot2_HTagBase
|
#include <kernaux/multiboot2/header_is_valid.h>
|
||||||
*KernAux_Multiboot2_Header_first_tag_with_type(
|
#include <kernaux/multiboot2/info_is_valid.h>
|
||||||
const struct KernAux_Multiboot2_Header *multiboot2_header,
|
|
||||||
enum KernAux_Multiboot2_HTag tag_type
|
|
||||||
);
|
|
||||||
|
|
||||||
const struct KernAux_Multiboot2_HTagBase
|
/*******************
|
||||||
*KernAux_Multiboot2_Header_tag_with_type_after(
|
* Print functions *
|
||||||
const struct KernAux_Multiboot2_Header *multiboot2_header,
|
*******************/
|
||||||
enum KernAux_Multiboot2_HTag tag_type,
|
|
||||||
const struct KernAux_Multiboot2_HTagBase *after_tag
|
|
||||||
);
|
|
||||||
|
|
||||||
/********************************
|
#include <kernaux/multiboot2/header_print.h>
|
||||||
* Information helper functions *
|
#include <kernaux/multiboot2/info_print.h>
|
||||||
********************************/
|
|
||||||
|
|
||||||
const struct KernAux_Multiboot2_ITagBase
|
|
||||||
*KernAux_Multiboot2_Info_first_tag_with_type(
|
|
||||||
const struct KernAux_Multiboot2_Info *multiboot2_info,
|
|
||||||
enum KernAux_Multiboot2_ITag tag_type
|
|
||||||
);
|
|
||||||
|
|
||||||
const struct KernAux_Multiboot2_ITagBase
|
|
||||||
*KernAux_Multiboot2_Info_tag_with_type_after(
|
|
||||||
const struct KernAux_Multiboot2_Info *multiboot2_info,
|
|
||||||
enum KernAux_Multiboot2_ITag tag_type,
|
|
||||||
const struct KernAux_Multiboot2_ITagBase *after_tag
|
|
||||||
);
|
|
||||||
|
|
||||||
const char *KernAux_Multiboot2_Info_boot_cmd_line(
|
|
||||||
const struct KernAux_Multiboot2_Info *multiboot2_info
|
|
||||||
);
|
|
||||||
|
|
||||||
/*******************************
|
|
||||||
* Header validation functions *
|
|
||||||
*******************************/
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_Header_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_Header *multiboot2_header
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_HTagBase_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_HTagBase *tag_base
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_HTag_None_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_HTag_None *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_HTag_InfoReq_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_HTag_InfoReq *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_HTag_Addr_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_HTag_Addr *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_HTag_EntryAddr_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_HTag_EntryAddr *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_HTag_Flags_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_HTag_Flags *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_HTag_Framebuffer_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_HTag_Framebuffer *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_HTag_ModuleAlign_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_HTag_ModuleAlign *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_HTag_EFIBootServices_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_HTag_EFIBootServices *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_HTag_EFII386EntryAddr_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_HTag_EFII386EntryAddr *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_HTag_EFIAmd64EntryAddr_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_HTag_EFIAmd64EntryAddr *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_HTag_RelocatableHeader_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_HTag_RelocatableHeader *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
/************************************
|
|
||||||
* Information validation functions *
|
|
||||||
************************************/
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_Info_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_Info *multiboot2_info
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITagBase_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITagBase *tag_base
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_None_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_None *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_BootCmdLine_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_BootCmdLine *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_BootLoaderName_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_BootLoaderName *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_Module_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_Module *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_BasicMemoryInfo_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_BasicMemoryInfo *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_BIOSBootDevice_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_BIOSBootDevice *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_MemoryMap_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_MemoryMap *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_VBEInfo_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_VBEInfo *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_FramebufferInfo_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_FramebufferInfo *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_ELFSymbols_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_ELFSymbols *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_APMTable_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_APMTable *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_EFI32bitSystemTablePtr_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_EFI32bitSystemTablePtr *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_EFI64bitSystemTablePtr_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_EFI64bitSystemTablePtr *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_SMBIOSTables_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_SMBIOSTables *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_ACPIOldRSDP_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_ACPIOldRSDP *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_ACPINewRSDP_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_ACPINewRSDP *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_NetworkingInfo_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_NetworkingInfo *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_EFIMemoryMap_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_EFIMemoryMap *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_EFIBootServicesNotTerminated_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_EFIBootServicesNotTerminated *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_EFI32bitImageHandlePtr_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_EFI32bitImageHandlePtr *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_EFI64bitImageHandlePtr_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_EFI64bitImageHandlePtr *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
bool KernAux_Multiboot2_ITag_ImageLoadBasePhysAddr_is_valid(
|
|
||||||
const struct KernAux_Multiboot2_ITag_ImageLoadBasePhysAddr *tag
|
|
||||||
);
|
|
||||||
|
|
||||||
/**************************
|
|
||||||
* Header print functions *
|
|
||||||
**************************/
|
|
||||||
|
|
||||||
void KernAux_Multiboot2_Header_print(
|
|
||||||
const struct KernAux_Multiboot2_Header *multiboot2_header,
|
|
||||||
KernAux_Display display
|
|
||||||
);
|
|
||||||
|
|
||||||
void KernAux_Multiboot2_HTagBase_print(
|
|
||||||
const struct KernAux_Multiboot2_HTagBase *tag_base,
|
|
||||||
KernAux_Display display
|
|
||||||
);
|
|
||||||
|
|
||||||
/*******************************
|
|
||||||
* Information print functions *
|
|
||||||
*******************************/
|
|
||||||
|
|
||||||
void KernAux_Multiboot2_Info_print(
|
|
||||||
const struct KernAux_Multiboot2_Info *multiboot2_info,
|
|
||||||
KernAux_Display display
|
|
||||||
);
|
|
||||||
|
|
||||||
void KernAux_Multiboot2_ITagBase_print(
|
|
||||||
const struct KernAux_Multiboot2_ITagBase *tag_base,
|
|
||||||
KernAux_Display display
|
|
||||||
);
|
|
||||||
|
|
||||||
void KernAux_Multiboot2_ITag_BootCmdLine_print(
|
|
||||||
const struct KernAux_Multiboot2_ITag_BootCmdLine *tag,
|
|
||||||
KernAux_Display display
|
|
||||||
);
|
|
||||||
|
|
||||||
void KernAux_Multiboot2_ITag_BootLoaderName_print(
|
|
||||||
const struct KernAux_Multiboot2_ITag_BootLoaderName *tag,
|
|
||||||
KernAux_Display display
|
|
||||||
);
|
|
||||||
|
|
||||||
void KernAux_Multiboot2_ITag_MemoryMap_print(
|
|
||||||
const struct KernAux_Multiboot2_ITag_MemoryMap *tag,
|
|
||||||
KernAux_Display display
|
|
||||||
);
|
|
||||||
|
|
||||||
void KernAux_Multiboot2_ITag_ELFSymbols_print(
|
|
||||||
const struct KernAux_Multiboot2_ITag_ELFSymbols *tag,
|
|
||||||
KernAux_Display display
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef KERNAUX_INCLUDED_MULTIBOOT2_HEADER_HELPERS
|
||||||
|
#define KERNAUX_INCLUDED_MULTIBOOT2_HEADER_HELPERS
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <kernaux/multiboot2.h>
|
||||||
|
|
||||||
|
const struct KernAux_Multiboot2_HTagBase
|
||||||
|
*KernAux_Multiboot2_Header_first_tag_with_type(
|
||||||
|
const struct KernAux_Multiboot2_Header *multiboot2_header,
|
||||||
|
enum KernAux_Multiboot2_HTag tag_type
|
||||||
|
);
|
||||||
|
|
||||||
|
const struct KernAux_Multiboot2_HTagBase
|
||||||
|
*KernAux_Multiboot2_Header_tag_with_type_after(
|
||||||
|
const struct KernAux_Multiboot2_Header *multiboot2_header,
|
||||||
|
enum KernAux_Multiboot2_HTag tag_type,
|
||||||
|
const struct KernAux_Multiboot2_HTagBase *after_tag
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,66 @@
|
||||||
|
#ifndef KERNAUX_INCLUDED_MULTIBOOT2_HEADER_IS_VALID
|
||||||
|
#define KERNAUX_INCLUDED_MULTIBOOT2_HEADER_IS_VALID
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <kernaux/multiboot2.h>
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_Header_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_Header *multiboot2_header
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_HTagBase_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_HTagBase *tag_base
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_HTag_None_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_HTag_None *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_HTag_InfoReq_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_HTag_InfoReq *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_HTag_Addr_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_HTag_Addr *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_HTag_EntryAddr_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_HTag_EntryAddr *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_HTag_Flags_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_HTag_Flags *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_HTag_Framebuffer_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_HTag_Framebuffer *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_HTag_ModuleAlign_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_HTag_ModuleAlign *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_HTag_EFIBootServices_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_HTag_EFIBootServices *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_HTag_EFII386EntryAddr_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_HTag_EFII386EntryAddr *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_HTag_EFIAmd64EntryAddr_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_HTag_EFIAmd64EntryAddr *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_HTag_RelocatableHeader_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_HTag_RelocatableHeader *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -10,6 +10,13 @@ extern "C" {
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define KERNAUX_MULTIBOOT2_HEADER_CHECKSUM(arch, total_size) \
|
||||||
|
((uint32_t)(-( \
|
||||||
|
((uint32_t)KERNAUX_MULTIBOOT2_HEADER_MAGIC) + \
|
||||||
|
((uint32_t)(arch)) + \
|
||||||
|
((uint32_t)(total_size)) \
|
||||||
|
)))
|
||||||
|
|
||||||
#define KERNAUX_MULTIBOOT2_HFIELDS_COMMON(name, type) \
|
#define KERNAUX_MULTIBOOT2_HFIELDS_COMMON(name, type) \
|
||||||
struct { \
|
struct { \
|
||||||
struct KernAux_Multiboot2_HTag_##type tag; \
|
struct KernAux_Multiboot2_HTag_##type tag; \
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
#ifndef KERNAUX_INCLUDED_MULTIBOOT2_HEADER_PRINT
|
||||||
|
#define KERNAUX_INCLUDED_MULTIBOOT2_HEADER_PRINT
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <kernaux/multiboot2.h>
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_Header_print(
|
||||||
|
const struct KernAux_Multiboot2_Header *multiboot2_header,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTagBase_print(
|
||||||
|
const struct KernAux_Multiboot2_HTagBase *tag_base,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_None_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_None *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_InfoReq_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_InfoReq *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_Addr_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_Addr *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_EntryAddr_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_EntryAddr *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_Flags_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_Flags *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_Framebuffer_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_Framebuffer *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_ModuleAlign_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_ModuleAlign *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_EFIBootServices_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_EFIBootServices *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_EFII386EntryAddr_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_EFII386EntryAddr *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_EFIAmd64EntryAddr_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_EFIAmd64EntryAddr *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_RelocatableHeader_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_RelocatableHeader *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef KERNAUX_INCLUDED_MULTIBOOT2_INFO_HELPERS
|
||||||
|
#define KERNAUX_INCLUDED_MULTIBOOT2_INFO_HELPERS
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <kernaux/multiboot2.h>
|
||||||
|
|
||||||
|
const struct KernAux_Multiboot2_ITagBase
|
||||||
|
*KernAux_Multiboot2_Info_first_tag_with_type(
|
||||||
|
const struct KernAux_Multiboot2_Info *multiboot2_info,
|
||||||
|
enum KernAux_Multiboot2_ITag tag_type
|
||||||
|
);
|
||||||
|
|
||||||
|
const struct KernAux_Multiboot2_ITagBase
|
||||||
|
*KernAux_Multiboot2_Info_tag_with_type_after(
|
||||||
|
const struct KernAux_Multiboot2_Info *multiboot2_info,
|
||||||
|
enum KernAux_Multiboot2_ITag tag_type,
|
||||||
|
const struct KernAux_Multiboot2_ITagBase *after_tag
|
||||||
|
);
|
||||||
|
|
||||||
|
const char *KernAux_Multiboot2_Info_boot_cmd_line(
|
||||||
|
const struct KernAux_Multiboot2_Info *multiboot2_info
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,110 @@
|
||||||
|
#ifndef KERNAUX_INCLUDED_MULTIBOOT2_INFO_IS_VALID
|
||||||
|
#define KERNAUX_INCLUDED_MULTIBOOT2_INFO_IS_VALID
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <kernaux/multiboot2.h>
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_Info_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_Info *multiboot2_info
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITagBase_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITagBase *tag_base
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_None_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_None *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_BootCmdLine_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_BootCmdLine *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_BootLoaderName_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_BootLoaderName *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_Module_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_Module *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_BasicMemoryInfo_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_BasicMemoryInfo *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_BIOSBootDevice_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_BIOSBootDevice *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_MemoryMap_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_MemoryMap *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_VBEInfo_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_VBEInfo *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_FramebufferInfo_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_FramebufferInfo *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_ELFSymbols_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_ELFSymbols *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_APMTable_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_APMTable *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_EFI32bitSystemTablePtr_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFI32bitSystemTablePtr *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_EFI64bitSystemTablePtr_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFI64bitSystemTablePtr *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_SMBIOSTables_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_SMBIOSTables *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_ACPIOldRSDP_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_ACPIOldRSDP *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_ACPINewRSDP_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_ACPINewRSDP *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_NetworkingInfo_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_NetworkingInfo *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_EFIMemoryMap_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFIMemoryMap *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_EFIBootServicesNotTerminated_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFIBootServicesNotTerminated *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_EFI32bitImageHandlePtr_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFI32bitImageHandlePtr *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_EFI64bitImageHandlePtr_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFI64bitImageHandlePtr *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
bool KernAux_Multiboot2_ITag_ImageLoadBasePhysAddr_is_valid(
|
||||||
|
const struct KernAux_Multiboot2_ITag_ImageLoadBasePhysAddr *tag
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,134 @@
|
||||||
|
#ifndef KERNAUX_INCLUDED_MULTIBOOT2_INFO_PRINT
|
||||||
|
#define KERNAUX_INCLUDED_MULTIBOOT2_INFO_PRINT
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <kernaux/multiboot2.h>
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_Info_print(
|
||||||
|
const struct KernAux_Multiboot2_Info *multiboot2_info,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITagBase_print(
|
||||||
|
const struct KernAux_Multiboot2_ITagBase *tag_base,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_None_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_None *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_BootCmdLine_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_BootCmdLine *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_BootLoaderName_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_BootLoaderName *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_Module_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_Module *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_BasicMemoryInfo_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_BasicMemoryInfo *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_BIOSBootDevice_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_BIOSBootDevice *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_MemoryMap_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_MemoryMap *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_VBEInfo_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_VBEInfo *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_FramebufferInfo_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_FramebufferInfo *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_ELFSymbols_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_ELFSymbols *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_APMTable_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_APMTable *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_EFI32bitSystemTablePtr_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFI32bitSystemTablePtr *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_EFI64bitSystemTablePtr_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFI64bitSystemTablePtr *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_SMBIOSTables_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_SMBIOSTables *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_ACPIOldRSDP_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_ACPIOldRSDP *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_ACPINewRSDP_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_ACPINewRSDP *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_NetworkingInfo_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_NetworkingInfo *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_EFIMemoryMap_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFIMemoryMap *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_EFIBootServicesNotTerminated_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFIBootServicesNotTerminated *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_EFI32bitImageHandlePtr_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFI32bitImageHandlePtr *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_EFI64bitImageHandlePtr_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFI64bitImageHandlePtr *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_ImageLoadBasePhysAddr_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_ImageLoadBasePhysAddr *tag,
|
||||||
|
KernAux_Display display
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -20,9 +20,11 @@ CPPCHECK_INC = \
|
||||||
-I$(top_srcdir)/include
|
-I$(top_srcdir)/include
|
||||||
|
|
||||||
CPPCHECK_SUPPRESS = \
|
CPPCHECK_SUPPRESS = \
|
||||||
--suppress='constArgument:$(top_srcdir)/examples/macro_cast.c' \
|
--suppress='constArgument:$(top_srcdir)/examples/macro_cast.c' \
|
||||||
--suppress='unusedStructMember:$(top_srcdir)/examples/*.c' \
|
--suppress='constParameter:$(top_srcdir)/examples/printf_file*.c' \
|
||||||
--suppress='unusedStructMember:$(top_srcdir)/tests/test_multiboot2_info_*.c'
|
--suppress='unusedStructMember:$(top_srcdir)/examples/*.c' \
|
||||||
|
--suppress='unusedStructMember:$(top_srcdir)/tests/test_multiboot2_info_*.c' \
|
||||||
|
--suppress='unusedVariable'
|
||||||
|
|
||||||
CPPCHECK_PATHS = \
|
CPPCHECK_PATHS = \
|
||||||
$(top_builddir)/examples \
|
$(top_builddir)/examples \
|
||||||
|
|
|
@ -13,7 +13,7 @@ const char *KernAux_Multiboot2_Header_Arch_to_str(
|
||||||
case KERNAUX_MULTIBOOT2_HEADER_ARCH_I386:
|
case KERNAUX_MULTIBOOT2_HEADER_ARCH_I386:
|
||||||
return "i386";
|
return "i386";
|
||||||
case KERNAUX_MULTIBOOT2_HEADER_ARCH_MIPS32:
|
case KERNAUX_MULTIBOOT2_HEADER_ARCH_MIPS32:
|
||||||
return "MIPS32"; // TODO: specify this architecture in README
|
return "MIPS32";
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,7 +248,6 @@ bool KernAux_Multiboot2_HTag_RelocatableHeader_is_valid(
|
||||||
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_RELOCATABLE_HEADER &&
|
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_RELOCATABLE_HEADER &&
|
||||||
tag->base.size == 24 &&
|
tag->base.size == 24 &&
|
||||||
tag->min_addr <= tag->max_addr
|
tag->min_addr <= tag->max_addr
|
||||||
// TODO: additional requirements?
|
|
||||||
)) {
|
)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,34 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define PRINTLN(s) KernAux_Display_println(display, s)
|
#define PRINTLN(s) do { KernAux_Display_println(display, s); } while (0)
|
||||||
|
|
||||||
|
#define PRINTF(format, ...) \
|
||||||
|
do { KernAux_Display_printf(display, format, __VA_ARGS__); } while (0)
|
||||||
#define PRINTLNF(format, ...) \
|
#define PRINTLNF(format, ...) \
|
||||||
KernAux_Display_printlnf(display, format, __VA_ARGS__)
|
do { KernAux_Display_printlnf(display, format, __VA_ARGS__); } while (0)
|
||||||
|
|
||||||
|
#define HEADER(Type) do { \
|
||||||
|
KERNAUX_ASSERT(tag); \
|
||||||
|
KERNAUX_ASSERT(display); \
|
||||||
|
\
|
||||||
|
if (!KernAux_Multiboot2_HTag_##Type##_is_valid(tag)) { \
|
||||||
|
PRINTLN("Multiboot 2 header tag // invalid!"); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, flags, tag->base.flags); \
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, size, tag->base.size); \
|
||||||
|
\
|
||||||
|
PRINTLN("Multiboot 2 header tag {"); \
|
||||||
|
PRINTLNF(" u16 type: %u (%s)", \
|
||||||
|
tag->base.type, \
|
||||||
|
KernAux_Multiboot2_HTag_to_str(tag->base.type) \
|
||||||
|
); \
|
||||||
|
PRINTLNF(" u16 flags: %lu", flags); \
|
||||||
|
PRINTLNF(" u32 size: %lu", size); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define FOOTER do { PRINTLN("}"); } while (0)
|
||||||
|
|
||||||
void KernAux_Multiboot2_Header_print(
|
void KernAux_Multiboot2_Header_print(
|
||||||
const struct KernAux_Multiboot2_Header *const multiboot2_header,
|
const struct KernAux_Multiboot2_Header *const multiboot2_header,
|
||||||
|
@ -25,14 +50,15 @@ void KernAux_Multiboot2_Header_print(
|
||||||
KERNAUX_CAST_CONST(unsigned long, total_size, multiboot2_header->total_size);
|
KERNAUX_CAST_CONST(unsigned long, total_size, multiboot2_header->total_size);
|
||||||
KERNAUX_CAST_CONST(unsigned long, checksum, multiboot2_header->checksum);
|
KERNAUX_CAST_CONST(unsigned long, checksum, multiboot2_header->checksum);
|
||||||
|
|
||||||
PRINTLN("Multiboot 2 header");
|
PRINTLN("Multiboot 2 header {");
|
||||||
PRINTLNF(" magic: %lu", magic);
|
PRINTLNF(" u32 magic: %lu", magic);
|
||||||
PRINTLNF(" arch: %u (%s)",
|
PRINTLNF(" u32 arch: %u (%s)",
|
||||||
multiboot2_header->arch,
|
multiboot2_header->arch,
|
||||||
KernAux_Multiboot2_Header_Arch_to_str(multiboot2_header->arch)
|
KernAux_Multiboot2_Header_Arch_to_str(multiboot2_header->arch)
|
||||||
);
|
);
|
||||||
PRINTLNF(" size: %lu", total_size);
|
PRINTLNF(" u32 size: %lu", total_size);
|
||||||
PRINTLNF(" checksum: %lu", checksum);
|
PRINTLNF(" u32 checksum: %lu", checksum);
|
||||||
|
PRINTLN("}");
|
||||||
|
|
||||||
const struct KernAux_Multiboot2_HTagBase *tag_base =
|
const struct KernAux_Multiboot2_HTagBase *tag_base =
|
||||||
(struct KernAux_Multiboot2_HTagBase*)
|
(struct KernAux_Multiboot2_HTagBase*)
|
||||||
|
@ -43,9 +69,7 @@ void KernAux_Multiboot2_Header_print(
|
||||||
((uint8_t*)multiboot2_header + multiboot2_header->total_size))
|
((uint8_t*)multiboot2_header + multiboot2_header->total_size))
|
||||||
{
|
{
|
||||||
if (!KernAux_Multiboot2_HTagBase_is_valid(tag_base)) return;
|
if (!KernAux_Multiboot2_HTagBase_is_valid(tag_base)) return;
|
||||||
|
|
||||||
KernAux_Multiboot2_HTagBase_print(tag_base, display);
|
KernAux_Multiboot2_HTagBase_print(tag_base, display);
|
||||||
|
|
||||||
tag_base = KERNAUX_MULTIBOOT2_HTAG_NEXT(tag_base);
|
tag_base = KERNAUX_MULTIBOOT2_HTAG_NEXT(tag_base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,71 +81,267 @@ void KernAux_Multiboot2_HTagBase_print(
|
||||||
KERNAUX_ASSERT(tag_base);
|
KERNAUX_ASSERT(tag_base);
|
||||||
KERNAUX_ASSERT(display);
|
KERNAUX_ASSERT(display);
|
||||||
|
|
||||||
if (!KernAux_Multiboot2_HTagBase_is_valid(tag_base)) return;
|
|
||||||
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, flags, tag_base->flags);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, size, tag_base->size);
|
|
||||||
|
|
||||||
PRINTLN("Multiboot 2 header tag");
|
|
||||||
PRINTLNF(" type: %u (%s)",
|
|
||||||
tag_base->type,
|
|
||||||
KernAux_Multiboot2_HTag_to_str(tag_base->type)
|
|
||||||
);
|
|
||||||
PRINTLNF(" flags: %lu", flags);
|
|
||||||
PRINTLNF(" size: %lu", size);
|
|
||||||
|
|
||||||
switch (tag_base->type) {
|
switch (tag_base->type) {
|
||||||
case KERNAUX_MULTIBOOT2_HTAG_NONE:
|
case KERNAUX_MULTIBOOT2_HTAG_NONE:
|
||||||
|
KernAux_Multiboot2_HTag_None_print(
|
||||||
|
(struct KernAux_Multiboot2_HTag_None*)tag_base,
|
||||||
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_HTAG_INFO_REQ:
|
case KERNAUX_MULTIBOOT2_HTAG_INFO_REQ:
|
||||||
{
|
KernAux_Multiboot2_HTag_InfoReq_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_HTag_InfoReq*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_HTAG_ADDR:
|
case KERNAUX_MULTIBOOT2_HTAG_ADDR:
|
||||||
{
|
KernAux_Multiboot2_HTag_Addr_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_HTag_Addr*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_HTAG_ENTRY_ADDR:
|
case KERNAUX_MULTIBOOT2_HTAG_ENTRY_ADDR:
|
||||||
{
|
KernAux_Multiboot2_HTag_EntryAddr_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_HTag_EntryAddr*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_HTAG_FLAGS:
|
case KERNAUX_MULTIBOOT2_HTAG_FLAGS:
|
||||||
{
|
KernAux_Multiboot2_HTag_Flags_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_HTag_Flags*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_HTAG_FRAMEBUFFER:
|
case KERNAUX_MULTIBOOT2_HTAG_FRAMEBUFFER:
|
||||||
{
|
KernAux_Multiboot2_HTag_Framebuffer_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_HTag_Framebuffer*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_HTAG_MODULE_ALIGN:
|
case KERNAUX_MULTIBOOT2_HTAG_MODULE_ALIGN:
|
||||||
{
|
KernAux_Multiboot2_HTag_ModuleAlign_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_HTag_ModuleAlign*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_HTAG_EFI_BOOT_SERVICES:
|
case KERNAUX_MULTIBOOT2_HTAG_EFI_BOOT_SERVICES:
|
||||||
{
|
KernAux_Multiboot2_HTag_EFIBootServices_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_HTag_EFIBootServices*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_HTAG_EFI_I386_ENTRY_ADDR:
|
case KERNAUX_MULTIBOOT2_HTAG_EFI_I386_ENTRY_ADDR:
|
||||||
{
|
KernAux_Multiboot2_HTag_EFII386EntryAddr_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_HTag_EFII386EntryAddr*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_HTAG_EFI_AMD64_ENTRY_ADDR:
|
case KERNAUX_MULTIBOOT2_HTAG_EFI_AMD64_ENTRY_ADDR:
|
||||||
{
|
KernAux_Multiboot2_HTag_EFIAmd64EntryAddr_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_HTag_EFIAmd64EntryAddr*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_HTAG_RELOCATABLE_HEADER:
|
case KERNAUX_MULTIBOOT2_HTAG_RELOCATABLE_HEADER:
|
||||||
{
|
KernAux_Multiboot2_HTag_RelocatableHeader_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_HTag_RelocatableHeader*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_None_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_None *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(None);
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_InfoReq_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_InfoReq *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(InfoReq);
|
||||||
|
|
||||||
|
// Print data:
|
||||||
|
|
||||||
|
PRINTLN(" u32 mbi_tag_types[]: [");
|
||||||
|
|
||||||
|
const uint32_t *const mbi_tag_types =
|
||||||
|
(const uint32_t*)KERNAUX_MULTIBOOT2_DATA(tag);
|
||||||
|
|
||||||
|
for (
|
||||||
|
size_t index = 0;
|
||||||
|
index < (tag->base.size - sizeof(*tag)) / sizeof(uint32_t);
|
||||||
|
++index
|
||||||
|
) {
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, type, mbi_tag_types[index]);
|
||||||
|
|
||||||
|
PRINTLNF(" %lu (%s)",
|
||||||
|
type,
|
||||||
|
KernAux_Multiboot2_ITag_to_str(type)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
PRINTLN(" ]");
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_Addr_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_Addr *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(Addr);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, header_addr, tag->header_addr);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, load_addr, tag->load_addr);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, load_end_addr, tag->load_end_addr);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, bss_end_addr, tag->bss_end_addr);
|
||||||
|
|
||||||
|
PRINTLNF(" u32 header_addr: %lu", header_addr);
|
||||||
|
PRINTLNF(" u32 load_addr: %lu", load_addr);
|
||||||
|
PRINTLNF(" u32 load_end_addr: %lu", load_end_addr);
|
||||||
|
PRINTLNF(" u32 bss_end_addr: %lu", bss_end_addr);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_EntryAddr_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_EntryAddr *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(EntryAddr);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, entry_addr, tag->entry_addr);
|
||||||
|
|
||||||
|
PRINTLNF(" u32 entry_addr: %lu", entry_addr);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_Flags_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_Flags *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(Flags);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, console_flags, tag->console_flags);
|
||||||
|
|
||||||
|
PRINTF(" u32 console_flags: %lu (", console_flags);
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
uint32_t number;
|
||||||
|
const char *name;
|
||||||
|
} flags[] = {
|
||||||
|
{
|
||||||
|
.number = KERNAUX_MULTIBOOT2_HTAG_FLAGS_REQUIRE_CONSOLE,
|
||||||
|
.name = "REQUIRE_CONSOLE",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.number = KERNAUX_MULTIBOOT2_HTAG_FLAGS_EGA_SUPPORT,
|
||||||
|
.name = "EGA_SUPPORT",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool is_first = true;
|
||||||
|
for (size_t index = 0; index < sizeof(flags) / sizeof(flags[0]); ++index) {
|
||||||
|
if (tag->console_flags & flags[index].number) {
|
||||||
|
if (is_first) {
|
||||||
|
PRINTLN("");
|
||||||
|
} else {
|
||||||
|
PRINTLN(" |");
|
||||||
|
}
|
||||||
|
PRINTF(" %s", flags[index].name);
|
||||||
|
is_first = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_first) {
|
||||||
|
PRINTLN(")");
|
||||||
|
} else {
|
||||||
|
PRINTLN("");
|
||||||
|
PRINTLN(" )");
|
||||||
|
}
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_Framebuffer_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_Framebuffer *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(Framebuffer);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, width, tag->width);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, height, tag->height);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, depth, tag->depth);
|
||||||
|
|
||||||
|
PRINTLNF(" u32 width: %lu", width);
|
||||||
|
PRINTLNF(" u32 height: %lu", height);
|
||||||
|
PRINTLNF(" u32 depth: %lu", depth);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_ModuleAlign_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_ModuleAlign *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(ModuleAlign);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_EFIBootServices_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_EFIBootServices *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(EFIBootServices);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_EFII386EntryAddr_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_EFII386EntryAddr *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(EFII386EntryAddr);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, entry_addr, tag->entry_addr);
|
||||||
|
|
||||||
|
PRINTLNF(" u32 entry_addr: %lu", entry_addr);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_EFIAmd64EntryAddr_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_EFIAmd64EntryAddr *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(EFIAmd64EntryAddr);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, entry_addr, tag->entry_addr);
|
||||||
|
|
||||||
|
PRINTLNF(" u32 entry_addr: %lu", entry_addr);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_HTag_RelocatableHeader_print(
|
||||||
|
const struct KernAux_Multiboot2_HTag_RelocatableHeader *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(RelocatableHeader);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, min_addr, tag->min_addr);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, max_addr, tag->max_addr);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, align, tag->align);
|
||||||
|
|
||||||
|
PRINTLNF(" u32 min_addr: %lu", min_addr);
|
||||||
|
PRINTLNF(" u32 max_addr: %lu", max_addr);
|
||||||
|
PRINTLNF(" u32 align: %lu", align);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <kernaux/assert.h>
|
|
||||||
#include <kernaux/multiboot2.h>
|
|
||||||
|
|
||||||
#ifdef WITH_MEMMAP
|
|
||||||
#include <kernaux/memmap.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#ifdef WITH_MEMMAP
|
|
||||||
// TODO: implement this
|
|
||||||
bool KernAux_Multiboot2_Info_to_memmap(
|
|
||||||
const struct KernAux_Multiboot2_Info *multiboot2_info,
|
|
||||||
KernAux_MemMap memmap
|
|
||||||
) {
|
|
||||||
KERNAUX_ASSERT(multiboot2_info);
|
|
||||||
|
|
||||||
KernAux_MemMap_init(memmap, 0);
|
|
||||||
if (!KernAux_Multiboot2_Info_is_valid(multiboot2_info)) return false;
|
|
||||||
|
|
||||||
const struct KernAux_Multiboot2_ITagBase *const basic_memory_info_tag_base =
|
|
||||||
KernAux_Multiboot2_Info_first_tag_with_type(
|
|
||||||
multiboot2_info,
|
|
||||||
KERNAUX_MULTIBOOT2_ITAG_BASIC_MEMORY_INFO
|
|
||||||
);
|
|
||||||
const struct KernAux_Multiboot2_ITagBase *const memory_map_tag_base =
|
|
||||||
KernAux_Multiboot2_Info_first_tag_with_type(
|
|
||||||
multiboot2_info,
|
|
||||||
KERNAUX_MULTIBOOT2_ITAG_MEMORY_MAP
|
|
||||||
);
|
|
||||||
|
|
||||||
// FIXME: Basic memory info tag may not be provided by some boot loaders on
|
|
||||||
// EFI platforms if EFI boot services are enabled and available for the
|
|
||||||
// loaded image (EFI boot services not terminated tag exists in Multiboot2
|
|
||||||
// information structure).
|
|
||||||
if (basic_memory_info_tag_base == NULL || memory_map_tag_base == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct KernAux_Multiboot2_ITag_BasicMemoryInfo *const
|
|
||||||
basic_memory_info_tag =
|
|
||||||
(const struct KernAux_Multiboot2_ITag_BasicMemoryInfo*)
|
|
||||||
basic_memory_info_tag_base;
|
|
||||||
const struct KernAux_Multiboot2_ITag_MemoryMap *const
|
|
||||||
memory_map_tag =
|
|
||||||
(const struct KernAux_Multiboot2_ITag_MemoryMap*)
|
|
||||||
memory_map_tag_base;
|
|
||||||
|
|
||||||
// FIXME: The value returned for upper memory is maximally the address of
|
|
||||||
// the first upper memory hole minus 1 megabyte. It is not guaranteed to be
|
|
||||||
// this value.
|
|
||||||
const size_t memory_size = (size_t)basic_memory_info_tag->mem_upper * 1024;
|
|
||||||
KernAux_MemMap_init(memmap, memory_size);
|
|
||||||
|
|
||||||
(void)memory_map_tag;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -287,7 +287,7 @@ bool KernAux_Multiboot2_ITag_FramebufferInfo_is_valid(
|
||||||
KERNAUX_ASSERT(tag);
|
KERNAUX_ASSERT(tag);
|
||||||
return (
|
return (
|
||||||
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_FRAMEBUFFER_INFO &&
|
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_FRAMEBUFFER_INFO &&
|
||||||
tag->base.size >= 31
|
tag->base.size >= 32
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,10 +297,10 @@ bool KernAux_Multiboot2_ITag_ELFSymbols_is_valid(
|
||||||
KERNAUX_ASSERT(tag);
|
KERNAUX_ASSERT(tag);
|
||||||
return (
|
return (
|
||||||
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_ELF_SYMBOLS &&
|
tag->base.type == KERNAUX_MULTIBOOT2_ITAG_ELF_SYMBOLS &&
|
||||||
tag->base.size >= 16 &&
|
tag->base.size >= 20 &&
|
||||||
(
|
(
|
||||||
tag->ent_size == 0 ||
|
tag->entsize == 0 ||
|
||||||
(tag->base.size - 16) % tag->ent_size == 0
|
(tag->base.size - 20) % tag->entsize == 0
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,18 +3,40 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <kernaux/assert.h>
|
#include <kernaux/assert.h>
|
||||||
|
#include <kernaux/generic/display.h>
|
||||||
#include <kernaux/macro.h>
|
#include <kernaux/macro.h>
|
||||||
#include <kernaux/multiboot2.h>
|
#include <kernaux/multiboot2.h>
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
// TODO: create macro for this
|
#define PRINT(s) do { KernAux_Display_print (display, s); } while (0)
|
||||||
#define INT_IF(a, b) (sizeof(int) == sizeof(long) ? (a) : (b))
|
#define PRINTLN(s) do { KernAux_Display_println(display, s); } while (0)
|
||||||
|
|
||||||
#define PRINTLN(s) KernAux_Display_println(display, s)
|
#define PRINTF(format, ...) \
|
||||||
|
do { KernAux_Display_printf (display, format, __VA_ARGS__); } while (0)
|
||||||
#define PRINTLNF(format, ...) \
|
#define PRINTLNF(format, ...) \
|
||||||
KernAux_Display_printlnf(display, format, __VA_ARGS__)
|
do { KernAux_Display_printlnf(display, format, __VA_ARGS__); } while (0)
|
||||||
|
|
||||||
|
#define HEADER(Type) do { \
|
||||||
|
KERNAUX_ASSERT(tag); \
|
||||||
|
KERNAUX_ASSERT(display); \
|
||||||
|
\
|
||||||
|
if (!KernAux_Multiboot2_ITag_##Type##_is_valid(tag)) { \
|
||||||
|
PRINTLN("Multiboot 2 info tag // invalid!"); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, size, tag->base.size); \
|
||||||
|
\
|
||||||
|
PRINTLN("Multiboot 2 info tag {"); \
|
||||||
|
PRINTLNF(" u32 type: %u (%s)", \
|
||||||
|
tag->base.type, \
|
||||||
|
KernAux_Multiboot2_ITag_to_str(tag->base.type) \
|
||||||
|
); \
|
||||||
|
PRINTLNF(" u32 size: %lu", size); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define FOOTER do { PRINTLN("}"); } while (0)
|
||||||
|
|
||||||
void KernAux_Multiboot2_Info_print(
|
void KernAux_Multiboot2_Info_print(
|
||||||
const struct KernAux_Multiboot2_Info *const multiboot2_info,
|
const struct KernAux_Multiboot2_Info *const multiboot2_info,
|
||||||
|
@ -24,11 +46,12 @@ void KernAux_Multiboot2_Info_print(
|
||||||
KERNAUX_ASSERT(display);
|
KERNAUX_ASSERT(display);
|
||||||
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, total_size, multiboot2_info->total_size);
|
KERNAUX_CAST_CONST(unsigned long, total_size, multiboot2_info->total_size);
|
||||||
KERNAUX_CAST_CONST(unsigned long, reserved1, multiboot2_info->reserved1);
|
KERNAUX_CAST_CONST(unsigned long, reserved, multiboot2_info->reserved);
|
||||||
|
|
||||||
PRINTLN("Multiboot 2 info");
|
PRINTLN("Multiboot 2 info {");
|
||||||
PRINTLNF(" size: %lu", total_size);
|
PRINTLNF(" u32 size: %lu", total_size);
|
||||||
PRINTLNF(" reserved1: %lu", reserved1);
|
PRINTLNF(" u32 reserved: %lu", reserved);
|
||||||
|
PRINTLN("}");
|
||||||
|
|
||||||
const struct KernAux_Multiboot2_ITagBase *tag_base =
|
const struct KernAux_Multiboot2_ITagBase *tag_base =
|
||||||
(struct KernAux_Multiboot2_ITagBase*)
|
(struct KernAux_Multiboot2_ITagBase*)
|
||||||
|
@ -39,9 +62,7 @@ void KernAux_Multiboot2_Info_print(
|
||||||
((uint8_t*)multiboot2_info + multiboot2_info->total_size))
|
((uint8_t*)multiboot2_info + multiboot2_info->total_size))
|
||||||
{
|
{
|
||||||
if (!KernAux_Multiboot2_ITagBase_is_valid(tag_base)) return;
|
if (!KernAux_Multiboot2_ITagBase_is_valid(tag_base)) return;
|
||||||
|
|
||||||
KernAux_Multiboot2_ITagBase_print(tag_base, display);
|
KernAux_Multiboot2_ITagBase_print(tag_base, display);
|
||||||
|
|
||||||
tag_base = KERNAUX_MULTIBOOT2_ITAG_NEXT(tag_base);
|
tag_base = KERNAUX_MULTIBOOT2_ITAG_NEXT(tag_base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,20 +74,12 @@ void KernAux_Multiboot2_ITagBase_print(
|
||||||
KERNAUX_ASSERT(tag_base);
|
KERNAUX_ASSERT(tag_base);
|
||||||
KERNAUX_ASSERT(display);
|
KERNAUX_ASSERT(display);
|
||||||
|
|
||||||
if (!KernAux_Multiboot2_ITagBase_is_valid(tag_base)) return;
|
|
||||||
|
|
||||||
PRINTLN("Multiboot 2 info tag");
|
|
||||||
|
|
||||||
PRINTLNF(" type: %u (%s)",
|
|
||||||
tag_base->type,
|
|
||||||
KernAux_Multiboot2_ITag_to_str(tag_base->type)
|
|
||||||
);
|
|
||||||
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, size, tag_base->size);
|
|
||||||
PRINTLNF(" size: %lu", size);
|
|
||||||
|
|
||||||
switch (tag_base->type) {
|
switch (tag_base->type) {
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_NONE:
|
case KERNAUX_MULTIBOOT2_ITAG_NONE:
|
||||||
|
KernAux_Multiboot2_ITag_None_print(
|
||||||
|
(struct KernAux_Multiboot2_ITag_None*)tag_base,
|
||||||
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_BOOT_CMD_LINE:
|
case KERNAUX_MULTIBOOT2_ITAG_BOOT_CMD_LINE:
|
||||||
KernAux_Multiboot2_ITag_BootCmdLine_print(
|
KernAux_Multiboot2_ITag_BootCmdLine_print(
|
||||||
|
@ -81,43 +94,22 @@ void KernAux_Multiboot2_ITagBase_print(
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_MODULE:
|
case KERNAUX_MULTIBOOT2_ITAG_MODULE:
|
||||||
{
|
KernAux_Multiboot2_ITag_Module_print(
|
||||||
const struct KernAux_Multiboot2_ITag_Module *const tag_module =
|
(struct KernAux_Multiboot2_ITag_Module*)tag_base,
|
||||||
(struct KernAux_Multiboot2_ITag_Module*)tag_base;
|
display
|
||||||
|
);
|
||||||
KERNAUX_CAST_CONST(unsigned long, mod_start, tag_module->mod_start);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, mod_end, tag_module->mod_end);
|
|
||||||
|
|
||||||
PRINTLNF(" start: %lu", mod_start);
|
|
||||||
PRINTLNF(" end: %lu", mod_end);
|
|
||||||
PRINTLNF(" cmdline: %s", KERNAUX_MULTIBOOT2_DATA(tag_module));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_BASIC_MEMORY_INFO:
|
case KERNAUX_MULTIBOOT2_ITAG_BASIC_MEMORY_INFO:
|
||||||
{
|
KernAux_Multiboot2_ITag_BasicMemoryInfo_print(
|
||||||
const struct KernAux_Multiboot2_ITag_BasicMemoryInfo *const tag_bmi =
|
(struct KernAux_Multiboot2_ITag_BasicMemoryInfo*)tag_base,
|
||||||
(struct KernAux_Multiboot2_ITag_BasicMemoryInfo*)tag_base;
|
display
|
||||||
|
);
|
||||||
KERNAUX_CAST_CONST(unsigned long, mem_lower, tag_bmi->mem_lower);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, mem_upper, tag_bmi->mem_upper);
|
|
||||||
|
|
||||||
PRINTLNF(" mem lower: %lu", mem_lower);
|
|
||||||
PRINTLNF(" mem upper: %lu", mem_upper);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE:
|
case KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE:
|
||||||
{
|
KernAux_Multiboot2_ITag_BIOSBootDevice_print(
|
||||||
const struct KernAux_Multiboot2_ITag_BIOSBootDevice *const tag_bbd =
|
(struct KernAux_Multiboot2_ITag_BIOSBootDevice*)tag_base,
|
||||||
(struct KernAux_Multiboot2_ITag_BIOSBootDevice*)tag_base;
|
display
|
||||||
|
);
|
||||||
KERNAUX_CAST_CONST(unsigned long, bios_dev, tag_bbd->bios_dev);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, partition, tag_bbd->partition);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, sub_partition, tag_bbd->sub_partition);
|
|
||||||
|
|
||||||
PRINTLNF(" bios dev: %lu", bios_dev);
|
|
||||||
PRINTLNF(" partition: %lu", partition);
|
|
||||||
PRINTLNF(" sub_partition: %lu", sub_partition);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_MEMORY_MAP:
|
case KERNAUX_MULTIBOOT2_ITAG_MEMORY_MAP:
|
||||||
KernAux_Multiboot2_ITag_MemoryMap_print(
|
KernAux_Multiboot2_ITag_MemoryMap_print(
|
||||||
|
@ -126,42 +118,16 @@ void KernAux_Multiboot2_ITagBase_print(
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_VBE_INFO:
|
case KERNAUX_MULTIBOOT2_ITAG_VBE_INFO:
|
||||||
{
|
KernAux_Multiboot2_ITag_VBEInfo_print(
|
||||||
const struct KernAux_Multiboot2_ITag_VBEInfo *const tag_vbe =
|
(struct KernAux_Multiboot2_ITag_VBEInfo*)tag_base,
|
||||||
(struct KernAux_Multiboot2_ITag_VBEInfo*)tag_base;
|
display
|
||||||
|
);
|
||||||
KERNAUX_CAST_CONST(unsigned long, vbe_mode, tag_vbe->vbe_mode);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, vbe_interface_seg, tag_vbe->vbe_interface_seg);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, vbe_interface_off, tag_vbe->vbe_interface_off);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, vbe_interface_len, tag_vbe->vbe_interface_len);
|
|
||||||
|
|
||||||
PRINTLNF(" VBE mode: %lu", vbe_mode);
|
|
||||||
PRINTLNF(" VBE interface seg: %lu", vbe_interface_seg);
|
|
||||||
PRINTLNF(" VBE interface off: %lu", vbe_interface_off);
|
|
||||||
PRINTLNF(" VBE interface len: %lu", vbe_interface_len);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_FRAMEBUFFER_INFO:
|
case KERNAUX_MULTIBOOT2_ITAG_FRAMEBUFFER_INFO:
|
||||||
{
|
KernAux_Multiboot2_ITag_FramebufferInfo_print(
|
||||||
const struct KernAux_Multiboot2_ITag_FramebufferInfo *const tag_fb =
|
(struct KernAux_Multiboot2_ITag_FramebufferInfo*)tag_base,
|
||||||
(struct KernAux_Multiboot2_ITag_FramebufferInfo*)tag_base;
|
display
|
||||||
|
);
|
||||||
KERNAUX_CAST_CONST(unsigned long long, framebuffer_addr, tag_fb->framebuffer_addr);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, framebuffer_pitch, tag_fb->framebuffer_pitch);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, framebuffer_width, tag_fb->framebuffer_width);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, framebuffer_height, tag_fb->framebuffer_height);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, framebuffer_bpp, tag_fb->framebuffer_bpp);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, framebuffer_type, tag_fb->framebuffer_type);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, reserved1, tag_fb->reserved1);
|
|
||||||
|
|
||||||
PRINTLNF(" framebuffer addr: %llu", framebuffer_addr);
|
|
||||||
PRINTLNF(" framebuffer pitch: %lu", framebuffer_pitch);
|
|
||||||
PRINTLNF(" framebuffer width: %lu", framebuffer_width);
|
|
||||||
PRINTLNF(" framebuffer height: %lu", framebuffer_height);
|
|
||||||
PRINTLNF(" framebuffer bpp: %lu", framebuffer_bpp);
|
|
||||||
PRINTLNF(" framebuffer type: %lu", framebuffer_type);
|
|
||||||
PRINTLNF(" reserved1: %lu", reserved1);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_ELF_SYMBOLS:
|
case KERNAUX_MULTIBOOT2_ITAG_ELF_SYMBOLS:
|
||||||
KernAux_Multiboot2_ITag_ELFSymbols_print(
|
KernAux_Multiboot2_ITag_ELFSymbols_print(
|
||||||
|
@ -170,159 +136,178 @@ void KernAux_Multiboot2_ITagBase_print(
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_APM_TABLE:
|
case KERNAUX_MULTIBOOT2_ITAG_APM_TABLE:
|
||||||
{
|
KernAux_Multiboot2_ITag_APMTable_print(
|
||||||
const struct KernAux_Multiboot2_ITag_APMTable *const tag_apm =
|
(struct KernAux_Multiboot2_ITag_APMTable*)tag_base,
|
||||||
(struct KernAux_Multiboot2_ITag_APMTable*)tag_base;
|
display
|
||||||
|
);
|
||||||
KERNAUX_CAST_CONST(unsigned long, version, tag_apm->version);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, cseg, tag_apm->cseg);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, offset, tag_apm->offset);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, cseg_16, tag_apm->cseg_16);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, dseg, tag_apm->dseg);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, flags, tag_apm->flags);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, cseg_len, tag_apm->cseg_len);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, cseg_16_len, tag_apm->cseg_16_len);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, dseg_len, tag_apm->dseg_len);
|
|
||||||
|
|
||||||
PRINTLNF(" version: %lu", version);
|
|
||||||
PRINTLNF(" cseg: %lu", cseg);
|
|
||||||
PRINTLNF(" offset: %lu", offset);
|
|
||||||
PRINTLNF(" cseg 16: %lu", cseg_16);
|
|
||||||
PRINTLNF(" dseg: %lu", dseg);
|
|
||||||
PRINTLNF(" flags: %lu", flags);
|
|
||||||
PRINTLNF(" cseg len: %lu", cseg_len);
|
|
||||||
PRINTLNF(" cseg 16 len: %lu", cseg_16_len);
|
|
||||||
PRINTLNF(" dseg len: %lu", dseg_len);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_EFI_32BIT_SYSTEM_TABLE_PTR:
|
case KERNAUX_MULTIBOOT2_ITAG_EFI_32BIT_SYSTEM_TABLE_PTR:
|
||||||
{
|
KernAux_Multiboot2_ITag_EFI32bitSystemTablePtr_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_ITag_EFI32bitSystemTablePtr*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_EFI_64BIT_SYSTEM_TABLE_PTR:
|
case KERNAUX_MULTIBOOT2_ITAG_EFI_64BIT_SYSTEM_TABLE_PTR:
|
||||||
{
|
KernAux_Multiboot2_ITag_EFI64bitSystemTablePtr_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_ITag_EFI64bitSystemTablePtr*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_SMBIOS_TABLES:
|
case KERNAUX_MULTIBOOT2_ITAG_SMBIOS_TABLES:
|
||||||
{
|
KernAux_Multiboot2_ITag_SMBIOSTables_print(
|
||||||
const struct KernAux_Multiboot2_ITag_SMBIOSTables *const tag_smbios =
|
(struct KernAux_Multiboot2_ITag_SMBIOSTables*)tag_base,
|
||||||
(struct KernAux_Multiboot2_ITag_SMBIOSTables*)tag_base;
|
display
|
||||||
|
);
|
||||||
KERNAUX_CAST_CONST(unsigned long, major, tag_smbios->major);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, minor, tag_smbios->minor);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, reserved0, tag_smbios->reserved1[0]);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, reserved1, tag_smbios->reserved1[1]);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, reserved2, tag_smbios->reserved1[2]);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, reserved3, tag_smbios->reserved1[3]);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, reserved4, tag_smbios->reserved1[4]);
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, reserved5, tag_smbios->reserved1[5]);
|
|
||||||
|
|
||||||
PRINTLNF(" major: %lu", major);
|
|
||||||
PRINTLNF(" minor: %lu", minor);
|
|
||||||
|
|
||||||
PRINTLNF(
|
|
||||||
" reserved1: {%lu, %lu, %lu, %lu, %lu, %lu}",
|
|
||||||
reserved0, reserved1, reserved2,
|
|
||||||
reserved3, reserved4, reserved5
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_ACPI_OLD_RSDP:
|
case KERNAUX_MULTIBOOT2_ITAG_ACPI_OLD_RSDP:
|
||||||
{
|
KernAux_Multiboot2_ITag_ACPIOldRSDP_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_ITag_ACPIOldRSDP*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_ACPI_NEW_RSDP:
|
case KERNAUX_MULTIBOOT2_ITAG_ACPI_NEW_RSDP:
|
||||||
{
|
KernAux_Multiboot2_ITag_ACPINewRSDP_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_ITag_ACPINewRSDP*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_NETWORKING_INFO:
|
case KERNAUX_MULTIBOOT2_ITAG_NETWORKING_INFO:
|
||||||
{
|
KernAux_Multiboot2_ITag_NetworkingInfo_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_ITag_NetworkingInfo*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_EFI_MEMORY_MAP:
|
case KERNAUX_MULTIBOOT2_ITAG_EFI_MEMORY_MAP:
|
||||||
{
|
KernAux_Multiboot2_ITag_EFIMemoryMap_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_ITag_EFIMemoryMap*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_EFI_BOOT_SERVICES_NOT_TERMINATED:
|
case KERNAUX_MULTIBOOT2_ITAG_EFI_BOOT_SERVICES_NOT_TERMINATED:
|
||||||
|
KernAux_Multiboot2_ITag_EFIBootServicesNotTerminated_print(
|
||||||
|
(struct KernAux_Multiboot2_ITag_EFIBootServicesNotTerminated*)
|
||||||
|
tag_base,
|
||||||
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_EFI_32BIT_IMAGE_HANDLE_PTR:
|
case KERNAUX_MULTIBOOT2_ITAG_EFI_32BIT_IMAGE_HANDLE_PTR:
|
||||||
{
|
KernAux_Multiboot2_ITag_EFI32bitImageHandlePtr_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_ITag_EFI32bitImageHandlePtr*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_EFI_64BIT_IMAGE_HANDLE_PTR:
|
case KERNAUX_MULTIBOOT2_ITAG_EFI_64BIT_IMAGE_HANDLE_PTR:
|
||||||
{
|
KernAux_Multiboot2_ITag_EFI64bitImageHandlePtr_print(
|
||||||
// TODO: print
|
(struct KernAux_Multiboot2_ITag_EFI64bitImageHandlePtr*)tag_base,
|
||||||
}
|
display
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case KERNAUX_MULTIBOOT2_ITAG_IMAGE_LOAD_BASE_PHYS_ADDR:
|
case KERNAUX_MULTIBOOT2_ITAG_IMAGE_LOAD_BASE_PHYS_ADDR:
|
||||||
{
|
KernAux_Multiboot2_ITag_ImageLoadBasePhysAddr_print(
|
||||||
KERNAUX_CAST_CONST(
|
(struct KernAux_Multiboot2_ITag_ImageLoadBasePhysAddr*)tag_base,
|
||||||
unsigned long,
|
display
|
||||||
load_base_addr,
|
);
|
||||||
((struct KernAux_Multiboot2_ITag_ImageLoadBasePhysAddr*)
|
|
||||||
tag_base)->load_base_addr
|
|
||||||
);
|
|
||||||
PRINTLNF(" load base addr: %lu", load_base_addr);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_None_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_None *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(None);
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
void KernAux_Multiboot2_ITag_BootCmdLine_print(
|
void KernAux_Multiboot2_ITag_BootCmdLine_print(
|
||||||
const struct KernAux_Multiboot2_ITag_BootCmdLine *const tag,
|
const struct KernAux_Multiboot2_ITag_BootCmdLine *const tag,
|
||||||
const KernAux_Display display
|
const KernAux_Display display
|
||||||
) {
|
) {
|
||||||
KERNAUX_ASSERT(tag);
|
HEADER(BootCmdLine);
|
||||||
KERNAUX_ASSERT(display);
|
|
||||||
|
|
||||||
if (!KernAux_Multiboot2_ITag_BootCmdLine_is_valid(tag)) {
|
// Print data:
|
||||||
PRINTLN(" invalid!");
|
PRINTLNF(" char cmdline[]: \"%s\"", KERNAUX_MULTIBOOT2_DATA(tag));
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRINTLNF(" cmdline: %s", KERNAUX_MULTIBOOT2_DATA(tag));
|
FOOTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernAux_Multiboot2_ITag_BootLoaderName_print(
|
void KernAux_Multiboot2_ITag_BootLoaderName_print(
|
||||||
const struct KernAux_Multiboot2_ITag_BootLoaderName *const tag,
|
const struct KernAux_Multiboot2_ITag_BootLoaderName *const tag,
|
||||||
const KernAux_Display display
|
const KernAux_Display display
|
||||||
) {
|
) {
|
||||||
KERNAUX_ASSERT(tag);
|
HEADER(BootLoaderName);
|
||||||
KERNAUX_ASSERT(display);
|
|
||||||
|
|
||||||
if (!KernAux_Multiboot2_ITag_BootLoaderName_is_valid(tag)) {
|
// Print data:
|
||||||
PRINTLN(" invalid!");
|
PRINTLNF(" char name[]: \"%s\"", KERNAUX_MULTIBOOT2_DATA(tag));
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRINTLNF(" name: %s", KERNAUX_MULTIBOOT2_DATA(tag));
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_Module_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_Module *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(Module);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, mod_start, tag->mod_start);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, mod_end, tag->mod_end);
|
||||||
|
|
||||||
|
PRINTLNF(" u32 mod_start: %lu", mod_start);
|
||||||
|
PRINTLNF(" u32 mod_end: %lu", mod_end);
|
||||||
|
|
||||||
|
// Print data:
|
||||||
|
PRINTLNF(" char cmdline[]: \"%s\"", KERNAUX_MULTIBOOT2_DATA(tag));
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_BasicMemoryInfo_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_BasicMemoryInfo *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(BasicMemoryInfo);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, mem_lower, tag->mem_lower);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, mem_upper, tag->mem_upper);
|
||||||
|
|
||||||
|
PRINTLNF(" u32 mem_lower: %lu", mem_lower);
|
||||||
|
PRINTLNF(" u32 mem_upper: %lu", mem_upper);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_BIOSBootDevice_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_BIOSBootDevice *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(BIOSBootDevice);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, biosdev, tag->biosdev);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, partition, tag->partition);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, sub_partition, tag->sub_partition);
|
||||||
|
|
||||||
|
PRINTLNF(" u32 biosdev: %lu", biosdev);
|
||||||
|
PRINTLNF(" u32 partition: %lu", partition);
|
||||||
|
PRINTLNF(" u32 sub_partition: %lu", sub_partition);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernAux_Multiboot2_ITag_MemoryMap_print(
|
void KernAux_Multiboot2_ITag_MemoryMap_print(
|
||||||
const struct KernAux_Multiboot2_ITag_MemoryMap *const tag,
|
const struct KernAux_Multiboot2_ITag_MemoryMap *const tag,
|
||||||
const KernAux_Display display
|
const KernAux_Display display
|
||||||
) {
|
) {
|
||||||
KERNAUX_ASSERT(tag);
|
HEADER(MemoryMap);
|
||||||
KERNAUX_ASSERT(display);
|
|
||||||
|
|
||||||
if (!KernAux_Multiboot2_ITag_MemoryMap_is_valid(tag)) {
|
|
||||||
PRINTLN(" invalid!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, entry_size, tag->entry_size);
|
KERNAUX_CAST_CONST(unsigned long, entry_size, tag->entry_size);
|
||||||
KERNAUX_CAST_CONST(unsigned long, entry_version, tag->entry_version);
|
KERNAUX_CAST_CONST(unsigned long, entry_version, tag->entry_version);
|
||||||
|
|
||||||
PRINTLNF(" entry size: %lu", entry_size);
|
PRINTLNF(" u32 entry_size: %lu", entry_size);
|
||||||
PRINTLNF(" entry version: %lu", entry_version);
|
PRINTLNF(" u32 entry_version: %lu", entry_version);
|
||||||
PRINTLN(" entries:");
|
|
||||||
|
// Print data:
|
||||||
|
|
||||||
|
PRINTLN (" varies(entry_size) entries[]: [");
|
||||||
|
|
||||||
const struct KernAux_Multiboot2_ITag_MemoryMap_EntryBase *const entries =
|
const struct KernAux_Multiboot2_ITag_MemoryMap_EntryBase *const entries =
|
||||||
(struct KernAux_Multiboot2_ITag_MemoryMap_EntryBase*)
|
(struct KernAux_Multiboot2_ITag_MemoryMap_EntryBase*)
|
||||||
|
@ -336,37 +321,291 @@ void KernAux_Multiboot2_ITag_MemoryMap_print(
|
||||||
KERNAUX_CAST_CONST(unsigned long long, base_addr, entries[index].base_addr);
|
KERNAUX_CAST_CONST(unsigned long long, base_addr, entries[index].base_addr);
|
||||||
KERNAUX_CAST_CONST(unsigned long long, length, entries[index].length);
|
KERNAUX_CAST_CONST(unsigned long long, length, entries[index].length);
|
||||||
KERNAUX_CAST_CONST(unsigned long, type, entries[index].type);
|
KERNAUX_CAST_CONST(unsigned long, type, entries[index].type);
|
||||||
KERNAUX_CAST_CONST(unsigned long, reserved1, entries[index].reserved1);
|
KERNAUX_CAST_CONST(unsigned long, reserved, entries[index].reserved);
|
||||||
|
|
||||||
PRINTLNF(" entry %zu", index);
|
PRINTLNF(" [%zu] entry: {", index);
|
||||||
PRINTLNF(" base addr: %llu", base_addr);
|
PRINTLNF(" u64 base_addr: %llu", base_addr);
|
||||||
PRINTLNF(" length: %llu", length);
|
PRINTLNF(" u64 length: %llu", length);
|
||||||
PRINTLNF(" type: %lu", type);
|
PRINTLNF(" u32 type: %lu", type);
|
||||||
PRINTLNF(" reserved1: %lu", reserved1);
|
PRINTLNF(" u32 reserved: %lu", reserved);
|
||||||
|
PRINTLN (" }");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRINTLN(" ]");
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_VBEInfo_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_VBEInfo *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(VBEInfo);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, mode, tag->vbe_mode);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, interface_seg, tag->vbe_interface_seg);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, interface_off, tag->vbe_interface_off);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, interface_len, tag->vbe_interface_len);
|
||||||
|
|
||||||
|
PRINTLNF(" u16 vbe_mode: %lu", mode);
|
||||||
|
PRINTLNF(" u16 vbe_interface_seg: %lu", interface_seg);
|
||||||
|
PRINTLNF(" u16 vbe_interface_off: %lu", interface_off);
|
||||||
|
PRINTLNF(" u16 vbe_interface_len: %lu", interface_len);
|
||||||
|
|
||||||
|
const size_t cols = 16;
|
||||||
|
|
||||||
|
PRINTLN (" u8 vbe_control_info[]: [");
|
||||||
|
for (
|
||||||
|
size_t index = 0;
|
||||||
|
index < sizeof(tag->vbe_control_info) / sizeof(tag->vbe_control_info[0]);
|
||||||
|
index += cols
|
||||||
|
) {
|
||||||
|
PRINTF(" %-3u", tag->vbe_control_info[index]);
|
||||||
|
for (size_t col = 1; col < cols; ++col) {
|
||||||
|
PRINTF(" %-3u", tag->vbe_control_info[index + col]);
|
||||||
|
}
|
||||||
|
PRINTLN("");
|
||||||
|
}
|
||||||
|
PRINTLN (" ]");
|
||||||
|
|
||||||
|
PRINTLN (" u8 vbe_mode_info[]: [");
|
||||||
|
for (
|
||||||
|
size_t index = 0;
|
||||||
|
index < sizeof(tag->vbe_mode_info) / sizeof(tag->vbe_mode_info[0]);
|
||||||
|
index += cols
|
||||||
|
) {
|
||||||
|
PRINTF(" %-3u", tag->vbe_mode_info[index]);
|
||||||
|
for (size_t col = 1; col < cols; ++col) {
|
||||||
|
PRINTF(" %-3u", tag->vbe_mode_info[index + col]);
|
||||||
|
}
|
||||||
|
PRINTLN("");
|
||||||
|
}
|
||||||
|
PRINTLN (" ]");
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_FramebufferInfo_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_FramebufferInfo *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(FramebufferInfo);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long long, addr, tag->framebuffer_addr);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, pitch, tag->framebuffer_pitch);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, width, tag->framebuffer_width);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, height, tag->framebuffer_height);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, bpp, tag->framebuffer_bpp);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, type, tag->framebuffer_type);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, reserved, tag->reserved);
|
||||||
|
|
||||||
|
PRINTLNF(" u64 framebuffer_addr: %llu", addr);
|
||||||
|
PRINTLNF(" u32 framebuffer_pitch: %lu", pitch);
|
||||||
|
PRINTLNF(" u32 framebuffer_width: %lu", width);
|
||||||
|
PRINTLNF(" u32 framebuffer_height: %lu", height);
|
||||||
|
PRINTLNF(" u8 framebuffer_bpp: %lu", bpp);
|
||||||
|
PRINTLNF(" u8 framebuffer_type: %lu", type);
|
||||||
|
PRINTLNF(" u16 reserved: %lu", reserved);
|
||||||
|
|
||||||
|
// TODO: Print data?
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernAux_Multiboot2_ITag_ELFSymbols_print(
|
void KernAux_Multiboot2_ITag_ELFSymbols_print(
|
||||||
const struct KernAux_Multiboot2_ITag_ELFSymbols *const tag,
|
const struct KernAux_Multiboot2_ITag_ELFSymbols *const tag,
|
||||||
const KernAux_Display display
|
const KernAux_Display display
|
||||||
) {
|
) {
|
||||||
KERNAUX_ASSERT(tag);
|
HEADER(ELFSymbols);
|
||||||
KERNAUX_ASSERT(display);
|
|
||||||
|
|
||||||
if (!KernAux_Multiboot2_ITag_ELFSymbols_is_valid(tag)) {
|
KERNAUX_CAST_CONST(unsigned long, num, tag->num);
|
||||||
PRINTLN(" invalid!");
|
KERNAUX_CAST_CONST(unsigned long, entsize, tag->entsize);
|
||||||
return;
|
KERNAUX_CAST_CONST(unsigned long, shndx, tag->shndx);
|
||||||
}
|
|
||||||
|
|
||||||
KERNAUX_CAST_CONST(unsigned long, num, tag->num);
|
PRINTLNF(" u32 num: %lu", num);
|
||||||
KERNAUX_CAST_CONST(unsigned long, ent_size, tag->ent_size);
|
PRINTLNF(" u32 entsize: %lu", entsize);
|
||||||
KERNAUX_CAST_CONST(unsigned long, shndx, tag->shndx);
|
PRINTLNF(" u32 shndx: %lu", shndx);
|
||||||
KERNAUX_CAST_CONST(unsigned long, reserved1, tag->reserved1);
|
|
||||||
|
|
||||||
PRINTLNF(" num: %lu", num);
|
// TODO: Print data?
|
||||||
PRINTLNF(" entsize: %lu", ent_size);
|
|
||||||
PRINTLNF(" shndx: %lu", shndx);
|
|
||||||
PRINTLNF(" reserved1: %lu", reserved1);
|
|
||||||
|
|
||||||
// TODO: implement this
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_APMTable_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_APMTable *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(APMTable);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, version, tag->version);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, cseg, tag->cseg);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, offset, tag->offset);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, cseg_16, tag->cseg_16);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, dseg, tag->dseg);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, flags, tag->flags);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, cseg_len, tag->cseg_len);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, cseg_16_len, tag->cseg_16_len);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, dseg_len, tag->dseg_len);
|
||||||
|
|
||||||
|
PRINTLNF(" u16 version: %lu", version);
|
||||||
|
PRINTLNF(" u16 cseg: %lu", cseg);
|
||||||
|
PRINTLNF(" u32 offset: %lu", offset);
|
||||||
|
PRINTLNF(" u16 cseg_16: %lu", cseg_16);
|
||||||
|
PRINTLNF(" u16 dseg: %lu", dseg);
|
||||||
|
PRINTLNF(" u16 flags: %lu", flags);
|
||||||
|
PRINTLNF(" u16 cseg_len: %lu", cseg_len);
|
||||||
|
PRINTLNF(" u16 cseg_16_len: %lu", cseg_16_len);
|
||||||
|
PRINTLNF(" u16 dseg_len: %lu", dseg_len);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_EFI32bitSystemTablePtr_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFI32bitSystemTablePtr *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(EFI32bitSystemTablePtr);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, pointer, tag->pointer);
|
||||||
|
|
||||||
|
PRINTLNF(" u32 pointer: %lu", pointer);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_EFI64bitSystemTablePtr_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFI64bitSystemTablePtr *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(EFI64bitSystemTablePtr);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long long, pointer, tag->pointer);
|
||||||
|
|
||||||
|
PRINTLNF(" u64 pointer: %llu", pointer);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_SMBIOSTables_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_SMBIOSTables *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(SMBIOSTables);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, major, tag->major);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, minor, tag->minor);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, reserved0, tag->reserved[0]);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, reserved1, tag->reserved[1]);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, reserved2, tag->reserved[2]);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, reserved3, tag->reserved[3]);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, reserved4, tag->reserved[4]);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, reserved5, tag->reserved[5]);
|
||||||
|
|
||||||
|
PRINTLNF(" u8 major: %lu", major);
|
||||||
|
PRINTLNF(" u8 minor: %lu", minor);
|
||||||
|
PRINTLNF(" u8 reserved[6]: [%lu, %lu, %lu, %lu, %lu, %lu]",
|
||||||
|
reserved0, reserved1, reserved2,
|
||||||
|
reserved3, reserved4, reserved5
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: Print data?
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_ACPIOldRSDP_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_ACPIOldRSDP *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(ACPIOldRSDP);
|
||||||
|
|
||||||
|
// TODO: Print data?
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_ACPINewRSDP_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_ACPINewRSDP *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(ACPINewRSDP);
|
||||||
|
|
||||||
|
// TODO: Print data?
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_NetworkingInfo_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_NetworkingInfo *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(NetworkingInfo);
|
||||||
|
|
||||||
|
// TODO: Print data?
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_EFIMemoryMap_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFIMemoryMap *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(EFIMemoryMap);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, descr_size, tag->descriptor_size);
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, descr_version, tag->descriptor_version);
|
||||||
|
|
||||||
|
PRINTLNF(" u32 descriptor_size: %lu", descr_size);
|
||||||
|
PRINTLNF(" u32 descriptor_version: %lu", descr_version);
|
||||||
|
|
||||||
|
// TODO: Print data?
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_EFIBootServicesNotTerminated_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFIBootServicesNotTerminated *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(EFIBootServicesNotTerminated);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_EFI32bitImageHandlePtr_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFI32bitImageHandlePtr *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(EFI32bitImageHandlePtr);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, pointer, tag->pointer);
|
||||||
|
|
||||||
|
PRINTLNF(" u32 pointer: %lu", pointer);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_EFI64bitImageHandlePtr_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_EFI64bitImageHandlePtr *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(EFI64bitImageHandlePtr);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long long, pointer, tag->pointer);
|
||||||
|
|
||||||
|
PRINTLNF(" u64 pointer: %llu", pointer);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernAux_Multiboot2_ITag_ImageLoadBasePhysAddr_print(
|
||||||
|
const struct KernAux_Multiboot2_ITag_ImageLoadBasePhysAddr *const tag,
|
||||||
|
const KernAux_Display display
|
||||||
|
) {
|
||||||
|
HEADER(ImageLoadBasePhysAddr);
|
||||||
|
|
||||||
|
KERNAUX_CAST_CONST(unsigned long, load_base_addr, tag->load_base_addr);
|
||||||
|
|
||||||
|
PRINTLNF(" u32 load_base_addr: %lu", load_base_addr);
|
||||||
|
|
||||||
|
FOOTER;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,19 @@ CLEANFILES =
|
||||||
TESTS =
|
TESTS =
|
||||||
noinst_PROGRAMS = $(TESTS)
|
noinst_PROGRAMS = $(TESTS)
|
||||||
|
|
||||||
|
############################
|
||||||
|
# multiboot2_header_print0 #
|
||||||
|
############################
|
||||||
|
|
||||||
|
if WITH_MULTIBOOT2
|
||||||
|
noinst_PROGRAMS += multiboot2_header_print0
|
||||||
|
multiboot2_header_print0_LDADD = $(top_builddir)/libkernaux.la
|
||||||
|
multiboot2_header_print0_SOURCES = \
|
||||||
|
main.c \
|
||||||
|
multiboot2_header_print0.c \
|
||||||
|
multiboot2_header_example0.h
|
||||||
|
endif
|
||||||
|
|
||||||
############################
|
############################
|
||||||
# multiboot2_header_print1 #
|
# multiboot2_header_print1 #
|
||||||
############################
|
############################
|
||||||
|
@ -30,6 +43,19 @@ multiboot2_header_print2_SOURCES = \
|
||||||
multiboot2_header_example2.h
|
multiboot2_header_example2.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
##########################
|
||||||
|
# multiboot2_info_print0 #
|
||||||
|
##########################
|
||||||
|
|
||||||
|
if WITH_MULTIBOOT2
|
||||||
|
noinst_PROGRAMS += multiboot2_info_print0
|
||||||
|
multiboot2_info_print0_LDADD = $(top_builddir)/libkernaux.la
|
||||||
|
multiboot2_info_print0_SOURCES = \
|
||||||
|
main.c \
|
||||||
|
multiboot2_info_print0.c \
|
||||||
|
multiboot2_info_example0.h
|
||||||
|
endif
|
||||||
|
|
||||||
##########################
|
##########################
|
||||||
# multiboot2_info_print1 #
|
# multiboot2_info_print1 #
|
||||||
##########################
|
##########################
|
||||||
|
@ -104,7 +130,7 @@ endif
|
||||||
CLEANFILES += test_cmdline_gen.c
|
CLEANFILES += test_cmdline_gen.c
|
||||||
|
|
||||||
test_cmdline_gen.c: $(top_srcdir)/tests/cmdline_gen.py $(top_srcdir)/tests/cmdline_gen.jinja $(top_srcdir)/common/cmdline.yml
|
test_cmdline_gen.c: $(top_srcdir)/tests/cmdline_gen.py $(top_srcdir)/tests/cmdline_gen.jinja $(top_srcdir)/common/cmdline.yml
|
||||||
$(PYTHON) $+ $@
|
$(PYTHON) $(top_srcdir)/tests/cmdline_gen.py $(top_srcdir)/tests/cmdline_gen.jinja $(top_srcdir)/common/cmdline.yml test_cmdline_gen.c
|
||||||
|
|
||||||
############
|
############
|
||||||
# test_elf #
|
# test_elf #
|
||||||
|
@ -189,6 +215,7 @@ endif
|
||||||
if WITH_MULTIBOOT2
|
if WITH_MULTIBOOT2
|
||||||
TESTS += test_multiboot2_header_print
|
TESTS += test_multiboot2_header_print
|
||||||
test_multiboot2_header_print_DEPENDENCIES = \
|
test_multiboot2_header_print_DEPENDENCIES = \
|
||||||
|
multiboot2_header_print0 \
|
||||||
multiboot2_header_print1 \
|
multiboot2_header_print1 \
|
||||||
multiboot2_header_print2
|
multiboot2_header_print2
|
||||||
test_multiboot2_header_print_LDADD = $(top_builddir)/libkernaux.la
|
test_multiboot2_header_print_LDADD = $(top_builddir)/libkernaux.la
|
||||||
|
@ -232,6 +259,7 @@ endif
|
||||||
if WITH_MULTIBOOT2
|
if WITH_MULTIBOOT2
|
||||||
TESTS += test_multiboot2_info_print
|
TESTS += test_multiboot2_info_print
|
||||||
test_multiboot2_info_print_DEPENDENCIES = \
|
test_multiboot2_info_print_DEPENDENCIES = \
|
||||||
|
multiboot2_info_print0 \
|
||||||
multiboot2_info_print1 \
|
multiboot2_info_print1 \
|
||||||
multiboot2_info_print2
|
multiboot2_info_print2
|
||||||
test_multiboot2_info_print_LDADD = $(top_builddir)/libkernaux.la
|
test_multiboot2_info_print_LDADD = $(top_builddir)/libkernaux.la
|
||||||
|
@ -338,7 +366,7 @@ endif
|
||||||
CLEANFILES += test_printf_fmt_gen.c
|
CLEANFILES += test_printf_fmt_gen.c
|
||||||
|
|
||||||
test_printf_fmt_gen.c: $(top_srcdir)/tests/printf_fmt_gen.py $(top_srcdir)/tests/printf_fmt_gen.jinja $(top_srcdir)/common/printf_fmt.yml
|
test_printf_fmt_gen.c: $(top_srcdir)/tests/printf_fmt_gen.py $(top_srcdir)/tests/printf_fmt_gen.jinja $(top_srcdir)/common/printf_fmt.yml
|
||||||
$(PYTHON) $+ $@
|
$(PYTHON) $(top_srcdir)/tests/printf_fmt_gen.py $(top_srcdir)/tests/printf_fmt_gen.jinja $(top_srcdir)/common/printf_fmt.yml test_printf_fmt_gen.c
|
||||||
|
|
||||||
###################
|
###################
|
||||||
# test_printf_gen #
|
# test_printf_gen #
|
||||||
|
@ -361,7 +389,7 @@ endif
|
||||||
CLEANFILES += test_printf_gen.c
|
CLEANFILES += test_printf_gen.c
|
||||||
|
|
||||||
test_printf_gen.c: $(top_srcdir)/tests/printf_gen.py $(top_srcdir)/tests/printf_gen.jinja $(top_srcdir)/common/printf.yml $(top_srcdir)/common/printf_orig.yml
|
test_printf_gen.c: $(top_srcdir)/tests/printf_gen.py $(top_srcdir)/tests/printf_gen.jinja $(top_srcdir)/common/printf.yml $(top_srcdir)/common/printf_orig.yml
|
||||||
$(PYTHON) $+ $@
|
$(PYTHON) $(top_srcdir)/tests/printf_gen.py $(top_srcdir)/tests/printf_gen.jinja $(top_srcdir)/common/printf.yml $(top_srcdir)/common/printf_orig.yml test_printf_gen.c
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# test_units_human #
|
# test_units_human #
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#include <kernaux/macro.h>
|
||||||
|
#include <kernaux/multiboot2.h>
|
||||||
|
|
||||||
|
#include <kernaux/macro/packing_start.run>
|
||||||
|
|
||||||
|
// Minimal example
|
||||||
|
KERNAUX_ALIGNED(KERNAUX_MULTIBOOT2_HEADER_ALIGN)
|
||||||
|
static const struct {
|
||||||
|
struct KernAux_Multiboot2_Header multiboot2_header;
|
||||||
|
struct KernAux_Multiboot2_HTag_None tag_none;
|
||||||
|
}
|
||||||
|
KERNAUX_PACKED
|
||||||
|
multiboot2_header_example0 = {
|
||||||
|
.multiboot2_header = {
|
||||||
|
.magic = KERNAUX_MULTIBOOT2_HEADER_MAGIC,
|
||||||
|
.arch = KERNAUX_MULTIBOOT2_HEADER_ARCH_I386,
|
||||||
|
.total_size = sizeof(multiboot2_header_example0),
|
||||||
|
.checksum = KERNAUX_MULTIBOOT2_HEADER_CHECKSUM(
|
||||||
|
KERNAUX_MULTIBOOT2_HEADER_ARCH_I386,
|
||||||
|
sizeof(multiboot2_header_example0)
|
||||||
|
),
|
||||||
|
},
|
||||||
|
.tag_none = {
|
||||||
|
.base = {
|
||||||
|
.type = KERNAUX_MULTIBOOT2_HTAG_NONE,
|
||||||
|
.flags = 0,
|
||||||
|
.size = sizeof(multiboot2_header_example0.tag_none),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <kernaux/macro/packing_end.run>
|
|
@ -1,7 +1,30 @@
|
||||||
|
#include <kernaux/macro.h>
|
||||||
|
#include <kernaux/multiboot2.h>
|
||||||
|
|
||||||
#include <kernaux/macro/packing_start.run>
|
#include <kernaux/macro/packing_start.run>
|
||||||
|
|
||||||
|
KERNAUX_ALIGNED(KERNAUX_MULTIBOOT2_HEADER_ALIGN)
|
||||||
static const struct {
|
static const struct {
|
||||||
struct KernAux_Multiboot2_Header multiboot2_header;
|
struct KernAux_Multiboot2_Header multiboot2_header;
|
||||||
|
|
||||||
|
struct KernAux_Multiboot2_HTag_Flags tag_flags1;
|
||||||
|
uint8_t _align1[4];
|
||||||
|
|
||||||
|
struct KernAux_Multiboot2_HTag_Flags tag_flags2;
|
||||||
|
uint8_t _align2[4];
|
||||||
|
|
||||||
|
struct KernAux_Multiboot2_HTag_Flags tag_flags3;
|
||||||
|
uint8_t _align3[4];
|
||||||
|
|
||||||
|
struct KernAux_Multiboot2_HTag_Flags tag_flags4;
|
||||||
|
uint8_t _align4[4];
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct KernAux_Multiboot2_HTag_InfoReq tag;
|
||||||
|
uint32_t mbi_tag_types[1];
|
||||||
|
} tag_info_req;
|
||||||
|
uint8_t _align5[4];
|
||||||
|
|
||||||
struct KernAux_Multiboot2_HTag_None tag_none;
|
struct KernAux_Multiboot2_HTag_None tag_none;
|
||||||
}
|
}
|
||||||
KERNAUX_PACKED
|
KERNAUX_PACKED
|
||||||
|
@ -15,6 +38,52 @@ multiboot2_header_example1 = {
|
||||||
sizeof(multiboot2_header_example1)
|
sizeof(multiboot2_header_example1)
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
.tag_flags1 = {
|
||||||
|
.base = {
|
||||||
|
.type = KERNAUX_MULTIBOOT2_HTAG_FLAGS,
|
||||||
|
.flags = 0,
|
||||||
|
.size = sizeof(multiboot2_header_example1.tag_flags1),
|
||||||
|
},
|
||||||
|
.console_flags = 0,
|
||||||
|
},
|
||||||
|
.tag_flags2 = {
|
||||||
|
.base = {
|
||||||
|
.type = KERNAUX_MULTIBOOT2_HTAG_FLAGS,
|
||||||
|
.flags = 0,
|
||||||
|
.size = sizeof(multiboot2_header_example1.tag_flags2),
|
||||||
|
},
|
||||||
|
.console_flags = KERNAUX_MULTIBOOT2_HTAG_FLAGS_REQUIRE_CONSOLE,
|
||||||
|
},
|
||||||
|
.tag_flags3 = {
|
||||||
|
.base = {
|
||||||
|
.type = KERNAUX_MULTIBOOT2_HTAG_FLAGS,
|
||||||
|
.flags = 0,
|
||||||
|
.size = sizeof(multiboot2_header_example1.tag_flags3),
|
||||||
|
},
|
||||||
|
.console_flags = KERNAUX_MULTIBOOT2_HTAG_FLAGS_EGA_SUPPORT,
|
||||||
|
},
|
||||||
|
.tag_flags4 = {
|
||||||
|
.base = {
|
||||||
|
.type = KERNAUX_MULTIBOOT2_HTAG_FLAGS,
|
||||||
|
.flags = 0,
|
||||||
|
.size = sizeof(multiboot2_header_example1.tag_flags4),
|
||||||
|
},
|
||||||
|
.console_flags =
|
||||||
|
KERNAUX_MULTIBOOT2_HTAG_FLAGS_REQUIRE_CONSOLE |
|
||||||
|
KERNAUX_MULTIBOOT2_HTAG_FLAGS_EGA_SUPPORT,
|
||||||
|
},
|
||||||
|
.tag_info_req = {
|
||||||
|
.tag = {
|
||||||
|
.base = {
|
||||||
|
.type = KERNAUX_MULTIBOOT2_HTAG_INFO_REQ,
|
||||||
|
.flags = 0,
|
||||||
|
.size = sizeof(multiboot2_header_example1.tag_info_req),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.mbi_tag_types = {
|
||||||
|
KERNAUX_MULTIBOOT2_ITAG_NONE,
|
||||||
|
},
|
||||||
|
},
|
||||||
.tag_none = {
|
.tag_none = {
|
||||||
.base = {
|
.base = {
|
||||||
.type = KERNAUX_MULTIBOOT2_HTAG_NONE,
|
.type = KERNAUX_MULTIBOOT2_HTAG_NONE,
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include <kernaux/macro.h>
|
#include <kernaux/macro.h>
|
||||||
|
#include <kernaux/multiboot2.h>
|
||||||
|
|
||||||
#include <kernaux/macro/packing_start.run>
|
#include <kernaux/macro/packing_start.run>
|
||||||
|
|
||||||
|
KERNAUX_ALIGNED(KERNAUX_MULTIBOOT2_HEADER_ALIGN)
|
||||||
static const struct {
|
static const struct {
|
||||||
struct KernAux_Multiboot2_Header multiboot2_header;
|
struct KernAux_Multiboot2_Header multiboot2_header;
|
||||||
|
|
||||||
|
@ -85,10 +87,10 @@ multiboot2_header_example2 = {
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.size = sizeof(multiboot2_header_example2.tag_addr),
|
.size = sizeof(multiboot2_header_example2.tag_addr),
|
||||||
},
|
},
|
||||||
.header_addr = 0,
|
.header_addr = 0xcafebabe,
|
||||||
.load_addr = 0,
|
.load_addr = 0xdeadbeaf,
|
||||||
.load_end_addr = 0,
|
.load_end_addr = 0xdeadbabe,
|
||||||
.bss_end_addr = 0,
|
.bss_end_addr = 0xcafebeaf,
|
||||||
},
|
},
|
||||||
.tag_entry_addr = {
|
.tag_entry_addr = {
|
||||||
.base = {
|
.base = {
|
||||||
|
@ -96,7 +98,7 @@ multiboot2_header_example2 = {
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.size = sizeof(multiboot2_header_example2.tag_entry_addr),
|
.size = sizeof(multiboot2_header_example2.tag_entry_addr),
|
||||||
},
|
},
|
||||||
.entry_addr = 0,
|
.entry_addr = 0xcafebabe,
|
||||||
},
|
},
|
||||||
.tag_flags = {
|
.tag_flags = {
|
||||||
.base = {
|
.base = {
|
||||||
|
@ -104,10 +106,7 @@ multiboot2_header_example2 = {
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.size = sizeof(multiboot2_header_example2.tag_flags),
|
.size = sizeof(multiboot2_header_example2.tag_flags),
|
||||||
},
|
},
|
||||||
.console_flags = (
|
.console_flags = 0,
|
||||||
KERNAUX_MULTIBOOT2_HTAG_FLAGS_REQUIRE_CONSOLE |
|
|
||||||
KERNAUX_MULTIBOOT2_HTAG_FLAGS_EGA_SUPPORT
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
.tag_framebuffer = {
|
.tag_framebuffer = {
|
||||||
.base = {
|
.base = {
|
||||||
|
@ -115,9 +114,9 @@ multiboot2_header_example2 = {
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.size = sizeof(multiboot2_header_example2.tag_framebuffer),
|
.size = sizeof(multiboot2_header_example2.tag_framebuffer),
|
||||||
},
|
},
|
||||||
.width = 0,
|
.width = 80,
|
||||||
.height = 0,
|
.height = 25,
|
||||||
.depth = 0,
|
.depth = 8,
|
||||||
},
|
},
|
||||||
.tag_module_align = {
|
.tag_module_align = {
|
||||||
.base = {
|
.base = {
|
||||||
|
@ -139,7 +138,7 @@ multiboot2_header_example2 = {
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.size = sizeof(multiboot2_header_example2.tag_efi_i386_entry_addr),
|
.size = sizeof(multiboot2_header_example2.tag_efi_i386_entry_addr),
|
||||||
},
|
},
|
||||||
.entry_addr = 0,
|
.entry_addr = 0xcafebabe,
|
||||||
},
|
},
|
||||||
.tag_efi_amd64_entry_addr = {
|
.tag_efi_amd64_entry_addr = {
|
||||||
.base = {
|
.base = {
|
||||||
|
@ -147,7 +146,7 @@ multiboot2_header_example2 = {
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.size = sizeof(multiboot2_header_example2.tag_efi_amd64_entry_addr),
|
.size = sizeof(multiboot2_header_example2.tag_efi_amd64_entry_addr),
|
||||||
},
|
},
|
||||||
.entry_addr = 0,
|
.entry_addr = 0xdeadbeaf,
|
||||||
},
|
},
|
||||||
.tag_relocatable_header = {
|
.tag_relocatable_header = {
|
||||||
.base = {
|
.base = {
|
||||||
|
@ -155,9 +154,9 @@ multiboot2_header_example2 = {
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.size = sizeof(multiboot2_header_example2.tag_relocatable_header),
|
.size = sizeof(multiboot2_header_example2.tag_relocatable_header),
|
||||||
},
|
},
|
||||||
.min_addr = 0,
|
.min_addr = 0xcafebabe,
|
||||||
.max_addr = 0,
|
.max_addr = 0xdeadbeaf,
|
||||||
.align = 0,
|
.align = 8,
|
||||||
.preferences =
|
.preferences =
|
||||||
KERNAUX_MULTIBOOT2_HTAG_RELOCATABLE_HEADER_PREFERENCE_LOWEST,
|
KERNAUX_MULTIBOOT2_HTAG_RELOCATABLE_HEADER_PREFERENCE_LOWEST,
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define KERNAUX_ACCESS_PROTECTED
|
||||||
|
|
||||||
|
#include <kernaux/generic/display.h>
|
||||||
|
#include <kernaux/macro.h>
|
||||||
|
#include <kernaux/multiboot2.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "multiboot2_header_example0.h"
|
||||||
|
|
||||||
|
static void my_putc(void *display KERNAUX_UNUSED, char c)
|
||||||
|
{
|
||||||
|
putchar(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void my_vprintf(void *display KERNAUX_UNUSED, const char *format, va_list va)
|
||||||
|
{
|
||||||
|
vprintf(format, va);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct KernAux_Display display = {
|
||||||
|
.putc = my_putc,
|
||||||
|
.vprintf = my_vprintf,
|
||||||
|
};
|
||||||
|
|
||||||
|
void test_main()
|
||||||
|
{
|
||||||
|
assert(KernAux_Multiboot2_Header_is_valid(
|
||||||
|
(struct KernAux_Multiboot2_Header*)&multiboot2_header_example0
|
||||||
|
));
|
||||||
|
|
||||||
|
KernAux_Multiboot2_Header_print(
|
||||||
|
(struct KernAux_Multiboot2_Header*)&multiboot2_header_example0,
|
||||||
|
&display
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#include <kernaux/macro.h>
|
||||||
|
#include <kernaux/multiboot2.h>
|
||||||
|
|
||||||
|
#include <kernaux/macro/packing_start.run>
|
||||||
|
|
||||||
|
// Minimal example
|
||||||
|
KERNAUX_ALIGNED(KERNAUX_MULTIBOOT2_INFO_ALIGN)
|
||||||
|
static const struct {
|
||||||
|
struct KernAux_Multiboot2_Info multiboot2_info;
|
||||||
|
struct KernAux_Multiboot2_ITag_None tag_none;
|
||||||
|
}
|
||||||
|
KERNAUX_PACKED
|
||||||
|
multiboot2_info_example0 = {
|
||||||
|
.multiboot2_info = {
|
||||||
|
.total_size = sizeof(multiboot2_info_example0),
|
||||||
|
.reserved = 0,
|
||||||
|
},
|
||||||
|
.tag_none = {
|
||||||
|
.base = {
|
||||||
|
.type = KERNAUX_MULTIBOOT2_ITAG_NONE,
|
||||||
|
.size = sizeof(multiboot2_info_example0.tag_none),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <kernaux/macro/packing_end.run>
|
|
@ -1,3 +1,7 @@
|
||||||
|
#include <kernaux/macro.h>
|
||||||
|
#include <kernaux/multiboot2.h>
|
||||||
|
|
||||||
|
KERNAUX_ALIGNED(KERNAUX_MULTIBOOT2_INFO_ALIGN)
|
||||||
static const uint8_t multiboot2_info_example1[864] = {
|
static const uint8_t multiboot2_info_example1[864] = {
|
||||||
96, 3, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 12, 0, 0, 0,
|
96, 3, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 12, 0, 0, 0,
|
||||||
0, 0, 64, 0, 0, 0, 232, 133, 1, 0, 0, 0, 21, 0, 0, 0,
|
0, 0, 64, 0, 0, 0, 232, 133, 1, 0, 0, 0, 21, 0, 0, 0,
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include <kernaux/macro.h>
|
#include <kernaux/macro.h>
|
||||||
|
#include <kernaux/multiboot2.h>
|
||||||
|
|
||||||
#include <kernaux/macro/packing_start.run>
|
#include <kernaux/macro/packing_start.run>
|
||||||
|
|
||||||
|
KERNAUX_ALIGNED(KERNAUX_MULTIBOOT2_INFO_ALIGN)
|
||||||
static const struct {
|
static const struct {
|
||||||
struct KernAux_Multiboot2_Info multiboot2_info;
|
struct KernAux_Multiboot2_Info multiboot2_info;
|
||||||
|
|
||||||
|
@ -46,7 +48,6 @@ static const struct {
|
||||||
struct KernAux_Multiboot2_ITag_FramebufferInfo tag;
|
struct KernAux_Multiboot2_ITag_FramebufferInfo tag;
|
||||||
uint8_t data[8];
|
uint8_t data[8];
|
||||||
} tag_framebuffer_info;
|
} tag_framebuffer_info;
|
||||||
uint8_t _align6[1];
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct KernAux_Multiboot2_ITag_ELFSymbols tag;
|
struct KernAux_Multiboot2_ITag_ELFSymbols tag;
|
||||||
|
@ -110,7 +111,7 @@ KERNAUX_PACKED
|
||||||
multiboot2_info_example2 = {
|
multiboot2_info_example2 = {
|
||||||
.multiboot2_info = {
|
.multiboot2_info = {
|
||||||
.total_size = sizeof(multiboot2_info_example2),
|
.total_size = sizeof(multiboot2_info_example2),
|
||||||
.reserved1 = 0,
|
.reserved = 0,
|
||||||
},
|
},
|
||||||
.tag_boot_cmd_line = {
|
.tag_boot_cmd_line = {
|
||||||
.tag = {
|
.tag = {
|
||||||
|
@ -165,7 +166,7 @@ multiboot2_info_example2 = {
|
||||||
.type = KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE,
|
.type = KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE,
|
||||||
.size = sizeof(multiboot2_info_example2.tag_bios_boot_device),
|
.size = sizeof(multiboot2_info_example2.tag_bios_boot_device),
|
||||||
},
|
},
|
||||||
.bios_dev = 0,
|
.biosdev = 0,
|
||||||
.partition = 1,
|
.partition = 1,
|
||||||
.sub_partition = 2,
|
.sub_partition = 2,
|
||||||
},
|
},
|
||||||
|
@ -200,6 +201,24 @@ multiboot2_info_example2 = {
|
||||||
.vbe_interface_seg = 123,
|
.vbe_interface_seg = 123,
|
||||||
.vbe_interface_off = 456,
|
.vbe_interface_off = 456,
|
||||||
.vbe_interface_len = 789,
|
.vbe_interface_len = 789,
|
||||||
|
.vbe_control_info = {
|
||||||
|
[0] = 0,
|
||||||
|
[16] = 1,
|
||||||
|
[32] = 12,
|
||||||
|
[48] = 123,
|
||||||
|
[79] = 1,
|
||||||
|
[95] = 12,
|
||||||
|
[111] = 123,
|
||||||
|
},
|
||||||
|
.vbe_mode_info = {
|
||||||
|
[0] = 0,
|
||||||
|
[16] = 3,
|
||||||
|
[32] = 32,
|
||||||
|
[48] = 255,
|
||||||
|
[79] = 3,
|
||||||
|
[95] = 32,
|
||||||
|
[111] = 255,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
.tag_framebuffer_info = {
|
.tag_framebuffer_info = {
|
||||||
.tag = {
|
.tag = {
|
||||||
|
@ -223,12 +242,11 @@ multiboot2_info_example2 = {
|
||||||
.size = sizeof(multiboot2_info_example2.tag_elf_symbols),
|
.size = sizeof(multiboot2_info_example2.tag_elf_symbols),
|
||||||
},
|
},
|
||||||
.num = 10,
|
.num = 10,
|
||||||
.ent_size = 0,
|
.entsize = 40,
|
||||||
.shndx = 40,
|
.shndx = 9,
|
||||||
.reserved1 = 0,
|
|
||||||
},
|
},
|
||||||
.data = {
|
.data = {
|
||||||
9, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 27, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0,
|
0, 0, 0, 0, 27, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0,
|
||||||
|
@ -293,7 +311,7 @@ multiboot2_info_example2 = {
|
||||||
},
|
},
|
||||||
.major = 1,
|
.major = 1,
|
||||||
.minor = 2,
|
.minor = 2,
|
||||||
.reserved1 = {0, 0, 0, 0, 0, 0},
|
.reserved = {0, 0, 0, 0, 0, 0},
|
||||||
},
|
},
|
||||||
.data = {0, 0, 0, 0, 0, 0, 0, 0},
|
.data = {0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define KERNAUX_ACCESS_PROTECTED
|
||||||
|
|
||||||
|
#include <kernaux/generic/display.h>
|
||||||
|
#include <kernaux/macro.h>
|
||||||
|
#include <kernaux/multiboot2.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "multiboot2_info_example0.h"
|
||||||
|
|
||||||
|
static void my_putc(void *display KERNAUX_UNUSED, char c)
|
||||||
|
{
|
||||||
|
putchar(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void my_vprintf(void *display KERNAUX_UNUSED, const char *format, va_list va)
|
||||||
|
{
|
||||||
|
vprintf(format, va);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct KernAux_Display display = {
|
||||||
|
.putc = my_putc,
|
||||||
|
.vprintf = my_vprintf,
|
||||||
|
};
|
||||||
|
|
||||||
|
void test_main()
|
||||||
|
{
|
||||||
|
assert(KernAux_Multiboot2_Info_is_valid(
|
||||||
|
&multiboot2_info_example0.multiboot2_info
|
||||||
|
));
|
||||||
|
|
||||||
|
KernAux_Multiboot2_Info_print(
|
||||||
|
&multiboot2_info_example0.multiboot2_info,
|
||||||
|
&display
|
||||||
|
);
|
||||||
|
}
|
|
@ -106,8 +106,8 @@ void test_main()
|
||||||
INFO_SIZEOF1(BIOSBootDevice, bios_boot_device, 20 );
|
INFO_SIZEOF1(BIOSBootDevice, bios_boot_device, 20 );
|
||||||
INFO_SIZEOF2(MemoryMap, memory_map, 16, 160 - 16);
|
INFO_SIZEOF2(MemoryMap, memory_map, 16, 160 - 16);
|
||||||
INFO_SIZEOF1(VBEInfo, vbe_info, 784 );
|
INFO_SIZEOF1(VBEInfo, vbe_info, 784 );
|
||||||
INFO_SIZEOF2(FramebufferInfo, framebuffer_info, 31, 8 );
|
INFO_SIZEOF2(FramebufferInfo, framebuffer_info, 32, 8 );
|
||||||
INFO_SIZEOF2(ELFSymbols, elf_symbols, 16, 420 - 16);
|
INFO_SIZEOF2(ELFSymbols, elf_symbols, 20, 420 - 20);
|
||||||
INFO_SIZEOF1(APMTable, apm_table, 28 );
|
INFO_SIZEOF1(APMTable, apm_table, 28 );
|
||||||
INFO_SIZEOF1(EFI32bitSystemTablePtr, efi_32bit_system_table_ptr, 12 );
|
INFO_SIZEOF1(EFI32bitSystemTablePtr, efi_32bit_system_table_ptr, 12 );
|
||||||
INFO_SIZEOF1(EFI64bitSystemTablePtr, efi_64bit_system_table_ptr, 16 );
|
INFO_SIZEOF1(EFI64bitSystemTablePtr, efi_64bit_system_table_ptr, 16 );
|
||||||
|
|
|
@ -9,70 +9,186 @@
|
||||||
#endif
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static const char output0[] =
|
||||||
|
"Multiboot 2 header {\n"
|
||||||
|
" u32 magic: 3897708758\n"
|
||||||
|
" u32 arch: 0 (i386)\n"
|
||||||
|
" u32 size: 24\n"
|
||||||
|
" u32 checksum: 397258514\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 header tag {\n"
|
||||||
|
" u16 type: 0 (none)\n"
|
||||||
|
" u16 flags: 0\n"
|
||||||
|
" u32 size: 8\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
static const char output1[] =
|
static const char output1[] =
|
||||||
"Multiboot 2 header\n"
|
"Multiboot 2 header {\n"
|
||||||
" magic: 3897708758\n"
|
" u32 magic: 3897708758\n"
|
||||||
" arch: 4 (MIPS32)\n"
|
" u32 arch: 4 (MIPS32)\n"
|
||||||
" size: 24\n"
|
" u32 size: 104\n"
|
||||||
" checksum: 397258510\n"
|
" u32 checksum: 397258430\n"
|
||||||
"Multiboot 2 header tag\n"
|
"}\n"
|
||||||
" type: 0 (none)\n"
|
"Multiboot 2 header tag {\n"
|
||||||
" flags: 0\n"
|
" u16 type: 4 (flags)\n"
|
||||||
" size: 8\n";
|
" u16 flags: 0\n"
|
||||||
|
" u32 size: 12\n"
|
||||||
|
" u32 console_flags: 0 ()\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 header tag {\n"
|
||||||
|
" u16 type: 4 (flags)\n"
|
||||||
|
" u16 flags: 0\n"
|
||||||
|
" u32 size: 12\n"
|
||||||
|
" u32 console_flags: 1 (\n"
|
||||||
|
" REQUIRE_CONSOLE\n"
|
||||||
|
" )\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 header tag {\n"
|
||||||
|
" u16 type: 4 (flags)\n"
|
||||||
|
" u16 flags: 0\n"
|
||||||
|
" u32 size: 12\n"
|
||||||
|
" u32 console_flags: 2 (\n"
|
||||||
|
" EGA_SUPPORT\n"
|
||||||
|
" )\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 header tag {\n"
|
||||||
|
" u16 type: 4 (flags)\n"
|
||||||
|
" u16 flags: 0\n"
|
||||||
|
" u32 size: 12\n"
|
||||||
|
" u32 console_flags: 3 (\n"
|
||||||
|
" REQUIRE_CONSOLE |\n"
|
||||||
|
" EGA_SUPPORT\n"
|
||||||
|
" )\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 header tag {\n"
|
||||||
|
" u16 type: 1 (information request)\n"
|
||||||
|
" u16 flags: 0\n"
|
||||||
|
" u32 size: 12\n"
|
||||||
|
" u32 mbi_tag_types[]: [\n"
|
||||||
|
" 0 (none)\n"
|
||||||
|
" ]\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 header tag {\n"
|
||||||
|
" u16 type: 0 (none)\n"
|
||||||
|
" u16 flags: 0\n"
|
||||||
|
" u32 size: 8\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
static const char output2[] =
|
static const char output2[] =
|
||||||
"Multiboot 2 header\n"
|
"Multiboot 2 header {\n"
|
||||||
" magic: 3897708758\n"
|
" u32 magic: 3897708758\n"
|
||||||
" arch: 0 (i386)\n"
|
" u32 arch: 0 (i386)\n"
|
||||||
" size: 272\n"
|
" u32 size: 272\n"
|
||||||
" checksum: 397258266\n"
|
" u32 checksum: 397258266\n"
|
||||||
"Multiboot 2 header tag\n"
|
"}\n"
|
||||||
" type: 1 (information request)\n"
|
"Multiboot 2 header tag {\n"
|
||||||
" flags: 0\n"
|
" u16 type: 1 (information request)\n"
|
||||||
" size: 96\n"
|
" u16 flags: 0\n"
|
||||||
"Multiboot 2 header tag\n"
|
" u32 size: 96\n"
|
||||||
" type: 2 (address)\n"
|
" u32 mbi_tag_types[]: [\n"
|
||||||
" flags: 0\n"
|
" 0 (none)\n"
|
||||||
" size: 24\n"
|
" 1 (boot cmd line)\n"
|
||||||
"Multiboot 2 header tag\n"
|
" 2 (boot loader name)\n"
|
||||||
" type: 3 (entry address)\n"
|
" 3 (module)\n"
|
||||||
" flags: 0\n"
|
" 4 (basic memory info)\n"
|
||||||
" size: 12\n"
|
" 5 (BIOS boot device)\n"
|
||||||
"Multiboot 2 header tag\n"
|
" 6 (memory map)\n"
|
||||||
" type: 4 (flags)\n"
|
" 7 (VBE info)\n"
|
||||||
" flags: 0\n"
|
" 8 (framebuffer info)\n"
|
||||||
" size: 12\n"
|
" 9 (ELF symbols)\n"
|
||||||
"Multiboot 2 header tag\n"
|
" 10 (APM table)\n"
|
||||||
" type: 5 (framebuffer)\n"
|
" 11 (EFI 32bit system table ptr)\n"
|
||||||
" flags: 0\n"
|
" 12 (EFI 64bit system table ptr)\n"
|
||||||
" size: 20\n"
|
" 13 (SMBIOS tables)\n"
|
||||||
"Multiboot 2 header tag\n"
|
" 14 (ACPI old RSDP)\n"
|
||||||
" type: 6 (module alignment)\n"
|
" 15 (ACPI new RSDP)\n"
|
||||||
" flags: 0\n"
|
" 16 (networking info)\n"
|
||||||
" size: 8\n"
|
" 17 (EFI memory map)\n"
|
||||||
"Multiboot 2 header tag\n"
|
" 18 (EFI boot services not terminated)\n"
|
||||||
" type: 7 (EFI boot services)\n"
|
" 19 (EFI 32bit image handle ptr)\n"
|
||||||
" flags: 0\n"
|
" 20 (EFI 64bit image handle ptr)\n"
|
||||||
" size: 8\n"
|
" 21 (image load base phys addr)\n"
|
||||||
"Multiboot 2 header tag\n"
|
" ]\n"
|
||||||
" type: 8 (EFI i386 entry address)\n"
|
"}\n"
|
||||||
" flags: 0\n"
|
"Multiboot 2 header tag {\n"
|
||||||
" size: 12\n"
|
" u16 type: 2 (address)\n"
|
||||||
"Multiboot 2 header tag\n"
|
" u16 flags: 0\n"
|
||||||
" type: 9 (EFI amd64 entry address)\n"
|
" u32 size: 24\n"
|
||||||
" flags: 0\n"
|
" u32 header_addr: 3405691582\n"
|
||||||
" size: 12\n"
|
" u32 load_addr: 3735928495\n"
|
||||||
"Multiboot 2 header tag\n"
|
" u32 load_end_addr: 3735927486\n"
|
||||||
" type: 10 (relocatable header)\n"
|
" u32 bss_end_addr: 3405692591\n"
|
||||||
" flags: 0\n"
|
"}\n"
|
||||||
" size: 24\n"
|
"Multiboot 2 header tag {\n"
|
||||||
"Multiboot 2 header tag\n"
|
" u16 type: 3 (entry address)\n"
|
||||||
" type: 0 (none)\n"
|
" u16 flags: 0\n"
|
||||||
" flags: 0\n"
|
" u32 size: 12\n"
|
||||||
" size: 8\n";
|
" u32 entry_addr: 3405691582\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 header tag {\n"
|
||||||
|
" u16 type: 4 (flags)\n"
|
||||||
|
" u16 flags: 0\n"
|
||||||
|
" u32 size: 12\n"
|
||||||
|
" u32 console_flags: 0 ()\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 header tag {\n"
|
||||||
|
" u16 type: 5 (framebuffer)\n"
|
||||||
|
" u16 flags: 0\n"
|
||||||
|
" u32 size: 20\n"
|
||||||
|
" u32 width: 80\n"
|
||||||
|
" u32 height: 25\n"
|
||||||
|
" u32 depth: 8\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 header tag {\n"
|
||||||
|
" u16 type: 6 (module alignment)\n"
|
||||||
|
" u16 flags: 0\n"
|
||||||
|
" u32 size: 8\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 header tag {\n"
|
||||||
|
" u16 type: 7 (EFI boot services)\n"
|
||||||
|
" u16 flags: 0\n"
|
||||||
|
" u32 size: 8\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 header tag {\n"
|
||||||
|
" u16 type: 8 (EFI i386 entry address)\n"
|
||||||
|
" u16 flags: 0\n"
|
||||||
|
" u32 size: 12\n"
|
||||||
|
" u32 entry_addr: 3405691582\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 header tag {\n"
|
||||||
|
" u16 type: 9 (EFI amd64 entry address)\n"
|
||||||
|
" u16 flags: 0\n"
|
||||||
|
" u32 size: 12\n"
|
||||||
|
" u32 entry_addr: 3735928495\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 header tag {\n"
|
||||||
|
" u16 type: 10 (relocatable header)\n"
|
||||||
|
" u16 flags: 0\n"
|
||||||
|
" u32 size: 24\n"
|
||||||
|
" u32 min_addr: 3405691582\n"
|
||||||
|
" u32 max_addr: 3735928495\n"
|
||||||
|
" u32 align: 8\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 header tag {\n"
|
||||||
|
" u16 type: 0 (none)\n"
|
||||||
|
" u16 flags: 0\n"
|
||||||
|
" u32 size: 8\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
void test_main()
|
void test_main()
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
FILE *const fd = popen("./multiboot2_header_print0", "r");
|
||||||
|
assert(fd != NULL);
|
||||||
|
|
||||||
|
for (const char *ch = output0; *ch; ++ch) {
|
||||||
|
assert(fgetc(fd) == *ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int status = pclose(fd);
|
||||||
|
assert(status == 0);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
FILE *const fd = popen("./multiboot2_header_print1", "r");
|
FILE *const fd = popen("./multiboot2_header_print1", "r");
|
||||||
assert(fd != NULL);
|
assert(fd != NULL);
|
||||||
|
|
|
@ -18,7 +18,7 @@ static const struct {
|
||||||
} KERNAUX_PACKED multiboot2_without_boot_cmd_line = {
|
} KERNAUX_PACKED multiboot2_without_boot_cmd_line = {
|
||||||
.multiboot2_info = {
|
.multiboot2_info = {
|
||||||
.total_size = sizeof(multiboot2_without_boot_cmd_line),
|
.total_size = sizeof(multiboot2_without_boot_cmd_line),
|
||||||
.reserved1 = 0,
|
.reserved = 0,
|
||||||
},
|
},
|
||||||
.tag_none = {
|
.tag_none = {
|
||||||
.base = {
|
.base = {
|
||||||
|
@ -42,7 +42,7 @@ static const struct {
|
||||||
} KERNAUX_PACKED multiboot2_with_some_boot_cmd_line = {
|
} KERNAUX_PACKED multiboot2_with_some_boot_cmd_line = {
|
||||||
.multiboot2_info = {
|
.multiboot2_info = {
|
||||||
.total_size = sizeof(multiboot2_with_some_boot_cmd_line),
|
.total_size = sizeof(multiboot2_with_some_boot_cmd_line),
|
||||||
.reserved1 = 0,
|
.reserved = 0,
|
||||||
},
|
},
|
||||||
.tag_boot_cmd_line = {
|
.tag_boot_cmd_line = {
|
||||||
.tag = {
|
.tag = {
|
||||||
|
@ -84,7 +84,7 @@ static const struct {
|
||||||
} KERNAUX_PACKED multiboot2_with_two_boot_cmd_lines = {
|
} KERNAUX_PACKED multiboot2_with_two_boot_cmd_lines = {
|
||||||
.multiboot2_info = {
|
.multiboot2_info = {
|
||||||
.total_size = sizeof(multiboot2_with_two_boot_cmd_lines),
|
.total_size = sizeof(multiboot2_with_two_boot_cmd_lines),
|
||||||
.reserved1 = 0,
|
.reserved = 0,
|
||||||
},
|
},
|
||||||
.tag_boot_cmd_line1 = {
|
.tag_boot_cmd_line1 = {
|
||||||
.tag = {
|
.tag = {
|
||||||
|
|
|
@ -3,273 +3,409 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#ifndef __USE_POSIX2
|
#ifndef __USE_POSIX2
|
||||||
#define __USE_POSIX2
|
#define __USE_POSIX2
|
||||||
#endif
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
static const char output1[] =
|
static const char output0[] =
|
||||||
"Multiboot 2 info\n"
|
"Multiboot 2 info {\n"
|
||||||
" size: 864\n"
|
" u32 size: 16\n"
|
||||||
" reserved1: 0\n"
|
" u32 reserved: 0\n"
|
||||||
"Multiboot 2 info tag\n"
|
"}\n"
|
||||||
" type: 21 (image load base phys addr)\n"
|
"Multiboot 2 info tag {\n"
|
||||||
" size: 12\n"
|
" u32 type: 0 (none)\n"
|
||||||
" load base addr: 4194304\n"
|
" u32 size: 8\n"
|
||||||
"Multiboot 2 info tag\n"
|
"}\n";
|
||||||
" type: 1 (boot cmd line)\n"
|
|
||||||
" size: 21\n"
|
|
||||||
" cmdline: hello kernel\n"
|
|
||||||
"Multiboot 2 info tag\n"
|
|
||||||
" type: 2 (boot loader name)\n"
|
|
||||||
" size: 30\n"
|
|
||||||
" name: GRUB 2.02-2ubuntu8.20\n"
|
|
||||||
"Multiboot 2 info tag\n"
|
|
||||||
" type: 10 (APM table)\n"
|
|
||||||
" size: 28\n"
|
|
||||||
" version: 258\n"
|
|
||||||
" cseg: 61440\n"
|
|
||||||
" offset: 54479\n"
|
|
||||||
" cseg 16: 61440\n"
|
|
||||||
" dseg: 61440\n"
|
|
||||||
" flags: 3\n"
|
|
||||||
" cseg len: 65520\n"
|
|
||||||
" cseg 16 len: 65520\n"
|
|
||||||
" dseg len: 65520\n"
|
|
||||||
"Multiboot 2 info tag\n"
|
|
||||||
" type: 3 (module)\n"
|
|
||||||
" size: 29\n"
|
|
||||||
" start: 1056768\n"
|
|
||||||
" end: 1061532\n"
|
|
||||||
" cmdline: hello module\n"
|
|
||||||
"Multiboot 2 info tag\n"
|
|
||||||
" type: 3 (module)\n"
|
|
||||||
" size: 17\n"
|
|
||||||
" start: 1064960\n"
|
|
||||||
" end: 1069652\n"
|
|
||||||
" cmdline: \n"
|
|
||||||
"Multiboot 2 info tag\n"
|
|
||||||
" type: 6 (memory map)\n"
|
|
||||||
" size: 160\n"
|
|
||||||
" entry size: 24\n"
|
|
||||||
" entry version: 0\n"
|
|
||||||
" entries:\n"
|
|
||||||
" entry 0\n"
|
|
||||||
" base addr: 0\n"
|
|
||||||
" length: 654336\n"
|
|
||||||
" type: 1\n"
|
|
||||||
" reserved1: 0\n"
|
|
||||||
" entry 1\n"
|
|
||||||
" base addr: 654336\n"
|
|
||||||
" length: 1024\n"
|
|
||||||
" type: 2\n"
|
|
||||||
" reserved1: 0\n"
|
|
||||||
" entry 2\n"
|
|
||||||
" base addr: 983040\n"
|
|
||||||
" length: 65536\n"
|
|
||||||
" type: 2\n"
|
|
||||||
" reserved1: 0\n"
|
|
||||||
" entry 3\n"
|
|
||||||
" base addr: 1048576\n"
|
|
||||||
" length: 133038080\n"
|
|
||||||
" type: 1\n"
|
|
||||||
" reserved1: 0\n"
|
|
||||||
" entry 4\n"
|
|
||||||
" base addr: 134086656\n"
|
|
||||||
" length: 131072\n"
|
|
||||||
" type: 2\n"
|
|
||||||
" reserved1: 0\n"
|
|
||||||
" entry 5\n"
|
|
||||||
" base addr: 4294705152\n"
|
|
||||||
" length: 262144\n"
|
|
||||||
" type: 2\n"
|
|
||||||
" reserved1: 0\n"
|
|
||||||
"Multiboot 2 info tag\n"
|
|
||||||
" type: 9 (ELF symbols)\n"
|
|
||||||
" size: 420\n"
|
|
||||||
" num: 10\n"
|
|
||||||
" entsize: 0\n"
|
|
||||||
" shndx: 40\n"
|
|
||||||
" reserved1: 0\n"
|
|
||||||
"Multiboot 2 info tag\n"
|
|
||||||
" type: 4 (basic memory info)\n"
|
|
||||||
" size: 16\n"
|
|
||||||
" mem lower: 639\n"
|
|
||||||
" mem upper: 129920\n"
|
|
||||||
"Multiboot 2 info tag\n"
|
|
||||||
" type: 5 (BIOS boot device)\n"
|
|
||||||
" size: 20\n"
|
|
||||||
" bios dev: 224\n"
|
|
||||||
" partition: 4294967295\n"
|
|
||||||
" sub_partition: 4294967295\n"
|
|
||||||
"Multiboot 2 info tag\n"
|
|
||||||
" type: 8 (framebuffer info)\n"
|
|
||||||
" size: 32\n"
|
|
||||||
" framebuffer addr: 753664\n"
|
|
||||||
" framebuffer pitch: 160\n"
|
|
||||||
" framebuffer width: 80\n"
|
|
||||||
" framebuffer height: 25\n"
|
|
||||||
" framebuffer bpp: 16\n"
|
|
||||||
" framebuffer type: 2\n"
|
|
||||||
" reserved1: 0\n"
|
|
||||||
"Multiboot 2 info tag\n"
|
|
||||||
" type: 14 (ACPI old RSDP)\n"
|
|
||||||
" size: 28\n"
|
|
||||||
"Multiboot 2 info tag\n"
|
|
||||||
" type: 0 (none)\n"
|
|
||||||
" size: 8\n";
|
|
||||||
|
|
||||||
static const char output2[] =
|
static const char output1[] =
|
||||||
"Multiboot 2 info\n"
|
"Multiboot 2 info {\n"
|
||||||
" size: 1816\n"
|
" u32 size: 864\n"
|
||||||
" reserved1: 0\n"
|
" u32 reserved: 0\n"
|
||||||
"Multiboot 2 info tag\n"
|
"}\n"
|
||||||
" type: 1 (boot cmd line)\n"
|
"Multiboot 2 info tag {\n"
|
||||||
" size: 23\n"
|
" u32 type: 21 (image load base phys addr)\n"
|
||||||
" cmdline: Hello, Kernel!\n"
|
" u32 size: 12\n"
|
||||||
"Multiboot 2 info tag\n"
|
" u32 load_base_addr: 4194304\n"
|
||||||
" type: 2 (boot loader name)\n"
|
"}\n"
|
||||||
" size: 30\n"
|
"Multiboot 2 info tag {\n"
|
||||||
" name: GRUB 2.02-2ubuntu8.20\n"
|
" u32 type: 1 (boot cmd line)\n"
|
||||||
"Multiboot 2 info tag\n"
|
" u32 size: 21\n"
|
||||||
" type: 3 (module)\n"
|
" char cmdline[]: \"hello kernel\"\n"
|
||||||
" size: 33\n"
|
"}\n"
|
||||||
" start: 123\n"
|
"Multiboot 2 info tag {\n"
|
||||||
" end: 456\n"
|
" u32 type: 2 (boot loader name)\n"
|
||||||
" cmdline: Hello, Module 1!\n"
|
" u32 size: 30\n"
|
||||||
"Multiboot 2 info tag\n"
|
" char name[]: \"GRUB 2.02-2ubuntu8.20\"\n"
|
||||||
" type: 3 (module)\n"
|
"}\n"
|
||||||
" size: 33\n"
|
"Multiboot 2 info tag {\n"
|
||||||
" start: 123\n"
|
" u32 type: 10 (APM table)\n"
|
||||||
" end: 456\n"
|
" u32 size: 28\n"
|
||||||
" cmdline: Hello, Module 2!\n"
|
" u16 version: 258\n"
|
||||||
"Multiboot 2 info tag\n"
|
" u16 cseg: 61440\n"
|
||||||
" type: 4 (basic memory info)\n"
|
" u32 offset: 54479\n"
|
||||||
" size: 16\n"
|
" u16 cseg_16: 61440\n"
|
||||||
" mem lower: 123\n"
|
" u16 dseg: 61440\n"
|
||||||
" mem upper: 456\n"
|
" u16 flags: 3\n"
|
||||||
"Multiboot 2 info tag\n"
|
" u16 cseg_len: 65520\n"
|
||||||
" type: 5 (BIOS boot device)\n"
|
" u16 cseg_16_len: 65520\n"
|
||||||
" size: 20\n"
|
" u16 dseg_len: 65520\n"
|
||||||
" bios dev: 0\n"
|
"}\n"
|
||||||
" partition: 1\n"
|
"Multiboot 2 info tag {\n"
|
||||||
" sub_partition: 2\n"
|
" u32 type: 3 (module)\n"
|
||||||
"Multiboot 2 info tag\n"
|
" u32 size: 29\n"
|
||||||
" type: 6 (memory map)\n"
|
" u32 mod_start: 1056768\n"
|
||||||
" size: 160\n"
|
" u32 mod_end: 1061532\n"
|
||||||
" entry size: 24\n"
|
" char cmdline[]: \"hello module\"\n"
|
||||||
" entry version: 0\n"
|
"}\n"
|
||||||
" entries:\n"
|
"Multiboot 2 info tag {\n"
|
||||||
" entry 0\n"
|
" u32 type: 3 (module)\n"
|
||||||
" base addr: 0\n"
|
" u32 size: 17\n"
|
||||||
" length: 654336\n"
|
" u32 mod_start: 1064960\n"
|
||||||
" type: 1\n"
|
" u32 mod_end: 1069652\n"
|
||||||
" reserved1: 0\n"
|
" char cmdline[]: \"\"\n"
|
||||||
" entry 1\n"
|
"}\n"
|
||||||
" base addr: 654336\n"
|
"Multiboot 2 info tag {\n"
|
||||||
" length: 1024\n"
|
" u32 type: 6 (memory map)\n"
|
||||||
" type: 2\n"
|
" u32 size: 160\n"
|
||||||
" reserved1: 0\n"
|
" u32 entry_size: 24\n"
|
||||||
" entry 2\n"
|
" u32 entry_version: 0\n"
|
||||||
" base addr: 983040\n"
|
" varies(entry_size) entries[]: [\n"
|
||||||
" length: 65536\n"
|
" [0] entry: {\n"
|
||||||
" type: 2\n"
|
" u64 base_addr: 0\n"
|
||||||
" reserved1: 0\n"
|
" u64 length: 654336\n"
|
||||||
" entry 3\n"
|
" u32 type: 1\n"
|
||||||
" base addr: 1048576\n"
|
" u32 reserved: 0\n"
|
||||||
" length: 133038080\n"
|
" }\n"
|
||||||
" type: 1\n"
|
" [1] entry: {\n"
|
||||||
" reserved1: 0\n"
|
" u64 base_addr: 654336\n"
|
||||||
" entry 4\n"
|
" u64 length: 1024\n"
|
||||||
" base addr: 134086656\n"
|
" u32 type: 2\n"
|
||||||
" length: 131072\n"
|
" u32 reserved: 0\n"
|
||||||
" type: 2\n"
|
" }\n"
|
||||||
" reserved1: 0\n"
|
" [2] entry: {\n"
|
||||||
" entry 5\n"
|
" u64 base_addr: 983040\n"
|
||||||
" base addr: 4294705152\n"
|
" u64 length: 65536\n"
|
||||||
" length: 262144\n"
|
" u32 type: 2\n"
|
||||||
" type: 2\n"
|
" u32 reserved: 0\n"
|
||||||
" reserved1: 0\n"
|
" }\n"
|
||||||
"Multiboot 2 info tag\n"
|
" [3] entry: {\n"
|
||||||
" type: 7 (VBE info)\n"
|
" u64 base_addr: 1048576\n"
|
||||||
" size: 784\n"
|
" u64 length: 133038080\n"
|
||||||
" VBE mode: 0\n"
|
" u32 type: 1\n"
|
||||||
" VBE interface seg: 123\n"
|
" u32 reserved: 0\n"
|
||||||
" VBE interface off: 456\n"
|
" }\n"
|
||||||
" VBE interface len: 789\n"
|
" [4] entry: {\n"
|
||||||
"Multiboot 2 info tag\n"
|
" u64 base_addr: 134086656\n"
|
||||||
" type: 8 (framebuffer info)\n"
|
" u64 length: 131072\n"
|
||||||
" size: 39\n"
|
" u32 type: 2\n"
|
||||||
" framebuffer addr: 123\n"
|
" u32 reserved: 0\n"
|
||||||
" framebuffer pitch: 456\n"
|
" }\n"
|
||||||
" framebuffer width: 123\n"
|
" [5] entry: {\n"
|
||||||
" framebuffer height: 456\n"
|
" u64 base_addr: 4294705152\n"
|
||||||
" framebuffer bpp: 8\n"
|
" u64 length: 262144\n"
|
||||||
" framebuffer type: 1\n"
|
" u32 type: 2\n"
|
||||||
" reserved1: 0\n"
|
" u32 reserved: 0\n"
|
||||||
"Multiboot 2 info tag\n"
|
" }\n"
|
||||||
" type: 9 (ELF symbols)\n"
|
" ]\n"
|
||||||
" size: 420\n"
|
"}\n"
|
||||||
" num: 10\n"
|
"Multiboot 2 info tag {\n"
|
||||||
" entsize: 0\n"
|
" u32 type: 9 (ELF symbols)\n"
|
||||||
" shndx: 40\n"
|
" u32 size: 420\n"
|
||||||
" reserved1: 0\n"
|
" u32 num: 10\n"
|
||||||
"Multiboot 2 info tag\n"
|
" u32 entsize: 40\n"
|
||||||
" type: 10 (APM table)\n"
|
" u32 shndx: 9\n"
|
||||||
" size: 28\n"
|
"}\n"
|
||||||
" version: 0\n"
|
"Multiboot 2 info tag {\n"
|
||||||
" cseg: 123\n"
|
" u32 type: 4 (basic memory info)\n"
|
||||||
" offset: 456\n"
|
" u32 size: 16\n"
|
||||||
" cseg 16: 789\n"
|
" u32 mem_lower: 639\n"
|
||||||
" dseg: 123\n"
|
" u32 mem_upper: 129920\n"
|
||||||
" flags: 1\n"
|
"}\n"
|
||||||
" cseg len: 456\n"
|
"Multiboot 2 info tag {\n"
|
||||||
" cseg 16 len: 789\n"
|
" u32 type: 5 (BIOS boot device)\n"
|
||||||
" dseg len: 123\n"
|
" u32 size: 20\n"
|
||||||
"Multiboot 2 info tag\n"
|
" u32 biosdev: 224\n"
|
||||||
" type: 11 (EFI 32bit system table ptr)\n"
|
" u32 partition: 4294967295\n"
|
||||||
" size: 12\n"
|
" u32 sub_partition: 4294967295\n"
|
||||||
"Multiboot 2 info tag\n"
|
"}\n"
|
||||||
" type: 12 (EFI 64bit system table ptr)\n"
|
"Multiboot 2 info tag {\n"
|
||||||
" size: 16\n"
|
" u32 type: 8 (framebuffer info)\n"
|
||||||
"Multiboot 2 info tag\n"
|
" u32 size: 32\n"
|
||||||
" type: 13 (SMBIOS tables)\n"
|
" u64 framebuffer_addr: 753664\n"
|
||||||
" size: 24\n"
|
" u32 framebuffer_pitch: 160\n"
|
||||||
" major: 1\n"
|
" u32 framebuffer_width: 80\n"
|
||||||
" minor: 2\n"
|
" u32 framebuffer_height: 25\n"
|
||||||
" reserved1: {0, 0, 0, 0, 0, 0}\n"
|
" u8 framebuffer_bpp: 16\n"
|
||||||
"Multiboot 2 info tag\n"
|
" u8 framebuffer_type: 2\n"
|
||||||
" type: 14 (ACPI old RSDP)\n"
|
" u16 reserved: 0\n"
|
||||||
" size: 16\n"
|
"}\n"
|
||||||
"Multiboot 2 info tag\n"
|
"Multiboot 2 info tag {\n"
|
||||||
" type: 15 (ACPI new RSDP)\n"
|
" u32 type: 14 (ACPI old RSDP)\n"
|
||||||
" size: 16\n"
|
" u32 size: 28\n"
|
||||||
"Multiboot 2 info tag\n"
|
"}\n"
|
||||||
" type: 16 (networking info)\n"
|
"Multiboot 2 info tag {\n"
|
||||||
" size: 16\n"
|
" u32 type: 0 (none)\n"
|
||||||
"Multiboot 2 info tag\n"
|
" u32 size: 8\n"
|
||||||
" type: 17 (EFI memory map)\n"
|
"}\n";
|
||||||
" size: 24\n"
|
|
||||||
"Multiboot 2 info tag\n"
|
static const char output2_part1[] =
|
||||||
" type: 18 (EFI boot services not terminated)\n"
|
"Multiboot 2 info {\n"
|
||||||
" size: 8\n"
|
" u32 size: 1816\n"
|
||||||
"Multiboot 2 info tag\n"
|
" u32 reserved: 0\n"
|
||||||
" type: 19 (EFI 32bit image handle ptr)\n"
|
"}\n"
|
||||||
" size: 12\n"
|
"Multiboot 2 info tag {\n"
|
||||||
"Multiboot 2 info tag\n"
|
" u32 type: 1 (boot cmd line)\n"
|
||||||
" type: 20 (EFI 64bit image handle ptr)\n"
|
" u32 size: 23\n"
|
||||||
" size: 16\n"
|
" char cmdline[]: \"Hello, Kernel!\"\n"
|
||||||
"Multiboot 2 info tag\n"
|
"}\n"
|
||||||
" type: 21 (image load base phys addr)\n"
|
"Multiboot 2 info tag {\n"
|
||||||
" size: 12\n"
|
" u32 type: 2 (boot loader name)\n"
|
||||||
" load base addr: 123\n"
|
" u32 size: 30\n"
|
||||||
"Multiboot 2 info tag\n"
|
" char name[]: \"GRUB 2.02-2ubuntu8.20\"\n"
|
||||||
" type: 0 (none)\n"
|
"}\n"
|
||||||
" size: 8\n";
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 3 (module)\n"
|
||||||
|
" u32 size: 33\n"
|
||||||
|
" u32 mod_start: 123\n"
|
||||||
|
" u32 mod_end: 456\n"
|
||||||
|
" char cmdline[]: \"Hello, Module 1!\"\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 3 (module)\n"
|
||||||
|
" u32 size: 33\n"
|
||||||
|
" u32 mod_start: 123\n"
|
||||||
|
" u32 mod_end: 456\n"
|
||||||
|
" char cmdline[]: \"Hello, Module 2!\"\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 4 (basic memory info)\n"
|
||||||
|
" u32 size: 16\n"
|
||||||
|
" u32 mem_lower: 123\n"
|
||||||
|
" u32 mem_upper: 456\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 5 (BIOS boot device)\n"
|
||||||
|
" u32 size: 20\n"
|
||||||
|
" u32 biosdev: 0\n"
|
||||||
|
" u32 partition: 1\n"
|
||||||
|
" u32 sub_partition: 2\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 6 (memory map)\n"
|
||||||
|
" u32 size: 160\n"
|
||||||
|
" u32 entry_size: 24\n"
|
||||||
|
" u32 entry_version: 0\n"
|
||||||
|
" varies(entry_size) entries[]: [\n"
|
||||||
|
" [0] entry: {\n"
|
||||||
|
" u64 base_addr: 0\n"
|
||||||
|
" u64 length: 654336\n"
|
||||||
|
" u32 type: 1\n"
|
||||||
|
" u32 reserved: 0\n"
|
||||||
|
" }\n"
|
||||||
|
" [1] entry: {\n"
|
||||||
|
" u64 base_addr: 654336\n"
|
||||||
|
" u64 length: 1024\n"
|
||||||
|
" u32 type: 2\n"
|
||||||
|
" u32 reserved: 0\n"
|
||||||
|
" }\n"
|
||||||
|
" [2] entry: {\n"
|
||||||
|
" u64 base_addr: 983040\n"
|
||||||
|
" u64 length: 65536\n"
|
||||||
|
" u32 type: 2\n"
|
||||||
|
" u32 reserved: 0\n"
|
||||||
|
" }\n"
|
||||||
|
" [3] entry: {\n"
|
||||||
|
" u64 base_addr: 1048576\n"
|
||||||
|
" u64 length: 133038080\n"
|
||||||
|
" u32 type: 1\n"
|
||||||
|
" u32 reserved: 0\n"
|
||||||
|
" }\n"
|
||||||
|
" [4] entry: {\n"
|
||||||
|
" u64 base_addr: 134086656\n"
|
||||||
|
" u64 length: 131072\n"
|
||||||
|
" u32 type: 2\n"
|
||||||
|
" u32 reserved: 0\n"
|
||||||
|
" }\n"
|
||||||
|
" [5] entry: {\n"
|
||||||
|
" u64 base_addr: 4294705152\n"
|
||||||
|
" u64 length: 262144\n"
|
||||||
|
" u32 type: 2\n"
|
||||||
|
" u32 reserved: 0\n"
|
||||||
|
" }\n"
|
||||||
|
" ]\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
static const char output2_part2[] =
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 7 (VBE info)\n"
|
||||||
|
" u32 size: 784\n"
|
||||||
|
" u16 vbe_mode: 0\n"
|
||||||
|
" u16 vbe_interface_seg: 123\n"
|
||||||
|
" u16 vbe_interface_off: 456\n"
|
||||||
|
" u16 vbe_interface_len: 789\n"
|
||||||
|
" u8 vbe_control_info[]: [\n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 123 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 123\n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" ]\n"
|
||||||
|
" u8 vbe_mode_info[]: [\n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255\n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n"
|
||||||
|
" ]\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
static const char output2_part3[] =
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 8 (framebuffer info)\n"
|
||||||
|
" u32 size: 40\n"
|
||||||
|
" u64 framebuffer_addr: 123\n"
|
||||||
|
" u32 framebuffer_pitch: 456\n"
|
||||||
|
" u32 framebuffer_width: 123\n"
|
||||||
|
" u32 framebuffer_height: 456\n"
|
||||||
|
" u8 framebuffer_bpp: 8\n"
|
||||||
|
" u8 framebuffer_type: 1\n"
|
||||||
|
" u16 reserved: 0\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 9 (ELF symbols)\n"
|
||||||
|
" u32 size: 420\n"
|
||||||
|
" u32 num: 10\n"
|
||||||
|
" u32 entsize: 40\n"
|
||||||
|
" u32 shndx: 9\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 10 (APM table)\n"
|
||||||
|
" u32 size: 28\n"
|
||||||
|
" u16 version: 0\n"
|
||||||
|
" u16 cseg: 123\n"
|
||||||
|
" u32 offset: 456\n"
|
||||||
|
" u16 cseg_16: 789\n"
|
||||||
|
" u16 dseg: 123\n"
|
||||||
|
" u16 flags: 1\n"
|
||||||
|
" u16 cseg_len: 456\n"
|
||||||
|
" u16 cseg_16_len: 789\n"
|
||||||
|
" u16 dseg_len: 123\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 11 (EFI 32bit system table ptr)\n"
|
||||||
|
" u32 size: 12\n"
|
||||||
|
" u32 pointer: 0\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 12 (EFI 64bit system table ptr)\n"
|
||||||
|
" u32 size: 16\n"
|
||||||
|
" u64 pointer: 0\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 13 (SMBIOS tables)\n"
|
||||||
|
" u32 size: 24\n"
|
||||||
|
" u8 major: 1\n"
|
||||||
|
" u8 minor: 2\n"
|
||||||
|
" u8 reserved[6]: [0, 0, 0, 0, 0, 0]\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 14 (ACPI old RSDP)\n"
|
||||||
|
" u32 size: 16\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 15 (ACPI new RSDP)\n"
|
||||||
|
" u32 size: 16\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 16 (networking info)\n"
|
||||||
|
" u32 size: 16\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 17 (EFI memory map)\n"
|
||||||
|
" u32 size: 24\n"
|
||||||
|
" u32 descriptor_size: 123\n"
|
||||||
|
" u32 descriptor_version: 1\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 18 (EFI boot services not terminated)\n"
|
||||||
|
" u32 size: 8\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 19 (EFI 32bit image handle ptr)\n"
|
||||||
|
" u32 size: 12\n"
|
||||||
|
" u32 pointer: 0\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 20 (EFI 64bit image handle ptr)\n"
|
||||||
|
" u32 size: 16\n"
|
||||||
|
" u64 pointer: 0\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 21 (image load base phys addr)\n"
|
||||||
|
" u32 size: 12\n"
|
||||||
|
" u32 load_base_addr: 123\n"
|
||||||
|
"}\n"
|
||||||
|
"Multiboot 2 info tag {\n"
|
||||||
|
" u32 type: 0 (none)\n"
|
||||||
|
" u32 size: 8\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
void test_main()
|
void test_main()
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
FILE *const fd = popen("./multiboot2_info_print0", "r");
|
||||||
|
assert(fd != NULL);
|
||||||
|
|
||||||
|
for (const char *ch = output0; *ch; ++ch) {
|
||||||
|
assert(fgetc(fd) == *ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int status = pclose(fd);
|
||||||
|
assert(status == 0);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
FILE *const fd = popen("./multiboot2_info_print1", "r");
|
FILE *const fd = popen("./multiboot2_info_print1", "r");
|
||||||
assert(fd != NULL);
|
assert(fd != NULL);
|
||||||
|
@ -283,6 +419,15 @@ void test_main()
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
const size_t part1_len = strlen(output2_part1);
|
||||||
|
const size_t part2_len = strlen(output2_part2);
|
||||||
|
const size_t part3_len = strlen(output2_part3);
|
||||||
|
char *const output2 = malloc(1 + part1_len + part2_len + part3_len);
|
||||||
|
assert(output2);
|
||||||
|
strcpy(output2, output2_part1);
|
||||||
|
strcat(output2, output2_part2);
|
||||||
|
strcat(output2, output2_part3);
|
||||||
|
|
||||||
FILE *const fd = popen("./multiboot2_info_print2", "r");
|
FILE *const fd = popen("./multiboot2_info_print2", "r");
|
||||||
assert(fd != NULL);
|
assert(fd != NULL);
|
||||||
|
|
||||||
|
|
|
@ -328,7 +328,7 @@ tag_bios_boot_device_valid = {
|
||||||
.type = KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE,
|
.type = KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE,
|
||||||
.size = 20,
|
.size = 20,
|
||||||
},
|
},
|
||||||
.bios_dev = 123,
|
.biosdev = 123,
|
||||||
.partition = 456,
|
.partition = 456,
|
||||||
.sub_partition = 789,
|
.sub_partition = 789,
|
||||||
};
|
};
|
||||||
|
@ -339,7 +339,7 @@ tag_bios_boot_device_invalid_type = {
|
||||||
.type = KERNAUX_MULTIBOOT2_ITAG_NONE,
|
.type = KERNAUX_MULTIBOOT2_ITAG_NONE,
|
||||||
.size = 20,
|
.size = 20,
|
||||||
},
|
},
|
||||||
.bios_dev = 123,
|
.biosdev = 123,
|
||||||
.partition = 456,
|
.partition = 456,
|
||||||
.sub_partition = 789,
|
.sub_partition = 789,
|
||||||
};
|
};
|
||||||
|
@ -350,7 +350,7 @@ tag_bios_boot_device_invalid_size = {
|
||||||
.type = KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE,
|
.type = KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE,
|
||||||
.size = 21,
|
.size = 21,
|
||||||
},
|
},
|
||||||
.bios_dev = 123,
|
.biosdev = 123,
|
||||||
.partition = 456,
|
.partition = 456,
|
||||||
.sub_partition = 789,
|
.sub_partition = 789,
|
||||||
};
|
};
|
||||||
|
@ -530,15 +530,14 @@ tag_vbe_info_invalid_size = {
|
||||||
******************/
|
******************/
|
||||||
|
|
||||||
static const struct KernAux_Multiboot2_ITag_ELFSymbols
|
static const struct KernAux_Multiboot2_ITag_ELFSymbols
|
||||||
tag_elf_symbols_with_zero_ent_size_valid = {
|
tag_elf_symbols_with_zero_entsize_valid = {
|
||||||
.base = {
|
.base = {
|
||||||
.type = KERNAUX_MULTIBOOT2_ITAG_ELF_SYMBOLS,
|
.type = KERNAUX_MULTIBOOT2_ITAG_ELF_SYMBOLS,
|
||||||
.size = 16,
|
.size = 20,
|
||||||
},
|
},
|
||||||
.num = 0,
|
.num = 0,
|
||||||
.ent_size = 0,
|
.entsize = 0,
|
||||||
.shndx = 0,
|
.shndx = 0,
|
||||||
.reserved1 = 0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**************
|
/**************
|
||||||
|
@ -551,7 +550,7 @@ static const struct {
|
||||||
} KERNAUX_PACKED multiboot2_empty_valid = {
|
} KERNAUX_PACKED multiboot2_empty_valid = {
|
||||||
.multiboot2_info = {
|
.multiboot2_info = {
|
||||||
.total_size = 8 + 8,
|
.total_size = 8 + 8,
|
||||||
.reserved1 = 0,
|
.reserved = 0,
|
||||||
},
|
},
|
||||||
.tag_none = {
|
.tag_none = {
|
||||||
.base = {
|
.base = {
|
||||||
|
@ -568,7 +567,7 @@ static const struct {
|
||||||
} KERNAUX_PACKED multiboot2_with_some_additional_tag_valid = {
|
} KERNAUX_PACKED multiboot2_with_some_additional_tag_valid = {
|
||||||
.multiboot2_info = {
|
.multiboot2_info = {
|
||||||
.total_size = 8 + 16 + 8,
|
.total_size = 8 + 16 + 8,
|
||||||
.reserved1 = 0,
|
.reserved = 0,
|
||||||
},
|
},
|
||||||
.tag_basic_memory_info = {
|
.tag_basic_memory_info = {
|
||||||
.base = {
|
.base = {
|
||||||
|
@ -595,7 +594,7 @@ static const struct {
|
||||||
} KERNAUX_PACKED multiboot2_with_more_additional_tags_valid = {
|
} KERNAUX_PACKED multiboot2_with_more_additional_tags_valid = {
|
||||||
.multiboot2_info = {
|
.multiboot2_info = {
|
||||||
.total_size = 8 + 16 + (20 + 4) + 8,
|
.total_size = 8 + 16 + (20 + 4) + 8,
|
||||||
.reserved1 = 0,
|
.reserved = 0,
|
||||||
},
|
},
|
||||||
.tag_basic_memory_info = {
|
.tag_basic_memory_info = {
|
||||||
.base = {
|
.base = {
|
||||||
|
@ -610,7 +609,7 @@ static const struct {
|
||||||
.type = KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE,
|
.type = KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE,
|
||||||
.size = 20,
|
.size = 20,
|
||||||
},
|
},
|
||||||
.bios_dev = 123,
|
.biosdev = 123,
|
||||||
.partition = 456,
|
.partition = 456,
|
||||||
.sub_partition = 789,
|
.sub_partition = 789,
|
||||||
},
|
},
|
||||||
|
@ -628,7 +627,7 @@ static const struct {
|
||||||
} KERNAUX_PACKED multiboot2_empty_invalid_size = {
|
} KERNAUX_PACKED multiboot2_empty_invalid_size = {
|
||||||
.multiboot2_info = {
|
.multiboot2_info = {
|
||||||
.total_size = 8,
|
.total_size = 8,
|
||||||
.reserved1 = 0,
|
.reserved = 0,
|
||||||
},
|
},
|
||||||
.tag_none = {
|
.tag_none = {
|
||||||
.base = {
|
.base = {
|
||||||
|
@ -641,7 +640,7 @@ static const struct {
|
||||||
static const struct KernAux_Multiboot2_Info
|
static const struct KernAux_Multiboot2_Info
|
||||||
multiboot2_without_none_tag_invalid = {
|
multiboot2_without_none_tag_invalid = {
|
||||||
.total_size = 8,
|
.total_size = 8,
|
||||||
.reserved1 = 0,
|
.reserved = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
|
@ -650,7 +649,7 @@ static const struct {
|
||||||
} KERNAUX_PACKED multiboot2_with_invalid_last_tag_invalid = {
|
} KERNAUX_PACKED multiboot2_with_invalid_last_tag_invalid = {
|
||||||
.multiboot2_info = {
|
.multiboot2_info = {
|
||||||
.total_size = 8 + 16,
|
.total_size = 8 + 16,
|
||||||
.reserved1 = 0,
|
.reserved = 0,
|
||||||
},
|
},
|
||||||
.tag_basic_memory_info = {
|
.tag_basic_memory_info = {
|
||||||
.base = {
|
.base = {
|
||||||
|
@ -672,7 +671,7 @@ static const struct {
|
||||||
} KERNAUX_PACKED multiboot2_with_early_none_tag_invalid = {
|
} KERNAUX_PACKED multiboot2_with_early_none_tag_invalid = {
|
||||||
.multiboot2_info = {
|
.multiboot2_info = {
|
||||||
.total_size = 8 + 16 + 8 + (20 + 4) + 8,
|
.total_size = 8 + 16 + 8 + (20 + 4) + 8,
|
||||||
.reserved1 = 0,
|
.reserved = 0,
|
||||||
},
|
},
|
||||||
.tag_basic_memory_info = {
|
.tag_basic_memory_info = {
|
||||||
.base = {
|
.base = {
|
||||||
|
@ -693,7 +692,7 @@ static const struct {
|
||||||
.type = KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE,
|
.type = KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE,
|
||||||
.size = 20,
|
.size = 20,
|
||||||
},
|
},
|
||||||
.bios_dev = 123,
|
.biosdev = 123,
|
||||||
.partition = 456,
|
.partition = 456,
|
||||||
.sub_partition = 789,
|
.sub_partition = 789,
|
||||||
},
|
},
|
||||||
|
@ -714,7 +713,7 @@ static const struct {
|
||||||
} KERNAUX_PACKED multiboot2_with_more_additional_tags_invalid_size_too_big = {
|
} KERNAUX_PACKED multiboot2_with_more_additional_tags_invalid_size_too_big = {
|
||||||
.multiboot2_info = {
|
.multiboot2_info = {
|
||||||
.total_size = 8 + 16 + (20 + 4) + 8 + 1,
|
.total_size = 8 + 16 + (20 + 4) + 8 + 1,
|
||||||
.reserved1 = 0,
|
.reserved = 0,
|
||||||
},
|
},
|
||||||
.tag_basic_memory_info = {
|
.tag_basic_memory_info = {
|
||||||
.base = {
|
.base = {
|
||||||
|
@ -729,7 +728,7 @@ static const struct {
|
||||||
.type = KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE,
|
.type = KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE,
|
||||||
.size = 20,
|
.size = 20,
|
||||||
},
|
},
|
||||||
.bios_dev = 123,
|
.biosdev = 123,
|
||||||
.partition = 456,
|
.partition = 456,
|
||||||
.sub_partition = 789,
|
.sub_partition = 789,
|
||||||
},
|
},
|
||||||
|
@ -750,7 +749,7 @@ static const struct {
|
||||||
} KERNAUX_PACKED multiboot2_with_more_additional_tags_invalid_size_too_small = {
|
} KERNAUX_PACKED multiboot2_with_more_additional_tags_invalid_size_too_small = {
|
||||||
.multiboot2_info = {
|
.multiboot2_info = {
|
||||||
.total_size = 8 + 16 + (20 + 4) + 8 - 1,
|
.total_size = 8 + 16 + (20 + 4) + 8 - 1,
|
||||||
.reserved1 = 0,
|
.reserved = 0,
|
||||||
},
|
},
|
||||||
.tag_basic_memory_info = {
|
.tag_basic_memory_info = {
|
||||||
.base = {
|
.base = {
|
||||||
|
@ -765,7 +764,7 @@ static const struct {
|
||||||
.type = KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE,
|
.type = KERNAUX_MULTIBOOT2_ITAG_BIOS_BOOT_DEVICE,
|
||||||
.size = 20,
|
.size = 20,
|
||||||
},
|
},
|
||||||
.bios_dev = 123,
|
.biosdev = 123,
|
||||||
.partition = 456,
|
.partition = 456,
|
||||||
.sub_partition = 789,
|
.sub_partition = 789,
|
||||||
},
|
},
|
||||||
|
@ -955,7 +954,7 @@ void test_main()
|
||||||
));
|
));
|
||||||
|
|
||||||
assert(KernAux_Multiboot2_ITagBase_is_valid(
|
assert(KernAux_Multiboot2_ITagBase_is_valid(
|
||||||
&tag_elf_symbols_with_zero_ent_size_valid.base
|
&tag_elf_symbols_with_zero_entsize_valid.base
|
||||||
));
|
));
|
||||||
|
|
||||||
// Tag_None
|
// Tag_None
|
||||||
|
@ -1124,6 +1123,6 @@ void test_main()
|
||||||
|
|
||||||
|
|
||||||
assert(KernAux_Multiboot2_ITag_ELFSymbols_is_valid(
|
assert(KernAux_Multiboot2_ITag_ELFSymbols_is_valid(
|
||||||
&tag_elf_symbols_with_zero_ent_size_valid
|
&tag_elf_symbols_with_zero_entsize_valid
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue