oops
This commit is contained in:
+34
-6
@@ -1,4 +1,5 @@
|
|||||||
#include <zinnia/alloc.h>
|
#include <zinnia/alloc.h>
|
||||||
|
#include <zinnia/assert.h>
|
||||||
#include <zinnia/cmdline.h>
|
#include <zinnia/cmdline.h>
|
||||||
#include <zinnia/init.h>
|
#include <zinnia/init.h>
|
||||||
#include <zinnia/print.h>
|
#include <zinnia/print.h>
|
||||||
@@ -41,10 +42,15 @@ void kernel_entry() {
|
|||||||
|
|
||||||
struct boot_info info = {};
|
struct boot_info info = {};
|
||||||
|
|
||||||
struct limine_memmap_response* mm_res = memmap_request.response;
|
const struct limine_memmap_response* mm_res = memmap_request.response;
|
||||||
struct limine_module_response* module_res = module_request.response;
|
const struct limine_hhdm_response* hhdm_res = hhdm_request.response;
|
||||||
struct limine_executable_address_response* exec_res = executable_address_request.response;
|
const struct limine_module_response* module_res = module_request.response;
|
||||||
struct limine_executable_file_response* exec_file_res = executable_file_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;
|
info.cmdline = exec_file_res->executable_file->string;
|
||||||
|
|
||||||
@@ -74,7 +80,7 @@ void kernel_entry() {
|
|||||||
info.files = files;
|
info.files = files;
|
||||||
info.num_files = MIN(ARRAY_SIZE(files), module_res->module_count);
|
info.num_files = MIN(ARRAY_SIZE(files), module_res->module_count);
|
||||||
for (size_t i = 0; i < info.num_files; i++) {
|
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;
|
files[i].length = module_res->modules[i]->size;
|
||||||
strncpy(files[i].path, module_res->modules[i]->path, sizeof(files[i].path) - 1);
|
strncpy(files[i].path, module_res->modules[i]->path, sizeof(files[i].path) - 1);
|
||||||
files[i].path[sizeof(files[i].path) - 1] = 0;
|
files[i].path[sizeof(files[i].path) - 1] = 0;
|
||||||
@@ -84,7 +90,29 @@ void kernel_entry() {
|
|||||||
info.mem_map = mem;
|
info.mem_map = mem;
|
||||||
info.phys_base = (phys_t)exec_res->physical_base;
|
info.phys_base = (phys_t)exec_res->physical_base;
|
||||||
info.virt_base = (uintptr_t)exec_res->virtual_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 CONFIG_ACPI
|
||||||
if (rsdp_request.response) {
|
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 ")";
|
", " ZINNIA_COMPILER_ID ", " ZINNIA_LINKER_ID ")";
|
||||||
|
|
||||||
static void kernel_main_task(uintptr_t arg0) {
|
static void kernel_main_task(uintptr_t arg0) {
|
||||||
|
errno_t status = 0;
|
||||||
struct boot_info* info = (struct boot_info*)arg0;
|
struct boot_info* info = (struct boot_info*)arg0;
|
||||||
|
|
||||||
log("main: Hello from main task!\n");
|
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, "");
|
assert(vma_new(&init_space) == EOK, "");
|
||||||
|
|
||||||
struct boot_file* file_data = &info->files[0];
|
struct boot_file* file_data = &info->files[0];
|
||||||
|
struct task* init_task = nullptr;
|
||||||
|
|
||||||
struct paged_vmo* init_file;
|
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);
|
vmo_write(&init_file->object, 0, HHDM_PTR(file_data->data), file_data->length, nullptr);
|
||||||
|
|
||||||
// Load init.
|
// Load init.
|
||||||
@@ -53,11 +58,10 @@ static void kernel_main_task(uintptr_t arg0) {
|
|||||||
.envp = init_envp,
|
.envp = init_envp,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct task* init_task = nullptr;
|
status = elf_load(&exec, &init_task);
|
||||||
errno_t status = elf_load(&exec, &init_task);
|
|
||||||
vmo_unref(&init_file->object);
|
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);
|
sched_add_task(&percpu_get()->sched, init_task);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|||||||
+34
-57
@@ -1,8 +1,8 @@
|
|||||||
#include <zinnia/compiler.h>
|
#include <zinnia/compiler.h>
|
||||||
|
#include <zinnia/string.h>
|
||||||
#include <zinnia/utils.h>
|
#include <zinnia/utils.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <zinnia/string.h>
|
|
||||||
|
|
||||||
[[__hot]]
|
[[__hot]]
|
||||||
size_t strlen(const char* str) {
|
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++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
if (s1ptr[i] != s2ptr[i])
|
if (s1ptr[i] != s2ptr[i])
|
||||||
return s1ptr[i] - s2ptr[i];
|
return (int)s1ptr[i] - (int)s2ptr[i];
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef size_t word_t [[__may_alias]]
|
||||||
|
;
|
||||||
|
|
||||||
[[__hot]]
|
[[__hot]]
|
||||||
void* memcpy(void* restrict dest, const void* restrict src, size_t n) {
|
void* memcpy(void* restrict dest, const void* restrict src, size_t n) {
|
||||||
if (__unlikely(n == 0))
|
uint8_t* d = dest;
|
||||||
return dest;
|
const uint8_t* s = src;
|
||||||
|
|
||||||
size_t d = (size_t)dest;
|
// Word copies are only possible if both pointers can be aligned at the same time.
|
||||||
size_t s = (size_t)src;
|
if (((uintptr_t)d - (uintptr_t)s) % sizeof(word_t) == 0) {
|
||||||
|
while (n && (uintptr_t)d % sizeof(word_t) != 0) {
|
||||||
if (d % sizeof(size_t) != 0 || s % sizeof(size_t) != 0) {
|
*d++ = *s++;
|
||||||
while (n && (d % sizeof(size_t) != 0) && (s % sizeof(size_t) != 0)) {
|
|
||||||
*((uint8_t*)d) = *((uint8_t*)s);
|
|
||||||
d++;
|
|
||||||
s++;
|
|
||||||
n--;
|
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;
|
while (n--)
|
||||||
const size_t* qword_src = (const size_t*)s;
|
*d++ = *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++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dest;
|
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) {
|
void* memmove(void* dstptr, const void* srcptr, size_t size) {
|
||||||
uint8_t* dst = (uint8_t*)dstptr;
|
uint8_t* dst = (uint8_t*)dstptr;
|
||||||
const uint8_t* src = (const uint8_t*)srcptr;
|
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++)
|
for (size_t i = 0; i < size; i++)
|
||||||
dst[i] = src[i];
|
dst[i] = src[i];
|
||||||
} else {
|
} else {
|
||||||
@@ -88,38 +81,22 @@ void* memmove(void* dstptr, const void* srcptr, size_t size) {
|
|||||||
|
|
||||||
[[__hot]]
|
[[__hot]]
|
||||||
void* memset(void* dest, int value, size_t n) {
|
void* memset(void* dest, int value, size_t n) {
|
||||||
if (__unlikely(n == 0))
|
uint8_t* d = dest;
|
||||||
return dest;
|
const uint8_t byte = (uint8_t)value;
|
||||||
|
|
||||||
size_t d = (size_t)dest;
|
while (n && (uintptr_t)d % sizeof(word_t) != 0) {
|
||||||
|
*d++ = byte;
|
||||||
if (d % sizeof(size_t) != 0) {
|
|
||||||
while (n && (d % sizeof(size_t) != 0)) {
|
|
||||||
*((uint8_t*)d) = value;
|
|
||||||
d++;
|
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
size_t* qword_dest = (size_t*)d;
|
const word_t word_value = (SIZE_MAX / 0xFF) * byte;
|
||||||
size_t qword_value = (uint8_t)value;
|
word_t* word_dest = (word_t*)d;
|
||||||
qword_value |= (qword_value << 8);
|
for (; n >= sizeof(word_t); n -= sizeof(word_t))
|
||||||
qword_value |= (qword_value << 16);
|
*word_dest++ = word_value;
|
||||||
qword_value |= (qword_value << 32);
|
|
||||||
|
|
||||||
const size_t word_count = n / sizeof(size_t);
|
d = (uint8_t*)word_dest;
|
||||||
|
while (n--)
|
||||||
for (size_t i = 0; i < word_count; i++) {
|
*d++ = byte;
|
||||||
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++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-4
@@ -3,9 +3,9 @@
|
|||||||
#include <zinnia/init.h>
|
#include <zinnia/init.h>
|
||||||
#include <zinnia/panic.h>
|
#include <zinnia/panic.h>
|
||||||
#include <zinnia/print.h>
|
#include <zinnia/print.h>
|
||||||
|
#include <zinnia/string.h>
|
||||||
#include <zinnia/utils.h>
|
#include <zinnia/utils.h>
|
||||||
#include <zinnia/vma.h>
|
#include <zinnia/vma.h>
|
||||||
#include <zinnia/string.h>
|
|
||||||
|
|
||||||
extern uint8_t __ld_text_start[];
|
extern uint8_t __ld_text_start[];
|
||||||
extern uint8_t __ld_text_end[];
|
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.
|
// Set up the bootstrap allocator.
|
||||||
struct phys_mem* largest = map;
|
struct phys_mem* largest = nullptr;
|
||||||
for (size_t i = 0; i < map_len; i++) {
|
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];
|
largest = &map[i];
|
||||||
}
|
}
|
||||||
|
assert(largest && largest->length >= pgsz, "No usable memory for bootstrap allocator");
|
||||||
mem_phys_bootstrap(largest);
|
mem_phys_bootstrap(largest);
|
||||||
log("mem: Using region [%p - %p] for bootstrap allocator\n",
|
log("mem: Using region [%p - %p] for bootstrap allocator\n",
|
||||||
(void*)largest->address,
|
(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) {
|
for (size_t page = 0; page < length; page += pgsz) {
|
||||||
phys_t paddr;
|
phys_t paddr;
|
||||||
assert(!mem_phys_alloc(1, 0, &paddr), "Failed to allocate memory for PFNDB!\n");
|
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();
|
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) {
|
void vmo_truncate_paged(struct paged_vmo* paged, size_t length) {
|
||||||
const size_t page_size = arch_mem_page_size();
|
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);
|
spin_lock(&paged->lock);
|
||||||
struct page_list** pp = &list_first(&paged->cache);
|
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(
|
kernel_sources += files(
|
||||||
'ident.c',
|
'ident.c',
|
||||||
|
'init.c',
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#define __section(x) gnu::section(x)
|
#define __section(x) gnu::section(x)
|
||||||
#define __aligned(x) gnu::aligned(x)
|
#define __aligned(x) gnu::aligned(x)
|
||||||
#define __packed gnu::packed
|
#define __packed gnu::packed
|
||||||
|
#define __may_alias gnu::may_alias
|
||||||
#define __naked gnu::naked
|
#define __naked gnu::naked
|
||||||
|
|
||||||
// These hints may improve code generation.
|
// These hints may improve code generation.
|
||||||
@@ -12,7 +13,7 @@
|
|||||||
#define __used gnu::used
|
#define __used gnu::used
|
||||||
#define __unused gnu::unused
|
#define __unused gnu::unused
|
||||||
#define __format(like, ...) gnu::format(like, __VA_ARGS__)
|
#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 __visibility gnu::visibility
|
||||||
#define __pure gnu::pure
|
#define __pure gnu::pure
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
|
|
||||||
struct dpc {
|
struct dpc {
|
||||||
void (*const callback)(struct dpc* dpc, void* data);
|
void (*callback)(struct dpc* dpc, void* data);
|
||||||
void* data;
|
void* data;
|
||||||
atomic_bool inserted;
|
atomic_bool inserted;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
struct file_desc {};
|
|
||||||
+13
-1
@@ -17,6 +17,17 @@ struct boot_file {
|
|||||||
char path[128];
|
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 {
|
struct boot_info {
|
||||||
char* cmdline;
|
char* cmdline;
|
||||||
struct phys_mem* mem_map;
|
struct phys_mem* mem_map;
|
||||||
@@ -26,8 +37,9 @@ struct boot_info {
|
|||||||
uintptr_t hhdm_base;
|
uintptr_t hhdm_base;
|
||||||
struct boot_file* files;
|
struct boot_file* files;
|
||||||
size_t num_files;
|
size_t num_files;
|
||||||
|
struct boot_framebuffer fb;
|
||||||
void* dtb;
|
void* dtb;
|
||||||
|
size_t dtb_size;
|
||||||
#if CONFIG_ACPI
|
#if CONFIG_ACPI
|
||||||
phys_t rsdp;
|
phys_t rsdp;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -7,8 +7,10 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <uapi/uio.h>
|
#include <uapi/uio.h>
|
||||||
|
|
||||||
|
typedef struct __iovec iovec_t;
|
||||||
|
|
||||||
struct iovec_iter {
|
struct iovec_iter {
|
||||||
struct __iovec* iovecs;
|
iovec_t* iovecs;
|
||||||
size_t iovecs_len;
|
size_t iovecs_len;
|
||||||
size_t total_len;
|
size_t total_len;
|
||||||
size_t total_offset;
|
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.
|
// 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;
|
size_t total = 0;
|
||||||
for (size_t i = 0; i < count; i++)
|
for (size_t i = 0; i < count; i++)
|
||||||
total += iovecs[i].len;
|
total += iovecs[i].len;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#define MODULE_VERSION(version) MODULE_PROPERTY("version", version)
|
#define MODULE_VERSION(version) MODULE_PROPERTY("version", version)
|
||||||
#define MODULE_LICENSE(license) MODULE_PROPERTY("license", license)
|
#define MODULE_LICENSE(license) MODULE_PROPERTY("license", license)
|
||||||
|
|
||||||
|
#ifdef IN_MODULE
|
||||||
#define MODULE_ENTRY(func) \
|
#define MODULE_ENTRY(func) \
|
||||||
[[__used]] \
|
[[__used]] \
|
||||||
errno_t __module_entry(struct module* __module) { \
|
errno_t __module_entry(struct module* __module) { \
|
||||||
@@ -28,6 +29,15 @@
|
|||||||
} \
|
} \
|
||||||
[[__used, __section(".mod.exit")]] \
|
[[__used, __section(".mod.exit")]] \
|
||||||
static const void* __exit_fn = &__module_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 {
|
struct module {
|
||||||
const char* name;
|
const char* name;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
//
|
//
|
||||||
// Defining variables with `[[__percpu]]` will put them in a special section.
|
// 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
|
// 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
|
// ## Example
|
||||||
//
|
//
|
||||||
@@ -23,7 +23,8 @@
|
|||||||
// ```
|
// ```
|
||||||
|
|
||||||
#define __percpu __used, __section(".percpu.data")
|
#define __percpu __used, __section(".percpu.data")
|
||||||
#define percpu_ref(x) ((typeof(&(x)))((void*)percpu_get() + ((void*)&(x) - (void*)&percpu_bsp)))
|
#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.
|
// CPU-relative information.
|
||||||
struct percpu {
|
struct percpu {
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ foreach name, v : modules
|
|||||||
name_suffix: 'kso',
|
name_suffix: 'kso',
|
||||||
link_with: mod_link,
|
link_with: mod_link,
|
||||||
override_options: ['b_lundef=false'],
|
override_options: ['b_lundef=false'],
|
||||||
|
install_dir: get_option('datadir') / 'zinnia' / 'modules',
|
||||||
#link_depends: kernel.full_path(),
|
#link_depends: kernel.full_path(),
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user