Commit Graph

81 Commits

Author SHA1 Message Date
Justin C. Miller
9f54927a82 [util] Remove enum_bitfields
The enum_bitfields system never worked quite right, and always had edge cases where name
resolution for the SFINAE would fail. Move everything over to use util::bitset, which can
be constexpr and boils down to inline integer bitops in release mode.

Improved util::bitset itself, moving the array-backed base implementation into a new
util::sized_bitset, and making the single-inttype backed implementation the base case.
Also added a distinction between | or |= (which work with real bit values) and + or +=
(which work with bit indexes).
2024-02-25 23:40:14 -08:00
Justin C. Miller
bc46c9a7d5 [libj6] Add log area and severity to j6::syslog()
User code can now set the log area and severity of log messages. This also updates the j6_log
syscall to take these parameters, but removes all calls to it except through j6::syslog().
2024-02-24 13:39:24 -08:00
Justin C. Miller
a1e2c58afc [kernel] Add spam logging to trace mailbox calls
Added a new IPC log category, and logging of mailbox calls in it. Also added
some logs in init's service locator to help track down the bug fixed in the
previous commit.
2024-02-21 19:40:28 -08:00
Justin C. Miller
4e73e933db [libj6] Update how init args are passed and used
Now the init args are a linked list - this also means ld.so can use its
own plus those of the program (eg, SLP and VFS handles). __init_libj6
now adds the head of the list to its global init_args structure, and the
j6_find_init_handle function can be used to find a handle in those args
for a given proto.

This fixes situations like the logger using the wrong mailbox for the
service locator and never finding the uart driver.
2024-02-20 20:51:14 -08:00
Justin C. Miller
9f8e75f680 [ld.so] Properly handle stack alignment in ld.so args
Now when loading a process, init will push all the loader args, align
the stack so that the next pointer will have correct alignment, then
push a pointer to the loader args.

Also:
* _ldso_start will pop all loader args off of the stack before jumping
  to the loaded program's entrypoint, as if it had never run.
* The sentinel arg structures have a size instead of being all zeros, so
  that they can be popped off properly when done.
2024-02-20 19:42:12 -08:00
Justin C. Miller
dff9e53658 [init] Randomize load address of dynamic ELF modules
Update init to use the new xoroshiro RNG to create a random load address for dynamic executables.
Also pass an address past the end of the loader in the loader_arg to use when loading dynamic
dependencies.
2024-02-19 15:00:42 -08:00
Justin C. Miller
c245949ea4 [ld.so] Add dynamic library linking
ld.so will now go through all DT_NEEDED entries in the dynamic table and load and relocate
those shared libraries as well. Lazy linking of functions via the PLT is not yet supported,
all PLT entries are looked up ahead of time by ld.so.
2024-02-18 17:39:42 -08:00
Justin C. Miller
fc16ed54b3 [kernel] Change VMA syscall addr param to inout
This change allows the `vma_map` and `vma_create_map` syscalls to map to
addresses other than the one specified, and therefore makes the address
parameter to those syscalls `inout` in order to return the mapped
address.

Also add the `exact` flag for specifying that mapping needs to be done
at the exact address given. If the mapping collides with another, the
new `j6_err_collision` error is returned.
2023-08-31 19:40:02 -07:00
Justin C. Miller
646a534dfd [libj6] Remove driver_main
The `driver_main` sinature was an alternate signature for `main`
implemented with weak symbols, but it causes linking issues when not
statically linked, and drivers are going to work differently soon
anyway. Just get rid of it for now.
2023-08-26 19:23:13 -07:00
Justin C. Miller
eda816ad90 [build] Add build knowledge of dynamic libraries
Bonnibel will now build dynamic libraries when they're dependencies for
non-statically linked modules. It will also copy those shared libraries
into the initrd image for programs being copied into the image.
2023-08-26 19:19:04 -07:00
Justin C. Miller
c4bb60299e [ld.so] Add a minimal dynamic linker
This commit includes a number of changes to enable loading of PIE
executables:

- The loader in srv.init checks for a `PT_INTERP` segment in the program
  its loading, and if it exists, loads the specified interpreter and
  passes control to it instead of the program itself.
- Added ld.so the dynamic linker executable and set it as the
  interpreter for all user-target programs.
- Program initial stack changed again to now contain a number of
  possible tagged structures, including a new one for ld.so's arguments,
  and for passing handles tagged with protocol ids.
- Added a stub for a new VFS protocol. Unused so far, but srv.init will
  need to serve VFS requests from ld.so once I transition libraries to
  shared libs for user-target programs. (Right now all executables are
  PIE but statically linked, so they only need internal relocations.)
- Added 16 and 8 bit variants of `util::bitset`. This ended up not being
  used, but could be useful.
2023-08-12 22:55:37 -07:00
Justin C. Miller
3cfd0cf86b [libj6] Make j6::thread a template for lambdas
Instead of a C-style function pointer taking `void *userdata`, let
j6::thread take a lambda as its thread procedure.
2023-08-09 21:08:45 -07:00
Justin C. Miller
8b3fa3ed01 [kernel] Make mailbox non-fixed-length again
Going back to letting mailboxes use variable-length data. Note that this
requires extra copies, so shared memory channels should be used for
anything in the hot path. But this allows better RPC over mailboxes and
other flexibility.

Other changes:
- added a j6::proto::sl::client class to act as a service locator
  client, instead of duplicating that code in every program.
- moved protocol ids into j6/tables/protocols.inc so that C++ clients
  can easily have their own API
2023-08-07 22:59:03 -07:00
Justin C. Miller
ce27749705 [srv.init] Allow init loader to load dynamic ELFs
Use the `elf::file::valid()` change to allow the loader to load `ET_DYN`
binaries, and add a static offset to all load addresses for them.
2023-08-06 10:42:25 -07:00
Justin C. Miller
bbe27c6b53 [build] Move init to its own target
In order to allow -fpic and -fpie in the user target, move init to it's
own target -- it needs its own special build rules to make it loadable
by boot.
2023-07-31 00:16:02 -07:00
Justin C. Miller
a449a88395 [user] Update logging and return in user apps
Update some userspace apps to return more distinct error messages and
make better use of j6::syslog.
2023-07-10 01:41:55 -07:00
Justin C. Miller
b5662bfd25 [kernel] Initial XSAVE support implementation
Initial support for XSAVE, but not XSAVEOPT or XSAVEC:

- Enable XSAVE and set up xcr0 for all CPUs
- Allocate XSAVE area for all non-kernel threads
- Call XSAVE and XRSTOR on task switch
2023-05-05 12:04:37 -06:00
Justin C. Miller
692e0d8656 [drv.uart] Replace user code with new channels
Move all the user space uses of channels to use j6::channel.
2023-03-16 19:59:28 -07:00
Justin C. Miller
4052911ac4 [kernel] Clean up log areas
Removing several log areas that are not used
2023-02-20 11:35:44 -08:00
Justin C. Miller
3a7a18011c [init] Move PCIe probing to srv.init
This was kept in the kernel as a way to keep exercising the code, but it
doesn't belong there. This moves it to init, which doesn't do anything
but probe for devices currently - but at least it's executing the code
in userspace now.
2023-02-20 11:23:49 -08:00
Justin C. Miller
508058c3d7 [uefi_fb] Fix log messages not showing in drv.uefi_fb
Also add drv.uefi_fb to the default manifest.
2023-02-20 11:18:59 -08:00
Justin C. Miller
4c9ff44b1c [init] Switch init to driver_main instead of custom _start
init still uses a custom _start to set up the stack, but then jumps to
_libc_crt0_start. The modules data passed to it is taken from the
j6_init_args instead of having it stashed into a global variable.

Also replace several uses of snprintf/j6_log with j6::syslog.
2023-02-20 11:15:08 -08:00
Justin C. Miller
c092e07832 [libj6] Allow driver_main instead of main for accepting extra arguments
Clang will complain if main() is not declared with 0, 2, or 3 arguments.
In order to allow an extra 4th parameter, a new weak main() symbol which
just jumps to driver_main is defined, and _start passes the extra init
pointer to main.

Additionally, libc's crt0.s _start is made weak, and a matching
_libc_crt0_start symbol is defined for implementations that wish to
override _start but still call libc's _start. (Will be used by init.)
2023-02-20 11:05:53 -08:00
Justin C. Miller
cca8e8b3ad [init] Let init pass module data to drivers
First pass at passing module data to drivers in init. Also fix some
remaining __handle_self references.
2023-02-19 14:44:16 -08:00
Justin C. Miller
7c194950bb [uart] Make UART driver single-threaded
The design of the UART driver was needlessly multi-threaded and a source
of threading bugs. Just make it single-threaded.
2023-02-19 14:41:55 -08:00
Justin C. Miller
7b29ba7d23 [uart] Pass com1 address directly to thread proc
To avoid a race condition I was seeing where the child thread was
reading g_com1 and seeing it as null, now we just pass the pointer as an
argument.
2023-02-14 20:35:03 -08:00
Justin C. Miller
ea587076ed [init] Go back to boot modules having inline data
In order to pass along arguments like the framebuffer, it's far simpler
to have that data stored along with the modules than mapping new pages
for every structure. Also now optionally pass a module's data to a
driver as init starts it.
2023-02-10 01:01:01 -08:00
Justin C. Miller
0eddb002f0 [libj6] Create a standard definition of the log entry type
Move logger::entry to libj6 as j6_log_entry, and use that everywhere. It
was silly that it was copied into srv.logger and drv.uefi_fb
2023-02-10 00:57:00 -08:00
Justin C. Miller
8f968f4954 [uart] Fix uart driver & testapp j6::thread usage
The prior change to j6::thread allowing arguments did not test drv.uart
or testapp. Oops.
2023-02-08 23:20:44 -08:00
Justin C. Miller
094b54d728 [tests] Get mailbox test running again
This commit fixes the mailbox tests in test_runner, which broke when
mailbox was simplified to just use call and respond. It also fixes a
bug the tests uncovered: if the mailbox is closed while a caller is in
the reply map (ie, when its call data has been passed on to a thread
calling respond, but has yet to be responded to itself), that caller is
never awoken.
2023-02-08 23:16:22 -08:00
Justin C. Miller
4125175870 [kernel] Give threads initial arguments
This commit changes the add_user_thunk to point to a new routine,
initialize_user_cpu, which sets all the registers that were previously
unset when starting a new user thread. The values for rdi and rsi are
popped off the initial stack values that add_user_thunk sets up, so that
user thread procs can take up to two arguments.

To suppor this, j6_thread_create gained two new arguments, which are
passed on to the thread.

This also let me finally get rid of the hack of passing an argument in
rsp when starting init.
2023-02-08 23:10:17 -08:00
Justin C. Miller
1cb8f1258d [testapp] Re-add testapp to default manifest
This commit re-adds testapp to the default manifest and does some
housecleaning on the module:

- Remove the old serial.* and io.*
- Update it to use current syscall APIs
- Update it to use libj6's higher-level thread API
2023-02-08 22:44:05 -08:00
Justin C. Miller
393db1e792 [kernel] Switch logger from bip to ring buffer
A bip-buffer is good for producer/consumer systems, but ideally logs
will stay in the buffer until they're ousted because they need to be
overwritten. Now they're a regular ring buffer and every entry has an
incremental id. Consumers pass in the last id they've seen, and will get
the next log in the sequence.
2023-02-07 20:19:02 -08:00
Justin C. Miller
118ee73ff1 [srv.init] Iterate and load drivers and services from initrd
Previously we were hard-coding loading specific files (the UART driver
and logging server) from the initrd. Now j6romfs has a for_each() method
to allow iterating all files in a directory, and init loads all programs
from /jsix/drivers and /jsix/services. Eventually this will need more
dynamic loading decisions for drivers but for now it's fine.
2023-02-07 01:05:38 -08:00
Justin C. Miller
359ee035d8 [kernel] Only accept invalid handles for optional syscall args
The syscall helpers.h get_handle functions should be returing
j6_err_invalid_arg if the handle they're given is j6_handle_invalid,
unless explicitly set to optional.
2023-02-06 01:13:55 -08:00
Justin C. Miller
ab31825ab3 [boot] Restructure boot paging and program loading
Restructuring paging into an object that carries its page cache with it
and makes for simpler code. Program loading is also changed to not copy
the pages loaded from the file into new pages - we can impose a new
constraint that anything loaded by boot have a simple, page-aligned
layout so that we can just map the existing pages into the right
addresses. Also included are some linker script changes to help
accommodate this.
2023-02-05 22:02:41 -08:00
Justin C. Miller
aba45b9b67 [boot] Go back to loading symbol table in boot
The symbol table needs to be passed to the panic handler very early in
the kernel, loading it in init is far less useful. Return it to the boot
directory and remove it from the initrd.
2023-02-04 00:03:03 -08:00
Justin C. Miller
8b29680850 [init] Load uart and logger from initrd
Load drv.uart.elf and srv.logger.elf from the initrd and start them.
It's extremely manual and hard-coded at the moment, but it works and
they run, getting us back to where we were pre-initrd branch.
2023-01-29 21:35:12 -08:00
Justin C. Miller
66abcc57a2 [boot] Build, load, and pass initrd from boot to init
The initrd image is now created by the build system, loaded by the
bootloader, and passed to srv.init, which loads it (but doesn't do
anything with it yet, so this is actually a functional regression).

This simplifies a lot of the modules code between boot and init as well:
Gone are the many subclasses of module and all the data being inline
with the module structs, except for any loaded files. Now the only
modules loaded and passed will be the initrd, and any devices only the
bootloader has knowledge of, like the UEFI framebuffer.
2023-01-28 21:13:52 -08:00
Justin C. Miller
6ef15a2721 [init] Add new initrd format
A new compressed initrd format for srv.init to load drivers, services,
and data from, instead of every file getting loaded by the bootloader.
This will allow for less memory allocated by the bootloader and passed
to init if not every driver or data file is loaded.

Loading, passing, and using the new initrd will be done in a coming
commit.
2023-01-18 10:59:34 -08:00
Justin C. Miller
99b59393fe [init] Use a real std::unordered_map for the services map
Now that ceil* works in libc, use std::unordered_map instead of
util::node_map to store the protocol to service mapping.
2023-01-14 15:32:42 -08:00
Justin C. Miller
6583744532 [libj6] Add thread wrapper class
This new class makes it easier for user programs to spawn threads. This
change also includes support for .hh files in modules, to differentiate
headers that are C++-only in system libraries.
2022-10-20 22:12:02 -07:00
Justin C. Miller
194776d226 [kernel] Remove status code from thread exit
The status code from thread exit had too many issues, (eg, how does it
relate to process exit code? what happens when different threads exit
with different exit codes?) and not enough value, so I'm getting rid of
it.
2022-10-20 21:49:40 -07:00
Justin C. Miller
1a04310f80 [kernel] Simplify mailbox code, and messages
A number of simplifications of mailboxes now that the interface is much
simpler, and synchronous.

* call and respond can now only transfer one handle at a time
* mailbox objects got rid of the message queue, and just have
  wait_queues of blocked threads, and a reply_to map.
* threads now have a message_data struct on them for use by mailboxes
2022-10-14 01:02:56 -07:00
Justin C. Miller
c9bcc87511 [kernel] Simplify mailbox interface to call/respond
The only real usage of mailbox was mailbox_call or
mailbox_respond_receive. This change simplifies the interface to just
these syscalls.
2022-10-11 17:42:04 -07:00
Justin C. Miller
9ac4e51224 [kernel] Make capabilities/handles global
Instead of handles / capabilities having numeric ids that are only valid
for the owning process, they are now global in a system capabilities
table. This will allow for specifying capabilities in IPC that doesn't
need to be kernel-controlled.

Processes will still need to be granted access to given capabilities,
but that can become a simpler system call than the current method of
sending them through mailbox messages (and worse, having to translate
every one into a new capability like was the case before). In order to
track which handles a process has access to, a new node_set based on
node_map allows for an efficient storage and lookup of handles.
2022-10-10 21:19:25 -07:00
Justin C. Miller
e90647d498 [kernel] Change heap alloc for better alignment
Created a new util/node_map.h that implements a map that grows in-place.
Now this is used for tracking blocks' size orders, instead of a header
at the start of the memory block. This allows the whole buddy block to
be allocated, allowing for page-aligned (or greater) blocks to be
requested from the heap.
2022-10-02 17:32:26 -07:00
Justin C. Miller
11b61ab345 [kernel] Change kernel log levels
The kernel log levels are now numerically reversed so that more-verbose
levels can be added to the end. Replaced 'debug' with 'verbose', and
added new 'spam' level.
2022-09-25 17:25:43 -07:00
Justin C. Miller
7b8fd76af0 [libj6] Move caps.h to cap_flags.h
This file is just the generated cap flag constants. Move it to not
collide with more capability code to be added.
2022-09-25 17:23:14 -07:00
Justin C. Miller
bb0d30610e [util] Add util::format replacement for snprintf
The printf library I have been using, while useful, has way more than I
need in it, and had comparably huge stack space requirements. This
change adds a new util::format() which is a replacement for snprintf,
but with only the features used by kernel logging.

The logger has been changed to use it, as well as the few instances of
snprintf in the interrupt handling code before calling kassert.

Also part of this change: the logger's (now vestigial) immediate output
handling code is removed, as well as the "sequence" field on log
message headers.
2022-03-13 17:59:56 -07:00