From 4130562b1555cabe441efe9420cebe12e7ed8d39 Mon Sep 17 00:00:00 2001 From: Benji Dial Date: Sat, 13 Jan 2024 16:43:49 -0500 Subject: application loading --- include/mercury/kernel/application.hpp | 72 ++++++++++++++++++++++++++++++++++ include/mercury/kernel/framebuffer.hpp | 2 + include/mercury/kernel/paging.hpp | 17 ++++++-- include/mercury/kernel/terminal.hpp | 2 + include/mercury/kernel/vfile.hpp | 5 +++ include/mercury/syscall.hpp | 26 ++++++++++++ 6 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 include/mercury/kernel/application.hpp create mode 100644 include/mercury/syscall.hpp (limited to 'include') diff --git a/include/mercury/kernel/application.hpp b/include/mercury/kernel/application.hpp new file mode 100644 index 0000000..bc4a763 --- /dev/null +++ b/include/mercury/kernel/application.hpp @@ -0,0 +1,72 @@ +#ifndef MERCURY_KERNEL_APPLICATION_HPP +#define MERCURY_KERNEL_APPLICATION_HPP + +#include +#include + +namespace mercury::kernel::application { + + enum class app_state { + running, + paused, + zombie + }; + + struct app_instance { + + app_state state; + + uint64_t *p4; + uint64_t *p3; + uint64_t *p2; + + bool *p2es_to_free_on_exit; + + uint64_t p4_paddr; + + //set to 0 if none + uint64_t framebuffer_vaddr; + + //only valid if state is zombie + int exit_code; + + //only valid if state is paused + struct { + uint64_t rip; + uint64_t rsp; + //TODO: etc. + } saved_regs; + + app_instance(); + ~app_instance(); + + //2MiB page. vaddr and paddr must be aligned, and vaddr in valid range. + void map_page(uint64_t vaddr, uint64_t paddr, + bool write, bool execute, bool free_pram_on_exit); + + //2MiB pages. returns start of first page. + uint64_t get_free_vaddr_pages(uint64_t count); + + void create_stack(); + + void set_instruction_pointer(uint64_t vaddr); + + //2MiB pages; only lower half. + uint64_t count_mapped_vram_pages(); + + }; + + extern app_instance *running_app; + + enum class create_app_result { + success, + device_error, + app_corrupt, + fs_corrupt + }; + + create_app_result create_app(const vfile::vfile &file, app_instance *&out); + +} + +#endif diff --git a/include/mercury/kernel/framebuffer.hpp b/include/mercury/kernel/framebuffer.hpp index 5c6ca23..677a42a 100644 --- a/include/mercury/kernel/framebuffer.hpp +++ b/include/mercury/kernel/framebuffer.hpp @@ -5,8 +5,10 @@ namespace mercury::kernel::framebuffer { + extern uint32_t *vaddr; extern int width; extern int height; + extern int dword_pitch; void init_framebuffer(uint64_t vaddr, uint64_t width, uint64_t height, uint64_t pitch); diff --git a/include/mercury/kernel/paging.hpp b/include/mercury/kernel/paging.hpp index 4ba5fdf..f6d400a 100644 --- a/include/mercury/kernel/paging.hpp +++ b/include/mercury/kernel/paging.hpp @@ -11,27 +11,36 @@ namespace mercury::kernel::paging { void mark_all_pram_used(); void mark_all_vram_free(); - //assumes page-alignment void mark_pram_region_free(uint64_t start_addr, uint64_t end_addr); - //assumes page-alignment void mark_vram_region_used(uint64_t start_addr, uint64_t end_addr); uint64_t find_unmapped_vram_region(uint64_t page_count); + uint64_t encode_pte( + uint64_t addr, bool user, bool write, bool execute, bool ps); + void init_kernel_page_tables(uint64_t kernel_offset); - void map_kernel_stack(); + void map_kernel_stacks(); - //assumes page-alignment void map_kernel_page( uint64_t paddr, uint64_t vaddr, bool write, bool execute); + void unmap_kernel_page(uint64_t vaddr); + //maps writable and not executable void *map_new_kernel_pages(uint64_t count); + //maps writable and not executable + void map_new_kernel_page(uint64_t &vaddr_out, uint64_t &paddr_out); + uint64_t get_used_vram_page_count(); uint64_t get_free_pram_page_count(); + extern uint64_t kernel_p4e; + + uint64_t take_2mib_pram_page(); + } #endif diff --git a/include/mercury/kernel/terminal.hpp b/include/mercury/kernel/terminal.hpp index 8efbcac..7b2d27a 100644 --- a/include/mercury/kernel/terminal.hpp +++ b/include/mercury/kernel/terminal.hpp @@ -28,6 +28,8 @@ namespace mercury::kernel::terminal { void put_int_decimal(uint64_t n, bool with_commas = true); + void put_int_hex(uint64_t n, int digits, bool with_dots = true); + } #endif diff --git a/include/mercury/kernel/vfile.hpp b/include/mercury/kernel/vfile.hpp index 43dff96..ce72bb1 100644 --- a/include/mercury/kernel/vfile.hpp +++ b/include/mercury/kernel/vfile.hpp @@ -48,6 +48,11 @@ namespace mercury::kernel::vfile { //dir_entry.type is assumed to be directory. out must be empty on entry. storage::fs_result get_children(utility::vector &out) const; + //assumes file is a regular file and [start, start + length) + //is in bounds of file. start and length are in bytes. + storage::fs_result read_file( + uint64_t start, uint64_t length, void *into) const; + }; //path must be absolute. follows symlinks on all but the last node. diff --git a/include/mercury/syscall.hpp b/include/mercury/syscall.hpp new file mode 100644 index 0000000..f434d91 --- /dev/null +++ b/include/mercury/syscall.hpp @@ -0,0 +1,26 @@ +#ifndef MERCURY_SYSCALL_HPP +#define MERCURY_SYSCALL_HPP + +#include + +namespace mercury::syscall { + + typedef uint32_t encoded_color; + + struct [[gnu::packed]] color { + uint8_t r; + uint8_t g; + uint8_t b; + }; + + extern "C" encoded_color encode_color(color c); + + extern "C" void get_framebuffer(encoded_color *&framebuffer_out, + uint32_t &width_out, uint32_t &height_out, uint32_t &pitch_out + ); + + extern "C" void draw_framebuffer(); + +} + +#endif -- cgit v1.2.3