Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory #190

Merged
merged 33 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f210422
doc: update README
MRNIU Jul 6, 2024
566b6d5
Merge branch 'new_intr' into memory
MRNIU Jul 6, 2024
9868ed9
feat(libc): bit operations
MRNIU Jul 6, 2024
c876f6a
feat(memory): add mem
MRNIU Jul 7, 2024
e7280d8
Merge branch 'new_intr' into memory
MRNIU Jul 8, 2024
4b7f4b5
feat(memory): update
MRNIU Jul 8, 2024
b915b68
Merge branch 'new_intr' into memory
MRNIU Jul 8, 2024
adf2368
working on pmm
MRNIU Jul 8, 2024
12e4d19
merge
MRNIU Aug 1, 2024
74a6301
Merge branch 'new_intr' into memory
MRNIU Aug 1, 2024
4c22a77
fix: add return 0
MRNIU Aug 1, 2024
0230af9
Merge branch 'new_intr' into memory
MRNIU Aug 7, 2024
a134f7c
Merge branch 'new_intr' into memory
MRNIU Aug 7, 2024
2829138
Merge branch 'new_intr' into memory
MRNIU Aug 7, 2024
60b3e6e
Merge branch 'new_intr' into memory
MRNIU Aug 7, 2024
58cdc82
Merge branch 'new_intr' into memory
MRNIU Aug 7, 2024
f4413c0
Merge branch 'new_intr' into memory
MRNIU Aug 26, 2024
89e5c63
style: PAGE_SIZE->kPageSize
MRNIU Aug 27, 2024
e3e38d7
Merge branch 'new_intr' into memory
MRNIU Aug 27, 2024
03faff1
feat: working on vmm
MRNIU Aug 27, 2024
386f001
refactor: firstfit_allocator as template
MRNIU Aug 28, 2024
61b29bd
feat: working on vmm
MRNIU Aug 30, 2024
58e18ad
feat: working on vmm
MRNIU Aug 30, 2024
adb0c8e
Merge branch 'new_intr' into memory
MRNIU Aug 30, 2024
8cbab95
feat: working on vmm
MRNIU Aug 30, 2024
da67739
feat: working on vmm
MRNIU Aug 30, 2024
fa85cbd
Merge branch 'new_intr' into memory
MRNIU Aug 30, 2024
939f3aa
feat: working on vmm
MRNIU Aug 30, 2024
75af411
feat: working on vmm
MRNIU Sep 11, 2024
1ca8daa
Merge branch 'new_intr' into memory
MRNIU Sep 11, 2024
8af08a7
fix: overflow
MRNIU Sep 11, 2024
26478d9
Merge branch 'new_intr' into memory
MRNIU Sep 11, 2024
77d443e
feat: working on vmm
MRNIU Sep 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 17 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

# SimpleKernel

intr branch
memory branch

## 关键词

Expand Down Expand Up @@ -113,27 +113,15 @@ intr branch

- riscv64

1. 对 CSR 寄存器的抽象
2. 寄存器状态打印
3. 基于 Direct 的中断处理
4. 中断注册函数
5. 时钟中断

1.

- X86_64

1. cpu 抽象
2. 8259A pic 控制器抽象
3. 8253/8254 timer 控制器抽象
4. gdt 初始化
5. 中断处理流程
6. 中断注册函数
7. 时钟中断
1.

- TODO

riscv64 PLIC

x86_64 APIC


- 全局对象

Expand All @@ -150,44 +138,37 @@ intr branch
## 已支持特性

- [x] [BUILD] 使用 CMake 的构建系统

- [x] [BUILD] 使用 gdb remote 调试

- [x] [BUILD] 第三方资源集成

- [x] [COMMON] C++ 全局对象的构造

- [x] [COMMON] C++ 静态局部对象构造

- [x] [COMMON] C 栈保护支持

- [x] [COMMON] printf 支持

- [x] [COMMON] 简单的 C++ 异常支持

- [x] [COMMON] 带颜色的字符串输出

- [x] [x86_64] 基于 gnuefi 的 bootloader

- [x] [x86_64] 基于 serial 的基本输出

- [x] [x86_64] 物理内存信息探测

- [x] [x86_64] 显示缓冲区探测

- [x] [x86_64] 调用栈回溯

- [x] [riscv64] gp 寄存器的初始化

- [x] [riscv64] 基于 opensbi 的基本输出

- [x] [riscv64] device tree 硬件信息解析

- [x] [riscv64] ns16550a 串口驱动

- [x] [riscv64] 调用栈回溯(仅打印地址)

- [ ] [aarch64] 基于 gnuefi 的 bootloader(调试中)
- [x] [riscv64] 对 CSR 寄存器的抽象
- [x] [riscv64] 寄存器状态打印
- [x] [riscv64] 基于 Direct 的中断处理
- [x] [riscv64] 中断注册函数
- [x] [riscv64] 时钟中断
- [x] [x86_64] cpu 抽象
- [x] [x86_64] 8259A pic 控制器抽象
- [x] [x86_64] 8253/8254 timer 控制器抽象
- [x] [x86_64] gdt 初始化
- [x] [x86_64] 中断处理流程
- [x] [x86_64] 中断注册函数
- [x] [x86_64] 时钟中断

## 使用的第三方资源

Expand Down
4 changes: 3 additions & 1 deletion src/kernel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ add_subdirectory(${PROJECT_SOURCE_DIR}/driver)

add_executable(${PROJECT_NAME}
main.cpp
physical_memory_manager.cpp
virtual_memory_manager.cpp
)

# 添加头文件
target_include_directories(kernel PRIVATE
include
../
)

# 添加要链接的库
Expand Down
8 changes: 8 additions & 0 deletions src/kernel/arch/aarch64/interrupt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
#include "kernel_log.hpp"
#include "sk_cstdio"

<<<<<<< HEAD
Interrupt::Interrupt() { log::Info("Interrupt init.\n"); }
=======
Interrupt::Interrupt() { klog::Info("Interrupt init.\n"); }
>>>>>>> new_intr

void Interrupt::Do(uint64_t cause, uint8_t *context) {
(void)cause;
Expand All @@ -31,7 +35,11 @@ void Interrupt::RegisterInterruptFunc(uint64_t cause, InterruptFunc func) {
}

uint32_t InterruptInit(uint32_t, uint8_t *) {
<<<<<<< HEAD
log::Info("Hello InterruptInit\n");
=======
klog::Info("Hello InterruptInit\n");
>>>>>>> new_intr

return 0;
}
80 changes: 80 additions & 0 deletions src/kernel/arch/riscv64/include/cpu/cpu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,84 @@
#include "sk_cstdio"
#include "sk_iostream"

namespace cpu {
namespace vmm {
enum {
VALID_OFFSET = 0,
READ_OFFSET = 1,
WRITE_OFFSET = 2,
EXEC_OFFSET = 3,
USER_OFFSET = 4,
GLOBAL_OFFSET = 5,
ACCESSED_OFFSET = 6,
DIRTY_OFFSET = 7,
VALID = 1 << VALID_OFFSET,
READ = 1 << READ_OFFSET,
WRITE = 1 << WRITE_OFFSET,
EXEC = 1 << EXEC_OFFSET,
USER = 1 << USER_OFFSET,
GLOBAL = 1 << GLOBAL_OFFSET,
ACCESSED = 1 << ACCESSED_OFFSET,
DIRTY = 1 << DIRTY_OFFSET,
};
/// 有效位
static constexpr const uint8_t VMM_PAGE_VALID = VALID;
/// 可读位
static constexpr const uint8_t VMM_PAGE_READABLE = READ;
/// 可写位s
static constexpr const uint8_t VMM_PAGE_WRITABLE = WRITE;
/// 可执行位
static constexpr const uint8_t VMM_PAGE_EXECUTABLE = EXEC;
/// 用户位
static constexpr const uint8_t VMM_PAGE_USER = USER;
/// 全局位,我们不会使用
static constexpr const uint8_t VMM_PAGE_GLOBAL = GLOBAL;
/// 已使用位,用于替换算法
static constexpr const uint8_t VMM_PAGE_ACCESSED = ACCESSED;
/// 已修改位,用于替换算法
static constexpr const uint8_t VMM_PAGE_DIRTY = DIRTY;
/// 内核虚拟地址相对物理地址的偏移
static constexpr const size_t KERNEL_OFFSET = 0x0;
/// PTE 属性位数
static constexpr const size_t VMM_PTE_PROP_BITS = 10;
/// PTE 页内偏移位数
static constexpr const size_t VMM_PAGE_OFF_BITS = 12;
/// VPN 位数
static constexpr const size_t VMM_VPN_BITS = 9;
/// VPN 位数掩码,9 位 VPN
static constexpr const size_t VMM_VPN_BITS_MASK = 0x1FF;
/// riscv64 使用了三级页表
static constexpr const size_t VMM_PT_LEVEL = 3;

// 开启 PG
inline void EnablePage() {
kAllCsr.satp.asid.Write(0);
kAllCsr.satp.mode.Write(register_info::csr::SatpInfo::kSv39);
}
inline void DisablePage() {
kAllCsr.satp.mode.Write(register_info::csr::SatpInfo::kBare);
}

/**
* @brief 设置 页目录
* @param _pgd 要设置的页表
* @return true 成功
* @return false 失败
*/
inline void SetPageDirectory(uint64_t pgd) { kAllCsr.satp.ppn.Write(pgd); }

/**
* @brief 获取页目录
* @return uint64_t 页目录值
*/
inline uint64_t GetPageDirectory() { return kAllCsr.satp.ppn.Get(); }

inline void FlushPage(uint64_t addr) {
(void)addr;
__asm__ volatile("sfence.vma zero, zero");
}

} // namespace vmm
} // namespace cpu

#endif // SIMPLEKERNEL_SRC_KERNEL_ARCH_RISCV64_INCLUDE_CPU_CPU_HPP_
31 changes: 31 additions & 0 deletions src/kernel/arch/riscv64/include/cpu/regs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,37 @@
*/
namespace cpu {

// namespace vmm_info {
// /// 有效位
// static constexpr const uint8_t VMM_PAGE_VALID = CPU::pte_t::VALID;
// /// 可读位
// static constexpr const uint8_t VMM_PAGE_READABLE = CPU::pte_t::READ;
// /// 可写位s
// static constexpr const uint8_t VMM_PAGE_WRITABLE = CPU::pte_t::WRITE;
// /// 可执行位
// static constexpr const uint8_t VMM_PAGE_EXECUTABLE = CPU::pte_t::EXEC;
// /// 用户位
// static constexpr const uint8_t VMM_PAGE_USER = CPU::pte_t::USER;
// /// 全局位,我们不会使用
// static constexpr const uint8_t VMM_PAGE_GLOBAL = CPU::pte_t::GLOBAL;
// /// 已使用位,用于替换算法
// static constexpr const uint8_t VMM_PAGE_ACCESSED = CPU::pte_t::ACCESSED;
// /// 已修改位,用于替换算法
// static constexpr const uint8_t VMM_PAGE_DIRTY = CPU::pte_t::DIRTY;
// /// 内核虚拟地址相对物理地址的偏移
// static constexpr const size_t KERNEL_OFFSET = 0x0;
// /// PTE 属性位数
// static constexpr const size_t VMM_PTE_PROP_BITS = 10;
// /// PTE 页内偏移位数
// static constexpr const size_t VMM_PAGE_OFF_BITS = 12;
// /// VPN 位数
// static constexpr const size_t VMM_VPN_BITS = 9;
// /// VPN 位数掩码,9 位 VPN
// static constexpr const size_t VMM_VPN_BITS_MASK = 0x1FF;
// /// riscv64 使用了三级页表
// static constexpr const size_t VMM_PT_LEVEL = 3;
// }; // namespace vmm_info

// 第一部分:寄存器定义
namespace register_info {

Expand Down
47 changes: 47 additions & 0 deletions src/kernel/arch/x86_64/include/cpu/cpu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,53 @@ struct InterruptContextErrorCode {
}
};

namespace vmm {
/// P = 1 表示有效; P = 0 表示无效。
static constexpr const uint8_t VMM_PAGE_VALID = 1 << 0;
/// 如果为 0 表示页面只读或可执行。
static constexpr const uint8_t VMM_PAGE_READABLE = 0;
static constexpr const uint8_t VMM_PAGE_WRITABLE = 1 << 1;
static constexpr const uint8_t VMM_PAGE_EXECUTABLE = 0;
/// U/S-- 位 2 是用户 / 超级用户 (User/Supervisor) 标志。
/// 如果为 1 那么运行在任何特权级上的程序都可以访问该页面。
static constexpr const uint8_t VMM_PAGE_USER = 1 << 2;
/// 内核虚拟地址相对物理地址的偏移
static constexpr const size_t KERNEL_OFFSET = 0x0;
/// PTE 属性位数
static constexpr const size_t VMM_PTE_PROP_BITS = 12;
/// PTE 页内偏移位数
static constexpr const size_t VMM_PAGE_OFF_BITS = 12;
/// VPN 位数
static constexpr const size_t VMM_VPN_BITS = 9;
/// VPN 位数掩码,9 位 VPN
static constexpr const size_t VMM_VPN_BITS_MASK = 0x1FF;
/// x86_64 使用了四级页表
static constexpr const size_t VMM_PT_LEVEL = 4;

// 开启 PG
inline void EnablePage() { kAllCr.cr0.pg.Set(); }
inline void DisablePage() { kAllCr.cr0.pg.Clear(); }

/**
* @brief 设置 页目录
* @param _pgd 要设置的页表
* @return true 成功
* @return false 失败
*/
inline void SetPageDirectory(uint64_t pgd) { kAllCr.cr3.Write(pgd); }

/**
* @brief 获取页目录 CR3
* @return uint64_t CR3 值
*/
inline uint64_t GetPageDirectory() { return kAllCr.cr3.Read(); }

inline void FlushPage(uint64_t addr) {
__asm__ volatile("invlpg (%0)" : : "r"(addr) : "memory");
}

}; // namespace vmm

}; // namespace cpu

#endif // SIMPLEKERNEL_SRC_KERNEL_ARCH_X86_64_INCLUDE_CPU_CPU_HPP_
21 changes: 19 additions & 2 deletions src/kernel/arch/x86_64/include/cpu/regs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -999,7 +999,15 @@ class WriteOnlyRegBase {
klog::Err("TODO\n");
} else if constexpr (std::is_same<RegInfo,
register_info::cr::Cr0Info>::value) {
__asm__ volatile("bts %%cr0, %0" : : "r"(offset) :);
// __asm__ volatile("bts %%cr0, %0" : : "r"(offset) :);
uint64_t value;
__asm__ volatile(
"mov %%cr0, %0\n\t"
"bts %1, %0\n\t"
"mov %0, %%cr0"
: "=r"(value)
: "r"(offset)
: "memory");
} else if constexpr (std::is_same<RegInfo,
register_info::cr::Cr2Info>::value) {
__asm__ volatile("bts %%cr2, %0" : : "r"(offset) :);
Expand Down Expand Up @@ -1059,7 +1067,16 @@ class WriteOnlyRegBase {
klog::Err("TODO\n");
} else if constexpr (std::is_same<RegInfo,
register_info::cr::Cr0Info>::value) {
__asm__ volatile("btr %%cr0, %0" : : "r"(offset) :);
// __asm__ volatile("btr %%cr0, %0" : : "r"(offset) :);
// __asm__ volatile("bts %%cr0, %0" : : "r"(offset) :);
uint64_t value;
__asm__ volatile(
"mov %%cr0, %0\n\t"
"btr %1, %0\n\t"
"mov %0, %%cr0"
: "=r"(value)
: "r"(offset)
: "memory");
} else if constexpr (std::is_same<RegInfo,
register_info::cr::Cr2Info>::value) {
__asm__ volatile("btr %%cr2, %0" : : "r"(offset) :);
Expand Down
4 changes: 4 additions & 0 deletions src/kernel/include/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,8 @@ uint32_t main(uint32_t argc, uint8_t* argv);

uint32_t InterruptInit(uint32_t argc, uint8_t* argv);

uint32_t PhysicalMemoryInit(uint32_t argc, uint8_t* argv);

uint32_t VirtualMemoryInit(uint32_t argc, uint8_t* argv);

#endif /* SIMPLEKERNEL_SRC_KERNEL_INCLUDE_KERNEL_H_ */
Loading
Loading