重构内存分配器、增加中断支持、整理rust运行时环境 #4

Merged
pointer-to-bios merged 39 commits from downstream into main 2024-04-11 00:36:14 +08:00
12 changed files with 610 additions and 117 deletions
Showing only changes of commit 5bd549328f - Show all commits

View File

@ -57,6 +57,8 @@ make debug
* [x] raw_allocator
* [x] tty
* [x] 内核日志
* [ ] 系统调用
* [ ] 中断管理
* [ ] 文件系统
* [ ] vfs
* [ ] fat32驱动移植
@ -64,9 +66,19 @@ make debug
* [ ] 驱动管理
* [ ] 进程管理
## 文档
* 从源代码注释生成文档
```bash
make doc
```
(开发中)
## 作出贡献
通过向此仓库发送PR为我们作出贡献。
通过向此仓库发送PR为我们作出贡献,详见[contribution.md](docs/contribution.md)
## 版权声明

13
docs/contribution.md Normal file
View File

@ -0,0 +1,13 @@
# 向Metaverse内核贡献代码
通过如下方式向内核增加你的代码:
* 从[github仓库](https://github.com/metaverse-kernel/kernel-dev)或[Random World Studio内部仓库](http://git.suthby.org:2024/metaverse/kernel-dev)创建一个分支
* 在你的分支中增加代码
* 测试你增加的代码的正确性,并尽量确保对原有代码没有影响
* 无需在注释中加入代码更改日志git可以做到
* 在文档的适当的位置增加对新特性的描述
* 完成编码和文档的工作后向主仓库发送PR
* 等待审核代码
若你的代码通过审核将会把你的PR合并到主分支中。

View File

@ -4,6 +4,12 @@
#include <types.h>
#include <utils.h>
/**
* @name gate_descriptor_t
* @addindex x86_64
*
*
*/
typedef struct __gate_descriptor_t
{
u16 offset_01;
@ -14,14 +20,25 @@ typedef struct __gate_descriptor_t
u32 reserved;
} DISALIGNED gate_descriptor_t;
// interrupt stack table每个表项都指向tss
// 需要加载寄存器IA32_INTERRUPT_SSP_TABLE
/**
* @name INTERRUPT_DESCRIPTOR_FLAG_IST
* @addindex x86_64
*
* `gate_descriptor_t``flags`
*
* `ssp`tss描述符在任务段中的的索引
*/
#define INTERRUPT_DESCRIPTOR_FLAG_IST(ssp) (ssp)
// 在第15位上有一个表示代码段是否存在的标志位代码段总是存在故直接设置为1
#define INTERRUPT_DESCRIPTOR_FLAG_TYPE_INTERRUPT (0x8e << 8)
#define INTERRUPT_DESCRIPTOR_FLAG_TYPE_TRAP (0x8f << 8)
/**
* @name idt
*
*
*/
extern gate_descriptor_t idt[256];
#endif

View File

@ -3,7 +3,13 @@
#include <types.h>
// 具有返回值是为了留出一个寄存器用于调整栈顶
extern usize prepare_stack();
/**
* @name prepare_stack
*
* ```c
* void prepare_stack();
* ```
*/
extern void prepare_stack();
#endif

View File

@ -4,8 +4,18 @@
#include <types.h>
#include <libk/bits.h>
/* 页大小以MEMM_PAGE_SIZE为单位 */
/**
* @name MEMM_PAGE_SIZE
* @addindex
*
*
*
* @if arch == x86_64 then
* 4096
* @endif
*/
#define MEMM_PAGE_SIZE 4096
typedef enum __memm_page_size
{
MEMM_PAGE_SIZE_4K = 1, // 1个4KB页大小
@ -15,14 +25,49 @@ typedef enum __memm_page_size
extern u64 PML4[512];
/**
* @name MEMM_PAGE_TABLE_FLAGS_MASK
* @addindex x86_64
*
* 使12`0xfff`
*/
#define MEMM_PAGE_TABLE_FLAGS_MASK ((u64)0xfff)
/* 页对齐掩码 */
/**
* @name MEMM_xx_ALIGN_MASK
* @addindex x86_64
*
*
* `xx``x86_64``4K``2M``1G`n位总为0的情况
* `4K``0xfff``2M``0x1fffff``1G``0x3fffffff`
*/
#define MEMM_4K_ALIGN_MASK ((u64)0xfff)
#define MEMM_2M_ALIGN_MASK ((u64)0x1fffff)
#define MEMM_1G_ALIGN_MASK ((u64)0x3fffffff)
/* 页表项属性FLAGS */
/**
* @name MEMM_ENTRY_FLAG_xx
* @addindex x86_64
*
*
*
* ```c
* #define MEMM_ENTRY_FLAG_PRESENT ((u64)1)
* #define MEMM_ENTRY_FLAG_WRITE ((u64)1 << 1)
* #define MEMM_ENTRY_FLAG_USER ((u64)1 << 2)
* #define MEMM_ENTRY_FLAG_PWT ((u64)1 << 3)
* #define MEMM_ENTRY_FLAG_PCD ((u64)1 << 4)
* #define MEMM_ENTRY_FLAG_ACCECED ((u64)1 << 5)
* #define MEMM_ENTRY_FLAG_DIRTY ((u64)1 << 6)
* #define MEMM_ENTRY_FLAG_PS ((u64)1 << 7)
* #define MEMM_ENTRY_FLAG_GLOBAL ((u64)1 << 8)
* #define MEMM_ENTRY_FLAG_PAT ((u64)1 << 12)
* #define MEMM_PTE_ENTRY_FLAG_PAT ((u64)1 << 7)
* #define MEMM_ENTRY_FLAG_XD ((u64)1 << 63)
* ```
*
* `MEMM_PTE_ENTRY_FLAG_PAT``pte``pte`
*/
#define MEMM_ENTRY_FLAG_PRESENT ((u64)1)
#define MEMM_ENTRY_FLAG_WRITE ((u64)1 << 1)
#define MEMM_ENTRY_FLAG_USER ((u64)1 << 2)
@ -35,18 +80,47 @@ extern u64 PML4[512];
#define MEMM_ENTRY_FLAG_PAT ((u64)1 << 12)
#define MEMM_PTE_ENTRY_FLAG_PAT ((u64)1 << 7)
#define MEMM_ENTRY_FLAG_XD ((u64)1 << 63)
/**
* @name memm_entry_flag_get(entry, flag)
* @addindex x86_64
*
*
*
* `flag``MEMM_ENTRY_FLAG_xx`
*/
#define memm_entry_flag_get(entry, flag) \
((entry & flag) ? true : false)
/* 页表(大型页)项地址域掩码 */
/**
* @name MEMM_ENTRY_ADDRESS_MASK, MEMM_BP_ENTRY_ADDRESS_MASK
* @addindex x86_64
*
* ********
*
* `BP`
*
*
*
* ```c
* #define MEMM_ENTRY_ADDRESS_MASK ((u64)0x000ffffffffff000)
* #define MEMM_BP_ENTRY_ADDRESS_MASK ((u64)0x000fffffffffe000)
* ```
*/
#define MEMM_ENTRY_ADDRESS_MASK ((u64)0x000ffffffffff000)
#define MEMM_BP_ENTRY_ADDRESS_MASK ((u64)0x000fffffffffe000)
/**
* @name memm_entry_get_address(entry)
* @addindex x86_64
*
*
*/
#define memm_entry_get_address(entry) \
((entry) & (memm_entry_flag_get(entry, MEMM_ENTRY_FLAG_PS) \
? MEMM_BP_ENTRY_ADDRESS_MASK \
: MEMM_ENTRY_ADDRESS_MASK))
/* 线性地址表项索引或页内偏移掩码 */
#define MEMM_LA_PML4EI_MASK ((u64)0x0000ff8000000000)
#define MEMM_LA_PDPTEI_MASK ((u64)0x0000007fc0000000)
#define MEMM_LA_PDEI_MASK ((u64)0x000000003fe00000)
@ -56,50 +130,119 @@ extern u64 PML4[512];
#define MEMM_LA_2MB_PAGE_OFFSET_MASK ((u64)0x00000000001fffff)
#define MEMM_LA_4KB_PAGE_OFFSET_MASK ((u64)0x0000000000000fff)
/* 线性地址表项索引偏移位数 */
#define MEMM_LA_PML4EI_OFFSET (39)
#define MEMM_LA_PDPTEI_OFFSET (30)
#define MEMM_LA_PDEI_OFFSET (21)
#define MEMM_LA_PEI_OFFSET (12)
/* 获取线性地址中某个表项索引以及获取页内偏移 */
/**
* @name MEMM_LA_xxxxI
* @addindex x86_64
*
* 4线`xxxx``PML4E``PDPTE``PDE``PE`
*/
#define MEMM_LA_PML4EI
#define MEMM_LA_PDPTEI
#define MEMM_LA_PDEI
#define MEMM_LA_PEI
/**
* @name memm_la_get_entry_index(addr, entry)
* @addindex x86_64
*
* 线`addr``entry`
*
* `entry``MEMM_LA_xxxxI`
*/
#define memm_la_get_entry_index(addr, entry) \
(((addr) & (entry##_MASK)) >> (entry##_OFFSET))
/**
* @name MEMM_LA_xxx_PAGE_OFFSET
* @addindex x86_64
*
* 线`xxx``4KB``2MB``1GB`
*/
#define MEMM_LA_1GB_PAGE_OFFSET
#define MEMM_LA_2MB_PAGE_OFFSET
#define MEMM_LA_4KB_PAGE_OFFSET
/**
* @name memm_la_get_offset(addr, page_type)
* @addindex x86_64
*
* 线
*
* `page_type``MEMM_LA_xxx_PAGE_OFFSET`
*/
#define memm_la_get_offset(addr, page_type) \
((addr) & (page_type##_MASK))
/*
canonical型地址
target与physical至少都是以MEMM_PAGE_SIZE对齐的
MEMM_PAGE_SIZE对齐的canonical型地址都会返回false
1GB的一半且地址1GB对齐1GB页
2MB的一半且地址2MB对齐2MB页
4KB页
/**
* @name memm_map_pageframes_to
*
* ```c
* bool memm_map_pageframes_to(
* u64 target, u64 physical,
* usize size,
* bool user, bool write);
* ```
*
* **canonical**
*
* `target``physical`MEMM_PAGE_SIZE对齐的
*
* MEMM_PAGE_SIZE对齐的canonical型地址都会返回false
*
* 1GB的一半且地址1GB对齐1GB页
* 2MB的一半且地址2MB对齐2MB页
* 4KB页
*/
bool memm_map_pageframes_to(
u64 target, u64 physical,
usize size,
bool user, bool write);
/**
* @name reload_pml4
* @addindex x86_64
*
* ```c
* void reload_pml4();
* ```
*/
extern void reload_pml4();
/**
* @name is_user_address(addr)
* @addindex
*
* `addr`
*
* @if arch == x86_64
* `canonical`
* @endif
*/
#define is_user_address(addr) \
(((addr) > 0xffff7fffffffffff) ? true : false)
/**
* @name is_cannonical(addr)
* @addindex x86_64
*
* `addr`cannonical型地址
*/
#define is_cannonical(addr) \
(((addr) < 0x0000800000000000 || (addr) > 0xffff7fffffffffff) ? true : false)
/**
* @name memm_get_page_align(addr)
* @addindex x86_64
*
* `addr``memm_page_size`
*
* `addr`*4KB对齐**4KB对齐时*`MEMM_PAGE_SIZE_4K`
*/
#define memm_get_page_align(addr) \
(is_aligned(addr, MEMM_PAGE_SIZE_1G) \
? MEMM_PAGE_SIZE_1G \

View File

@ -5,27 +5,50 @@
extern void *system_calls_table[256];
// 系统调用使用的寄存器:
// rax - 调用号
// rbx - 系统调用程序保留
// rcx - rip寄存器缓存
// rdi - 系统调用程序保留
// rdx - 参数1
// r8 - 参数2
// r9 - 参数3
// r10 - 参数4
// r11 - rflags寄存器缓存
// r12 - 参数5
// r13 - 参数6
// r14 - 参数7
// r15 - 参数8
// 系统调用时,使用内核主堆栈
// 故设置一组函数用于在sysret前保存和在syscall后加载
// rbp, rsp的函数
extern void save_kernel_stack();
extern void load_kernel_stack();
/**
* @brief
* @addindex x86_64
*
* 使
* rax -
* rbx -
* rcx - rip寄存器缓存
* rdi -
* rdx - 1
* r8 - 2
* r9 - 3
* r10 - 4
* r11 - rflags寄存器缓存
* r12 - 5
* r13 - 6
* r14 - 7
* r15 - 8
*
* 使
*/
/**
* @name set_kernel_stack_cache
* @addindex x86_64
*
* ```c
* void set_kernel_stack_cache(usize stack);
* ```
*
* `stack`
*/
extern void set_kernel_stack_cache(usize stack);
/**
* @name return_from_systemcall
* @addindex x86_64
*
* ```c
* void return_from_systemcall();
* ```
*
* `sysret`
*/
extern void return_from_systemcall();
#endif

View File

@ -4,12 +4,45 @@
#include <types.h>
// 使用UNIX时间戳
/**
* @name system_time_get
*
* ```c
* usize system_time_get();
* ```
*
*
*
* 使unix时间`0`1970-1-1 00:00:00
*/
usize system_time_get();
// 如果硬件支持更高的计时精度,
// 此函数提供从系统unix时间开始到现在的纳秒为单位的时间
/**
* @name system_time_ns_get
*
* ```c
* usize system_time_ns_get();
* ```
*
*
*
*
*
* 使使
*/
usize system_time_ns_get();
/**
* @name system_time_increase
*
* ```c
* void system_time_increase();
* ```
*
*
*/
void system_time_increase();
#endif

View File

@ -1,7 +1,28 @@
#ifndef INTERRUPT_H
#define INTERRUPT_H 1
/**
* @name interrupt_open
* @addindex
*
* ```c
* void interrupt_open();
* ```
*
*
*/
void interrupt_open();
/**
* @name interrupt_close
* @addindex
*
* ```c
* void interrupt_close();
* ```
*
*
*/
void interrupt_close();
#endif

View File

@ -11,11 +11,33 @@
#endif
/**
* @name KERNEL_TODO
*
*
*/
#define KERNEL_TODO() \
while (true) \
{ \
}
/**
* @name simple_lock
*
*
*
* ```c
* #define simple_lock_lock(lock)
* ```
*
*
*
* ```c
* #define simple_lock_unlock(lock)
* ```
*
*
*/
#define simple_lock_lock(lock) \
{ \
while (lock == true) \
@ -24,8 +46,20 @@
}
#define simple_lock_unlock(lock) (lock) = false;
/**
* @name kmain_rust
*
* rust内核主程序
*/
extern void kmain_rust();
extern void *kend; // 内核结束的标记
/**
* @name kend
*
*
*
*
*/
extern void *kend;
#endif

View File

@ -8,27 +8,102 @@
#include <libk/lst.h>
/**
* @brief
* @name MEMM_MAX_SUPPORTED_MEMORY
*
* TODO
* `1TB`
*/
/* 最大支持1TB内存 */
#define MEMM_MAX_SUPPORTED_MEMORY (1024 * (1024 * (1024 * (usize)1024)))
/* 最大支持的分页数量 */
// 这里的页均以最小的页大小计算
/**
* @name MEMM_MAX_SUPPORTED_PAGES
*
* `MEMM_MAX_SUPPORTED_MEMORY``MEMM_PAGE_SIZE`
*/
#define MEMM_MAX_SUPPORTED_PAGES (MEMM_MAX_SUPPORTED_MEMORY / MEMM_PAGE_SIZE)
/* 只分配不映射空间 */
/**
* @name MEMM_ALLOC_ONLY_MEMORY
*
* `128MB``0`\~`MEMM_ALLOC_ONLY_MEMORY`
*
* **1MB以内低地址******
*/
#define MEMM_ALLOC_ONLY_MEMORY (128 * 1024 * 1024)
/**
* @name memm_allocate_t, memm_free_t
*
* ````使`allocator`
*
*
* `kernel/memm/allocator/`
*
* ****
*
* **`memm_allocate_t`**
*
* ```c
* typedef void *(*memm_allocate_t)(void *allocator, usize size);
* ```
*
* `allocator``size`
*
* `nullptr``size`0`nullptr`
* **16**8
*
* **`memm_free_t`**
*
* ```c
* typedef void (*memm_free_t)(void *allocator, void *mem);
* ```
*
* `allocator``mem`
*
* `mem``allocator`
*/
typedef void *(*memm_allocate_t)(void *allocator, usize size);
typedef void (*memm_free_t)(void *allocator, void *mem);
/*
MEMM_PAGE_SIZE对齐的
/**
* @name allocator_t
*
* ```c
* typedef struct { } allocator_t;
* ```
*
*
*
* `memm_allocate`
*
* ****`MEMM_ALLOC_ONLY_MEMORY```
*
* ****使
*
* @internal full
*
* `allocate``nullptr``true`
* `free``false`
*
* @internal pid
*
* 0
*
* @internal type
*
* `include/kernel/memm/allocator`
*
* @internal allocate
*
* allocate函数nullptrsize参数为0时
* nullptr
*
* @internal free
*
* free函数allocate得到的地址则什么都不做
*
* @internal allocator_instance
*
*
*/
typedef struct __allocator_t
{
@ -37,28 +112,23 @@ typedef struct __allocator_t
bool initialized;
// 在本分配器中调用allocate返回nullptr后为true
// 调用free后为false
// 调用分配器的`allocate`方法后,在返回`nullptr`时会设为`true`。
// 调用分配器的`free`方法时设为`false`。
bool full;
// 进程id当pid=0时代表内核
// 进程标志服表示此分配器所属的进程为0代表属于内核。
usize pid;
// 分配器类型
// 分配器类型。在目录`include/kernel/memm/allocator`中对每个分配器分别定义一个唯一值。
usize type;
usize size;
// 分配器实例的allocate函数
// 无法分配空间返回nullptr
// 在size参数为0时保证不可以分配空间但是如果空间已满依然返回nullptr
// 分配器实例的allocate函数。当无法分配空间时返回nullptr。在size参数为0时
// 保证不可以分配空间但是如果空间已满依然返回nullptr。
memm_allocate_t allocate;
// 分配器实例的free函数
// 若不是allocate得到的地址则什么都不做
// 分配器实例的free函数。若不是allocate得到的地址则什么都不做。
memm_free_t free;
// 分配器实例
// 对应`type`类型使用
// 在kernel/memm/allocator/中是所有的内存分配器
// 分配器实例。
u64 allocator_instance[0];
} allocator_t;
@ -68,75 +138,131 @@ typedef struct __allocator_iterator_t
struct __allocator_iterator_t *left, *right;
} allocator_iterator_t;
/*
allocator记录中allocator完成
page_map中置位map_with_allocator中复位map_with_destructed_allocator中复位
available_pages_table中的页使
/**
* @name
*
* @internal alloc_only_memory
*
*
*
* @internal mapped_page_amount
*
*
*
* @internal mapped_4k_page, mapped_2m_page, mapped_1g_page
* @addindex x86_64
*
*
*
* @internal page_map
*
* bit表示对应的最小页是否被映射
*
* @internal allocator_map
*
* bit表示对应的最小页是否被一个分配器控制
*
* @internal destructed_allocator_map
*
* bit表示对应的最小页是否曾经被分配器控制并且现在控制这个页的分配器已经释放
*
* 1bit位对应的最小页可以直接************
*
* @internal available_pages_table
*
* 线
*
* @internal allocators
*
*
*/
typedef struct __mem_manager_t
{
usize memory_size;
usize page_amount;
// 这里记录的数量为最小的页的数量
usize mapped_page_amount;
// 在进入内核主程序之前,有些不在内核中的虚拟内存空间已经被
// 页表映射,这部分内存不可以再映射到物理页框
// 在进入内核主程序之前,有些不在内核中的虚拟内存空间已经被页表映射,这部分内存不可以再映射到物理页框
usize alloc_only_memory;
// 已经映射的页数量。若不是最小的页会被视作多个最小页计数。
usize mapped_page_amount;
#ifdef __x86_64__
// 在这里三种页的数量分别记录
usize mapped_4k_page;
usize mapped_2m_page;
usize mapped_1g_page;
#endif
// 页地图
// 每个bit都表示这个页是否被映射
// 页地图。每个bit都表示这个页是否被映射
u8 *page_map;
// 分配器页地图
// 每个bit表示这个页是否被内存分配器控制
// (不代表每个页都包含完整的分配器)
u8 *map_with_allocator;
// 分配器释放页地图
// 每个bit表示这个页是否曾经被内存分配器控制且现在被释放
// 需要取消映射
u8 *map_with_destructed_allocator;
// 分配器页地图。每个bit表示这个页是否被内存分配器控制。
u8 *allocator_map;
// 释放的分配器页地图。每个bit表示这个页是否曾经被内存分配器控制且现在被释放。
// 值为1的bit位对应的最小页可以直接**取消映射**、**重新构造一个分配器**、**加载可执行程序**等。
u8 *destructed_allocator_map;
// 空闲页线段搜索表
lst_iterator_t *available_pages_table;
// 分配器树
// 为方便查找,以二叉树的形式存储
// index=0为无效项
// 分配器二叉树
allocator_iterator_t *allocators;
} mem_manager_t;
} memory_manager_t;
mem_manager_t *memm_new(usize mem_size);
/**
* @name memm_new
*
* ```c
* memory_manager_t *memm_new(usize mem_size);
* ```
*
*
*/
memory_manager_t *memm_new(usize mem_size);
/*
`start``length`
`pid`0使
/**
* @name memm_get_manager
*
* ```c
* memory_manager_t *memm_get_manager();
* ```
*
*
*/
memory_manager_t *memm_get_manager();
/**
* @name memm_allocator_new
*
* ```c
* allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid);
* ```
*
* `start``length``pid`0使
*/
allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid);
/*
/**
* @name memm_allocator_destruct
*
* ```c
* void memm_allocator_destruct(allocator_t *allocator);
* ```
*
*
*
* ****
*/
void memm_allocator_destruct(allocator_t *allocator);
/*
pid=0
线
allocator对象在进程与内核之间传递时一律使用内核空间的映射地址
## 要求在返回的地址前16字节处保留8字节空间作为它所在的allocator地址并且不需要分配器的具体实现做这个事
/**
* @name memm_allocate
*
* ```c
* void *memm_allocate(usize size, usize pid);
* ```
*
* `pid`0
*
*
*/
void *memm_allocate(usize size, usize pid);
#define memm_addr_set_allocator(mem, allocator) \
@ -144,17 +270,46 @@ void *memm_allocate(usize size, usize pid);
#define memm_addr_get_allocator(mem) \
((*(allocator_t **)((void *)(mem)-16)))
/**
* @name memm_kernel_allocate
*
* ```c
* void *memm_kernel_allocate(usize size);
* ```
*
*
*/
void *memm_kernel_allocate(usize size);
/**
* @name memm_user_allocate
*
* ```c
* void *memm_user_allocate(usize size, usize pid);
* ```
*
*
*/
void *memm_user_allocate(usize size, usize pid);
/*
/**
* @name memm_free
*
* ```c
* void memm_free(void *mem);
* ```
*
*
*/
void memm_free(void *mem);
/*
/**
* @name find_fitable_pages
*
* ```c
* usize find_fitable_pages(usize page_count);
* ```
*
*/
usize find_fitable_pages(usize page_count);

View File

@ -24,6 +24,19 @@ typedef struct __raw_allocator_cell
//
// 统计从上次细胞合并以来free的调用次数当调用次数很多或可用空间不足时
// 触发细胞合并。
/**
* @name raw_allocator_t
*
* cellcell的分裂一样将空白的一段分成两段length归零cell合并
*
* `length`0cell称为空cell
*
* free的调用次数`RAW_ALLOCATOR_FREE_MAX`
*
* @internal free_count
*
* free方法的调用次数`RAW_ALLOCATOR_FREE_MAX`
*/
typedef struct __raw_allocator_t
{
usize size;
@ -34,8 +47,22 @@ typedef struct __raw_allocator_t
} raw_allocator_t;
#define raw_allocator_end(allocator) ((void *)(allocator) + (allocator)->size)
/**
* @name raw_allocator_new
*
* ```c
* void raw_allocator_new(raw_allocator_t *allocator, usize size);
* ```
*
* `raw_allocator`
*/
void raw_allocator_new(raw_allocator_t *allocator, usize size);
/**
* @name raw_allocator_allocate, raw_allocator_free
*
* `raw_allocator`allocate, free方法
*/
void *raw_allocator_allocate(raw_allocator_t *allocator, usize size);
void raw_allocator_free(raw_allocator_t *allocator, void *mem);

View File

@ -5,6 +5,15 @@
#include <kernel/arch/x86_64/syscall.h>
#endif
/**
* @name syscall_init
*
* ```c
* void syscall_init();
* ```
*
*
*/
void syscall_init();
#endif