Commit Graph

45 Commits

Author SHA1 Message Date
Justin C. Miller
1802c5ea2e [boot] Seperate video out from console
Separate the video mode setting out from the console code into video.*,
and remove the framebuffer from the kernel args, moving it to the new
init args format.
2021-07-28 14:58:55 -07:00
Justin C. Miller
269324c553 [project] Clean up src/ tree
A long overdue cleanup of the src/ tree.

- Moved src/drivers to src/user because it contains more than drivers
- Removed src/drivers/ahci because it's unused - will restore it when I
  make a real AHCI driver
- Removed unused src/tools
- Moved kernel.ld (the only used file under src/arch) to src/kernel for
  now, if/when there's a multi-platform effort that should be figured
  out as part of it
- Removed the rest of the unused src/arch
- Renamed 'fb' to 'drv.uefi_fb' and 'nulldrv' to 'testapp'
2021-07-25 23:47:23 -07:00
Justin C. Miller
0b2df134ce [boot] Improve bootloader allocation accounting
The bootloader relied on the kernel to know which parts of memory to not
allocate over. For the future shift of having the init process load
other processes instead of the kernel, the bootloader needs a mechanism
to just hand the kernel a list of allocations. This is now done through
the new bootloader allocator, which all allocation goes through. Pool
memory will not be tracked, and so can be overwritten - this means the
args structure and its other structures like programs need to be handled
right away, or copied by the kernel.

- Add bootloader allocator
- Implement a new linked-list based set of pages that act as allocation
  registers
- Allow for operator new in the bootloader, which goes through the
  global allocator for pool memory
- Split memory map and frame accouting code in the bootloader into
  separate memory_map.* files
- Remove many includes that could be replaced by forward declaration in
  the bootloader
- Add a new global template type, `counted`, which replaces the
  bootloader's `buffer` type, and updated kernel args structure to use it.
- Move bootloader's pointer_manipulation.h to the global include dir
- Make offset_iterator try to return references instead of pointers to
  make it more consistent with static array iteration
- Implement a stub atexit() in the bootloader to satisfy clang
2021-07-25 16:51:10 -07:00
Justin C. Miller
9fbbd8b954 [kernel] Update kernel binary's header structure
The kernel's file header has not been verified for a long time. This
change returns file verification to the bootloader to make sure the ELF
loaded in position 0 is actually the kernel.
2021-05-28 14:44:13 -07:00
Justin C. Miller
910fde3b2c [all] Rename kernel::args to kernel::init
The kernel::args namespace is really the protocol for initializing the
kernel from the bootloader. Also, the header struct in that namespace
isn't actually a header, but a collection of parameters. This change
renames the namespace to kernel::init and the struct to args.
2021-05-28 12:34:46 -07:00
Justin C. Miller
793bba95b5 [boot] Do address virtualization in the bootloader
More and more places in the kernel init code are taking addresses from
the bootloader and translating them to offset-mapped addresses. The
bootloader can do this, so it should.
2021-02-10 01:23:50 -08:00
Justin C. Miller
c88170f6e0 [kernel] Start all other processors in the system
This very large commit is mainly focused on getting the APs started and
to a state where they're waiting to have work scheduled. (Actually
scheduling on them is for another commit.)

To do this, a bunch of major changes were needed:

- Moving a lot of the CPU initialization (including for the BSP) to
  init_cpu(). This includes setting up IST stacks, writing MSRs, and
  creating the cpu_data structure. For the APs, this also creates and
  installs the GDT and TSS, and installs the global IDT.

- Creating the AP startup code, which tries to be as position
  independent as possible. It's copied from its location to 0x8000 for
  AP startup, and some of it is fixed at that address. The AP startup
  code jumps from real mode to long mode with paging in one swell foop.

- Adding limited IPI capability to the lapic class. This will need to
  improve.

- Renaming cpu/cpu.* to cpu/cpu_id.* because it was just annoying in GDB
  and really isn't anything but cpu_id anymore.

- Moved all the GDT, TSS, and IDT code into their own files and made
  them classes instead of a mess of free functions.

- Got rid of bsp_cpu_data everywhere. Now always call the new
  current_cpu() to get the current CPU's cpu_data.

- Device manager keeps a list of APIC ids now. This should go somewhere
  else eventually, device_manager needs to be refactored away.

- Moved some more things (notably the g_kernel_stacks vma) to the
  pre-constructor setup in memory_bootstrap. That whole file is in bad
  need of a refactor.
2021-02-07 23:44:28 -08:00
Justin C. Miller
c0f304559f [boot] Send module addresses as physical
This makes the job of the kernel easier when marking module pages as
used in the frame allocator. This will also help when sending modules
over to the init process.
2021-01-23 20:30:09 -08:00
Justin C. Miller
aae18fd035 [boot][kernel] Replace frame allocator with bitmap-based one
The previous frame allocator involved a lot of splitting and merging
linked lists and lost all information about frames while they were
allocated. The new allocator is based on an array of descriptor
structures and a bitmap. Each memory map region of allocatable memory
becomes one or more descriptors, each mapping up to 1GiB of physical
memory. The descriptors implement two levels of a bitmap tree, and have
a pointer into the large contiguous bitmap to track individual pages.
2021-01-22 00:16:01 -08:00
Justin C. Miller
cb612c36ea [boot][kernel] Split programs into sections
To enable setting sections as NX or read-only, the boot program loader
now loads programs as lists of sections, and the kernel args are updated
accordingly. The kernel's loader now just takes a program pointer to
iterate the sections. Also enable NX in IA32_EFER in the bootloader.
2021-01-20 01:25:47 -08:00
Justin C. Miller
14aad62e02 [boot] Improve non-printing error handling
Add an implicit __LINE__ to the try_or_raise macro, which gets set in
r11 on cpu_assert. Also made status lines smarter about when to call
cpu_assert.
2021-01-20 01:18:31 -08:00
Justin C. Miller
c3a0266354 [cpu] Split cpuid validation into separate lib
In order to allow the bootloader to do preliminary CPUID validation
while UEFI is still handling displaying information to the user, split
most of the kernel's CPUID handling into a library to be used by both
kernel and boot.
2021-01-18 13:49:59 -08:00
Justin C. Miller
8dbdebff3f [boot] Don't use custom UEFI memory types
The UEFI spec specifically calls out memory types with the high bit set
as being available for OS loaders' custom use. However, it seems many
UEFI firmware implementations don't handle this well. (Virtualbox, and
the firmware on my Intel NUC and Dell XPS laptop to name a few.)

So sadly since we can't rely on this feature of UEFI in all cases, we
can't use it at all. Instead, treat _all_ memory tagged as EfiLoaderData
as possibly containing data that's been passed to the OS by the
bootloader and don't free it yet.

This will need to be followed up with a change that copies anything we
need to save and frees this memory.

See: https://github.com/kiznit/rainbow-os/blob/master/boot/machine/efi/README.md
2021-01-18 13:49:10 -08:00
Justin C. Miller
61845b8761 [boot] Add framebuffer progress bar
After exiting UEFI, the bootloader had no way of displaying status to
the user. Now it will display a series of small boxes as a progress bar
along the bottom of the screen if a framebuffer exists. Errors or
warnings during a step will cause that step's box to turn red or orange,
and display bars above it to signal the error code.

This caused the simplification of the error handling system (which was
mostly just calling status_line::fail) and added different types of
status objects.
2021-01-18 13:49:10 -08:00
19cbf1ca67 [fb] Create fb driver
Create a new framebuffer driver. Also hackily passing frame buffer size
in the list of init handles to all processes and mapping the framebuffer
into all processes. Changed bootloader passing frame buffer as a module
to its own struct.
2021-01-18 13:48:11 -08:00
1904e240cf [kernel] Let endpoints get interrupt notifications
- Add a tag field to all endpoint messages, which doubles as a
  notification field
- Add a endpoint_bind_irq syscall to enable an endpoint to listen for
  interrupt notifications. This mechanism needs to change.
- Add a temporary copy of the serial port code to nulldrv, and let it
  take responsibility for COM2
2020-10-05 01:06:49 -07:00
4ccaa2dfea [boot] Load programs in boot, not kernel
Remove ELF and initrd loading from the kernel. The bootloader now loads
the initial programs, as it does with the kernel. Other files that were
in the initrd are now on the ESP, and non-program files are just passed
as modules.
2020-10-04 17:11:03 -07:00
Justin C. Miller
83b330bf2b [kernel] Use constants for known pml4e indices
There were a few lingering bugs due to places where 510/511 were
hard-coded as the kernel-space PML4 entries. These are now constants
defined in kernel_memory.h instead.

Tags: boot memory paging
2020-05-24 22:06:24 -07:00
Justin C. Miller
ce0bcbd3b6 [boot] Set up CR4 in bootloader
Moving the initial CR4 settings from the kernel's `memory_initialize`
(where it doesn't really fit anyway) to the bootloader's `hardware.cpp`.
2020-05-23 12:35:59 -07:00
Justin C. Miller
b491a09686 [boot] Virtualize memory in the bootloader
Finish updating the page tables, call UEFI's `set_virtual_address_map`
and jump to the kernel!
2020-05-21 23:49:49 -07:00
Justin C. Miller
6a538ad4f3 [boot] Fix several errors getting to kernel
* When using the non-allocating version of `get_uefi_mappings` the
  length was not getting set. Reworked this function.
* Having `build_kernel_mem_map` from `bootloader_main_uefi` caused it to
  get an out of date map key. Moved this function into `efi_main` right
  before exiting boot services.
2020-05-21 23:00:32 -07:00
Justin C. Miller
4f4a35a7be [boot] Set up initial page tables
Set up initial page tables for both the offset-mapped area and the
loaded kernel code and data.

* Got rid of the `loaded_elf` struct - the loader now runs after the
  initial PML4 is created and maps the ELF sections itself.
* Copied in the `page_table` and `page_table_indices` from the kernel,
  still need to clean this up and extract it into shared code.
* Added `page_table_cache` to the kernel args to pass along free pages
  that can be used for initial page tables.

Tags: paging
2020-05-17 22:03:44 -07:00
Justin C. Miller
42dfa6ccfe [boot] Only allocate memory map once
The `build_kernel_mem_map` function now calls `get_uefi_mappings`
itself, instead of having the efi map passed in. `get_uefi_mappings`
also now takes a `bool allocate` to direct it to actually allocate
the map or not. If it doesn't, it instead just returns the size of
the map and the metadata - which `build_kernel_mem_map`	uses to decide
how much space to first allocate for the kernel's map.
2020-05-16 18:48:28 -07:00
Justin C. Miller
a6e4995963 [boot] Fix call to exit_boot_services
Exiting boot services can't actually be done from inside
`bootloader_uefi_main`, because there are objects in that scope that run
code requiring boot services in their destructors.

Also added `support.cpp` with `memcpy` because clang will emit
references to `memcpy` even in freestanding mode.

Added a `debug_break` function to allow for faking breakpoints when
connecting to the bootloader with GDB.

Tags: debug
2020-05-13 02:08:47 -07:00
Justin C. Miller
2bd91c2d94 [boot] Split get_uefi_mappings and module creation
The `get_mappings()` function was getting too large, and some of its
output is needed by more than just the building of the kernel map. Split
it out into two.

Tags: boot memory
2020-05-10 16:43:18 -07:00
Justin C. Miller
10c8f6e4b5 Clean and document header files.
- Add missing doc comments to header files
- Move allocate_kernel_args to main.cpp
- Split functions out into pointer_manipulation.h
2020-05-10 01:42:22 -07:00
Justin C. Miller
9aa749e877 Parse ELF and load kernel, specify mem types
* Very bare-bones ELF parsing to load the kernel
* Custom memory type values for allocated memory
2020-05-09 21:25:45 -07:00
Justin C. Miller
f78a99927a [boot] Add initial stubs for loading kernel ELF 2020-05-02 23:58:41 -07:00
Justin C. Miller
ec794f4f99 Move module loading in main into helper function 2020-03-02 19:43:44 -08:00
Justin C. Miller
d94907ae79 Loading files 2020-02-25 22:22:12 -08:00
Justin C. Miller
4accfd136e Add file functionality in fs.cpp 2020-02-24 02:19:15 -08:00
Justin C. Miller
1a223d6ef5 Move args structure allocation to a function in memory.cpp 2020-02-24 02:18:14 -08:00
Justin C. Miller
303a78065e Move find_acpi_table to new hardware.cpp 2020-02-23 18:28:20 -08:00
Justin C. Miller
93f0b70eba Move to RAII-style status_line objects for console status 2020-02-23 17:55:53 -08:00
Justin C. Miller
6f5a2a3d3f Update kernel args to be module-based
- The old kernel_args structure is now mostly represented as a series of
  'modules' or memory ranges, tagged with a type. An arbitrary number
  can be passed to the kernel
- Update bootloader to allocate space for the args header and 10 module
  descriptors
2020-02-23 00:07:50 -08:00
Justin C. Miller
ec563ea8e4 Allow multiple calls to console::status_* functions 2020-02-22 17:52:51 -08:00
Justin C. Miller
570638bba6 Don't require system_table in console 2020-02-22 15:47:07 -08:00
Justin C. Miller
f627ea7de0 Re-add functionality to boot with new UEFI headers
- Pointer fixup event
- ACPI searching
- Move CHECK_* to using try_or_raise()
2020-02-22 14:57:28 -08:00
Justin C. Miller
521c132801 Back to a basic UEFI stub 2020-02-22 01:54:00 -08:00
Justin C. Miller
6285517ef7 Rename Popcorn to jsix.
See README.md for more information.
2019-05-27 14:07:29 -07:00
Justin C. Miller
39baec852b Allow larger initrd images 2019-03-25 01:42:36 -07:00
Justin C. Miller
870ca1db45 Allow debug option to be communicated at boot 2019-03-11 03:04:57 -07:00
Justin C. Miller
8cdc39fdee Switch page_manager to use frame_allocator.
Removed the frame allocation logic from page_manager and replaced it
with using an instance of frame_allocator instead. This had several
major ripple effects:

- memory_initalize() had to change to support this new world
  - Where to map used blocks is now passed as a flag, since blocks don't
    track their virtual address anymore
  - Instead of the complicated "find N contiguous pages that can be
    mapped in with one page table", we now just have the bootloader give
    us some (currently 64) pages to use both for tables and scratch
    space.
  - frame_allocator initialization was split into two steps to allow
    mapping used blocks before std::move()ing them over
2019-02-28 00:37:00 -08:00
Justin C. Miller
863e5bda15 Turning console into a class 2019-02-04 00:48:18 -08:00
Justin C. Miller
579f6f64e6 First step of moving bootloader to C++ 2019-02-03 01:38:12 -08:00