forked from Simple-XX/SimpleKernel
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: digmouse233 <[email protected]>
- Loading branch information
Showing
66 changed files
with
2,817 additions
and
1,279 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,48 @@ | ||
|
||
# This file is a part of Simple-XX/SimpleKernel (https://github.com/Simple-XX/SimpleKernel). | ||
# This file is a part of Simple-XX/SimpleKernel | ||
# (https://github.com/Simple-XX/SimpleKernel). | ||
# Based on https://github.com/SynestiaOS/SynestiaOS | ||
# CMakeLists.txt for Simple-XX/SimpleKernel. | ||
# CMake 入口 | ||
|
||
# Set minimum cmake version | ||
# 设置最小 cmake 版本 | ||
cmake_minimum_required(VERSION 3.10) | ||
|
||
# skip cmake compiler check | ||
# 跳过编译器检查 | ||
set(CMAKE_C_COMPILER_WORKS TRUE) | ||
set(CMAKE_CXX_COMPILER_WORKS TRUE) | ||
|
||
# 设置项目名与使用的语言 | ||
project(SimpleKernel LANGUAGES CXX ASM) | ||
|
||
# 禁止原地编译 | ||
if(${SimpleKernel_SOURCE_DIR} STREQUAL ${SimpleKernel_BINARY_DIR}) | ||
message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.") | ||
endif() | ||
|
||
# Set C gnu11 | ||
# 设置使用的 C/C++ 版本 | ||
set(CMAKE_C_STANDARD 11) | ||
set(CMAKE_CXX_STANDARD 17) | ||
|
||
# Set cmake moudle path | ||
# 设置辅助 cmake 脚本路径 | ||
set(CMAKE_MODULE_PATH "${SimpleKernel_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) | ||
|
||
# Set arch | ||
# 设置 arch | ||
include(${SimpleKernel_SOURCE_DIR}/cmake/arch_detector.cmake) | ||
# Set header files | ||
# 引入添加头文件函数 | ||
include(${SimpleKernel_SOURCE_DIR}/cmake/header_files.cmake) | ||
# Find asm source files | ||
# 引入添加汇编文件函数 | ||
include(${SimpleKernel_SOURCE_DIR}/cmake/find_asm_files.cmake) | ||
|
||
# 设置输出路径 | ||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) | ||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) | ||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) | ||
|
||
# Set kernel name | ||
# 设置内核名称 | ||
set(KernelName kernel.elf) | ||
|
||
# 设置 src 路径 | ||
set(SimpleKernel_SOURCE_CODE_DIR ${SimpleKernel_SOURCE_DIR}/src) | ||
# 跳转到 SimpleKernel_SOURCE_CODE_DIR 下的 CMakeLists | ||
add_subdirectory(${SimpleKernel_SOURCE_CODE_DIR}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,28 @@ | ||
|
||
# This file is a part of Simple-XX/SimpleKernel (https://github.com/Simple-XX/SimpleKernel). | ||
# This file is a part of Simple-XX/SimpleKernel | ||
# (https://github.com/Simple-XX/SimpleKernel). | ||
# Based on https://github.com/SynestiaOS/SynestiaOS | ||
# arch_detector.cmake for Simple-XX/SimpleKernel. | ||
# CMakeLists.txt for Simple-XX/SimpleKernel. | ||
# 对 shell 传入的 ARCH 参数进行处理 | ||
|
||
# TODO: 优化 CMake 流程,环境搭建由自动脚本实现 | ||
|
||
# 如果 ARCH 为 i386 或 x86_64,统一添加 ia32 前缀 | ||
if (ARCH STREQUAL i386) | ||
set(SimpleKernelArch "ia32/i386") | ||
elseif (ARCH STREQUAL x86_64) | ||
set(SimpleKernelArch "ia32/x86_64") | ||
# 其它情况不变 | ||
elseif (ARCH STREQUAL arm) | ||
set(SimpleKernelArch arm) | ||
elseif (ARCH STREQUAL riscv64) | ||
set(SimpleKernelArch riscv64) | ||
else () | ||
# 不支持的 ARCH | ||
message(WARNING "unexpected ARCH: ${ARCH}, using default value \"riscv64\"") | ||
# 默认设为 riscv64 | ||
set(SimpleKernelArch riscv64) | ||
endif () | ||
|
||
# 输出 SimpleKernelArch | ||
message(STATUS "SimpleKernelArch is ${SimpleKernelArch}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# SimpleKernel 参考资料汇总 | ||
|
||
关于交叉编译的一些说明:https://wiki.osdev.org/GCC_Cross-Compiler | ||
|
||
arm 工具链:https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads | ||
|
||
riscv 工具链:https://github.com/riscv/riscv-gnu-toolchain | ||
|
||
GCC 安装: https://gcc.gnu.org/install/ | ||
|
||
i386 的启动代码:https://wiki.osdev.org/Bare_Bones | ||
|
||
grub:https://www.gnu.org/software/grub/manual/grub/grub.html | ||
|
||
multiboot2 规范:https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html | ||
|
||
opensbi:https://github.com/riscv/opensbi | ||
|
||
c++ 的使用:https://wiki.osdev.org/C++ | ||
|
||
如何对全局对象进行构造:https://wiki.osdev.org/Calling_Global_Constructors | ||
|
||
c++ abi 支持:https://wiki.osdev.org/C%2B%2B_Exception_Support | ||
|
||
gcc 内嵌汇编:https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html | ||
|
||
IA32 prots:https://wiki.osdev.org/I/O_Ports | ||
|
||
IA32 VGA:https://wiki.osdev.org/VGA_Hardware | ||
|
||
IA32 text ui:https://wiki.osdev.org/Text_UI | ||
|
||
IA32 text 模式的光标:https://wiki.osdev.org/Text_Mode_Cursor | ||
|
||
IA32 text 模式在屏幕上输出:https://wiki.osdev.org/Printing_To_Screen | ||
|
||
device-tree:https://github.com/devicetree-org/devicetree-specification | ||
|
||
dtb解析0: https://e-mailky.github.io/2016-12-06-dts-introduce | ||
|
||
dtb解析1: https://e-mailky.github.io/2019-01-14-dts-1 | ||
|
||
dtb解析2: https://e-mailky.github.io/2019-01-14-dts-2 | ||
|
||
dtb解析3: https://e-mailky.github.io/2019-01-14-dts-3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
# SimpleKernel 工具链 | ||
|
||
SimpleKernel 为了保证在各个平台上的可用性,选择了较为通用的工具链,主要分为三个部分 | ||
|
||
1. 构建系统 | ||
|
||
使用 CMake 对代码进行管理,同时控制编译选项 | ||
|
||
2. 内核的编译 | ||
|
||
使用 g++, ld 进行编译与链接 | ||
|
||
3. 虚拟机 | ||
|
||
对于 x86/x86_64 架构,使用 bochs | ||
|
||
对于其它架构,使用 qemu | ||
|
||
4. 辅助脚本 | ||
|
||
在根目录下的 run.sh/run.py 属于此类,此外还有 tools/ 目录下的 *.sh | ||
|
||
|
||
|
||
## GCC | ||
|
||
GCC 需要根据目标平台与宿主机进行配置,即 target 与 host。 | ||
|
||
一般而言,网上有编译好的可以直接拿来用。 | ||
|
||
以 target=riscv64,host=osx 为例,可以在 https://github.com/riscv/homebrew-riscv 找到现成的,只需要按照说明使用 brew 安装即可。 | ||
|
||
对于特殊情况,可能需要自己手动编译 gcc,大致步骤如下[^1]: | ||
|
||
1. 安装依赖 | ||
2. 下载源码 | ||
3. 配置 | ||
4. 编译 | ||
|
||
其中比较重要的地方是第三步,需要根据需要进行配置,你可以参考 tools/x86_64-elf-gcc.sh 的内容进行编译。 | ||
|
||
|
||
|
||
## CMake | ||
|
||
CMake 可以分为两个部分 | ||
|
||
1. 主要 cmake 规则 | ||
|
||
所有 CMakeLists.txt 文件,规定了内核的编译方式。其中 | ||
|
||
- /CMakeLists.txt | ||
|
||
设置了一些 CMake 选项,并在最后通过 `add_subdirectory(${SimpleKernel_SOURCE_CODE_DIR})` 将控制权转移到 src/CMakeLists.txt | ||
|
||
- src/CMakeLists.txt | ||
|
||
规定了 gcc 的编译选项,指定生成的二进制文件名称,并规定生成二进制文件所需的模块 | ||
|
||
- src/*/CMakeLists.txt | ||
|
||
各个模块的编译规则 | ||
|
||
2. 辅助 cmake 规则 | ||
|
||
用于辅助主要规则,保存在 /cmake 目录下 | ||
|
||
- toolchain_*.cmake 用于判断依赖是否已安装 | ||
- header_files.cmake 用于添加头文件 | ||
- find_asm_files.cmake 用于讲汇编文件添加到编译列表 | ||
- arch_detector.cmake 用于判断目标架构 | ||
|
||
更多细节请查看注释。 | ||
|
||
|
||
|
||
## BOCHS | ||
|
||
bochs 是专门用于 x86/x86_64 的虚拟机。 | ||
|
||
tools/bochsrc_*.txt 规定了虚拟机的一些选项 | ||
|
||
tools/bochsinit 规定在虚拟机启动后执行的命令 | ||
|
||
更多细节请查看注释 | ||
|
||
|
||
|
||
## QEMU | ||
|
||
qemu 是支持范围更大的虚拟机,支持多种架构。 | ||
|
||
|
||
|
||
## 辅助脚本 | ||
|
||
- tools/env.sh | ||
|
||
设置目标架构,并根据设置的目标架构初始化相关变量。 | ||
|
||
更多细节请查看注释。 | ||
|
||
- run.sh | ||
|
||
根据 tools/env.sh 的设置在虚拟机中运行内核。 | ||
|
||
更多细节请查看注释。 | ||
|
||
|
||
|
||
## 相关文档 | ||
|
||
关于交叉编译的一些说明:https://wiki.osdev.org/GCC_Cross-Compiler | ||
|
||
arm 工具链:https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads | ||
|
||
riscv 工具链:https://github.com/riscv/riscv-gnu-toolchain | ||
|
||
[^1]: https://gcc.gnu.org/install/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# SimpleKernel cpp 的初始化 | ||
|
||
Simplekernel 主要是用 C++ 完成的,为了最大化 C++ 的优势,得对 C++ 的一些基础设施进行初始化。 | ||
|
||
这一工作大致分为两部分。 | ||
|
||
## cxxabi | ||
|
||
cxxabi 是 C++ 特性的支持者,一些特性必须由 cxxabi 实现后才能使用。 | ||
|
||
在 src/libcxx/include/cxxabi.h 与 src/libcxx/cxxabi.cpp 两个文件中定义了相关数据与函数。在链接阶段将这些定义链接上就可以正常使用相关特性了。 | ||
|
||
这部分不进行深究,水太深了。 | ||
|
||
## 全局对象的构造 | ||
|
||
另一个重点是全局对象的构造。 | ||
|
||
在通常场景下,C++ 的全局对象会在进入 main 函数之前进行构造,在 main 返回后析构。在内核里也是一样,我们需要在进入 kernel_main 之前完成构造,不同的是我们不需要考虑析构问题,因为内核是不会返回的,当它结束的时候意味着关机了。 | ||
|
||
编译器在链接时,会将所有的全局对象的构造函数函数指针收集在一起,放在一个名为 `.init_array` 的段中,在 src/arch/*/link.ld 中,有这么一段规则: | ||
|
||
``` | ||
/* 只读数据段 */ | ||
.rodata : ALIGN(4K) { | ||
/* 构造函数起点 */ | ||
PROVIDE(ctors_start = .); | ||
*(SORT_BY_INIT_PRIORITY (.init_array.*)) | ||
*(SORT_BY_INIT_PRIORITY (.ctors.*)) | ||
*(.init_array .ctors) | ||
/* 构造函数终点 */ | ||
PROVIDE(ctors_end = .); | ||
/* 析构函数起点 */ | ||
PROVIDE(dtors_start = .); | ||
*(.dtor*) | ||
/* 析构函数终点 */ | ||
PROVIDE(dtors_end = .); | ||
*(.rodata*) | ||
*(.gcc_except_table) | ||
} | ||
``` | ||
|
||
这部分规定将构造函数放在 .rodata 段里,并将这段内存用 `ctors_start` 和 `ctors_end` 两个地址进行标识,以便在代码中访问。 | ||
|
||
初始化由 `cpp_init` 执行,定义在 src/libcxx/src/cxxabi.cpp 中 | ||
|
||
```c++ | ||
typedef void (*ctor_t)(void); | ||
extern ctor_t ctors_start[]; | ||
extern ctor_t ctors_end[]; | ||
void cpp_init(void) { | ||
ctor_t *f; | ||
for (f = ctors_start; f < ctors_end; f++) { | ||
(*f)(); | ||
} | ||
return; | ||
} | ||
``` | ||
遍历这一区域的所有函数并执行,这样就完成了全局对象的构造。 | ||
更多细节请查看注释。 | ||
## 相关文档 | ||
https://wiki.osdev.org/C++ | ||
https://wiki.osdev.org/Calling_Global_Constructors | ||
Oops, something went wrong.