oops
This commit is contained in:
+34
-6
@@ -1,4 +1,5 @@
|
||||
#include <zinnia/alloc.h>
|
||||
#include <zinnia/assert.h>
|
||||
#include <zinnia/cmdline.h>
|
||||
#include <zinnia/init.h>
|
||||
#include <zinnia/print.h>
|
||||
@@ -41,10 +42,15 @@ void kernel_entry() {
|
||||
|
||||
struct boot_info info = {};
|
||||
|
||||
struct limine_memmap_response* mm_res = memmap_request.response;
|
||||
struct limine_module_response* module_res = module_request.response;
|
||||
struct limine_executable_address_response* exec_res = executable_address_request.response;
|
||||
struct limine_executable_file_response* exec_file_res = executable_file_request.response;
|
||||
const struct limine_memmap_response* mm_res = memmap_request.response;
|
||||
const struct limine_hhdm_response* hhdm_res = hhdm_request.response;
|
||||
const struct limine_module_response* module_res = module_request.response;
|
||||
const struct limine_executable_address_response* exec_res = executable_address_request.response;
|
||||
const struct limine_executable_file_response* exec_file_res = executable_file_request.response;
|
||||
const struct limine_rsdp_response* rsdp_res = rsdp_request.response;
|
||||
|
||||
assert(mm_res, "memmap_request returned no response!");
|
||||
assert(hhdm_res, "hhdm_request returned no response!");
|
||||
|
||||
info.cmdline = exec_file_res->executable_file->string;
|
||||
|
||||
@@ -74,7 +80,7 @@ void kernel_entry() {
|
||||
info.files = files;
|
||||
info.num_files = MIN(ARRAY_SIZE(files), module_res->module_count);
|
||||
for (size_t i = 0; i < info.num_files; i++) {
|
||||
files[i].data = (phys_t)module_res->modules[i]->address - hhdm_request.response->offset;
|
||||
files[i].data = (phys_t)module_res->modules[i]->address - hhdm_res->offset;
|
||||
files[i].length = module_res->modules[i]->size;
|
||||
strncpy(files[i].path, module_res->modules[i]->path, sizeof(files[i].path) - 1);
|
||||
files[i].path[sizeof(files[i].path) - 1] = 0;
|
||||
@@ -84,7 +90,29 @@ void kernel_entry() {
|
||||
info.mem_map = mem;
|
||||
info.phys_base = (phys_t)exec_res->physical_base;
|
||||
info.virt_base = (uintptr_t)exec_res->virtual_base;
|
||||
info.hhdm_base = (uintptr_t)hhdm_request.response->offset;
|
||||
info.hhdm_base = (uintptr_t)hhdm_res->offset;
|
||||
|
||||
const struct limine_framebuffer_response* fb_res = framebuffer_request.response;
|
||||
if (fb_res) {
|
||||
// Only use the first framebuffer.
|
||||
if (fb_res->framebuffer_count >= 1) {
|
||||
const struct limine_framebuffer* fb = framebuffer_request.response->framebuffers[0];
|
||||
info.fb.base = (phys_t)((uintptr_t)fb->address - hhdm_res->offset);
|
||||
info.fb.width = fb->width;
|
||||
info.fb.height = fb->height;
|
||||
info.fb.pitch = fb->pitch;
|
||||
info.fb.bytes_per_pixel = fb->bpp / 8;
|
||||
|
||||
info.fb.red.shift = fb->red_mask_shift;
|
||||
info.fb.red.size = fb->red_mask_size;
|
||||
|
||||
info.fb.green.shift = fb->green_mask_shift;
|
||||
info.fb.green.size = fb->green_mask_size;
|
||||
|
||||
info.fb.blue.shift = fb->blue_mask_shift;
|
||||
info.fb.blue.size = fb->blue_mask_size;
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_ACPI
|
||||
if (rsdp_request.response) {
|
||||
|
||||
+8
-4
@@ -25,6 +25,7 @@ static const char zinnia_banner[] = "Zinnia " ZINNIA_VERSION " " CONFIG_KERNEL_F
|
||||
", " ZINNIA_COMPILER_ID ", " ZINNIA_LINKER_ID ")";
|
||||
|
||||
static void kernel_main_task(uintptr_t arg0) {
|
||||
errno_t status = 0;
|
||||
struct boot_info* info = (struct boot_info*)arg0;
|
||||
|
||||
log("main: Hello from main task!\n");
|
||||
@@ -38,8 +39,12 @@ static void kernel_main_task(uintptr_t arg0) {
|
||||
assert(vma_new(&init_space) == EOK, "");
|
||||
|
||||
struct boot_file* file_data = &info->files[0];
|
||||
struct task* init_task = nullptr;
|
||||
|
||||
struct paged_vmo* init_file;
|
||||
assert(vmo_new_phys(&init_file) == EOK, "");
|
||||
status = vmo_new_phys(&init_file);
|
||||
assert(status == EOK, "Failed to allocate a memory object");
|
||||
|
||||
vmo_write(&init_file->object, 0, HHDM_PTR(file_data->data), file_data->length, nullptr);
|
||||
|
||||
// Load init.
|
||||
@@ -53,11 +58,10 @@ static void kernel_main_task(uintptr_t arg0) {
|
||||
.envp = init_envp,
|
||||
};
|
||||
|
||||
struct task* init_task = nullptr;
|
||||
errno_t status = elf_load(&exec, &init_task);
|
||||
status = elf_load(&exec, &init_task);
|
||||
vmo_unref(&init_file->object);
|
||||
|
||||
assert(status == 0, "Failed to load init process (%i)\n", status);
|
||||
assert(status == 0, "Failed to load init process (%i)", status);
|
||||
sched_add_task(&percpu_get()->sched, init_task);
|
||||
|
||||
while (true) {
|
||||
|
||||
+35
-58
@@ -1,8 +1,8 @@
|
||||
#include <zinnia/compiler.h>
|
||||
#include <zinnia/string.h>
|
||||
#include <zinnia/utils.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <zinnia/string.h>
|
||||
|
||||
[[__hot]]
|
||||
size_t strlen(const char* str) {
|
||||
@@ -29,45 +29,37 @@ int memcmp(const void* s1, const void* s2, size_t size) {
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
if (s1ptr[i] != s2ptr[i])
|
||||
return s1ptr[i] - s2ptr[i];
|
||||
return (int)s1ptr[i] - (int)s2ptr[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef size_t word_t [[__may_alias]]
|
||||
;
|
||||
|
||||
[[__hot]]
|
||||
void* memcpy(void* restrict dest, const void* restrict src, size_t n) {
|
||||
if (__unlikely(n == 0))
|
||||
return dest;
|
||||
uint8_t* d = dest;
|
||||
const uint8_t* s = src;
|
||||
|
||||
size_t d = (size_t)dest;
|
||||
size_t s = (size_t)src;
|
||||
|
||||
if (d % sizeof(size_t) != 0 || s % sizeof(size_t) != 0) {
|
||||
while (n && (d % sizeof(size_t) != 0) && (s % sizeof(size_t) != 0)) {
|
||||
*((uint8_t*)d) = *((uint8_t*)s);
|
||||
d++;
|
||||
s++;
|
||||
// Word copies are only possible if both pointers can be aligned at the same time.
|
||||
if (((uintptr_t)d - (uintptr_t)s) % sizeof(word_t) == 0) {
|
||||
while (n && (uintptr_t)d % sizeof(word_t) != 0) {
|
||||
*d++ = *s++;
|
||||
n--;
|
||||
}
|
||||
|
||||
word_t* word_dest = (word_t*)d;
|
||||
const word_t* word_src = (const word_t*)s;
|
||||
for (; n >= sizeof(word_t); n -= sizeof(word_t))
|
||||
*word_dest++ = *word_src++;
|
||||
|
||||
d = (uint8_t*)word_dest;
|
||||
s = (const uint8_t*)word_src;
|
||||
}
|
||||
|
||||
size_t* qword_dest = (size_t*)d;
|
||||
const size_t* qword_src = (const size_t*)s;
|
||||
const size_t word_count = n / sizeof(size_t);
|
||||
|
||||
for (size_t i = 0; i < word_count; i++) {
|
||||
qword_dest[i] = qword_src[i];
|
||||
}
|
||||
|
||||
size_t remaining_bytes = n % sizeof(size_t);
|
||||
d = (size_t)(qword_dest + word_count);
|
||||
s = (size_t)(qword_src + word_count);
|
||||
|
||||
while (remaining_bytes--) {
|
||||
*((uint8_t*)d) = *((uint8_t*)s);
|
||||
d++;
|
||||
s++;
|
||||
}
|
||||
while (n--)
|
||||
*d++ = *s++;
|
||||
|
||||
return dest;
|
||||
}
|
||||
@@ -76,7 +68,8 @@ void* memcpy(void* restrict dest, const void* restrict src, size_t n) {
|
||||
void* memmove(void* dstptr, const void* srcptr, size_t size) {
|
||||
uint8_t* dst = (uint8_t*)dstptr;
|
||||
const uint8_t* src = (const uint8_t*)srcptr;
|
||||
if (dst < src) {
|
||||
|
||||
if ((uintptr_t)dst < (uintptr_t)src) {
|
||||
for (size_t i = 0; i < size; i++)
|
||||
dst[i] = src[i];
|
||||
} else {
|
||||
@@ -88,38 +81,22 @@ void* memmove(void* dstptr, const void* srcptr, size_t size) {
|
||||
|
||||
[[__hot]]
|
||||
void* memset(void* dest, int value, size_t n) {
|
||||
if (__unlikely(n == 0))
|
||||
return dest;
|
||||
uint8_t* d = dest;
|
||||
const uint8_t byte = (uint8_t)value;
|
||||
|
||||
size_t d = (size_t)dest;
|
||||
|
||||
if (d % sizeof(size_t) != 0) {
|
||||
while (n && (d % sizeof(size_t) != 0)) {
|
||||
*((uint8_t*)d) = value;
|
||||
d++;
|
||||
n--;
|
||||
}
|
||||
while (n && (uintptr_t)d % sizeof(word_t) != 0) {
|
||||
*d++ = byte;
|
||||
n--;
|
||||
}
|
||||
|
||||
size_t* qword_dest = (size_t*)d;
|
||||
size_t qword_value = (uint8_t)value;
|
||||
qword_value |= (qword_value << 8);
|
||||
qword_value |= (qword_value << 16);
|
||||
qword_value |= (qword_value << 32);
|
||||
const word_t word_value = (SIZE_MAX / 0xFF) * byte;
|
||||
word_t* word_dest = (word_t*)d;
|
||||
for (; n >= sizeof(word_t); n -= sizeof(word_t))
|
||||
*word_dest++ = word_value;
|
||||
|
||||
const size_t word_count = n / sizeof(size_t);
|
||||
|
||||
for (size_t i = 0; i < word_count; i++) {
|
||||
qword_dest[i] = qword_value;
|
||||
}
|
||||
|
||||
size_t remaining_bytes = n % sizeof(size_t);
|
||||
d = (size_t)(qword_dest + word_count);
|
||||
|
||||
while (remaining_bytes--) {
|
||||
*((uint8_t*)d) = value;
|
||||
d++;
|
||||
}
|
||||
d = (uint8_t*)word_dest;
|
||||
while (n--)
|
||||
*d++ = byte;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
+8
-4
@@ -3,9 +3,9 @@
|
||||
#include <zinnia/init.h>
|
||||
#include <zinnia/panic.h>
|
||||
#include <zinnia/print.h>
|
||||
#include <zinnia/string.h>
|
||||
#include <zinnia/utils.h>
|
||||
#include <zinnia/vma.h>
|
||||
#include <zinnia/string.h>
|
||||
|
||||
extern uint8_t __ld_text_start[];
|
||||
extern uint8_t __ld_text_end[];
|
||||
@@ -48,11 +48,12 @@ void mem_init(struct phys_mem* map, size_t map_len, uintptr_t kernel_virt, phys_
|
||||
}
|
||||
|
||||
// Set up the bootstrap allocator.
|
||||
struct phys_mem* largest = map;
|
||||
struct phys_mem* largest = nullptr;
|
||||
for (size_t i = 0; i < map_len; i++) {
|
||||
if (map[i].length > largest->length && map[i].usage == PHYS_USABLE)
|
||||
if (map[i].usage == PHYS_USABLE && (!largest || map[i].length > largest->length))
|
||||
largest = &map[i];
|
||||
}
|
||||
assert(largest && largest->length >= pgsz, "No usable memory for bootstrap allocator");
|
||||
mem_phys_bootstrap(largest);
|
||||
log("mem: Using region [%p - %p] for bootstrap allocator\n",
|
||||
(void*)largest->address,
|
||||
@@ -150,7 +151,10 @@ void mem_init(struct phys_mem* map, size_t map_len, uintptr_t kernel_virt, phys_
|
||||
for (size_t page = 0; page < length; page += pgsz) {
|
||||
phys_t paddr;
|
||||
assert(!mem_phys_alloc(1, 0, &paddr), "Failed to allocate memory for PFNDB!\n");
|
||||
pmap_map(&kernel_vma.pmap, vaddr + page, paddr, PTE_READ | PTE_WRITE, CACHE_ANY);
|
||||
assert(
|
||||
!pmap_map(&kernel_vma.pmap, vaddr + page, paddr, PTE_READ | PTE_WRITE, CACHE_ANY),
|
||||
"Failed to map PFNDB memory"
|
||||
);
|
||||
}
|
||||
}
|
||||
vm_pfndb = (struct page*)arch_mem_pfndb_addr();
|
||||
|
||||
+1
-1
@@ -213,7 +213,7 @@ errno_t vmo_new_phys(struct paged_vmo** out) {
|
||||
|
||||
void vmo_truncate_paged(struct paged_vmo* paged, size_t length) {
|
||||
const size_t page_size = arch_mem_page_size();
|
||||
const size_t keep_pages = ROUND_UP(length, page_size) / page_size;
|
||||
const size_t keep_pages = ROUND_UP(length, page_size);
|
||||
|
||||
spin_lock(&paged->lock);
|
||||
struct page_list** pp = &list_first(&paged->cache);
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#include <zinnia/vfs.h>
|
||||
|
||||
void vfs_init() {}
|
||||
@@ -1,3 +1,4 @@
|
||||
kernel_sources += files(
|
||||
'ident.c',
|
||||
'init.c',
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#define __section(x) gnu::section(x)
|
||||
#define __aligned(x) gnu::aligned(x)
|
||||
#define __packed gnu::packed
|
||||
#define __may_alias gnu::may_alias
|
||||
#define __naked gnu::naked
|
||||
|
||||
// These hints may improve code generation.
|
||||
@@ -12,7 +13,7 @@
|
||||
#define __used gnu::used
|
||||
#define __unused gnu::unused
|
||||
#define __format(like, ...) gnu::format(like, __VA_ARGS__)
|
||||
#define __always_inline gnu::always_inline
|
||||
#define __force_inline gnu::always_inline
|
||||
#define __visibility gnu::visibility
|
||||
#define __pure gnu::pure
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <stdatomic.h>
|
||||
|
||||
struct dpc {
|
||||
void (*const callback)(struct dpc* dpc, void* data);
|
||||
void (*callback)(struct dpc* dpc, void* data);
|
||||
void* data;
|
||||
atomic_bool inserted;
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
struct file_desc {};
|
||||
+13
-1
@@ -17,6 +17,17 @@ struct boot_file {
|
||||
char path[128];
|
||||
};
|
||||
|
||||
struct boot_color {
|
||||
uint8_t shift, size;
|
||||
};
|
||||
|
||||
struct boot_framebuffer {
|
||||
phys_t base;
|
||||
size_t width, height, pitch;
|
||||
uint8_t bytes_per_pixel;
|
||||
struct boot_color red, green, blue;
|
||||
};
|
||||
|
||||
struct boot_info {
|
||||
char* cmdline;
|
||||
struct phys_mem* mem_map;
|
||||
@@ -26,8 +37,9 @@ struct boot_info {
|
||||
uintptr_t hhdm_base;
|
||||
struct boot_file* files;
|
||||
size_t num_files;
|
||||
|
||||
struct boot_framebuffer fb;
|
||||
void* dtb;
|
||||
size_t dtb_size;
|
||||
#if CONFIG_ACPI
|
||||
phys_t rsdp;
|
||||
#endif
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
#include <stddef.h>
|
||||
#include <uapi/uio.h>
|
||||
|
||||
typedef struct __iovec iovec_t;
|
||||
|
||||
struct iovec_iter {
|
||||
struct __iovec* iovecs;
|
||||
iovec_t* iovecs;
|
||||
size_t iovecs_len;
|
||||
size_t total_len;
|
||||
size_t total_offset;
|
||||
@@ -21,7 +23,7 @@ static inline size_t iovec_iter_len(struct iovec_iter* iter) {
|
||||
}
|
||||
|
||||
// Creates an iovec iterator over kernel memory.
|
||||
static inline struct iovec_iter iovec_iter_kernel(struct __iovec* iovecs, size_t count) {
|
||||
static inline struct iovec_iter iovec_iter_kernel(iovec_t* iovecs, size_t count) {
|
||||
size_t total = 0;
|
||||
for (size_t i = 0; i < count; i++)
|
||||
total += iovecs[i].len;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#define MODULE_VERSION(version) MODULE_PROPERTY("version", version)
|
||||
#define MODULE_LICENSE(license) MODULE_PROPERTY("license", license)
|
||||
|
||||
#ifdef IN_MODULE
|
||||
#define MODULE_ENTRY(func) \
|
||||
[[__used]] \
|
||||
errno_t __module_entry(struct module* __module) { \
|
||||
@@ -28,6 +29,15 @@
|
||||
} \
|
||||
[[__used, __section(".mod.exit")]] \
|
||||
static const void* __exit_fn = &__module_exit
|
||||
#else
|
||||
#define MODULE_ENTRY(func) \
|
||||
[[__used, __section(".mod.entry")]] \
|
||||
static const void* UNIQUE_IDENT(module_entry) = &(func)
|
||||
|
||||
#define MODULE_EXIT(func) \
|
||||
[[__used, __section(".mod.exit")]] \
|
||||
static const void* UNIQUE_IDENT(module_exit) = &(func)
|
||||
#endif
|
||||
|
||||
struct module {
|
||||
const char* name;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
//
|
||||
// Defining variables with `[[__percpu]]` will put them in a special section.
|
||||
// This section is unique for every CPU. To access the correct memory of the
|
||||
// caller's CPU, use `percpu_ref`.
|
||||
// caller's CPU, use `percpu_ref`. To access another CPU's copy, use `percpu_ref_on`.
|
||||
//
|
||||
// ## Example
|
||||
//
|
||||
@@ -22,8 +22,9 @@
|
||||
// }
|
||||
// ```
|
||||
|
||||
#define __percpu __used, __section(".percpu.data")
|
||||
#define percpu_ref(x) ((typeof(&(x)))((void*)percpu_get() + ((void*)&(x) - (void*)&percpu_bsp)))
|
||||
#define __percpu __used, __section(".percpu.data")
|
||||
#define percpu_ref_on(cpu, x) ((typeof(&(x)))((void*)(cpu) + ((void*)&(x) - (void*)&percpu_bsp)))
|
||||
#define percpu_ref(x) percpu_ref_on(percpu_get(), x)
|
||||
|
||||
// CPU-relative information.
|
||||
struct percpu {
|
||||
|
||||
@@ -124,6 +124,7 @@ foreach name, v : modules
|
||||
name_suffix: 'kso',
|
||||
link_with: mod_link,
|
||||
override_options: ['b_lundef=false'],
|
||||
install_dir: get_option('datadir') / 'zinnia' / 'modules',
|
||||
#link_depends: kernel.full_path(),
|
||||
)
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user