重构内存分配器、增加中断支持、整理rust运行时环境 #4
|
@ -1,4 +1,3 @@
|
||||||
/.vscode
|
|
||||||
/test/metaverse.img
|
/test/metaverse.img
|
||||||
*.o
|
*.o
|
||||||
*.map
|
*.map
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Linux",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/include"
|
||||||
|
],
|
||||||
|
"defines": [],
|
||||||
|
"compilerPath": "/usr/bin/gcc",
|
||||||
|
"cStandard": "c17",
|
||||||
|
"intelliSenseMode": "linux-gcc-x64",
|
||||||
|
"configurationProvider": "ms-vscode.makefile-tools"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"C_Cpp.errorSquiggles": "disabled",
|
||||||
|
"files.associations": {
|
||||||
|
"*.s": "nasm",
|
||||||
|
"LICENCE": "plaintext",
|
||||||
|
"*.h": "c"
|
||||||
|
},
|
||||||
|
"rust-analyzer.imports.preferNoStd" : true,
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
name = "metaverse"
|
name = "metaverse"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
# 此Cargo.toml仅用于rust-analyzer识别rust部分的代码
|
# 此Cargo.toml仅用于rust-analyzer识别rust部分的代码
|
||||||
# 不应使用cargo编译
|
# 不应使用cargo编译
|
||||||
|
|
39
Makefile
39
Makefile
|
@ -1,27 +1,42 @@
|
||||||
SOURCE := $(shell pwd)/src/scripts
|
SOURCE := $(shell pwd)/scripts
|
||||||
|
|
||||||
.PHONY: all clear run debug config
|
.PHONY: all clear run debug disass
|
||||||
|
|
||||||
all: config
|
all: metaverse_kernel
|
||||||
@make -C src all --no-print-directory
|
@make -C src all --no-print-directory
|
||||||
|
|
||||||
clear: config
|
clear: metaverse_kernel
|
||||||
@make -C src clear --no-print-directory
|
@make -C src clear --no-print-directory
|
||||||
|
|
||||||
run: config
|
run: metaverse_kernel
|
||||||
@make -C test run --no-print-directory
|
@make -C test run --no-print-directory
|
||||||
|
|
||||||
debug: config
|
debug: metaverse_kernel
|
||||||
@make -C test debug --no-print-directory
|
@make -C test debug --no-print-directory
|
||||||
|
|
||||||
config:
|
metaverse_kernel:
|
||||||
@if [ "${shell uname -s}" != "Linux" ]; then \
|
@if [ "${shell uname -s}" != "Linux" ]; then \
|
||||||
echo -e "\e[1;33mMetaverse\e[0m must build under \e[1;35mLinux\e[0m or itself."; \
|
echo -e "\e[1;33mMetaverse\e[0m must build under \e[1;35mLinux\e[0m or itself."; \
|
||||||
exit -1; \
|
exit -1; \
|
||||||
fi
|
fi
|
||||||
@if [ -f "metaverse_kernel" ]; then \
|
@"${SOURCE}/depcheck";
|
||||||
echo; \
|
@if [ $$? != 0 ]; then \
|
||||||
else \
|
exit $$?; \
|
||||||
touch metaverse_kernel; \
|
|
||||||
"${SOURCE}/depcheck"; \
|
|
||||||
fi
|
fi
|
||||||
|
@touch metaverse_kernel
|
||||||
|
|
||||||
|
disass:
|
||||||
|
objdump -D src/metaverse.elf > kerndisass.txt
|
||||||
|
|
||||||
|
install-grub:
|
||||||
|
@cp src/metaverse.elf /boot/
|
||||||
|
@if ! grep -q "Metaverse" /boot/grub/grub.cfg; then \
|
||||||
|
echo -e 'menuentry "Metaverse" {\n set root=(hd0,gpt1)\n multiboot2 /metaverse.elf\n}\n' >> \
|
||||||
|
/boot/grub/grub.cfg; \
|
||||||
|
echo -e 'Added Metaverse into grub entries.'; \
|
||||||
|
else \
|
||||||
|
echo -e 'Metaverse entry exists.'; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
remove-grub:
|
||||||
|
@-rm /boot/metaverse.elf
|
||||||
|
|
14
README.md
14
README.md
|
@ -57,6 +57,8 @@ make debug
|
||||||
* [x] raw_allocator
|
* [x] raw_allocator
|
||||||
* [x] tty
|
* [x] tty
|
||||||
* [x] 内核日志
|
* [x] 内核日志
|
||||||
|
* [ ] 系统调用
|
||||||
|
* [ ] 中断管理
|
||||||
* [ ] 文件系统
|
* [ ] 文件系统
|
||||||
* [ ] vfs
|
* [ ] vfs
|
||||||
* [ ] fat32驱动(移植)
|
* [ ] fat32驱动(移植)
|
||||||
|
@ -64,9 +66,19 @@ make debug
|
||||||
* [ ] 驱动管理
|
* [ ] 驱动管理
|
||||||
* [ ] 进程管理
|
* [ ] 进程管理
|
||||||
|
|
||||||
|
## 文档
|
||||||
|
|
||||||
|
* 从源代码注释生成文档
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make doc
|
||||||
|
```
|
||||||
|
|
||||||
|
(开发中)
|
||||||
|
|
||||||
## 作出贡献
|
## 作出贡献
|
||||||
|
|
||||||
通过向此仓库发送PR为我们作出贡献。
|
通过向此仓库发送PR为我们作出贡献,详见[contribution.md](docs/contribution.md)。
|
||||||
|
|
||||||
## 版权声明
|
## 版权声明
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
# 向Metaverse内核贡献代码
|
||||||
|
|
||||||
|
通过如下方式向内核增加你的代码:
|
||||||
|
|
||||||
|
* 从[github仓库](https://github.com/metaverse-kernel/kernel-dev)或[Random World Studio内部仓库](http://git.suthby.org:2024/metaverse/kernel-dev)创建一个分支
|
||||||
|
* 在你的分支中增加代码
|
||||||
|
* 测试你增加的代码的正确性,并尽量确保对原有代码没有影响
|
||||||
|
* 无需在注释中加入代码更改日志,git可以做到
|
||||||
|
* 在文档的适当的位置增加对新特性的描述
|
||||||
|
* 完成编码和文档的工作后向主仓库发送PR
|
||||||
|
* 等待审核代码
|
||||||
|
|
||||||
|
若你的代码通过审核,将会把你的PR合并到主分支中。
|
||||||
|
|
||||||
|
## 需要注意的还未解决的问题
|
||||||
|
|
||||||
|
* rust中所有有关字符串格式化的宏中,出现超过一个不止是`{}`的格式化占位符时内核必然崩溃。
|
||||||
|
* rust中所有有关字符串格式化的宏中,出现需要调用自定义的`Debug trait`的类型时内核必然崩溃,推荐定义`ToString trait`并调用`.to_string()`后传入宏参数。
|
||||||
|
* 鉴于以上两条原因,不建议在复杂的字符串格式化任务中使用`format!()`宏。推荐通过使用`::kernel::tty::tty::MessageBuilder`构造`kernel::tty::tty::Message`对象,或使用
|
||||||
|
`message`宏,并调用此对象的`.to_string()`方法实现格式化字符串。
|
|
@ -0,0 +1,69 @@
|
||||||
|
#ifndef X86_64_INTERRUPT_H
|
||||||
|
#define X86_64_INTERRUPT_H 1
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <utils.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name gate_descriptor_t
|
||||||
|
* @addindex 平台依赖结构 x86_64
|
||||||
|
*
|
||||||
|
* 门描述符的结构体形式。
|
||||||
|
*/
|
||||||
|
typedef struct __gate_descriptor_t
|
||||||
|
{
|
||||||
|
u16 offset_01;
|
||||||
|
u16 segment_selector; // for code segment
|
||||||
|
u16 flags;
|
||||||
|
u16 offset_23;
|
||||||
|
u32 offset_4567;
|
||||||
|
u32 reserved;
|
||||||
|
} DISALIGNED gate_descriptor_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name INTERRUPT_DESCRIPTOR_FLAG_IST
|
||||||
|
* @addindex 平台依赖结构 x86_64
|
||||||
|
*
|
||||||
|
* `gate_descriptor_t`的`flags`的标志位。
|
||||||
|
*
|
||||||
|
* `ssp`代表一个tss描述符在任务段中的的索引。
|
||||||
|
*/
|
||||||
|
#define INTERRUPT_DESCRIPTOR_FLAG_IST 1
|
||||||
|
|
||||||
|
// 在第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];
|
||||||
|
|
||||||
|
#define interrupt_gate_generate(desc, addr) \
|
||||||
|
{ \
|
||||||
|
(desc).segment_selector = 0x8; \
|
||||||
|
(desc).flags = INTERRUPT_DESCRIPTOR_FLAG_TYPE_INTERRUPT | \
|
||||||
|
INTERRUPT_DESCRIPTOR_FLAG_IST; \
|
||||||
|
(desc).reserved = 0; \
|
||||||
|
(desc).offset_01 = (u16)((u64)(addr)); \
|
||||||
|
(desc).offset_23 = (u16)(((u64)(addr)) >> 16); \
|
||||||
|
(desc).offset_4567 = (u32)(((u64)(addr)) >> 32); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define trap_gate_generate(desc, addr) \
|
||||||
|
{ \
|
||||||
|
(desc).segment_selector = 0x8; \
|
||||||
|
(desc).flags = INTERRUPT_DESCRIPTOR_FLAG_TYPE_TRAP | \
|
||||||
|
INTERRUPT_DESCRIPTOR_FLAG_IST; \
|
||||||
|
(desc).reserved = 0; \
|
||||||
|
(desc).offset_01 = (u16)((u64)(addr)); \
|
||||||
|
(desc).offset_23 = (u16)(((u64)(addr)) >> 16); \
|
||||||
|
(desc).offset_4567 = (u32)(((u64)(addr)) >> 32); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define interrupt_register_gate(desc, index) \
|
||||||
|
idt[index] = desc;
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,87 @@
|
||||||
|
#ifndef X86_64_INTERRUPT_PROCS_H
|
||||||
|
#define X86_64_INTERRUPT_PROCS_H 1
|
||||||
|
|
||||||
|
#include <utils.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name interrupt_entry
|
||||||
|
* @addindex 平台定制函数 x86_64
|
||||||
|
*
|
||||||
|
* 中断入口程序。
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* void interrupt_entry();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* ```asm
|
||||||
|
* interrupt_entry_xx:
|
||||||
|
* ; 保存寄存器上下文
|
||||||
|
* interrupt_entry_enter
|
||||||
|
*
|
||||||
|
* ; 调用真正的中断处理函数
|
||||||
|
* ...
|
||||||
|
*
|
||||||
|
* ; 恢复寄存器上下文
|
||||||
|
* interrupt_entry_leave
|
||||||
|
* iret
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
typedef void (*interrupt_entry)();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name interrupt_entry_gen
|
||||||
|
* @addindex 平台定制宏 x86_64
|
||||||
|
*
|
||||||
|
* 导入一个中断入口函数声明。
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* #define interrupt_entry_gen(interrupt)
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
#define interrupt_entry_gen(interrupt) \
|
||||||
|
extern void interrupt_entry_##interrupt()
|
||||||
|
#define interrupt_entry_sym(interrupt) \
|
||||||
|
interrupt_entry_##interrupt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name interrupt_request
|
||||||
|
* @addindex 平台定制函数
|
||||||
|
*
|
||||||
|
* 中断请求处理程序。
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* void interrupt_request(u64 rip, u64 rsp);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 由中断入口程序调用。
|
||||||
|
*/
|
||||||
|
typedef void (*interrupt_request)(u64 rip, u64 rsp, u64 errcode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name interrupt_req_gen
|
||||||
|
* @addindex 平台定制宏 x86_64
|
||||||
|
*
|
||||||
|
* 声明一个中断处理函数。
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* #define interrupt_req_gen(interrupt)
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
#define interrupt_req_gen(interrupt) \
|
||||||
|
void interrupt_req_##interrupt(u64 rip, u64 rsp, u64 errcode)
|
||||||
|
#define interrupt_req_sym(interrupt) \
|
||||||
|
interrupt_req_##interrupt
|
||||||
|
|
||||||
|
#define UNSUPPORTED
|
||||||
|
|
||||||
|
#define DE
|
||||||
|
#define NMI
|
||||||
|
#define BP
|
||||||
|
|
||||||
|
interrupt_entry_gen(UNSUPPORTED);
|
||||||
|
|
||||||
|
interrupt_entry_gen(DE);
|
||||||
|
interrupt_entry_gen(NMI);
|
||||||
|
interrupt_entry_gen(BP);
|
||||||
|
|
||||||
|
#endif
|
|
@ -3,7 +3,15 @@
|
||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
// 具有返回值是为了留出一个寄存器用于调整栈顶
|
/**
|
||||||
extern usize prepare_stack();
|
* @name prepare_stack
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* void prepare_stack();
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
extern void prepare_stack();
|
||||||
|
|
||||||
|
extern u32 TSS[26];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,8 +4,33 @@
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
#include <libk/bits.h>
|
#include <libk/bits.h>
|
||||||
|
|
||||||
/* 页大小,以MEMM_PAGE_SIZE为单位 */
|
/**
|
||||||
|
* @details x86_64
|
||||||
|
*
|
||||||
|
* 物理地址空间:
|
||||||
|
*
|
||||||
|
* * 0 \~ 1MB:保留。
|
||||||
|
* * 1MB \~ 2MB:内核头。
|
||||||
|
* * 2MB \~ 4MB:中断栈。
|
||||||
|
* * 4MB \~ 16MB:内核栈。
|
||||||
|
* * 16MB \~ ?:内核镜像。
|
||||||
|
* * ? \~ 128MB:内核大分配器。
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name MEMM_PAGE_SIZE
|
||||||
|
* @addindex 平台定制宏
|
||||||
|
*
|
||||||
|
* 最小的页大小。
|
||||||
|
*
|
||||||
|
* @if arch == x86_64 then
|
||||||
|
* 4096
|
||||||
|
* @endif
|
||||||
|
*/
|
||||||
#define MEMM_PAGE_SIZE 4096
|
#define MEMM_PAGE_SIZE 4096
|
||||||
|
|
||||||
|
#define MEMM_PAGE_TABLE_SIZE 4096
|
||||||
|
|
||||||
typedef enum __memm_page_size
|
typedef enum __memm_page_size
|
||||||
{
|
{
|
||||||
MEMM_PAGE_SIZE_4K = 1, // 1个4KB页大小
|
MEMM_PAGE_SIZE_4K = 1, // 1个4KB页大小
|
||||||
|
@ -15,14 +40,49 @@ typedef enum __memm_page_size
|
||||||
|
|
||||||
extern u64 PML4[512];
|
extern u64 PML4[512];
|
||||||
|
|
||||||
#define MEMM_PAGE_TABLE_FLAGS_AREA ((u64)0xfff)
|
/**
|
||||||
|
* @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_4K_ALIGN_MASK ((u64)0xfff)
|
||||||
#define MEMM_2M_ALIGN_MASK ((u64)0x1fffff)
|
#define MEMM_2M_ALIGN_MASK ((u64)0x1fffff)
|
||||||
#define MEMM_1G_ALIGN_MASK ((u64)0x3fffffff)
|
#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_PRESENT ((u64)1)
|
||||||
#define MEMM_ENTRY_FLAG_WRITE ((u64)1 << 1)
|
#define MEMM_ENTRY_FLAG_WRITE ((u64)1 << 1)
|
||||||
#define MEMM_ENTRY_FLAG_USER ((u64)1 << 2)
|
#define MEMM_ENTRY_FLAG_USER ((u64)1 << 2)
|
||||||
|
@ -35,18 +95,47 @@ extern u64 PML4[512];
|
||||||
#define MEMM_ENTRY_FLAG_PAT ((u64)1 << 12)
|
#define MEMM_ENTRY_FLAG_PAT ((u64)1 << 12)
|
||||||
#define MEMM_PTE_ENTRY_FLAG_PAT ((u64)1 << 7)
|
#define MEMM_PTE_ENTRY_FLAG_PAT ((u64)1 << 7)
|
||||||
#define MEMM_ENTRY_FLAG_XD ((u64)1 << 63)
|
#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) \
|
#define memm_entry_flag_get(entry, flag) \
|
||||||
((entry & flag) ? true : false)
|
((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_ENTRY_ADDRESS_MASK ((u64)0x000ffffffffff000)
|
||||||
#define MEMM_BP_ENTRY_ADDRESS_MASK ((u64)0x000fffffffffe000)
|
#define MEMM_BP_ENTRY_ADDRESS_MASK ((u64)0x000fffffffffe000)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name memm_entry_get_address(entry)
|
||||||
|
* @addindex 平台依赖宏 x86_64
|
||||||
|
*
|
||||||
|
* 获取页表项指向的地址。
|
||||||
|
*/
|
||||||
#define memm_entry_get_address(entry) \
|
#define memm_entry_get_address(entry) \
|
||||||
((entry) & (memm_entry_flag_get(entry, MEMM_ENTRY_FLAG_PS) \
|
((entry) & (memm_entry_flag_get(entry, MEMM_ENTRY_FLAG_PS) \
|
||||||
? MEMM_BP_ENTRY_ADDRESS_MASK \
|
? MEMM_BP_ENTRY_ADDRESS_MASK \
|
||||||
: MEMM_ENTRY_ADDRESS_MASK))
|
: MEMM_ENTRY_ADDRESS_MASK))
|
||||||
|
|
||||||
/* 线性地址表项索引或页内偏移掩码 */
|
|
||||||
#define MEMM_LA_PML4EI_MASK ((u64)0x0000ff8000000000)
|
#define MEMM_LA_PML4EI_MASK ((u64)0x0000ff8000000000)
|
||||||
#define MEMM_LA_PDPTEI_MASK ((u64)0x0000007fc0000000)
|
#define MEMM_LA_PDPTEI_MASK ((u64)0x0000007fc0000000)
|
||||||
#define MEMM_LA_PDEI_MASK ((u64)0x000000003fe00000)
|
#define MEMM_LA_PDEI_MASK ((u64)0x000000003fe00000)
|
||||||
|
@ -56,50 +145,119 @@ extern u64 PML4[512];
|
||||||
#define MEMM_LA_2MB_PAGE_OFFSET_MASK ((u64)0x00000000001fffff)
|
#define MEMM_LA_2MB_PAGE_OFFSET_MASK ((u64)0x00000000001fffff)
|
||||||
#define MEMM_LA_4KB_PAGE_OFFSET_MASK ((u64)0x0000000000000fff)
|
#define MEMM_LA_4KB_PAGE_OFFSET_MASK ((u64)0x0000000000000fff)
|
||||||
|
|
||||||
/* 线性地址表项索引偏移位数 */
|
|
||||||
#define MEMM_LA_PML4EI_OFFSET (39)
|
#define MEMM_LA_PML4EI_OFFSET (39)
|
||||||
#define MEMM_LA_PDPTEI_OFFSET (30)
|
#define MEMM_LA_PDPTEI_OFFSET (30)
|
||||||
#define MEMM_LA_PDEI_OFFSET (21)
|
#define MEMM_LA_PDEI_OFFSET (21)
|
||||||
#define MEMM_LA_PEI_OFFSET (12)
|
#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_PML4EI
|
||||||
#define MEMM_LA_PDPTEI
|
#define MEMM_LA_PDPTEI
|
||||||
#define MEMM_LA_PDEI
|
#define MEMM_LA_PDEI
|
||||||
#define MEMM_LA_PEI
|
#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) \
|
#define memm_la_get_entry_index(addr, entry) \
|
||||||
(((addr) & (entry##_MASK)) >> (entry##_OFFSET))
|
(((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_1GB_PAGE_OFFSET
|
||||||
#define MEMM_LA_2MB_PAGE_OFFSET
|
#define MEMM_LA_2MB_PAGE_OFFSET
|
||||||
#define MEMM_LA_4KB_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) \
|
#define memm_la_get_offset(addr, page_type) \
|
||||||
((addr) & (page_type##_MASK))
|
((addr) & (page_type##_MASK))
|
||||||
|
|
||||||
/*
|
/**
|
||||||
仅支持canonical型地址
|
* @name memm_map_pageframes_to
|
||||||
|
*
|
||||||
target与physical至少都是以MEMM_PAGE_SIZE对齐的
|
* ```c
|
||||||
|
* bool memm_map_pageframes_to(
|
||||||
没有MEMM_PAGE_SIZE对齐的,和非canonical型地址都会返回false
|
* u64 target, u64 physical,
|
||||||
|
* usize size,
|
||||||
当剩余长度超过1GB的一半且地址1GB对齐,则会映射一个1GB页;
|
* bool user, bool write);
|
||||||
当剩余长度超过2MB的一半且地址2MB对齐,则会映射一个2MB页;
|
* ```
|
||||||
否则映射4KB页。
|
*
|
||||||
|
* 仅支持**canonical**型地址
|
||||||
|
*
|
||||||
|
* `target`与`physical`保证至少都是以MEMM_PAGE_SIZE对齐的。
|
||||||
|
*
|
||||||
|
* 没有MEMM_PAGE_SIZE对齐的,和非canonical型地址都会返回false
|
||||||
|
*
|
||||||
|
* 当剩余长度超过1GB的一半且地址1GB对齐,则会映射一个1GB页;
|
||||||
|
* 当剩余长度超过2MB的一半且地址2MB对齐,则会映射一个2MB页;
|
||||||
|
* 否则映射4KB页。
|
||||||
*/
|
*/
|
||||||
bool memm_map_pageframes_to(
|
bool memm_map_pageframes_to(
|
||||||
u64 target, u64 physical,
|
u64 target, u64 physical,
|
||||||
usize size,
|
usize size,
|
||||||
bool user, bool write);
|
bool user, bool write);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name reload_pml4
|
||||||
|
* @addindex 平台依赖宏 x86_64
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* void reload_pml4();
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
extern 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) \
|
#define is_user_address(addr) \
|
||||||
(((addr) > 0xffff7fffffffffff) ? true : false)
|
(((addr) > 0xffff7fffffffffff) ? true : false)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name is_cannonical(addr)
|
||||||
|
* @addindex 平台依赖宏 x86_64
|
||||||
|
*
|
||||||
|
* 判断`addr`是否是一个cannonical型地址。
|
||||||
|
*/
|
||||||
#define is_cannonical(addr) \
|
#define is_cannonical(addr) \
|
||||||
(((addr) < 0x0000800000000000 || (addr) > 0xffff7fffffffffff) ? true : false)
|
(((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) \
|
#define memm_get_page_align(addr) \
|
||||||
(is_aligned(addr, MEMM_PAGE_SIZE_1G) \
|
(is_aligned(addr, MEMM_PAGE_SIZE_1G) \
|
||||||
? MEMM_PAGE_SIZE_1G \
|
? MEMM_PAGE_SIZE_1G \
|
||||||
|
@ -107,4 +265,21 @@ extern void reload_pml4();
|
||||||
? MEMM_PAGE_SIZE_2M \
|
? MEMM_PAGE_SIZE_2M \
|
||||||
: MEMM_PAGE_SIZE_4K))
|
: MEMM_PAGE_SIZE_4K))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name memm_page_counter
|
||||||
|
* @addindex 平台定制结构
|
||||||
|
*
|
||||||
|
* 页计数器
|
||||||
|
*
|
||||||
|
* @if arch == x86_64
|
||||||
|
* 使用三个成员分别记录`4KB`、`2MB`、`1GB`页的大小。
|
||||||
|
* @endif
|
||||||
|
*/
|
||||||
|
typedef struct __memm_page_counter
|
||||||
|
{
|
||||||
|
usize mapped_4k_page;
|
||||||
|
usize mapped_2m_page;
|
||||||
|
usize mapped_1g_page;
|
||||||
|
} memm_page_counter;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef X86_64_PROC_H
|
||||||
|
#define X86_64_PROC_H 1
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name proc_texture_registers_t
|
||||||
|
* @addindex 平台定制宏 x86_64
|
||||||
|
*
|
||||||
|
* 进程上下文的寄存器上下文。
|
||||||
|
*/
|
||||||
|
typedef struct __proc_texture_registers_t
|
||||||
|
{
|
||||||
|
u16 es, ds;
|
||||||
|
u32 reserved;
|
||||||
|
u64 r15, r14, r13, r12;
|
||||||
|
u64 r11, r10, r9, r8;
|
||||||
|
u64 rdi, rsi, rdx, rbx, rcx, rax;
|
||||||
|
u64 rbp;
|
||||||
|
u64 rip, cs;
|
||||||
|
u64 rflags;
|
||||||
|
u64 rsp, ss;
|
||||||
|
} proc_texture_registers_t;
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,56 @@
|
||||||
|
#ifndef X86_64_SYSCALL
|
||||||
|
#define X86_64_SYSCALL 1
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
extern void *system_calls_table[256];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
*
|
||||||
|
* 返回值 - rax
|
||||||
|
*
|
||||||
|
* 系统调用时,使用内核主堆栈。
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
|
@ -4,12 +4,45 @@
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
// 使用UNIX时间戳
|
// 使用UNIX时间戳
|
||||||
|
/**
|
||||||
|
* @name system_time_get
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* usize system_time_get();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 系统时间。
|
||||||
|
*
|
||||||
|
* 系统时间使用精确到毫秒的unix时间,即值`0`代表1970-1-1 00:00:00的第一毫秒前。
|
||||||
|
*/
|
||||||
usize system_time_get();
|
usize system_time_get();
|
||||||
|
|
||||||
// 如果硬件支持更高的计时精度,
|
// 如果硬件支持更高的计时精度,
|
||||||
// 此函数提供从系统unix时间开始到现在的纳秒为单位的时间
|
// 此函数提供从系统unix时间开始到现在的纳秒为单位的时间
|
||||||
|
/**
|
||||||
|
* @name system_time_ns_get
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* usize system_time_ns_get();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 纳秒级系统时间。
|
||||||
|
*
|
||||||
|
* 如果硬件支持更高的计时精度,此函数返回以纳秒为单位的时间。但不表明硬件必须支持纳秒级的计时。
|
||||||
|
*
|
||||||
|
* 即使硬件支持更高的计时精度,内核也会根据情况自主选择是否使用更高的精度计时。
|
||||||
|
*/
|
||||||
usize system_time_ns_get();
|
usize system_time_ns_get();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name system_time_increase
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* void system_time_increase();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 将毫秒级系统时间增加。
|
||||||
|
*/
|
||||||
void system_time_increase();
|
void system_time_increase();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef INTERRUPT_H
|
||||||
|
#define INTERRUPT_H 1
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#include <kernel/arch/x86_64/interrupt.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name interrupt_open
|
||||||
|
* @addindex 平台定制函数
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* void interrupt_open();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 开启中断
|
||||||
|
*/
|
||||||
|
void interrupt_open();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name interrupt_close
|
||||||
|
* @addindex 平台定制函数
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* void interrupt_close();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 开启中断
|
||||||
|
*/
|
||||||
|
void interrupt_close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name interrupt_init
|
||||||
|
* @addindex 平台定制函数
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* void interrupt_init();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 初始化中断功能。
|
||||||
|
*/
|
||||||
|
void interrupt_init();
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef INTERRUPT_PROCS
|
||||||
|
#define INTERRUPT_PROCS 1
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#include <kernel/arch/x86_64/interrupt_procs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -2,20 +2,44 @@
|
||||||
#define KERNEL_H 1
|
#define KERNEL_H 1
|
||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
#include <kernel/interrupt/procs.h>
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
|
|
||||||
#include <kernel/arch/x86_64/kernel.h>
|
#include <kernel/arch/x86_64/kernel.h>
|
||||||
|
|
||||||
#define ISA_NAME "x86_64"
|
#define ISA_NAME "x86_64"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef BUILD_ID
|
||||||
|
#define BUILD_ID 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name KERNEL_TODO
|
||||||
|
*
|
||||||
|
* 表示此处还没有实现代码。
|
||||||
|
*/
|
||||||
#define KERNEL_TODO() \
|
#define KERNEL_TODO() \
|
||||||
while (true) \
|
while (true) \
|
||||||
{ \
|
{ \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name simple_lock
|
||||||
|
*
|
||||||
|
* 简易同步锁。有如下两个方法:
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* #define simple_lock_lock(lock)
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 获取一个锁。
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* #define simple_lock_unlock(lock)
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 解开一个锁。
|
||||||
|
*/
|
||||||
#define simple_lock_lock(lock) \
|
#define simple_lock_lock(lock) \
|
||||||
{ \
|
{ \
|
||||||
while (lock == true) \
|
while (lock == true) \
|
||||||
|
@ -24,8 +48,20 @@
|
||||||
}
|
}
|
||||||
#define simple_lock_unlock(lock) (lock) = false;
|
#define simple_lock_unlock(lock) (lock) = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name kmain_rust
|
||||||
|
*
|
||||||
|
* rust内核主程序。
|
||||||
|
*/
|
||||||
extern void kmain_rust();
|
extern void kmain_rust();
|
||||||
|
|
||||||
extern void *kend; // 内核结束的标记
|
/**
|
||||||
|
* @name kend
|
||||||
|
*
|
||||||
|
* 内核结束的标记。
|
||||||
|
*
|
||||||
|
* 此变量不代表任何值,但是此变量的地址被安排到了内核镜像的末尾,用于标志内核结束的位置。
|
||||||
|
*/
|
||||||
|
extern void *kend;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
#ifndef KLOG_H
|
|
||||||
#define KLOG_H 1
|
|
||||||
|
|
||||||
#include <types.h>
|
|
||||||
|
|
||||||
#define KLOG_BUFFER_SIZE 2 * 1024 * 1024
|
|
||||||
|
|
||||||
typedef struct __klogger
|
|
||||||
{
|
|
||||||
usize tty;
|
|
||||||
char buffer[KLOG_BUFFER_SIZE];
|
|
||||||
usize index;
|
|
||||||
} klogger;
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -8,153 +8,227 @@
|
||||||
#include <libk/lst.h>
|
#include <libk/lst.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 内存管理模块
|
* @name MEMM_MAX_SUPPORTED_MEMORY
|
||||||
*
|
*
|
||||||
* TODO 还没设计页回收算法
|
* 支持的最大物理内存,为固定值`1TB`。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* 最大支持1TB内存 */
|
|
||||||
#define MEMM_MAX_SUPPORTED_MEMORY (1024 * (1024 * (1024 * (usize)1024)))
|
#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)
|
#define MEMM_MAX_SUPPORTED_PAGES (MEMM_MAX_SUPPORTED_MEMORY / MEMM_PAGE_SIZE)
|
||||||
|
|
||||||
/* 只分配不映射空间 */
|
/**
|
||||||
#define MEMM_ALLOC_ONLY_MEMORY (128 * 1024 * 1024)
|
* @name MEMM_ALLOC_ONLY_MEMORY
|
||||||
|
*
|
||||||
|
* 只分配不映射空间,暂时为固定值`64MB`。物理地址`0`\~`MEMM_ALLOC_ONLY_MEMORY`的空间在进入内核前已经映射至内核空间。
|
||||||
|
*
|
||||||
|
* 这段内存空间包含**1MB以内低地址**、**内核镜像**以及未分配空间,未分配空间被一个分配器独占。
|
||||||
|
*/
|
||||||
|
#define MEMM_ALLOC_ONLY_MEMORY (64 * 1024 * 1024)
|
||||||
|
|
||||||
typedef void *(*memm_allocate_t)(void *allocator, usize size, usize align);
|
#define MEMM_PAGE_TABLE_AREA_MAX (4 * 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);
|
typedef void (*memm_free_t)(void *allocator, void *mem);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
内存分配器
|
* @name allocator_t
|
||||||
分配器对象的首地址永远是MEMM_PAGE_SIZE对齐的
|
*
|
||||||
|
* ```c
|
||||||
|
* typedef struct { } allocator_t;
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 内存分配器。
|
||||||
|
*
|
||||||
|
* 内存分配器用于为`memm_allocate`函数提供管理数据以及分配空间。
|
||||||
|
*
|
||||||
|
* 在**内核镜像结尾**至`MEMM_ALLOC_ONLY_MEMORY`空间中,包含一个分配器`内核大分配器`。
|
||||||
|
*
|
||||||
|
* 分配器指针**必须**使用内核地址。
|
||||||
|
*
|
||||||
|
* @internal magic
|
||||||
|
*
|
||||||
|
* 分配器有效性由此检验,不为`MEMM_ALLOCATOR_MAGIC_NUM`说明获得了一个错误的分配器地址。
|
||||||
|
*
|
||||||
|
* @internal full
|
||||||
|
*
|
||||||
|
* 调用分配器的`allocate`方法后,在返回`nullptr`时会设为`true`。
|
||||||
|
* 调用分配器的`free`方法时设为`false`。
|
||||||
|
*
|
||||||
|
* @internal pid
|
||||||
|
*
|
||||||
|
* 进程标志服,表示此分配器所属的进程,为0代表属于内核。
|
||||||
|
*
|
||||||
|
* @internal userspace
|
||||||
|
*
|
||||||
|
* 若分配器不属于内核,此成员储存此分配器的用户空间地址。
|
||||||
|
*
|
||||||
|
* @internal type
|
||||||
|
*
|
||||||
|
* 分配器类型。在目录`include/kernel/memm/allocator`中对每个分配器分别定义一个唯一值。
|
||||||
|
*
|
||||||
|
* @internal allocate
|
||||||
|
*
|
||||||
|
* 分配器实例的allocate函数。当无法分配空间时返回nullptr。在size参数为0时,保证不可以分配空间,
|
||||||
|
* 但是如果空间已满依然返回nullptr。
|
||||||
|
*
|
||||||
|
* @internal free
|
||||||
|
*
|
||||||
|
* 分配器实例的free函数。若不是allocate得到的地址则什么都不做。
|
||||||
|
*
|
||||||
|
* @internal allocator_instance
|
||||||
|
*
|
||||||
|
* 分配器实例。
|
||||||
*/
|
*/
|
||||||
typedef struct __allocator_t
|
typedef struct __allocator_t
|
||||||
{
|
{
|
||||||
bool initialized;
|
#ifndef MEMM_ALLOCATOR_MAGIC
|
||||||
|
#define MEMM_ALLOCATOR_MAGIC ((u32)0x271fe441)
|
||||||
|
#endif
|
||||||
|
// 分配器有效性由此检验,不为`MEMM_ALLOCATOR_MAGIC_NUM`说明获得了一个错误的分配器地址。
|
||||||
|
// 此值在编译时通过各种方式确定,若
|
||||||
|
u32 magic;
|
||||||
|
|
||||||
// 在本分配器中调用allocate返回nullptr后为true
|
// 调用分配器的`allocate`方法后,在返回`nullptr`时会设为`true`。
|
||||||
// 调用free后为false
|
// 调用分配器的`free`方法时设为`false`。
|
||||||
bool full;
|
bool full;
|
||||||
|
|
||||||
// 进程id,当pid=0时代表内核
|
// 分配器类型。在目录`include/kernel/memm/allocator`中对每个分配器分别定义一个唯一值。
|
||||||
usize pid;
|
|
||||||
// 分配器类型
|
|
||||||
usize type;
|
usize type;
|
||||||
usize size;
|
usize size;
|
||||||
|
|
||||||
// 分配器实例的allocate函数
|
// 分配器实例的allocate函数。当无法分配空间时返回nullptr。在size参数为0时,
|
||||||
// 无法分配空间返回nullptr
|
// 保证不可以分配空间,但是如果空间已满依然返回nullptr。
|
||||||
// 在size参数为0时,保证不可以分配空间,但是如果空间已满依然返回nullptr
|
|
||||||
// 当参数align=0时表示不需要对齐
|
|
||||||
memm_allocate_t allocate;
|
memm_allocate_t allocate;
|
||||||
|
// 分配器实例的free函数。若不是allocate得到的地址则什么都不做。
|
||||||
// 分配器实例的free函数
|
|
||||||
// 若不是allocate得到的地址则什么都不做
|
|
||||||
memm_free_t free;
|
memm_free_t free;
|
||||||
|
|
||||||
// 分配器实例
|
// 分配器实例。
|
||||||
// 对应`type`类型使用
|
|
||||||
// 在kernel/memm/allocator/中是所有的内存分配器
|
|
||||||
u64 allocator_instance[0];
|
u64 allocator_instance[0];
|
||||||
} allocator_t;
|
} allocator_t;
|
||||||
|
|
||||||
typedef struct __allocator_iterator_t
|
/**
|
||||||
{
|
* @name 内存管理器
|
||||||
allocator_t *allocator;
|
*
|
||||||
struct __allocator_iterator_t *left, *right;
|
* @internal alloc_only_memory
|
||||||
} allocator_iterator_t;
|
*
|
||||||
|
* 在进入内核主程序之前,有些不在内核中的虚拟内存空间已经被页表映射,这部分内存不可以再映射到物理页框。
|
||||||
/*
|
*/
|
||||||
内存管理器
|
|
||||||
内存分配分成两个阶段:映射和分配
|
|
||||||
映射后的页进入allocator记录中,具体的分配工作由allocator完成
|
|
||||||
|
|
||||||
在page_map中置位、在map_with_allocator中复位、在map_with_destructed_allocator中复位
|
|
||||||
且不在available_pages_table中的页,是页表、程序代码段、内核代码等使用的页
|
|
||||||
*/
|
|
||||||
typedef struct __mem_manager_t
|
typedef struct __mem_manager_t
|
||||||
{
|
{
|
||||||
usize memory_size;
|
usize memory_size;
|
||||||
usize page_amount;
|
usize page_amount;
|
||||||
|
|
||||||
// 这里记录的数量为最小的页的数量
|
|
||||||
usize mapped_page_amount;
|
|
||||||
|
|
||||||
// 在进入内核主程序之前,有些不在内核中的虚拟内存空间已经被
|
|
||||||
// 页表映射,这部分内存不可以再映射到物理页框
|
|
||||||
usize alloc_only_memory;
|
usize alloc_only_memory;
|
||||||
#ifdef __x86_64__
|
|
||||||
// 在这里三种页的数量分别记录
|
|
||||||
usize mapped_4k_page;
|
|
||||||
usize mapped_2m_page;
|
|
||||||
usize mapped_1g_page;
|
|
||||||
#endif
|
|
||||||
// 页地图
|
|
||||||
// 每个bit都表示这个页是否被映射
|
|
||||||
u8 *page_map;
|
|
||||||
// 分配器页地图
|
|
||||||
// 每个bit表示这个页是否被内存分配器控制
|
|
||||||
// (不代表每个页都包含完整的分配器)
|
|
||||||
u8 *map_with_allocator;
|
|
||||||
// 分配器释放页地图
|
|
||||||
// 每个bit表示这个页是否曾经被内存分配器控制且现在被释放
|
|
||||||
// 需要取消映射
|
|
||||||
u8 *map_with_destructed_allocator;
|
|
||||||
|
|
||||||
// 空闲页线段搜索表
|
allocator_t *kernel_base_allocator;
|
||||||
lst_iterator_t *available_pages_table;
|
|
||||||
|
|
||||||
// 分配器树
|
usize page_table_area;
|
||||||
// 为方便查找,以二叉树的形式存储
|
} memory_manager_t;
|
||||||
// index=0为无效项
|
|
||||||
allocator_iterator_t *allocators;
|
|
||||||
} mem_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`的内存分配器
|
* @name memm_get_manager
|
||||||
当`pid`为0时,表示这个分配器只给内核使用
|
*
|
||||||
|
* ```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);
|
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);
|
void memm_allocator_destruct(allocator_t *allocator);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
申请内存
|
* @name memm_kernel_allocate
|
||||||
第三个参数也是返回值,表示申请内存使用的分配器
|
*
|
||||||
pid=0时为内核分配
|
* ```c
|
||||||
所有内存在内核空间都有对物理内存空间的直接映射,也就是线性地址与物理地址相同,称为内核地址
|
* void *memm_kernel_allocate(usize size);
|
||||||
|
* ```
|
||||||
allocator对象在进程与内核之间传递时一律使用内核空间的映射地址
|
*
|
||||||
|
* 为内核空间申请内存。
|
||||||
## 要求在返回的地址前16字节处保留8字节空间作为它所在的allocator地址,并且不需要分配器的具体实现做这个事
|
|
||||||
*/
|
*/
|
||||||
void *memm_allocate(usize size, usize pid);
|
|
||||||
#define memm_addr_set_allocator(mem, allocator) \
|
|
||||||
*(allocator_t **)((void *)(mem) - 16) = allocator;
|
|
||||||
#define memm_addr_get_allocator(mem) \
|
|
||||||
((*(allocator_t **)((void *)(mem) - 16)))
|
|
||||||
|
|
||||||
void *memm_kernel_allocate(usize size);
|
void *memm_kernel_allocate(usize size);
|
||||||
|
|
||||||
void *memm_user_allocate(usize size, usize pid);
|
/**
|
||||||
|
* @name memm_free
|
||||||
/*
|
*
|
||||||
释放内存
|
* ```c
|
||||||
|
* void memm_free(void *mem);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 释放内存。
|
||||||
*/
|
*/
|
||||||
void memm_free(void *mem);
|
void memm_free(void *mem);
|
||||||
|
|
||||||
/*
|
void *memm_allcate_pagetable();
|
||||||
寻找大小合适的一组页
|
|
||||||
*/
|
|
||||||
usize find_fitable_pages(usize page_count);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,20 +10,25 @@ typedef struct __raw_allocator_cell
|
||||||
{
|
{
|
||||||
usize capacity; // 是content的长度
|
usize capacity; // 是content的长度
|
||||||
usize length; // 是实际使用的长度
|
usize length; // 是实际使用的长度
|
||||||
allocator_t *allocator; // 所在的分配器
|
|
||||||
usize reserved;
|
|
||||||
u8 content[0];
|
u8 content[0];
|
||||||
} raw_allocator_cell;
|
} raw_allocator_cell;
|
||||||
#define raw_allocator_next_cell(cell) (raw_allocator_cell *)((void *)((cell)->content) + (cell)->capacity)
|
#define raw_allocator_next_cell(cell) (raw_allocator_cell *)((void *)((cell)->content) + (cell)->capacity)
|
||||||
|
|
||||||
// 原始分配器
|
/**
|
||||||
//
|
* @name raw_allocator_t
|
||||||
// 包括至少一个cell,分配时像cell的分裂一样将空白的一段分成两段,
|
*
|
||||||
// 释放时,只把length归零,并不将cell合并。
|
* 原始分配器。包括至少一个cell,分配时像cell的分裂一样将空白的一段分成两段,释放时,只把length归零,并不将cell合并。
|
||||||
// length=0的cell称为空cell
|
*
|
||||||
//
|
* `length`为0的cell称为空cell。
|
||||||
// 统计从上次细胞合并以来free的调用次数,当调用次数很多或可用空间不足时
|
*
|
||||||
// 触发细胞合并。
|
* 统计从上次细胞合并以来free的调用次数,当调用次数达到`RAW_ALLOCATOR_FREE_MAX`或无可用空间时触发细胞合并。
|
||||||
|
*
|
||||||
|
* 使用建议:只在少量allocate和free的情况下使用。使用大量allocate时效率低下并难以得到内存安全保证。
|
||||||
|
*
|
||||||
|
* @internal free_count
|
||||||
|
*
|
||||||
|
* free方法的调用次数,达到`RAW_ALLOCATOR_FREE_MAX`时归零。
|
||||||
|
*/
|
||||||
typedef struct __raw_allocator_t
|
typedef struct __raw_allocator_t
|
||||||
{
|
{
|
||||||
usize size;
|
usize size;
|
||||||
|
@ -34,9 +39,23 @@ typedef struct __raw_allocator_t
|
||||||
} raw_allocator_t;
|
} raw_allocator_t;
|
||||||
#define raw_allocator_end(allocator) ((void *)(allocator) + (allocator)->size)
|
#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);
|
void raw_allocator_new(raw_allocator_t *allocator, usize size);
|
||||||
|
|
||||||
void *raw_allocator_allocate(raw_allocator_t *allocator, usize size, usize align);
|
/**
|
||||||
|
* @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);
|
void raw_allocator_free(raw_allocator_t *allocator, void *mem);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef SYSCALL_H
|
||||||
|
#define SYSCALL_H 1
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#include <kernel/arch/x86_64/syscall.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name syscall_init
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* void syscall_init();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 初始化系统调用。
|
||||||
|
*/
|
||||||
|
void syscall_init();
|
||||||
|
|
||||||
|
#endif
|
|
@ -99,8 +99,8 @@ tty **tty_get(usize id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 获取tty的id
|
* @brief 获取tty的id
|
||||||
*
|
*
|
||||||
* @return usize
|
* @return usize
|
||||||
*/
|
*/
|
||||||
usize tty_get_id(tty *__tty);
|
usize tty_get_id(tty *__tty);
|
||||||
|
|
||||||
|
@ -121,6 +121,16 @@ void tty_set_framebuffer(tty *ttyx, framebuffer *fb);
|
||||||
void tty_text_print(tty *ttyx, char *string, u32 color, u32 bgcolor);
|
void tty_text_print(tty *ttyx, char *string, u32 color, u32 bgcolor);
|
||||||
|
|
||||||
#define gen_color(r, g, b) (((r) << 16) | ((g) << 8) | (b))
|
#define gen_color(r, g, b) (((r) << 16) | ((g) << 8) | (b))
|
||||||
|
#define WHITE gen_color(0xee, 0xee, 0xee)
|
||||||
|
#define BLACK gen_color(0, 0, 0)
|
||||||
|
#define RED gen_color(0xee, 0x22, 0x22)
|
||||||
|
#define GREEN gen_color(0x22, 0xee, 0x22)
|
||||||
|
#define BLUE gen_color(0x22, 0x22, 0xee)
|
||||||
|
#define YELLOW gen_color(0xee, 0xee, 0x22)
|
||||||
|
#define ORANGE gen_color(0xee, 0xaa, 0x22)
|
||||||
|
#define PURPLE gen_color(0xee, 0, 0xee)
|
||||||
|
#define PINK gen_color(0xee, 0x44, 0x66)
|
||||||
|
#define GRAY gen_color(0xaa, 0xaa, 0xaa)
|
||||||
|
|
||||||
usize tty_get_width(tty *ttyx);
|
usize tty_get_width(tty *ttyx);
|
||||||
usize tty_get_height(tty *ttyx);
|
usize tty_get_height(tty *ttyx);
|
||||||
|
@ -132,8 +142,8 @@ bool tty_is_enabled(tty *ttyx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 打开某个tty
|
* @brief 打开某个tty
|
||||||
*
|
*
|
||||||
* @param ttyx
|
* @param ttyx
|
||||||
* @return true 打开成功
|
* @return true 打开成功
|
||||||
* @return false 已经打开
|
* @return false 已经打开
|
||||||
* 或作为raw_framebuffer类型的tty,framebuffer已被其它raw_framebuffer
|
* 或作为raw_framebuffer类型的tty,framebuffer已被其它raw_framebuffer
|
||||||
|
|
|
@ -33,7 +33,7 @@ bool lst_remove(lst_iterator_t *lst, usize left, usize right, bool force);
|
||||||
/*
|
/*
|
||||||
在`lst`中添加一个线段[left,right)
|
在`lst`中添加一个线段[left,right)
|
||||||
force=true时忽略已经存在于`lst`中的线段
|
force=true时忽略已经存在于`lst`中的线段
|
||||||
force=false时若有存在于`lst`中的线段,只添加这些部分之外的线段,返回false,否则返回true
|
force=false时若有存在于`lst`中的线段,不添加任何线段,返回false,否则返回true
|
||||||
*/
|
*/
|
||||||
bool lst_add(lst_iterator_t *lst, usize left, usize right, bool force);
|
bool lst_add(lst_iterator_t *lst, usize left, usize right, bool force);
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,25 @@
|
||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
#define UTILS_BIT_GET(byte, bit) ((byte) & (1 << (bit)))
|
|
||||||
#define UTILS_BIT_SET(byte, bit) ((byte) |= (1 << (bit)));
|
|
||||||
#define UTILS_BIT_RESET(byte, bit) ((byte) &= ~(1 << (bit)));
|
|
||||||
|
|
||||||
#define UTILS_BITMAP_GET(map, bit) (((u8 *)(map))[bit / 8] & (1 << ((bit) % 8)))
|
|
||||||
#define UTILS_BITMAP_SET(map, bit) (((u8 *)(map))[bit / 8] |= (1 << ((bit) % 8)));
|
|
||||||
#define UTILS_BITMAP_RESET(map, bit) (((u8 *)(map))[bit / 8] &= ~(1 << ((bit) % 8)));
|
|
||||||
|
|
||||||
#define DISALIGNED __attribute__((packed))
|
#define DISALIGNED __attribute__((packed))
|
||||||
|
|
||||||
|
#define into_bytes(addr) ((u8 *)(addr))
|
||||||
|
#define bytes_into(bytes, type) ((type *)(bytes))
|
||||||
|
|
||||||
|
void pointer_to_string(u64 addr, char *dest);
|
||||||
|
|
||||||
|
typedef struct __va_args
|
||||||
|
{
|
||||||
|
usize length;
|
||||||
|
void *args[0];
|
||||||
|
} va_args;
|
||||||
|
|
||||||
|
#define va_args_gen(result, length) \
|
||||||
|
void *__reserved__[length]; \
|
||||||
|
va_args __va_args__; \
|
||||||
|
result = &__va_args__;
|
||||||
|
|
||||||
|
#define va_args_set(vaargs, index, val) \
|
||||||
|
vaargs->args[index] = &val;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "stable"
|
2
rustlib
2
rustlib
|
@ -1 +1 @@
|
||||||
Subproject commit 087c4795bbc23cd0baee060bda8c1159a971a542
|
Subproject commit 6a2ca2afcd651e46f1c19f8d8a3f685fd982d824
|
|
@ -49,15 +49,17 @@ for mod in kernel_modules:
|
||||||
print(" " + color['lpink'] + f"{mod}" + color['reset'] + " exists.")
|
print(" " + color['lpink'] + f"{mod}" + color['reset'] + " exists.")
|
||||||
else:
|
else:
|
||||||
print(" " + color['lred'] + f"{mod}" + color['reset'] + " not found.")
|
print(" " + color['lred'] + f"{mod}" + color['reset'] + " not found.")
|
||||||
print("Kernel module " +
|
print(
|
||||||
color['lred'] + f"{mod}" + color['reset'] + " is not installed.")
|
"Kernel module " +
|
||||||
|
color['lred'] + f"{mod}" + color['reset'] + " is not installed.")
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
# 检查软件依赖
|
# 检查软件依赖
|
||||||
pathsenv = os.environ.get("PATH").split(":")
|
pathsenv = os.environ.get("PATH").split(":")
|
||||||
for software, progs in softwares.items():
|
for software, progs in softwares.items():
|
||||||
print("Checking " + color['lcyan'] +
|
print(
|
||||||
f"{software}" + color['reset'] + " ...")
|
"Checking " + color['lcyan'] +
|
||||||
|
f"{software}" + color['reset'] + " ...")
|
||||||
for program in progs:
|
for program in progs:
|
||||||
exists = False
|
exists = False
|
||||||
for path in pathsenv:
|
for path in pathsenv:
|
||||||
|
@ -65,15 +67,19 @@ for software, progs in softwares.items():
|
||||||
exists = True
|
exists = True
|
||||||
break
|
break
|
||||||
if exists:
|
if exists:
|
||||||
print(" " + color['lyellow'] +
|
print(
|
||||||
f"{program}" + color['reset'] + " existed.")
|
" " + color['lyellow'] +
|
||||||
|
f"{program}" + color['reset'] + " existed.")
|
||||||
else:
|
else:
|
||||||
print(" " + color['lred'] +
|
print(
|
||||||
f"{program}" + color['reset'] + " not found.")
|
" " + color['lred'] +
|
||||||
|
f"{program}" + color['reset'] + " not found.")
|
||||||
|
|
||||||
print("Software " + color['lred'] + f"{software}" +
|
print(
|
||||||
color['reset'] + " is not installed or completed.")
|
"Software " + color['lred'] + f"{software}" +
|
||||||
|
color['reset'] + " is not installed or completed.")
|
||||||
exit(-2)
|
exit(-2)
|
||||||
|
|
||||||
print("All dependencies are " +
|
print(
|
||||||
color['lgreen'] + "satisfied." + color['reset'])
|
"All dependencies are " +
|
||||||
|
color['lgreen'] + "satisfied." + color['reset'])
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
curtime = str(int(time.time() * 1000))
|
||||||
|
|
||||||
|
print(curtime)
|
44
src/Makefile
44
src/Makefile
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
ARCH := $(shell uname -m)
|
ARCH := $(shell uname -m)
|
||||||
PWD := $(shell pwd)
|
PWD := $(shell pwd)
|
||||||
SOURCE := ${PWD}/scripts
|
SOURCE := ${PWD}/../scripts
|
||||||
ifeq (${ARCH},x86_64)
|
ifeq (${ARCH},x86_64)
|
||||||
ASM = nasm
|
ASM = nasm
|
||||||
ASMFLAGS = -f elf64
|
ASMFLAGS = -f elf64
|
||||||
|
@ -12,9 +12,14 @@ ifdef release
|
||||||
release = 1
|
release = 1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ALLOCATOR_MAGIC = $(shell "${SOURCE}/magicgen" | sha512sum | head -c 128 | md5sum | head -c 8)
|
||||||
|
|
||||||
|
BUILD_ID = $(shell "${SOURCE}/magicgen" | sha512sum | head -c 128 | md5sum | head -c 4)
|
||||||
|
|
||||||
SUBOBJS = kernel/kernel.o libk/libk.o rust.o
|
SUBOBJS = kernel/kernel.o libk/libk.o rust.o
|
||||||
|
|
||||||
DEFINES = ARCH="${ARCH}" ASM="${ASM}" ASMFLAGS="${ASMFLAGS}" SOURCE="${SOURCE}" PWD="${PWD}"
|
DEFINES = ARCH="${ARCH}" ASM="${ASM}" ASMFLAGS="${ASMFLAGS}" SOURCE="${SOURCE}" PWD="${PWD}" \
|
||||||
|
ALLOCATOR_MAGIC="${ALLOCATOR_MAGIC}" BUILD_ID="${BUILD_ID}"
|
||||||
ifdef release
|
ifdef release
|
||||||
DEFINES := ${DEFINES} release=1
|
DEFINES := ${DEFINES} release=1
|
||||||
endif
|
endif
|
||||||
|
@ -25,24 +30,21 @@ endif
|
||||||
RSCFLAGS = --emit obj --crate-type staticlib --verbose \
|
RSCFLAGS = --emit obj --crate-type staticlib --verbose \
|
||||||
--crate-name=metaverse \
|
--crate-name=metaverse \
|
||||||
--edition 2021 \
|
--edition 2021 \
|
||||||
-L crate="${PWD}/../rustlib/${ARCH}/src/" \
|
-L crate="${PWD}/../rustlib/src/" \
|
||||||
-C code-model=large \
|
-C code-model=large \
|
||||||
-C relocation-model=static \
|
-C relocation-model=static \
|
||||||
-C embed-bitcode=no
|
-C embed-bitcode=no
|
||||||
|
|
||||||
ifeq (${ARCH},x86_64)
|
ifeq (${ARCH},x86_64)
|
||||||
RSCFLAGS := ${RSCFLAGS} --target x86_64-unknown-none
|
RSCFLAGS := ${RSCFLAGS} --target x86_64-unknown-none
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef release
|
|
||||||
RSCFLAGS := -O
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq (${ARCH},x86_64)
|
|
||||||
RSCFLAGS := ${RSCFLAGS} -C target-feature=-sse
|
RSCFLAGS := ${RSCFLAGS} -C target-feature=-sse
|
||||||
endif
|
endif
|
||||||
|
|
||||||
RUSTLIB_PATH = ../rustlib/${ARCH}/lib
|
ifdef release
|
||||||
|
RSCFLAGS := ${RSCFLAGS} -O
|
||||||
|
endif
|
||||||
|
|
||||||
|
RUSTLIB_PATH = ../rustlib/${ARCH}
|
||||||
RUST_LIBS = "${RUSTLIB_PATH}/liballoc.rlib" "${RUSTLIB_PATH}/libcompiler_builtins.rlib" \
|
RUST_LIBS = "${RUSTLIB_PATH}/liballoc.rlib" "${RUSTLIB_PATH}/libcompiler_builtins.rlib" \
|
||||||
"${RUSTLIB_PATH}/libcore.rlib" "${RUSTLIB_PATH}/librustc_std_workspace_core.rlib"
|
"${RUSTLIB_PATH}/libcore.rlib" "${RUSTLIB_PATH}/librustc_std_workspace_core.rlib"
|
||||||
|
|
||||||
|
@ -56,6 +58,8 @@ metaverse.elf: kernel libk rust metaverse.lds
|
||||||
.PHONY: kernel libk all clear postproc rust
|
.PHONY: kernel libk all clear postproc rust
|
||||||
|
|
||||||
all: postproc metaverse.elf
|
all: postproc metaverse.elf
|
||||||
|
@echo -e "Build \e[1;32msucceeded\e[0m."
|
||||||
|
@echo -e "Build ID \e[1;31m${BUILD_ID}\e[0m."
|
||||||
|
|
||||||
postproc:
|
postproc:
|
||||||
@echo -n -e "\e[36m"
|
@echo -n -e "\e[36m"
|
||||||
|
@ -67,16 +71,24 @@ postproc:
|
||||||
@echo -e "\e[0m"
|
@echo -e "\e[0m"
|
||||||
|
|
||||||
kernel:
|
kernel:
|
||||||
@echo -e "\e[33m__\e[0m \e[1;35m[Building kernel]\e[0m \e[33m____\e[0m"
|
@if [ ! ${release} ]; then \
|
||||||
|
echo -e "\e[33m__\e[0m \e[1;35m[Building kernel]\e[0m \e[33m____\e[0m"; \
|
||||||
|
fi
|
||||||
@make -C kernel all --no-print-directory ${DEFINES}
|
@make -C kernel all --no-print-directory ${DEFINES}
|
||||||
@echo -e "\e[33m-------------------------\e[0m"
|
@if [ ! ${release} ]; then \
|
||||||
|
echo -e "\e[33m-------------------------\e[0m"; \
|
||||||
|
fi
|
||||||
|
|
||||||
libk:
|
libk:
|
||||||
@echo -e "\e[33m__\e[0m \e[1;35m[Building libk]\e[0m \e[33m______\e[0m"
|
@if [ ! ${release} ]; then \
|
||||||
|
echo -e "\e[33m__\e[0m \e[1;35m[Building libk]\e[0m \e[33m______\e[0m"; \
|
||||||
|
fi
|
||||||
@make -C libk all --no-print-directory ${DEFINES}
|
@make -C libk all --no-print-directory ${DEFINES}
|
||||||
@echo -e "\e[33m-------------------------\e[0m"
|
@if [ ! ${release} ]; then \
|
||||||
|
echo -e "\e[33m-------------------------\e[0m"; \
|
||||||
|
fi
|
||||||
|
|
||||||
rust:
|
rust: postproc
|
||||||
@echo -e "\e[1m\e[33mrustc\e[0m \e[34m-->\e[0m \e[1m\e[32m$@.o\e[0m"
|
@echo -e "\e[1m\e[33mrustc\e[0m \e[34m-->\e[0m \e[1m\e[32m$@.o\e[0m"
|
||||||
@rustc ${RSCFLAGS} lib.rs -o rust.o
|
@rustc ${RSCFLAGS} lib.rs -o rust.o
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,15 @@
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CCFLAGS = -m64 -mcmodel=large -I ../../include \
|
CCFLAGS = -m64 -mcmodel=large -I ../../include \
|
||||||
-fno-stack-protector -fno-exceptions \
|
-fno-stack-protector -fno-exceptions \
|
||||||
-fno-builtin -nostdinc -nostdlib
|
-fno-builtin -nostdinc -nostdlib \
|
||||||
|
-DMEMM_ALLOCATOR_MAGIC="(u32)(0x${ALLOCATOR_MAGIC})" \
|
||||||
|
-DBUILD_ID="${BUILD_ID}"
|
||||||
ifdef release
|
ifdef release
|
||||||
CCFLAGS := ${CCFLAGS} -O2
|
CCFLAGS := ${CCFLAGS} -O2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
C_SRCS = main.c tty.c font.c memm.c memm_${ARCH}.c raw.c time.c
|
C_SRCS = main.c tty.c font.c memm.c memm_${ARCH}.c raw.c time.c syscall_${ARCH}.c interrupt_${ARCH}.c \
|
||||||
|
interrupt_procs.c
|
||||||
C_OBJS = ${C_SRCS:.c=.c.o}
|
C_OBJS = ${C_SRCS:.c=.c.o}
|
||||||
|
|
||||||
################################
|
################################
|
||||||
|
@ -26,7 +29,8 @@ endif
|
||||||
ASMFLAGS := ${ASMFLAGS}
|
ASMFLAGS := ${ASMFLAGS}
|
||||||
ASMFLAGS32 = -f elf32
|
ASMFLAGS32 = -f elf32
|
||||||
|
|
||||||
S_SRCS = entry32.s entry.s memm_${ARCH}.s kernel.s
|
S_SRCS = entry32.s entry.s memm_${ARCH}.s kernel.s syscall_${ARCH}.s interrupt_${ARCH}.s \
|
||||||
|
interrupt_procs.s
|
||||||
S_OBJS = ${S_SRCS:.s=.s.o}
|
S_OBJS = ${S_SRCS:.s=.s.o}
|
||||||
|
|
||||||
################################
|
################################
|
||||||
|
|
|
@ -1,13 +1,32 @@
|
||||||
section .entry align=8
|
section .entry align=8
|
||||||
extern kmain
|
extern kmain
|
||||||
|
extern systemcall_procedure
|
||||||
global init64
|
global init64
|
||||||
init64:
|
init64:
|
||||||
endbr64
|
endbr64
|
||||||
cli
|
cli
|
||||||
|
|
||||||
mov rax, 0x1000000
|
mov rax, 0x1000000
|
||||||
mov rbp, rax
|
mov rbp, rax
|
||||||
mov rsp, rax
|
mov rsp, rax
|
||||||
mov rdi, rbx
|
mov rdi, rbx
|
||||||
|
|
||||||
|
lidt [0x104010]
|
||||||
|
|
||||||
|
; 加载系统调用相关寄存器
|
||||||
|
; IA32_STAR = 0x0018_0008_0000_0000
|
||||||
|
mov rcx, 0xc0000081
|
||||||
|
mov rax, 0x0018000800000000
|
||||||
|
wrmsr
|
||||||
|
; IA32_FMASK = 0xffff_ffff
|
||||||
|
inc rcx
|
||||||
|
mov rax, 0xffffffff
|
||||||
|
wrmsr
|
||||||
|
; IA32_LSTAR = [systemcall_procedure]
|
||||||
|
lea rcx, [rcx + 2]
|
||||||
|
lea rax, [systemcall_procedure]
|
||||||
|
wrmsr
|
||||||
|
|
||||||
jmp kmain
|
jmp kmain
|
||||||
|
|
||||||
section .multiboot2 align=8
|
section .multiboot2 align=8
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
section .entry
|
section .entry
|
||||||
extern init64
|
extern init64
|
||||||
; 寄存器ebx是multiboot2 information,不可以使用
|
; 寄存器ebx是multiboot2 information,不可以使用
|
||||||
;
|
|
||||||
; 由于这个代码是32位环境的代码,而链接器链接时会把它当作64位代码链接
|
|
||||||
; 所以这里所有的使用了常数的位置都要通过指令写入
|
|
||||||
init32:
|
init32:
|
||||||
cli
|
cli
|
||||||
|
|
||||||
|
@ -37,18 +34,17 @@ init32:
|
||||||
add edi, 4
|
add edi, 4
|
||||||
loop init32_loop0
|
loop init32_loop0
|
||||||
|
|
||||||
; 设置gdt_ptr
|
; 加载GDTR、段寄存器和TR寄存器
|
||||||
mov eax, 0x10402a ; gdt_ptr + 2
|
|
||||||
mov dword [eax], 0x104000 ; gdt
|
|
||||||
; 加载GDTR和段寄存器
|
|
||||||
db 0x66
|
db 0x66
|
||||||
lgdt [0x104028] ; gdt_ptr
|
lgdt [0x104000] ; gdt_ptr
|
||||||
mov ax, 0x10
|
mov ax, 0x10
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
|
mov ax, 0x30
|
||||||
|
ltr ax
|
||||||
|
|
||||||
; 打开PAE
|
; 打开PAE
|
||||||
mov eax, cr4
|
mov eax, cr4
|
||||||
|
@ -77,7 +73,6 @@ init32:
|
||||||
section .cpumeta align=4096
|
section .cpumeta align=4096
|
||||||
global PML4
|
global PML4
|
||||||
; 分页
|
; 分页
|
||||||
; 链接器会把这些数据替换掉所以要在代码中重新设置
|
|
||||||
PML4:
|
PML4:
|
||||||
dq 0x003 + PDPT0
|
dq 0x003 + PDPT0
|
||||||
resq 511
|
resq 511
|
||||||
|
@ -89,15 +84,43 @@ PDPT0:
|
||||||
PD0:
|
PD0:
|
||||||
resq 512
|
resq 512
|
||||||
|
|
||||||
; 分段
|
section .cpumeta.tblptrs
|
||||||
gdt:
|
|
||||||
dq 0
|
|
||||||
dq 0x0020980000000000 ; 内核态代码段
|
|
||||||
dq 0x0000920000000000 ; 内核态数据段
|
|
||||||
dq 0x0020f80000000000 ; 用户态代码段
|
|
||||||
dq 0x0000f20000000000 ; 用户态数据段
|
|
||||||
gdt_end:
|
|
||||||
|
|
||||||
gdt_ptr:
|
gdt_ptr: ; 0x104000
|
||||||
dw gdt_end - gdt - 1
|
dw gdt_end - gdt - 1
|
||||||
dq gdt
|
dq gdt
|
||||||
|
|
||||||
|
dd 0
|
||||||
|
dw 0
|
||||||
|
|
||||||
|
idt_ptr: ; 0x104010
|
||||||
|
dw 0x7ff
|
||||||
|
dq idt
|
||||||
|
|
||||||
|
section .cpumeta.gdt align=4096
|
||||||
|
gdt:
|
||||||
|
dq 0
|
||||||
|
dq 0x0020980000000000 ; 内核态代码段
|
||||||
|
dq 0x0000920000000000 ; 内核态数据段
|
||||||
|
dq 0x0020f80000000000 ; 用户态代码段
|
||||||
|
dq 0x0000f20000000000 ; 用户态数据段
|
||||||
|
dq 0
|
||||||
|
dq 0x0000891070000068 ; TSS段(低64位)
|
||||||
|
dq 0 ; TSS段(高64位)
|
||||||
|
gdt_end:
|
||||||
|
|
||||||
|
section .cpumeta.idt align=4096
|
||||||
|
global idt
|
||||||
|
idt:
|
||||||
|
resq 512 ; 16 bytes per descriptor (512 q-bytes)
|
||||||
|
|
||||||
|
section .cpumeta.tss align=4096
|
||||||
|
global TSS
|
||||||
|
TSS:
|
||||||
|
dd 0
|
||||||
|
dq 0x1000000 ; (rsp0)内核栈
|
||||||
|
dq 0 ; (rsp1)
|
||||||
|
dq 0 ; (rsp2)
|
||||||
|
dq 0
|
||||||
|
dq 0x400000 ; (ist1)中断栈
|
||||||
|
resb 104 - ($ - TSS)
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
%macro store_regs 0
|
||||||
|
push rax
|
||||||
|
push rcx
|
||||||
|
push rbx
|
||||||
|
push rdx
|
||||||
|
push rsi
|
||||||
|
push rdi
|
||||||
|
push r8
|
||||||
|
push r9
|
||||||
|
push r10
|
||||||
|
push r11
|
||||||
|
push r12
|
||||||
|
push r13
|
||||||
|
push r14
|
||||||
|
push r15
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro retrieve_regs 0
|
||||||
|
pop r15
|
||||||
|
pop r14
|
||||||
|
pop r13
|
||||||
|
pop r12
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
pop rdi
|
||||||
|
pop rsi
|
||||||
|
pop rdx
|
||||||
|
pop rbx
|
||||||
|
pop rcx
|
||||||
|
pop rax
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro switch_section 0
|
||||||
|
sub rsp, 4
|
||||||
|
mov ax, ds
|
||||||
|
push ax
|
||||||
|
mov ax, es
|
||||||
|
push ax
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro retrieve_section 0
|
||||||
|
pop ax
|
||||||
|
mov es, ax
|
||||||
|
pop ax
|
||||||
|
mov ds, ax
|
||||||
|
add rsp, 4
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro interrupt_entry_enter 0
|
||||||
|
push rbp
|
||||||
|
lea rbp, [rsp]
|
||||||
|
store_regs
|
||||||
|
switch_section
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro interrupt_entry_leave 0
|
||||||
|
retrieve_section
|
||||||
|
retrieve_regs
|
||||||
|
leave
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; 用于带有错误码的中断,创建一个没有错误码的上下文拷贝
|
||||||
|
%macro interrupt_stack_wrap_texture 0
|
||||||
|
extern memcpy
|
||||||
|
sub rsp, 21 * 8
|
||||||
|
mov rdi, rsp
|
||||||
|
lea rsi, [rsp + 21 * 8]
|
||||||
|
mov rdx, 16 * 8
|
||||||
|
call memcpy
|
||||||
|
lea rdi, [rsp + 16 * 8]
|
||||||
|
lea rsi, [rsp + 38 * 8]
|
||||||
|
mov rdx, 5 * 8
|
||||||
|
call memcpy
|
||||||
|
%endmacro
|
|
@ -0,0 +1,190 @@
|
||||||
|
#include <kernel/arch/x86_64/interrupt_procs.h>
|
||||||
|
#include <kernel/arch/x86_64/memm.h>
|
||||||
|
#include <kernel/arch/x86_64/proc.h>
|
||||||
|
#include <kernel/kernel.h>
|
||||||
|
#include <kernel/tty.h>
|
||||||
|
#include <libk/string.h>
|
||||||
|
|
||||||
|
interrupt_req_gen(UNSUPPORTED)
|
||||||
|
{
|
||||||
|
tty **tty0_option = tty_get(0);
|
||||||
|
if (tty0_option == nullptr)
|
||||||
|
{
|
||||||
|
KERNEL_TODO();
|
||||||
|
}
|
||||||
|
tty *tty0 = *tty0_option;
|
||||||
|
tty_text_print(tty0, "Panic: Unsupported interrupt.", RED, BLACK);
|
||||||
|
KERNEL_TODO();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rip_not_cannonical(u64 rip, tty *tty0)
|
||||||
|
{
|
||||||
|
char num[17];
|
||||||
|
memset(num, 0, sizeof(num));
|
||||||
|
pointer_to_string(rip, num);
|
||||||
|
tty_text_print(tty0, "Panic", RED, BLACK);
|
||||||
|
tty_text_print(tty0, ": Unexpected non-cannonical %rip value ", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, num, ORANGE, BLACK);
|
||||||
|
tty_text_print(tty0, ".\n", WHITE, BLACK);
|
||||||
|
KERNEL_TODO();
|
||||||
|
}
|
||||||
|
|
||||||
|
interrupt_req_gen(DE)
|
||||||
|
{
|
||||||
|
tty **tty0_option = tty_get(0);
|
||||||
|
if (tty0_option == nullptr)
|
||||||
|
{
|
||||||
|
KERNEL_TODO();
|
||||||
|
}
|
||||||
|
tty *tty0 = *tty0_option;
|
||||||
|
if (!is_cannonical(rip))
|
||||||
|
{
|
||||||
|
rip_not_cannonical(rip, tty0);
|
||||||
|
}
|
||||||
|
if (!is_user_address(rip))
|
||||||
|
{
|
||||||
|
char nums[34];
|
||||||
|
memset(nums, 0, sizeof(nums));
|
||||||
|
pointer_to_string(rip, nums);
|
||||||
|
pointer_to_string(rsp, nums + 17);
|
||||||
|
tty_text_print(tty0, "Panic", RED, BLACK);
|
||||||
|
tty_text_print(tty0, ": Divided by zero occurs in kernel,\n\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, "with %rip=", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, "0x", ORANGE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, ORANGE, BLACK);
|
||||||
|
tty_text_print(tty0, ", %rsp=", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, "0x", ORANGE, BLACK);
|
||||||
|
tty_text_print(tty0, nums + 17, ORANGE, BLACK);
|
||||||
|
tty_text_print(tty0, ".\n", WHITE, BLACK);
|
||||||
|
KERNEL_TODO();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // TODO 转储并结束进程
|
||||||
|
KERNEL_TODO();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interrupt_req_gen(BP)
|
||||||
|
{
|
||||||
|
tty **tty0_option = tty_get(0);
|
||||||
|
if (tty0_option == nullptr)
|
||||||
|
{
|
||||||
|
KERNEL_TODO();
|
||||||
|
}
|
||||||
|
tty *tty0 = *tty0_option;
|
||||||
|
if (!is_cannonical(rip))
|
||||||
|
{
|
||||||
|
rip_not_cannonical(rip, tty0);
|
||||||
|
}
|
||||||
|
proc_texture_registers_t *texture = (void *)errcode;
|
||||||
|
if (!is_user_address(rip))
|
||||||
|
{
|
||||||
|
char nums[34];
|
||||||
|
memset(nums, 0, sizeof(nums));
|
||||||
|
pointer_to_string(rip, nums);
|
||||||
|
pointer_to_string(rsp, nums + 17);
|
||||||
|
tty_text_print(tty0, "Debug", PURPLE, BLACK);
|
||||||
|
tty_text_print(tty0, ": Kernel hit a breakpoint,\n\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, "with %rip=", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, "0x", ORANGE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, ORANGE, BLACK);
|
||||||
|
tty_text_print(tty0, ", %rsp=", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, "0x", ORANGE, BLACK);
|
||||||
|
tty_text_print(tty0, nums + 17, ORANGE, BLACK);
|
||||||
|
tty_text_print(tty0, ",\n\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, "on texture: \n", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->rax, nums);
|
||||||
|
tty_text_print(tty0, "rax\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\t", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->rcx, nums);
|
||||||
|
tty_text_print(tty0, "rcx\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\n", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->rbx, nums);
|
||||||
|
tty_text_print(tty0, "rbx\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\t", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->rdx, nums);
|
||||||
|
tty_text_print(tty0, "rdx\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\n", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->rsi, nums);
|
||||||
|
tty_text_print(tty0, "rsi\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\t", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->rdi, nums);
|
||||||
|
tty_text_print(tty0, "rdi\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\n", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->rbp, nums);
|
||||||
|
tty_text_print(tty0, "rbp\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\t", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->rsp, nums);
|
||||||
|
tty_text_print(tty0, "rsp\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\n", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->rip, nums);
|
||||||
|
tty_text_print(tty0, "rip\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\t", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->rflags, nums);
|
||||||
|
tty_text_print(tty0, "rflags\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\n", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->r8, nums);
|
||||||
|
tty_text_print(tty0, "r8\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\t", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->r9, nums);
|
||||||
|
tty_text_print(tty0, "r9\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\n", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->r10, nums);
|
||||||
|
tty_text_print(tty0, "r10\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\t", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->r11, nums);
|
||||||
|
tty_text_print(tty0, "r11\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\n", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->r12, nums);
|
||||||
|
tty_text_print(tty0, "r12\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\t", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->r13, nums);
|
||||||
|
tty_text_print(tty0, "r13\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\n", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->r14, nums);
|
||||||
|
tty_text_print(tty0, "r14\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\t", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->r15, nums);
|
||||||
|
tty_text_print(tty0, "r15\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\n", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->cs, nums);
|
||||||
|
tty_text_print(tty0, "cs\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\t", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->ss, nums);
|
||||||
|
tty_text_print(tty0, "ss\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\n", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->ds, nums);
|
||||||
|
tty_text_print(tty0, "ds\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\t", WHITE, BLACK);
|
||||||
|
pointer_to_string(texture->es, nums);
|
||||||
|
tty_text_print(tty0, "es\t", WHITE, BLACK);
|
||||||
|
tty_text_print(tty0, nums, BLUE, BLACK);
|
||||||
|
tty_text_print(tty0, "\n", WHITE, BLACK);
|
||||||
|
KERNEL_TODO();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // TODO 将当前进程的状态设置为暂停并通知当前进程的调试程序
|
||||||
|
KERNEL_TODO();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
%include "arch/x86_64/interrupt.in"
|
||||||
|
|
||||||
|
; 栈中的寄存器上下文
|
||||||
|
; +------------
|
||||||
|
; | ss
|
||||||
|
; +------------<-- rsp+168(+160)
|
||||||
|
; | rsp
|
||||||
|
; +------------<-- rsp+160(+152)
|
||||||
|
; | rflags
|
||||||
|
; +------------<-- rsp+152(+144)
|
||||||
|
; | cs
|
||||||
|
; +------------<-- rsp+144(+136)
|
||||||
|
; | rip
|
||||||
|
; +------------<-- rsp+136(+128)
|
||||||
|
; | (err code)
|
||||||
|
; +------------<-- rsp+128
|
||||||
|
; | rbp
|
||||||
|
; +------------<-- rsp+120
|
||||||
|
; | rax
|
||||||
|
; +------------<-- rsp+112
|
||||||
|
; | rcx
|
||||||
|
; +------------<-- rsp+104
|
||||||
|
; | rbx
|
||||||
|
; +------------<-- rsp+96
|
||||||
|
; | rdx
|
||||||
|
; +------------<-- rsp+88
|
||||||
|
; | rsi
|
||||||
|
; +------------<-- rsp+80
|
||||||
|
; | rdi
|
||||||
|
; +------------<-- rsp+72
|
||||||
|
; | r8
|
||||||
|
; +------------<-- rsp+64
|
||||||
|
; | r9
|
||||||
|
; +------------<-- rsp+56
|
||||||
|
; | r10
|
||||||
|
; +------------<-- rsp+48
|
||||||
|
; | r11
|
||||||
|
; +------------<-- rsp+40
|
||||||
|
; | r12
|
||||||
|
; +------------<-- rsp+32
|
||||||
|
; | r13
|
||||||
|
; +------------<-- rsp+24
|
||||||
|
; | r14
|
||||||
|
; +------------<-- rsp+16
|
||||||
|
; | r15
|
||||||
|
; +------------<-- rsp+8
|
||||||
|
; | reserved
|
||||||
|
; +------------<-- rsp+4
|
||||||
|
; | ds
|
||||||
|
; +------------<-- rsp+2
|
||||||
|
; | es
|
||||||
|
; +------------<-- rsp+0
|
||||||
|
|
||||||
|
section .text
|
||||||
|
|
||||||
|
global interrupt_entry_UNSUPPORTED
|
||||||
|
extern interrupt_req_UNSUPPORTED
|
||||||
|
interrupt_entry_UNSUPPORTED:
|
||||||
|
interrupt_entry_enter
|
||||||
|
|
||||||
|
mov rdi, [rsp + 128]
|
||||||
|
mov rsi, [rsp + 152]
|
||||||
|
call interrupt_req_UNSUPPORTED
|
||||||
|
|
||||||
|
interrupt_entry_leave
|
||||||
|
iret
|
||||||
|
|
||||||
|
global interrupt_entry_DE
|
||||||
|
extern interrupt_req_DE
|
||||||
|
interrupt_entry_DE:
|
||||||
|
interrupt_entry_enter
|
||||||
|
|
||||||
|
mov rdi, [rsp + 128]
|
||||||
|
mov rsi, [rsp + 152]
|
||||||
|
call interrupt_req_DE
|
||||||
|
|
||||||
|
interrupt_entry_leave
|
||||||
|
iret
|
||||||
|
|
||||||
|
global interrupt_entry_DE
|
||||||
|
interrupt_entry_NMI:
|
||||||
|
; TODO 暂时不需要为这个中断实现任何功能
|
||||||
|
iret
|
||||||
|
|
||||||
|
global interrupt_entry_BP
|
||||||
|
extern interrupt_req_BP
|
||||||
|
interrupt_entry_BP:
|
||||||
|
interrupt_entry_enter
|
||||||
|
|
||||||
|
mov rdi, [rsp + 128]
|
||||||
|
mov rsi, [rsp + 152]
|
||||||
|
mov dword [rsp + 4], 0
|
||||||
|
mov rdx, rsp
|
||||||
|
call interrupt_req_BP
|
||||||
|
|
||||||
|
interrupt_entry_leave
|
||||||
|
iret
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include <kernel/interrupt.h>
|
||||||
|
#include <utils.h>
|
||||||
|
|
||||||
|
#include <kernel/arch/x86_64/interrupt_procs.h>
|
||||||
|
|
||||||
|
void interrupt_init()
|
||||||
|
{
|
||||||
|
gate_descriptor_t gate;
|
||||||
|
trap_gate_generate(gate, interrupt_entry_sym(UNSUPPORTED));
|
||||||
|
for (usize i = 4; i < 256; i++)
|
||||||
|
{
|
||||||
|
interrupt_register_gate(gate, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
trap_gate_generate(gate, interrupt_entry_sym(DE));
|
||||||
|
interrupt_register_gate(gate, 0);
|
||||||
|
trap_gate_generate(gate, interrupt_entry_sym(UNSUPPORTED));
|
||||||
|
interrupt_register_gate(gate, 1);
|
||||||
|
trap_gate_generate(gate, interrupt_entry_sym(NMI));
|
||||||
|
interrupt_register_gate(gate, 2);
|
||||||
|
trap_gate_generate(gate, interrupt_entry_sym(BP));
|
||||||
|
interrupt_register_gate(gate, 3);
|
||||||
|
|
||||||
|
interrupt_open();
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
section .text
|
||||||
|
|
||||||
|
global interrupt_open
|
||||||
|
interrupt_open:
|
||||||
|
sti
|
||||||
|
ret
|
||||||
|
|
||||||
|
global interrupt_close
|
||||||
|
interrupt_close:
|
||||||
|
cli
|
||||||
|
ret
|
|
@ -9,8 +9,9 @@
|
||||||
map_pageframe_to((u64)addr, (u64)addr, false, true, MEMM_PAGE_SIZE_4K);
|
map_pageframe_to((u64)addr, (u64)addr, false, true, MEMM_PAGE_SIZE_4K);
|
||||||
|
|
||||||
// 这里的physical必须保证根据ps对齐
|
// 这里的physical必须保证根据ps对齐
|
||||||
static void map_pageframe_to(u64 target, u64 physical,
|
static void map_pageframe_to(
|
||||||
bool user, bool write, memm_page_size ps)
|
u64 target, u64 physical,
|
||||||
|
bool user, bool write, memm_page_size ps)
|
||||||
{
|
{
|
||||||
if (!is_cannonical(target))
|
if (!is_cannonical(target))
|
||||||
return;
|
return;
|
||||||
|
@ -22,7 +23,7 @@ static void map_pageframe_to(u64 target, u64 physical,
|
||||||
PDPT = (u64 *)memm_entry_get_address(pml4e);
|
PDPT = (u64 *)memm_entry_get_address(pml4e);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PDPT = (u64 *)(find_fitable_pages(1) * MEMM_PAGE_SIZE);
|
PDPT = memm_allcate_pagetable();
|
||||||
map_pagemap(PDPT);
|
map_pagemap(PDPT);
|
||||||
memset(PDPT, 0, MEMM_PAGE_SIZE);
|
memset(PDPT, 0, MEMM_PAGE_SIZE);
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@ static void map_pageframe_to(u64 target, u64 physical,
|
||||||
PDT = (u64 *)memm_entry_get_address(pdpte);
|
PDT = (u64 *)memm_entry_get_address(pdpte);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PDT = (u64 *)(find_fitable_pages(1) * MEMM_PAGE_SIZE);
|
PDT = memm_allcate_pagetable();
|
||||||
map_pagemap(PDT);
|
map_pagemap(PDT);
|
||||||
memset(PDT, 0, MEMM_PAGE_SIZE);
|
memset(PDT, 0, MEMM_PAGE_SIZE);
|
||||||
|
|
||||||
|
@ -78,7 +79,7 @@ static void map_pageframe_to(u64 target, u64 physical,
|
||||||
PT = (u64 *)memm_entry_get_address(pde);
|
PT = (u64 *)memm_entry_get_address(pde);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PT = (u64 *)(find_fitable_pages(1) * MEMM_PAGE_SIZE);
|
PT = memm_allcate_pagetable();
|
||||||
map_pagemap(PT);
|
map_pagemap(PT);
|
||||||
memset(PT, 0, MEMM_PAGE_SIZE);
|
memset(PT, 0, MEMM_PAGE_SIZE);
|
||||||
|
|
||||||
|
@ -110,7 +111,6 @@ bool memm_map_pageframes_to(
|
||||||
return false;
|
return false;
|
||||||
while (size != 0)
|
while (size != 0)
|
||||||
{
|
{
|
||||||
// 这是当前需要映射的页的内存对齐(或者说是当前映射的页的大小)
|
|
||||||
memm_page_size align = memm_get_page_align(physical);
|
memm_page_size align = memm_get_page_align(physical);
|
||||||
if (align == MEMM_PAGE_SIZE_1G)
|
if (align == MEMM_PAGE_SIZE_1G)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include <kernel/syscall.h>
|
||||||
|
|
||||||
|
#include <libk/string.h>
|
||||||
|
|
||||||
|
void syscall_init()
|
||||||
|
{
|
||||||
|
memset(&system_calls_table, 0, sizeof(system_calls_table));
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
section .data
|
||||||
|
global system_calls_table
|
||||||
|
system_calls_table:
|
||||||
|
resq 256
|
||||||
|
|
||||||
|
kernel_stack_cache:
|
||||||
|
dq 0, 0 ; 分别为 rbp, rsp
|
||||||
|
|
||||||
|
section .text
|
||||||
|
global systemcall_procedure
|
||||||
|
global save_kernel_stack
|
||||||
|
systemcall_procedure:
|
||||||
|
endbr64
|
||||||
|
call load_kernel_stack
|
||||||
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
|
||||||
|
shl rax, 3 ; rax *= 8
|
||||||
|
; 将对应调用号的系统调用加载至rax
|
||||||
|
lea rdi, [system_calls_table]
|
||||||
|
lea rax, [rax + rdi]
|
||||||
|
; 判断是否为空调用
|
||||||
|
cmp rax, 0
|
||||||
|
je systemcall_procedure_none_call
|
||||||
|
mov rax, [rax]
|
||||||
|
; 调用对应的系统调用
|
||||||
|
call rax
|
||||||
|
|
||||||
|
leave
|
||||||
|
call save_kernel_stack
|
||||||
|
sysret
|
||||||
|
|
||||||
|
systemcall_procedure_none_call:
|
||||||
|
; TODO 调用了不存在的系统调用,属于无法恢复的错误,应保存错误状态并结束调用进程
|
||||||
|
; 暂时直接sysret
|
||||||
|
leave
|
||||||
|
call save_kernel_stack
|
||||||
|
sysret
|
||||||
|
|
||||||
|
; void set_kernel_stack_cache(usize stack)
|
||||||
|
set_kernel_stack_cache:
|
||||||
|
endbr64
|
||||||
|
push rax
|
||||||
|
|
||||||
|
lea rax, [kernel_stack_cache]
|
||||||
|
mov [rax], rdi
|
||||||
|
lea rax, [rax + 8]
|
||||||
|
mov [rax], rdi
|
||||||
|
|
||||||
|
pop rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; void return_from_systemcall()
|
||||||
|
return_from_systemcall:
|
||||||
|
sysret
|
||||||
|
|
||||||
|
save_kernel_stack:
|
||||||
|
endbr64
|
||||||
|
lea rbx, [kernel_stack_cache]
|
||||||
|
; 交换[rbx]与rbp
|
||||||
|
mov rdi, [rbx]
|
||||||
|
xor rbp, rdi
|
||||||
|
xor rdi, rbp
|
||||||
|
xor rbp, rdi
|
||||||
|
mov [rbx], rdi
|
||||||
|
lea rbx, [rbx + 8]
|
||||||
|
; 交换[rbx]与rsp
|
||||||
|
mov rdi, [rbx]
|
||||||
|
xor rsp, rdi
|
||||||
|
xor rdi, rsp
|
||||||
|
xor rsp, rdi
|
||||||
|
mov [rbx], rdi
|
||||||
|
ret
|
||||||
|
|
||||||
|
load_kernel_stack:
|
||||||
|
endbr64
|
||||||
|
lea rbx, [kernel_stack_cache]
|
||||||
|
; 交换[rbx]与rbp
|
||||||
|
mov rdi, [rbx]
|
||||||
|
xor rbp, rdi
|
||||||
|
xor rdi, rbp
|
||||||
|
xor rbp, rdi
|
||||||
|
mov [rbx], rdi
|
||||||
|
lea rbx, [rbx + 8]
|
||||||
|
; 交换[rbx]与rsp
|
||||||
|
mov rdi, [rbx]
|
||||||
|
xor rsp, rdi
|
||||||
|
xor rdi, rsp
|
||||||
|
xor rsp, rdi
|
||||||
|
mov [rbx], rdi
|
||||||
|
ret
|
|
@ -1,4 +1,3 @@
|
||||||
use alloc::string::ToString;
|
|
||||||
use alloc::vec;
|
use alloc::vec;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
|
@ -140,7 +139,7 @@ impl KernelLogger {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
true
|
||||||
};
|
};
|
||||||
while !all_end(&indeces, &logs) {
|
while !all_end(&indeces, &logs) {
|
||||||
let mut min_ind = None;
|
let mut min_ind = None;
|
||||||
|
@ -181,7 +180,7 @@ impl<'a> Iterator for LogIterator<'a> {
|
||||||
let res = if let Some((time, msg)) = self.logs.first() {
|
let res = if let Some((time, msg)) = self.logs.first() {
|
||||||
Some(
|
Some(
|
||||||
MessageBuilder::new()
|
MessageBuilder::new()
|
||||||
.message(&time.to_string())
|
.message(time)
|
||||||
.append(MessageBuilder::from_message(msg.clone()))
|
.append(MessageBuilder::from_message(msg.clone()))
|
||||||
.build(),
|
.build(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include <kernel/kernel.h>
|
#include <kernel/kernel.h>
|
||||||
#include <kernel/tty.h>
|
#include <kernel/tty.h>
|
||||||
#include <kernel/memm.h>
|
#include <kernel/memm.h>
|
||||||
|
#include <kernel/interrupt.h>
|
||||||
|
#include <kernel/syscall.h>
|
||||||
|
|
||||||
#include <libk/multiboot2.h>
|
#include <libk/multiboot2.h>
|
||||||
#include <libk/math.h>
|
#include <libk/math.h>
|
||||||
|
@ -33,7 +35,7 @@ void kmain(void *mb2_bootinfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化内存管理模块
|
// 初始化内存管理模块
|
||||||
mem_manager_t *memm = memm_new(mem_size);
|
memory_manager_t *memm = memm_new(mem_size);
|
||||||
|
|
||||||
// 初始化tty模块
|
// 初始化tty模块
|
||||||
tty_controller_t *tty_controler = tty_controller_new();
|
tty_controller_t *tty_controler = tty_controller_new();
|
||||||
|
@ -41,6 +43,13 @@ void kmain(void *mb2_bootinfo)
|
||||||
get_frame_buffer_with_bootinfo(&fb, &bootinfo);
|
get_frame_buffer_with_bootinfo(&fb, &bootinfo);
|
||||||
tty *tty0 = tty_new(tty_type_raw_framebuffer, tty_mode_text);
|
tty *tty0 = tty_new(tty_type_raw_framebuffer, tty_mode_text);
|
||||||
tty_set_framebuffer(tty0, &fb);
|
tty_set_framebuffer(tty0, &fb);
|
||||||
|
tty_enable(tty0);
|
||||||
|
|
||||||
|
// 初始化中断管理
|
||||||
|
interrupt_init();
|
||||||
|
|
||||||
|
// 初始化系统调用
|
||||||
|
syscall_init();
|
||||||
|
|
||||||
// 为rust准备正确对齐的栈
|
// 为rust准备正确对齐的栈
|
||||||
prepare_stack();
|
prepare_stack();
|
||||||
|
|
|
@ -8,7 +8,6 @@ use super::{
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn kmain_rust() -> ! {
|
extern "C" fn kmain_rust() -> ! {
|
||||||
let tty = Tty::from_id(0).unwrap();
|
let tty = Tty::from_id(0).unwrap();
|
||||||
tty.enable();
|
|
||||||
let mut logger = KernelLogger::new();
|
let mut logger = KernelLogger::new();
|
||||||
logger.info(message!(
|
logger.info(message!(
|
||||||
Msg("Hello, "),
|
Msg("Hello, "),
|
||||||
|
|
|
@ -13,7 +13,7 @@ void raw_allocator_new(raw_allocator_t *allocator, usize size)
|
||||||
allocator->cells[0].length = 0;
|
allocator->cells[0].length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *raw_allocator_allocate(raw_allocator_t *allocator, usize size, usize align)
|
void *raw_allocator_allocate(raw_allocator_t *allocator, usize size)
|
||||||
{
|
{
|
||||||
usize real_size = size;
|
usize real_size = size;
|
||||||
align_to(real_size, 16);
|
align_to(real_size, 16);
|
||||||
|
@ -72,7 +72,7 @@ void raw_allocator_free(raw_allocator_t *allocator, void *mem)
|
||||||
{
|
{
|
||||||
raw_allocator_cell *cell = allocator->cells;
|
raw_allocator_cell *cell = allocator->cells;
|
||||||
while ((void *)cell < raw_allocator_end(allocator))
|
while ((void *)cell < raw_allocator_end(allocator))
|
||||||
{
|
{ // TODO 内存错误
|
||||||
if (mem == cell->content)
|
if (mem == cell->content)
|
||||||
{
|
{
|
||||||
cell->length = 0;
|
cell->length = 0;
|
||||||
|
@ -83,7 +83,7 @@ void raw_allocator_free(raw_allocator_t *allocator, void *mem)
|
||||||
allocator->rest_memory += cell->capacity + sizeof(raw_allocator_cell);
|
allocator->rest_memory += cell->capacity + sizeof(raw_allocator_cell);
|
||||||
allocator->free_count++;
|
allocator->free_count++;
|
||||||
if ( // 可用内存不超过当前allocator的 5% 或调用free次数很多时
|
if ( // 可用内存不超过当前allocator的 5% 或调用free次数很多时
|
||||||
allocator->size / allocator->rest_memory > 20 &&
|
allocator->size / allocator->rest_memory > 20 ||
|
||||||
allocator->free_count > RAW_ALLOCATOR_FREE_MAX)
|
allocator->free_count > RAW_ALLOCATOR_FREE_MAX)
|
||||||
{
|
{
|
||||||
raw_allocator_cellmerge(allocator);
|
raw_allocator_cellmerge(allocator);
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
#include <libk/string.h>
|
#include <libk/string.h>
|
||||||
#include <libk/bits.h>
|
#include <libk/bits.h>
|
||||||
|
|
||||||
mem_manager_t memory_manager;
|
memory_manager_t memory_manager;
|
||||||
|
|
||||||
mem_manager_t *memm_new(usize mem_size)
|
memory_manager_t *memm_new(usize mem_size)
|
||||||
{
|
{
|
||||||
memset(&memory_manager, 0, sizeof(memory_manager));
|
memset(&memory_manager, 0, sizeof(memory_manager));
|
||||||
memory_manager.memory_size = mem_size;
|
memory_manager.memory_size = mem_size;
|
||||||
|
@ -17,62 +17,25 @@ mem_manager_t *memm_new(usize mem_size)
|
||||||
usize kernel_initial_size = (usize)&kend;
|
usize kernel_initial_size = (usize)&kend;
|
||||||
align_to(kernel_initial_size, MEMM_PAGE_SIZE);
|
align_to(kernel_initial_size, MEMM_PAGE_SIZE);
|
||||||
|
|
||||||
// 配置分配器树
|
|
||||||
allocator_t *allocator0 = memm_allocator_new(
|
allocator_t *allocator0 = memm_allocator_new(
|
||||||
(void *)kernel_initial_size,
|
(void *)kernel_initial_size,
|
||||||
memory_manager.alloc_only_memory - kernel_initial_size,
|
memory_manager.alloc_only_memory - MEMM_PAGE_TABLE_AREA_MAX - kernel_initial_size,
|
||||||
MEMM_RAW_ALLOCATOR, 0);
|
MEMM_RAW_ALLOCATOR, 0);
|
||||||
|
|
||||||
allocator_iterator_t *alcatr_ind = allocator0->allocate(
|
memory_manager.kernel_base_allocator = allocator0;
|
||||||
&allocator0->allocator_instance, sizeof(allocator_iterator_t), 0);
|
|
||||||
|
|
||||||
alcatr_ind->allocator = allocator0;
|
return &memory_manager;
|
||||||
alcatr_ind->left = nullptr;
|
}
|
||||||
alcatr_ind->right = nullptr;
|
|
||||||
|
|
||||||
memory_manager.allocators = alcatr_ind;
|
|
||||||
|
|
||||||
// 配置页映射地图
|
|
||||||
usize pmc_size = memory_manager.page_amount;
|
|
||||||
align_to(pmc_size, 8);
|
|
||||||
pmc_size /= 8;
|
|
||||||
|
|
||||||
memory_manager.page_map = allocator0->allocate(&allocator0->allocator_instance, pmc_size, 0);
|
|
||||||
memset(memory_manager.page_map, 0, pmc_size);
|
|
||||||
memset(memory_manager.page_map, 0xff, MEMM_ALLOC_ONLY_MEMORY / MEMM_PAGE_SIZE / 8);
|
|
||||||
for (usize i = (MEMM_ALLOC_ONLY_MEMORY / MEMM_PAGE_SIZE / 8) * (u8)8;
|
|
||||||
i < MEMM_ALLOC_ONLY_MEMORY / MEMM_PAGE_SIZE % 8; i++)
|
|
||||||
{
|
|
||||||
bitmap_set(memory_manager.page_map, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 配置分配器页地图
|
|
||||||
memory_manager.map_with_allocator =
|
|
||||||
allocator0->allocate(&allocator0->allocator_instance, pmc_size, 0);
|
|
||||||
memset(memory_manager.map_with_allocator, 0, pmc_size);
|
|
||||||
for (usize i = kernel_initial_size / MEMM_PAGE_SIZE;
|
|
||||||
i < MEMM_ALLOC_ONLY_MEMORY / MEMM_PAGE_SIZE;
|
|
||||||
i += MEMM_PAGE_SIZE)
|
|
||||||
{
|
|
||||||
bitmap_set(memory_manager.map_with_allocator, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分配器释放页地图
|
|
||||||
memory_manager.map_with_destructed_allocator =
|
|
||||||
allocator0->allocate(&allocator0->allocator_instance, pmc_size, 0);
|
|
||||||
memset(memory_manager.map_with_destructed_allocator, 0, pmc_size);
|
|
||||||
|
|
||||||
// 配置空闲页线段搜索表
|
|
||||||
memory_manager.available_pages_table = lst_new(0, memory_manager.page_amount);
|
|
||||||
lst_remove(memory_manager.available_pages_table, 0, MEMM_ALLOC_ONLY_MEMORY / MEMM_PAGE_SIZE, false);
|
|
||||||
|
|
||||||
|
memory_manager_t *memm_get_manager()
|
||||||
|
{
|
||||||
return &memory_manager;
|
return &memory_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid)
|
allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid)
|
||||||
{
|
{
|
||||||
allocator_t *allocator = start;
|
allocator_t *allocator = start;
|
||||||
allocator->initialized = true;
|
allocator->magic = MEMM_ALLOCATOR_MAGIC;
|
||||||
allocator->full = false;
|
allocator->full = false;
|
||||||
allocator->pid = 0;
|
allocator->pid = 0;
|
||||||
allocator->size = length;
|
allocator->size = length;
|
||||||
|
@ -85,166 +48,47 @@ allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid
|
||||||
allocator->free = (memm_free_t)raw_allocator_free;
|
allocator->free = (memm_free_t)raw_allocator_free;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
allocator->initialized = false;
|
allocator->magic = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void memm_allocator_destruct(allocator_t *allocator)
|
void memm_allocator_destruct(allocator_t *allocator)
|
||||||
{
|
{
|
||||||
allocator->initialized = false;
|
allocator->magic = 0;
|
||||||
// TODO 从分配器树中删除这个分配器
|
// TODO 从分配器树中删除这个分配器
|
||||||
KERNEL_TODO();
|
KERNEL_TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
void *memm_find_and_allocate(allocator_iterator_t *allocator_ind, usize size, usize pid, allocator_t **writeback)
|
|
||||||
{
|
|
||||||
void *ptr;
|
|
||||||
allocator_t *allocator = allocator_ind->allocator;
|
|
||||||
if (allocator->pid == pid && allocator->full == false)
|
|
||||||
{ // 尝试用本节点分配
|
|
||||||
if ((ptr = allocator->allocate(&allocator->allocator_instance, size, 0)) != nullptr)
|
|
||||||
{
|
|
||||||
*writeback = allocator;
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((ptr = allocator->allocate(&allocator->allocator_instance, 0, 0)) == nullptr)
|
|
||||||
allocator->full = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (allocator_ind->left != nullptr)
|
|
||||||
{ // 尝试用左子树分配
|
|
||||||
ptr = memm_find_and_allocate(allocator_ind->left, size, pid, writeback);
|
|
||||||
if (ptr != nullptr)
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
if (allocator_ind->right != nullptr)
|
|
||||||
{ // 尝试用右子树分配
|
|
||||||
ptr = memm_find_and_allocate(allocator_ind->right, size, pid, writeback);
|
|
||||||
if (ptr != nullptr)
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
// 都不行就只能返回nullptr
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void insert_allocator(allocator_iterator_t *iter, allocator_iterator_t *inserter)
|
|
||||||
{
|
|
||||||
if (inserter->allocator < iter->allocator)
|
|
||||||
{
|
|
||||||
if (iter->left == nullptr)
|
|
||||||
{
|
|
||||||
iter->left = inserter;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
insert_allocator(iter->left, inserter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (inserter->allocator > iter->allocator)
|
|
||||||
{
|
|
||||||
if (iter->right == nullptr)
|
|
||||||
{
|
|
||||||
iter->right = inserter;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
insert_allocator(iter->right, inserter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void *memm_allocate(usize size, usize pid)
|
|
||||||
{
|
|
||||||
usize orgsize = size;
|
|
||||||
// 从分配器树中分配内存
|
|
||||||
allocator_t *allocator;
|
|
||||||
void *ptr = memm_find_and_allocate(memory_manager.allocators, size, pid, &allocator);
|
|
||||||
if (ptr != nullptr)
|
|
||||||
goto after_allocation;
|
|
||||||
|
|
||||||
// 分配器树中没有可分配的内存
|
|
||||||
size += sizeof(allocator_t) + MEMM_PAGE_SIZE;
|
|
||||||
align_to(size, MEMM_PAGE_SIZE);
|
|
||||||
size /= MEMM_PAGE_SIZE;
|
|
||||||
usize allocator_start = find_fitable_pages(size);
|
|
||||||
if (allocator_start == 0)
|
|
||||||
return nullptr; // 内存中已经没有可分配的页了
|
|
||||||
for (usize i = allocator_start; i < allocator_start + size; i++)
|
|
||||||
{
|
|
||||||
bitmap_set(memory_manager.map_with_allocator, i);
|
|
||||||
}
|
|
||||||
memm_map_pageframes_to(
|
|
||||||
allocator_start * MEMM_PAGE_SIZE, allocator_start * MEMM_PAGE_SIZE,
|
|
||||||
size * MEMM_PAGE_SIZE,
|
|
||||||
false, // 用户空间标志
|
|
||||||
true // 写权限
|
|
||||||
);
|
|
||||||
|
|
||||||
// 在新映射的页中创建一个分配器
|
|
||||||
// TODO 在用户态可能需要实现一个效率更高的分配器
|
|
||||||
allocator_t *new_allocator =
|
|
||||||
memm_allocator_new((void *)(allocator_start * MEMM_PAGE_SIZE), size * MEMM_PAGE_SIZE,
|
|
||||||
MEMM_RAW_ALLOCATOR, pid);
|
|
||||||
allocator = new_allocator;
|
|
||||||
|
|
||||||
allocator_iterator_t *allind = memm_kernel_allocate(sizeof(allocator_iterator_t));
|
|
||||||
allind->allocator = new_allocator;
|
|
||||||
allind->left = nullptr;
|
|
||||||
allind->right = nullptr;
|
|
||||||
insert_allocator(memory_manager.allocators, allind);
|
|
||||||
ptr = new_allocator->allocate(&new_allocator->allocator_instance, orgsize, 0);
|
|
||||||
|
|
||||||
after_allocation:
|
|
||||||
if (ptr != nullptr)
|
|
||||||
memm_addr_set_allocator(ptr, allocator);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *memm_kernel_allocate(usize size)
|
void *memm_kernel_allocate(usize size)
|
||||||
{
|
{
|
||||||
return memm_allocate(size, 0);
|
allocator_t *allocator = memory_manager.kernel_base_allocator;
|
||||||
}
|
return allocator->allocate(allocator->allocator_instance, size);
|
||||||
|
|
||||||
void *memm_user_allocate(usize size, usize pid)
|
|
||||||
{
|
|
||||||
void *res = memm_allocate(size, pid);
|
|
||||||
// TODO 将内存空间映射到用户空间
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void memm_free(void *mem)
|
void memm_free(void *mem)
|
||||||
{
|
{
|
||||||
allocator_t *allocator = memm_addr_get_allocator(mem);
|
allocator_t *allocator = memory_manager.kernel_base_allocator;
|
||||||
|
if (allocator->magic != MEMM_ALLOCATOR_MAGIC)
|
||||||
|
return;
|
||||||
if (is_user_address((u64)mem))
|
if (is_user_address((u64)mem))
|
||||||
{ // TODO 对于用户空间的地址需要先转换到内核地址后释放
|
{
|
||||||
|
mem = mem - allocator->userspace + (void *)allocator;
|
||||||
}
|
}
|
||||||
allocator->free(allocator->allocator_instance, mem);
|
allocator->free(allocator->allocator_instance, mem);
|
||||||
if (allocator->full)
|
if (allocator->full)
|
||||||
allocator->full = false;
|
allocator->full = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
usize find_fitable_pages(usize page_count)
|
void *memm_allcate_pagetable()
|
||||||
{
|
{
|
||||||
usize res = 0;
|
if (memory_manager.page_table_area < MEMM_PAGE_TABLE_AREA_MAX)
|
||||||
lst_iterator_t *iter = memory_manager.available_pages_table;
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
if (iter->line.right - iter->line.left > page_count)
|
memory_manager.page_table_area += MEMM_PAGE_TABLE_SIZE;
|
||||||
{
|
return memory_manager.alloc_only_memory - memory_manager.page_table_area;
|
||||||
res = iter->line.left;
|
}
|
||||||
lst_remove(iter, res, res + page_count, false);
|
else
|
||||||
for (usize i = res; i < res + page_count; i++)
|
{
|
||||||
{
|
// TODO
|
||||||
bitmap_set(memory_manager.page_map, i);
|
}
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while ((iter = lst_next(iter)) != nullptr);
|
|
||||||
memory_manager.mapped_page_amount += page_count;
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,8 +58,8 @@ void tty_set_framebuffer(tty *ttyx, framebuffer *fb)
|
||||||
ttyx->height = ttyx->typeinfo.raw_framebuffer.height;
|
ttyx->height = ttyx->typeinfo.raw_framebuffer.height;
|
||||||
if (ttyx->mode == tty_mode_text)
|
if (ttyx->mode == tty_mode_text)
|
||||||
{
|
{
|
||||||
ttyx->text.width = fb->width / tty_get_font()->char_width;
|
ttyx->text.width = fb->width / (TTY_FONT_SCALE * tty_get_font()->char_width);
|
||||||
ttyx->text.height = fb->height / tty_get_font()->char_height;
|
ttyx->text.height = fb->height / (TTY_FONT_SCALE * tty_get_font()->char_height);
|
||||||
ttyx->text.line = 0;
|
ttyx->text.line = 0;
|
||||||
ttyx->text.column = 0;
|
ttyx->text.column = 0;
|
||||||
}
|
}
|
||||||
|
@ -175,17 +175,20 @@ void tty_text_print(tty *ttyx, char *string, u32 color, u32 bgcolor)
|
||||||
}
|
}
|
||||||
else if (c == '\t')
|
else if (c == '\t')
|
||||||
{ // 水平制表符
|
{ // 水平制表符
|
||||||
|
putchar(ttyx, ' ', 0, 0);
|
||||||
ttyx->text.column += 8;
|
ttyx->text.column += 8;
|
||||||
ttyx->text.column -= ttyx->text.column % 8;
|
ttyx->text.column -= ttyx->text.column % 8;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (c == '\r')
|
else if (c == '\r')
|
||||||
{ // 回到行首
|
{ // 回到行首
|
||||||
|
putchar(ttyx, ' ', 0, 0);
|
||||||
ttyx->text.column = 0;
|
ttyx->text.column = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (c == '\v')
|
else if (c == '\v')
|
||||||
{ // 垂直制表符
|
{ // 垂直制表符
|
||||||
|
putchar(ttyx, ' ', 0, 0);
|
||||||
ttyx->text.line++;
|
ttyx->text.line++;
|
||||||
if (ttyx->text.line == ttyx->text.height)
|
if (ttyx->text.line == ttyx->text.height)
|
||||||
{
|
{
|
||||||
|
|
|
@ -150,10 +150,11 @@ impl Color {
|
||||||
pub const RED: Color = Color(0xee, 0x22, 0x22);
|
pub const RED: Color = Color(0xee, 0x22, 0x22);
|
||||||
pub const GREEN: Color = Color(0x22, 0xee, 0x22);
|
pub const GREEN: Color = Color(0x22, 0xee, 0x22);
|
||||||
pub const BLUE: Color = Color(0x22, 0x22, 0xee);
|
pub const BLUE: Color = Color(0x22, 0x22, 0xee);
|
||||||
pub const YELLOW: Color = Color(0xee, 0x22, 0x22);
|
pub const YELLOW: Color = Color(0xee, 0xee, 0x22);
|
||||||
pub const ORANGE: Color = Color(0xee, 0xee, 0x22);
|
pub const ORANGE: Color = Color(0xee, 0xaa, 0x22);
|
||||||
pub const PURPLE: Color = Color(0xee, 0, 0xee);
|
pub const PURPLE: Color = Color(0xee, 0x22, 0xee);
|
||||||
pub const PINK: Color = Color(0xee, 0x44, 0x66);
|
pub const PINK: Color = Color(0xee, 0x44, 0x66);
|
||||||
|
pub const GRAY: Color = Color(0xaa, 0xaa, 0xaa);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Color> for u32 {
|
impl From<Color> for u32 {
|
||||||
|
@ -181,6 +182,16 @@ pub struct MessageSection {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Message(Vec<MessageSection>);
|
pub struct Message(Vec<MessageSection>);
|
||||||
|
|
||||||
|
impl ToString for Message {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
let mut res = String::new();
|
||||||
|
for MessageSection { msg, .. } in self.0.iter() {
|
||||||
|
res += msg;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// ## MessageBuilder
|
/// ## MessageBuilder
|
||||||
///
|
///
|
||||||
/// 使用链式调用模式构造一个消息.
|
/// 使用链式调用模式构造一个消息.
|
||||||
|
@ -196,6 +207,19 @@ pub struct Message(Vec<MessageSection>);
|
||||||
/// .build();
|
/// .build();
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// 定义了`message!`宏,简化构造消息的代码:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use crate::kernel::tty::tty::BuilderFunctions::*;
|
||||||
|
///
|
||||||
|
/// message!(
|
||||||
|
/// Msg("Hello, "),
|
||||||
|
/// Msg("Metaverse"),
|
||||||
|
/// FgColor(Color::GREEN),
|
||||||
|
/// Msg("!\n"),
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// 对于特殊情况可以使用非链式调用:
|
/// 对于特殊情况可以使用非链式调用:
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// let mut msg = MessageBuilder::new();
|
/// let mut msg = MessageBuilder::new();
|
||||||
|
@ -226,7 +250,7 @@ impl MessageBuilder {
|
||||||
Self { msg }
|
Self { msg }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn message(mut self, msg: &str) -> Self {
|
pub fn message<T: ToString + ?Sized>(mut self, msg: &T) -> Self {
|
||||||
self.msg.0.push(MessageSection {
|
self.msg.0.push(MessageSection {
|
||||||
msg: msg.to_string(),
|
msg: msg.to_string(),
|
||||||
fgcolor: Color(0xee, 0xee, 0xee),
|
fgcolor: Color(0xee, 0xee, 0xee),
|
||||||
|
@ -235,7 +259,7 @@ impl MessageBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn message_mut(&mut self, msg: &str) {
|
pub fn message_mut<T: ToString + ?Sized>(&mut self, msg: &T) {
|
||||||
self.msg.0.push(MessageSection {
|
self.msg.0.push(MessageSection {
|
||||||
msg: msg.to_string(),
|
msg: msg.to_string(),
|
||||||
fgcolor: Color(0xee, 0xee, 0xee),
|
fgcolor: Color(0xee, 0xee, 0xee),
|
||||||
|
|
|
@ -11,7 +11,7 @@ ifdef release
|
||||||
CCFLAGS := ${CCFLAGS} -O2
|
CCFLAGS := ${CCFLAGS} -O2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
C_SRCS = bootinfo.c lst.c
|
C_SRCS = bootinfo.c lst.c utils.c
|
||||||
C_OBJS = ${C_SRCS:.c=.c.o}
|
C_OBJS = ${C_SRCS:.c=.c.o}
|
||||||
|
|
||||||
################################
|
################################
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include <utils.h>
|
||||||
|
|
||||||
|
void pointer_to_string(u64 addr, char *dest)
|
||||||
|
{
|
||||||
|
for (u8 i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
char c = addr & 0xf;
|
||||||
|
dest[15 - i] = (c < 10) ? c + '0' : c - 10 + 'a';
|
||||||
|
addr >>= 4;
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,10 +13,26 @@ SECTIONS {
|
||||||
{
|
{
|
||||||
*(.multiboot2)
|
*(.multiboot2)
|
||||||
}
|
}
|
||||||
.cpumeta :
|
.cpumeta ALIGN(4096) :
|
||||||
{
|
{
|
||||||
*(.cpumeta)
|
*(.cpumeta)
|
||||||
}
|
}
|
||||||
|
.cpumeta.tblptrs ALIGN(4096) :
|
||||||
|
{
|
||||||
|
*(cpumeta.tblptrs)
|
||||||
|
}
|
||||||
|
.cpumeta.gdt ALIGN(4096) :
|
||||||
|
{
|
||||||
|
*(.cpumeta.gdt)
|
||||||
|
}
|
||||||
|
.cpumeta.idt ALIGN(4096) :
|
||||||
|
{
|
||||||
|
*(.cpumeta.idt)
|
||||||
|
}
|
||||||
|
.cpumeta.tss ALIGN(4096) :
|
||||||
|
{
|
||||||
|
*(.cpumeta.tss)
|
||||||
|
}
|
||||||
. = 16M;
|
. = 16M;
|
||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
|
|
Reference in New Issue