x86_64: 使用Rust重写内核初始化代码 (#507)

* x86_64: 使用Rust重写内核初始化代码
This commit is contained in:
LoGin 2024-02-04 15:46:24 +08:00 committed by GitHub
parent 453452cc02
commit 5b59005f93
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
52 changed files with 494 additions and 475 deletions

View File

@ -19,6 +19,8 @@ members = [
default = ["backtrace"]
# 内核栈回溯
backtrace = []
# kvm
kvm = []
# 运行时依赖项

View File

@ -1,13 +1,12 @@
use core::intrinsics::unreachable;
use fdt::node::FdtNode;
use system_error::SystemError;
use crate::{
arch::mm::init::mm_early_init,
driver::{firmware::efi::init::efi_init, open_firmware::fdt::open_firmware_fdt_driver},
init::{boot_params, init_before_mem_init},
init::{boot_params, init::start_kernel},
kdebug, kinfo,
mm::{init::mm_init, memblock::mem_block_manager, PhysAddr, VirtAddr},
mm::{memblock::mem_block_manager, PhysAddr, VirtAddr},
print, println,
};
@ -33,37 +32,19 @@ impl ArchBootParams {
}
}
static mut BOOT_HARTID: usize = 0;
static mut BOOT_FDT_PADDR: PhysAddr = PhysAddr::new(0);
#[no_mangle]
unsafe extern "C" fn kernel_main(hartid: usize, fdt_paddr: usize) -> ! {
let fdt_paddr = PhysAddr::new(fdt_paddr);
// system_reset(sbi::reset::ResetType::Shutdown, sbi::reset::ResetReason::NoReason);
init_before_mem_init();
boot_params().write().arch.fdt_paddr = fdt_paddr;
kinfo!(
"DragonOS kernel is running on hart {}, fdt address:{:?}",
hartid,
fdt_paddr
);
mm_early_init();
let fdt = fdt::Fdt::from_ptr(fdt_paddr.data() as *const u8).expect("Failed to parse fdt!");
print_node(fdt.find_node("/").unwrap(), 0);
parse_dtb();
for x in mem_block_manager().to_iter() {
kdebug!("before efi: {x:?}");
unsafe {
BOOT_HARTID = hartid;
BOOT_FDT_PADDR = fdt_paddr;
}
efi_init();
open_firmware_fdt_driver().early_init_fdt_scan_reserved_mem();
mm_init();
loop {}
unreachable()
start_kernel();
}
#[inline(never)]
@ -92,3 +73,44 @@ unsafe fn parse_dtb() {
.early_scan_device_tree()
.expect("Failed to scan device tree at boottime.");
}
#[inline(never)]
pub fn early_setup_arch() -> Result<(), SystemError> {
let hartid = unsafe { BOOT_HARTID };
let fdt_paddr = unsafe { BOOT_FDT_PADDR };
boot_params().write().arch.fdt_paddr = fdt_paddr;
kinfo!(
"DragonOS kernel is running on hart {}, fdt address:{:?}",
hartid,
fdt_paddr
);
mm_early_init();
let fdt =
unsafe { fdt::Fdt::from_ptr(fdt_paddr.data() as *const u8).expect("Failed to parse fdt!") };
print_node(fdt.find_node("/").unwrap(), 0);
unsafe { parse_dtb() };
for x in mem_block_manager().to_iter() {
kdebug!("before efi: {x:?}");
}
efi_init();
open_firmware_fdt_driver().early_init_fdt_scan_reserved_mem();
return Ok(());
}
#[inline(never)]
pub fn setup_arch() -> Result<(), SystemError> {
// todo
return Ok(());
}
#[inline(never)]
pub fn setup_arch_post() -> Result<(), SystemError> {
// todo
return Ok(());
}

View File

@ -13,6 +13,7 @@ pub mod pio;
pub mod process;
pub mod rand;
pub mod sched;
pub mod smp;
pub mod syscall;
pub mod time;
@ -24,3 +25,7 @@ pub use self::pio::RiscV64PortIOArch as CurrentPortIOArch;
pub use self::time::RiscV64TimeArch as CurrentTimeArch;
pub use self::elf::RiscV64ElfArch as CurrentElfArch;
pub use crate::arch::smp::RiscV64SMPArch as CurrentSMPArch;
pub use crate::arch::sched::RiscV64SchedArch as CurrentSchedArch;

View File

@ -0,0 +1,19 @@
use core::hint::spin_loop;
use crate::{arch::CurrentIrqArch, exception::InterruptArch, kBUG, process::ProcessManager};
impl ProcessManager {
/// 每个核的idle进程
pub fn arch_idle_func() -> ! {
loop {
if CurrentIrqArch::is_irq_enabled() {
unsafe {
riscv::asm::wfi();
}
} else {
kBUG!("Idle process should not be scheduled with IRQs disabled.");
spin_loop();
}
}
}
}

View File

@ -5,6 +5,7 @@ use crate::process::{fork::KernelCloneArgs, KernelStack, ProcessControlBlock, Pr
use super::interrupt::TrapFrame;
pub mod idle;
pub mod kthread;
pub mod syscall;

View File

@ -1,5 +1,23 @@
use crate::sched::SchedArch;
/// 发起调度
#[no_mangle]
pub extern "C" fn sched() {
unimplemented!("RiscV64::sched")
}
pub struct RiscV64SchedArch;
impl SchedArch for RiscV64SchedArch {
fn enable_sched_local() {
todo!()
}
fn disable_sched_local() {
todo!()
}
fn initial_setup_sched_local() {
todo!()
}
}

View File

@ -0,0 +1,15 @@
use system_error::SystemError;
use crate::smp::SMPArch;
pub struct RiscV64SMPArch;
impl SMPArch for RiscV64SMPArch {
fn prepare_cpus() -> Result<(), SystemError> {
todo!()
}
fn init() -> Result<(), SystemError> {
todo!()
}
}

View File

@ -417,15 +417,16 @@ repeat_set_idt:
pushq %rax
//
movq mb2_info, %rdi
movq mb2_magic, %rsi
movq %r13, %rdx // GDT size
movq %r12, %r10 // IDT size
movq mb2_info, %r15
movq mb2_magic, %r14
lretq
go_to_kernel:
.quad Start_Kernel
.quad kernel_main
start_smp:

View File

@ -1,15 +1,6 @@
use crate::time::TimeArch;
use super::{
driver::tsc::TSCManager, setup::setup_arch, syscall::init_syscall_64, CurrentTimeArch,
};
#[no_mangle]
unsafe extern "C" fn rs_setup_arch() -> i32 {
return setup_arch()
.map(|_| 0)
.unwrap_or_else(|e| e.to_posix_errno());
}
use super::{driver::tsc::TSCManager, syscall::init_syscall_64, CurrentTimeArch};
/// 获取当前的时间戳
#[no_mangle]

View File

@ -1,29 +1,4 @@
use super::{
hpet::{hpet_init, hpet_instance},
tsc::TSCManager,
};
#[no_mangle]
unsafe extern "C" fn rs_hpet_init() -> i32 {
hpet_init()
.map(|_| 0)
.unwrap_or_else(|e| e.to_posix_errno())
}
#[no_mangle]
unsafe extern "C" fn rs_hpet_enable() -> i32 {
hpet_instance()
.hpet_enable()
.map(|_| 0)
.unwrap_or_else(|e| e.to_posix_errno())
}
#[no_mangle]
unsafe extern "C" fn rs_tsc_init() -> i32 {
TSCManager::init()
.map(|_| 0)
.unwrap_or_else(|e| e.to_posix_errno())
}
use super::hpet::hpet_instance;
#[no_mangle]
unsafe extern "C" fn rs_handle_hpet_irq(timer_num: u32) {

View File

@ -106,7 +106,7 @@ impl Hpet {
}
/// 使能HPET
pub(super) fn hpet_enable(&self) -> Result<(), SystemError> {
pub fn hpet_enable(&self) -> Result<(), SystemError> {
// 这里是临时糊代码的需要在apic重构的时候修改
let (inner_guard, regs) = unsafe { self.hpet_regs_mut() };
let freq = regs.frequency();

View File

@ -2,207 +2,10 @@
// Created by longjin on 2022/1/20.
//
#include "common/glib.h"
#include "common/kprint.h"
#include "common/printk.h"
#include "exception/gate.h"
#include "exception/irq.h"
#include "exception/trap.h"
#include "mm/mm.h"
#include "mm/slab.h"
#include "process/process.h"
#include "smp/smp.h"
#include "syscall/syscall.h"
#include <exception/softirq.h>
#include <libs/lib_ui/screen_manager.h>
#include <libs/lib_ui/textui.h>
#include <sched/sched.h>
#include <smp/ipi.h>
#include <common/cpu.h>
#include <filesystem/vfs/VFS.h>
#include "driver/acpi/acpi.h"
#include "driver/disk/ata.h"
#include "driver/multiboot2/multiboot2.h"
#include <time/timer.h>
#include <arch/x86_64/driver/apic/apic_timer.h>
#include <debug/bug.h>
#include <virt/kvm/kvm.h>
extern int rs_driver_init();
extern void rs_softirq_init();
extern void rs_mm_init();
extern void rs_kthread_init();
extern void rs_init_intertrait();
extern void rs_init_before_mem_init();
extern int rs_setup_arch();
extern void rs_futex_init();
extern int rs_hpet_init();
extern int rs_hpet_enable();
extern int rs_tsc_init();
extern void rs_clocksource_boot_finish();
extern void rs_timekeeping_init();
extern void rs_process_init();
extern void rs_textui_init();
extern void rs_pci_init();
ul bsp_idt_size, bsp_gdt_size;
#pragma GCC push_options
#pragma GCC optimize("O0")
struct gdtr gdtp;
struct idtr idtp;
ul _stack_start;
void reload_gdt() {
gdtp.size = bsp_gdt_size - 1;
gdtp.gdt_vaddr = (ul)phys_2_virt((ul)&GDT_Table);
asm volatile("lgdt (%0) \n\t" ::"r"(&gdtp) : "memory");
void __init_set_cpu_stack_start(uint32_t cpu, uint64_t stack_start)
{
cpu_core_info[cpu].stack_start = stack_start;
}
void reload_idt() {
idtp.size = bsp_idt_size - 1;
idtp.idt_vaddr = (ul)phys_2_virt((ul)&IDT_Table);
// kdebug("gdtvaddr=%#018lx", p.gdt_vaddr);
// kdebug("gdt size=%d", p.size);
asm volatile("lidt (%0) \n\t" ::"r"(&idtp) : "memory");
}
// 初始化系统各模块
void system_initialize() {
rs_init_before_mem_init();
_stack_start =
head_stack_start; // 保存init
// proc的栈基地址由于之后取消了地址重映射因此必须在这里重新保存
kdebug("_stack_start=%#018lx", _stack_start);
set_current_core_tss(_stack_start, 0);
rs_load_current_core_tss();
cpu_core_info[0].stack_start = _stack_start;
// 初始化中断描述符表
sys_vector_init();
// 初始化内存管理单元
// mm_init();
rs_mm_init();
// 内存管理单元初始化完毕后,需要立即重新初始化显示驱动。
// 原因是系统启动初期framebuffer被映射到48M地址处
// mm初始化完毕后若不重新初始化显示驱动将会导致错误的数据写入内存从而造成其他模块崩溃
// 对显示模块进行低级初始化不启用double buffer
io_mfence();
scm_reinit();
rs_textui_init();
rs_init_intertrait();
// kinfo("vaddr:%#018lx", video_frame_buffer_info.vaddr);
io_mfence();
vfs_init();
rs_driver_init();
acpi_init();
rs_setup_arch();
io_mfence();
irq_init();
rs_process_init();
sched_init();
sti();
io_mfence();
rs_softirq_init();
syscall_init();
io_mfence();
rs_timekeeping_init();
io_mfence();
rs_timer_init();
io_mfence();
rs_jiffies_init();
io_mfence();
rs_kthread_init();
io_mfence();
io_mfence();
rs_clocksource_boot_finish();
io_mfence();
cpu_init();
io_mfence();
rs_pci_init();
// 这里必须加内存屏障,否则会出错
io_mfence();
smp_init();
io_mfence();
rs_futex_init();
cli();
rs_hpet_init();
rs_hpet_enable();
rs_tsc_init();
io_mfence();
kvm_init();
io_mfence();
// 系统初始化到此结束,剩下的初始化功能应当放在初始内核线程中执行
apic_timer_init();
// while(1);
io_mfence();
sti();
while (1)
;
}
// 操作系统内核从这里开始执行
void Start_Kernel(void) {
// 获取multiboot2的信息
uint64_t mb2_info, mb2_magic;
__asm__ __volatile__("movq %%r15, %0 \n\t"
"movq %%r14, %1 \n\t"
"movq %%r13, %2 \n\t"
"movq %%r12, %3 \n\t"
: "=r"(mb2_info), "=r"(mb2_magic), "=r"(bsp_gdt_size),
"=r"(bsp_idt_size)::"memory");
reload_gdt();
reload_idt();
mb2_info &= 0xffffffff;
mb2_magic &= 0xffffffff;
multiboot2_init(mb2_info, mb2_magic);
io_mfence();
system_initialize();
io_mfence();
// idle
while (1) {
// 如果调用的时候启用了中断则hlt。否则认为是bug
if (get_rflags() & 0x200) {
// kdebug("hlt");
hlt();
} else {
BUG_ON(1);
pause();
}
}
}
#pragma GCC pop_options

View File

@ -1,6 +1,123 @@
use core::sync::atomic::{compiler_fence, Ordering};
use system_error::SystemError;
use x86::dtables::DescriptorTablePointer;
use crate::{
arch::process::table::TSSManager,
driver::pci::pci::pci_init,
include::bindings::bindings::{cpu_init, irq_init},
init::init::start_kernel,
kdebug,
mm::{MemoryManagementArch, PhysAddr},
};
use super::{
driver::{
hpet::{hpet_init, hpet_instance},
tsc::TSCManager,
},
MMArch,
};
#[derive(Debug)]
pub struct ArchBootParams {}
impl ArchBootParams {
pub const DEFAULT: Self = ArchBootParams {};
}
extern "C" {
static mut GDT_Table: [usize; 0usize];
static mut IDT_Table: [usize; 0usize];
fn head_stack_start();
fn multiboot2_init(mb2_info: u64, mb2_magic: u32) -> bool;
fn __init_set_cpu_stack_start(cpu: u32, stack_start: u64);
fn sys_vector_init();
}
#[no_mangle]
unsafe extern "C" fn kernel_main(
mb2_info: u64,
mb2_magic: u64,
bsp_gdt_size: u64,
bsp_idt_size: u64,
) -> ! {
let mut gdtp = DescriptorTablePointer::<usize>::default();
let gdt_vaddr =
MMArch::phys_2_virt(PhysAddr::new(&GDT_Table as *const usize as usize)).unwrap();
let idt_vaddr =
MMArch::phys_2_virt(PhysAddr::new(&IDT_Table as *const usize as usize)).unwrap();
gdtp.base = gdt_vaddr.data() as *const usize;
gdtp.limit = bsp_gdt_size as u16 - 1;
let mut idtp = DescriptorTablePointer::<usize>::default();
idtp.base = idt_vaddr.data() as *const usize;
idtp.limit = bsp_idt_size as u16 - 1;
x86::dtables::lgdt(&gdtp);
x86::dtables::lidt(&idtp);
compiler_fence(Ordering::SeqCst);
multiboot2_init(mb2_info, (mb2_magic & 0xFFFF_FFFF) as u32);
compiler_fence(Ordering::SeqCst);
start_kernel();
}
/// 在内存管理初始化之前的架构相关的早期初始化
#[inline(never)]
pub fn early_setup_arch() -> Result<(), SystemError> {
let stack_start = unsafe { *(head_stack_start as *const u64) } as usize;
kdebug!("head_stack_start={:#x}\n", stack_start);
unsafe {
let gdt_vaddr =
MMArch::phys_2_virt(PhysAddr::new(&GDT_Table as *const usize as usize)).unwrap();
let idt_vaddr =
MMArch::phys_2_virt(PhysAddr::new(&IDT_Table as *const usize as usize)).unwrap();
kdebug!("GDT_Table={:?}, IDT_Table={:?}\n", gdt_vaddr, idt_vaddr);
}
set_current_core_tss(stack_start, 0);
unsafe { TSSManager::load_tr() };
unsafe { __init_set_cpu_stack_start(0, stack_start as u64) };
unsafe { sys_vector_init() };
return Ok(());
}
/// 架构相关的初始化
#[inline(never)]
pub fn setup_arch() -> Result<(), SystemError> {
unsafe {
irq_init();
cpu_init();
}
// todo: 将来pci接入设备驱动模型之后删掉这里。
pci_init();
return Ok(());
}
/// 架构相关的初始化在IDLE的最后一个阶段
#[inline(never)]
pub fn setup_arch_post() -> Result<(), SystemError> {
hpet_init().expect("hpet init failed");
hpet_instance().hpet_enable().expect("hpet enable failed");
TSCManager::init().expect("tsc init failed");
return Ok(());
}
fn set_current_core_tss(stack_start: usize, ist0: usize) {
let current_tss = unsafe { TSSManager::current_tss() };
kdebug!(
"set_current_core_tss: stack_start={:#x}, ist0={:#x}\n",
stack_start,
ist0
);
current_tss.set_rsp(x86::Ring::Ring0, stack_start as u64);
current_tss.set_ist(0, ist0 as u64);
}

View File

@ -17,7 +17,6 @@ pub mod pci;
pub mod process;
pub mod rand;
pub mod sched;
pub mod setup;
pub mod smp;
pub mod syscall;
pub mod time;
@ -36,3 +35,7 @@ pub use crate::arch::ipc::signal::X86_64SignalArch as CurrentSignalArch;
pub use crate::arch::time::X86_64TimeArch as CurrentTimeArch;
pub use crate::arch::elf::X86_64ElfArch as CurrentElfArch;
pub use crate::arch::smp::X86_64SMPArch as CurrentSMPArch;
pub use crate::arch::sched::X86_64SchedArch as CurrentSchedArch;

View File

@ -1,20 +0,0 @@
use crate::kdebug;
use super::table::TSSManager;
#[no_mangle]
unsafe extern "C" fn set_current_core_tss(stack_start: usize, ist0: usize) {
let current_tss = TSSManager::current_tss();
kdebug!(
"set_current_core_tss: stack_start={:#x}, ist0={:#x}\n",
stack_start,
ist0
);
current_tss.set_rsp(x86::Ring::Ring0, stack_start as u64);
current_tss.set_ist(0, ist0 as u64);
}
#[no_mangle]
unsafe extern "C" fn rs_load_current_core_tss() {
TSSManager::load_tr();
}

View File

@ -0,0 +1,19 @@
use core::hint::spin_loop;
use crate::{arch::CurrentIrqArch, exception::InterruptArch, kBUG, process::ProcessManager};
impl ProcessManager {
/// 每个核的idle进程
pub fn arch_idle_func() -> ! {
loop {
if CurrentIrqArch::is_irq_enabled() {
unsafe {
x86::halt();
}
} else {
kBUG!("Idle process should not be scheduled with IRQs disabled.");
spin_loop();
}
}
}
}

View File

@ -40,7 +40,7 @@ use self::{
use super::{fpu::FpState, interrupt::TrapFrame, syscall::X86_64GSData, CurrentIrqArch};
mod c_adapter;
pub mod idle;
pub mod kthread;
pub mod syscall;
pub mod table;

View File

@ -1,4 +1,9 @@
use crate::{include::bindings::bindings::enter_syscall_int, syscall::SYS_SCHED};
use crate::{
exception::InterruptArch, include::bindings::bindings::enter_syscall_int, sched::SchedArch,
syscall::SYS_SCHED,
};
use super::CurrentIrqArch;
/// @brief 若内核代码不处在中断上下文中那么将可以使用本函数发起一个sys_sched系统调用然后运行调度器。
/// 由于只能在中断上下文中进行进程切换因此需要发起一个系统调用SYS_SCHED。
@ -8,3 +13,28 @@ pub extern "C" fn sched() {
enter_syscall_int(SYS_SCHED as u64, 0, 0, 0, 0, 0, 0, 0, 0);
}
}
extern "C" {
fn apic_timer_init();
}
pub struct X86_64SchedArch;
impl SchedArch for X86_64SchedArch {
fn enable_sched_local() {
// fixme: 这里将来可能需要更改,毕竟这个直接开关中断有点暴力。
unsafe { CurrentIrqArch::interrupt_enable() };
}
fn disable_sched_local() {
unsafe {
CurrentIrqArch::interrupt_disable();
}
}
fn initial_setup_sched_local() {
unsafe {
apic_timer_init();
}
}
}

View File

@ -1,10 +0,0 @@
use system_error::SystemError;
use super::{acpi::early_acpi_boot_init, smp::X86_64_SMP_MANAGER};
/// 进行架构相关的初始化工作
pub fn setup_arch() -> Result<(), SystemError> {
early_acpi_boot_init()?;
X86_64_SMP_MANAGER.build_cpu_map()?;
return Ok(());
}

View File

@ -8,12 +8,17 @@ use kdepends::memoffset::offset_of;
use system_error::SystemError;
use crate::{
arch::process::table::TSSManager, exception::InterruptArch,
include::bindings::bindings::cpu_core_info, kdebug, libs::rwlock::RwLock, mm::percpu::PerCpu,
process::ProcessManager, smp::core::smp_get_processor_id,
arch::process::table::TSSManager,
exception::InterruptArch,
include::bindings::bindings::{cpu_core_info, smp_init},
kdebug,
libs::rwlock::RwLock,
mm::percpu::PerCpu,
process::ProcessManager,
smp::{core::smp_get_processor_id, SMPArch},
};
use super::CurrentIrqArch;
use super::{acpi::early_acpi_boot_init, CurrentIrqArch};
extern "C" {
fn smp_ap_start_stage2();
@ -139,3 +144,22 @@ impl X86_64SmpManager {
return Ok(());
}
}
pub struct X86_64SMPArch;
impl SMPArch for X86_64SMPArch {
#[inline(never)]
fn prepare_cpus() -> Result<(), SystemError> {
early_acpi_boot_init()?;
X86_64_SMP_MANAGER.build_cpu_map()?;
return Ok(());
}
#[inline(never)]
fn init() -> Result<(), SystemError> {
x86::fence::mfence();
unsafe { smp_init() };
x86::fence::mfence();
return Ok(());
}
}

View File

@ -32,7 +32,6 @@
#define EUNSUPPORTED 3 // 当前操作暂不被支持
#include "glib.h"
#include <libs/lib_ui/screen_manager.h>
#include <stdarg.h>
/**

View File

@ -1,10 +0,0 @@
use super::init::driver_init;
#[no_mangle]
unsafe extern "C" fn rs_driver_init() -> i32 {
let result = driver_init()
.map(|_| 0)
.unwrap_or_else(|e| e.to_posix_errno());
return result;
}

View File

@ -10,7 +10,9 @@ use super::{
platform::platform_bus_init,
};
pub(super) fn driver_init() -> Result<(), SystemError> {
/// 初始化设备驱动模型
#[inline(never)]
pub fn driver_init() -> Result<(), SystemError> {
devices_init()?;
buses_init()?;
classes_init()?;

View File

@ -1,5 +1,4 @@
pub mod block;
pub mod c_adapter;
pub mod char;
pub mod class;
pub mod cpu;

View File

@ -1090,25 +1090,9 @@ fn pci_check_bus(bus: u8) -> Result<u8, PciError> {
}
Ok(0)
}
/// @brief pci初始化函数(for c)
#[no_mangle]
pub extern "C" fn rs_pci_init() {
pci_init();
if PCI_ROOT_0.is_some() {
kdebug!("{}", PCI_ROOT_0.as_ref().unwrap());
//以下为ecam的读取寄存器值测试经测试可正常读取
// let bus_device_function = BusDeviceFunction {
// bus: 0,
// device: 2,
// function: 0,
// };
// kdebug!(
// "Ecam read virtio-net device status={:#x}",
// (PCI_ROOT_0.unwrap().read_config(bus_device_function, 4)>>16) as u16
// );
}
}
/// @brief pci初始化函数
/// pci初始化函数
#[inline(never)]
pub fn pci_init() {
kinfo!("Initializing PCI bus...");
if let Err(e) = pci_check_all_buses() {

View File

@ -32,6 +32,7 @@ pub extern "C" fn rs_softirq_init() {
softirq_init().expect("softirq_init failed");
}
#[inline(never)]
pub fn softirq_init() -> Result<(), SystemError> {
kinfo!("Initializing softirq...");
unsafe {

View File

@ -47,8 +47,9 @@ pub fn ROOT_INODE() -> Arc<dyn IndexNode> {
}
}
#[no_mangle]
pub extern "C" fn vfs_init() -> i32 {
/// 初始化虚拟文件系统
#[inline(never)]
pub fn vfs_init() -> Result<(), SystemError> {
// 使用Ramfs作为默认的根文件系统
let ramfs = RamFS::new();
let mount_fs = MountFS::new(ramfs, None);
@ -80,7 +81,7 @@ pub extern "C" fn vfs_init() -> i32 {
if root_entries.len() > 0 {
kinfo!("Successfully initialized VFS!");
}
return 0;
return Ok(());
}
/// @brief 真正执行伪文件系统迁移的过程

View File

@ -1,11 +0,0 @@
use super::{init_before_mem_init, init_intertrait};
#[no_mangle]
unsafe extern "C" fn rs_init_intertrait() {
init_intertrait();
}
#[no_mangle]
unsafe extern "C" fn rs_init_before_mem_init() {
init_before_mem_init();
}

84
kernel/src/init/init.rs Normal file
View File

@ -0,0 +1,84 @@
use crate::{
arch::{
init::{early_setup_arch, setup_arch, setup_arch_post},
CurrentIrqArch, CurrentSMPArch, CurrentSchedArch,
},
driver::{base::init::driver_init, tty::init::tty_early_init, video::VideoRefreshManager},
exception::{softirq::softirq_init, InterruptArch},
filesystem::vfs::core::vfs_init,
include::bindings::bindings::acpi_init,
init::init_intertrait,
libs::{
futex::futex::Futex,
lib_ui::{
screen_manager::{scm_init, scm_reinit},
textui::textui_init,
},
},
mm::init::mm_init,
process::{kthread::kthread_init, process_init, ProcessManager},
sched::{core::sched_init, SchedArch},
smp::SMPArch,
syscall::Syscall,
time::{
clocksource::clocksource_boot_finish, timekeeping::timekeeping_init, timer::timer_init,
},
};
/// The entry point for the kernel
///
/// 前面可能会有一个架构相关的函数
pub fn start_kernel() -> ! {
// 进入内核后,中断应该是关闭的
assert_eq!(CurrentIrqArch::is_irq_enabled(), false);
do_start_kernel();
CurrentSchedArch::initial_setup_sched_local();
CurrentSchedArch::enable_sched_local();
ProcessManager::arch_idle_func();
}
#[inline(never)]
fn do_start_kernel() {
init_before_mem_init();
early_setup_arch().expect("setup_arch failed");
unsafe { mm_init() };
scm_reinit().unwrap();
textui_init().unwrap();
init_intertrait();
vfs_init().expect("vfs init failed");
driver_init().expect("driver init failed");
unsafe { acpi_init() };
CurrentSMPArch::prepare_cpus().expect("prepare_cpus failed");
setup_arch().expect("setup_arch failed");
process_init();
sched_init();
softirq_init().expect("softirq init failed");
Syscall::init().expect("syscall init failed");
timekeeping_init();
timer_init();
kthread_init();
clocksource_boot_finish();
CurrentSMPArch::init().expect("smp init failed");
// SMP初始化有可能会开中断所以这里再次检查中断是否关闭
assert_eq!(CurrentIrqArch::is_irq_enabled(), false);
Futex::init();
setup_arch_post().expect("setup_arch_post failed");
#[cfg(all(target_arch = "x86_64", feature = "kvm"))]
crate::virt::kvm::kvm_init();
}
/// 在内存管理初始化之前,执行的初始化
#[inline(never)]
fn init_before_mem_init() {
tty_early_init().expect("tty early init failed");
let video_ok = unsafe { VideoRefreshManager::video_init().is_ok() };
scm_init(video_ok);
}

View File

@ -2,16 +2,12 @@ use core::cmp::min;
use crate::{
arch::init::ArchBootParams,
driver::{
tty::init::tty_early_init,
video::{fbdev::base::BootTimeScreenInfo, VideoRefreshManager},
},
libs::{lib_ui::screen_manager::scm_init, rwlock::RwLock},
driver::video::fbdev::base::BootTimeScreenInfo,
libs::rwlock::RwLock,
mm::{PhysAddr, VirtAddr},
};
mod c_adapter;
pub mod init;
pub mod initcall;
pub mod initial_kthread;
@ -23,18 +19,11 @@ pub fn boot_params() -> &'static RwLock<BootParams> {
&BOOT_PARAMS
}
#[inline(never)]
fn init_intertrait() {
intertrait::init_caster_map();
}
/// 在内存管理初始化之前,执行的初始化
#[inline(never)]
pub fn init_before_mem_init() {
tty_early_init().expect("tty early init failed");
let video_ok = unsafe { VideoRefreshManager::video_init().is_ok() };
scm_init(video_ok);
}
#[derive(Debug)]
pub struct BootParams {
pub screen_info: BootTimeScreenInfo,

View File

@ -640,8 +640,3 @@ impl Futex {
Ok(*oldval)
}
}
#[no_mangle]
unsafe extern "C" fn rs_futex_init() {
Futex::init();
}

View File

@ -1,7 +0,0 @@
#pragma once
/**
* @brief
*
*/
extern void scm_reinit();

View File

@ -409,15 +409,15 @@ pub fn scm_disable_put_to_window() {
}
}
/// 当内存管理单元被初始化之后,重新处理帧缓冲区问题
#[no_mangle]
pub extern "C" fn scm_reinit() -> i32 {
let r = true_scm_reinit().unwrap_or_else(|e| e.to_posix_errno());
if r.is_negative() {
#[inline(never)]
pub fn scm_reinit() -> Result<(), SystemError> {
let r = true_scm_reinit();
if r.is_err() {
send_to_default_serial8250_port("scm reinit failed.\n\0".as_bytes());
}
return r;
}
fn true_scm_reinit() -> Result<i32, SystemError> {
fn true_scm_reinit() -> Result<(), SystemError> {
video_refresh_manager()
.video_reinitialize(false)
.expect("video reinitialize failed");
@ -432,5 +432,5 @@ fn true_scm_reinit() -> Result<i32, SystemError> {
scm_enable_put_to_window();
return Ok(0);
return Ok(());
}

View File

@ -10,10 +10,3 @@
* @return int
*/
extern int rs_textui_putchar(uint16_t character, uint32_t FRcolor, uint32_t BKcolor);
/**
* @brief text ui框架
*
* @return int
*/
extern int textui_init();

View File

@ -68,8 +68,8 @@ pub fn textui_framework() -> Arc<TextUiFramework> {
}
/// 初始化TEXTUI_FRAMEWORK
pub unsafe fn textui_framwork_init() {
if __TEXTUI_FRAMEWORK.is_none() {
fn textui_framwork_init() {
if unsafe { __TEXTUI_FRAMEWORK.is_none() } {
kinfo!("textuiframework init");
let metadata = ScmUiFrameworkMetadata::new("TextUI".to_string(), ScmFramworkType::Text);
kdebug!("textui metadata: {:?}", metadata);
@ -93,12 +93,14 @@ pub unsafe fn textui_framwork_init() {
Arc::new(SpinLock::new(LinkedList::new()));
window_list.lock().push_back(current_window.clone());
__TEXTUI_FRAMEWORK = Some(Arc::new(TextUiFramework::new(
metadata,
window_list,
current_window,
default_window,
)));
unsafe {
__TEXTUI_FRAMEWORK = Some(Arc::new(TextUiFramework::new(
metadata,
window_list,
current_window,
default_window,
)))
};
scm_register(textui_framework()).expect("register textui framework failed");
kdebug!("textui framework init success");
@ -1055,18 +1057,9 @@ pub fn textui_putstr(
}
/// 初始化text ui框架
#[no_mangle]
pub extern "C" fn rs_textui_init() -> i32 {
let r = textui_init().unwrap_or_else(|e| e.to_posix_errno());
if r.is_negative() {
send_to_default_serial8250_port("textui init failed.\n\0".as_bytes());
}
return r;
}
fn textui_init() -> Result<i32, SystemError> {
unsafe { textui_framwork_init() };
#[inline(never)]
pub fn textui_init() -> Result<i32, SystemError> {
textui_framwork_init();
return Ok(0);
}

View File

@ -14,9 +14,8 @@ use crate::{
};
use super::{
allocator::page_frame::PageFrameCount, init::mm_init, kernel_mapper::KernelMapper,
mmio_buddy::mmio_pool, no_init::pseudo_map_phys, page::PageFlags, MemoryManagementArch,
PhysAddr, VirtAddr,
allocator::page_frame::PageFrameCount, kernel_mapper::KernelMapper, mmio_buddy::mmio_pool,
no_init::pseudo_map_phys, page::PageFlags, MemoryManagementArch, PhysAddr, VirtAddr,
};
lazy_static! {
@ -166,8 +165,3 @@ pub unsafe extern "C" fn rs_mmio_release(vaddr: u64, length: u64) -> i32 {
.release_mmio(VirtAddr::new(vaddr as usize), length as usize)
.unwrap_or_else(|err| err.to_posix_errno());
}
#[no_mangle]
unsafe extern "C" fn rs_mm_init() {
mm_init();
}

View File

@ -17,6 +17,7 @@ pub enum MMInitStatus {
/// 内存管理的初始化状态
static MM_INIT: AtomicMMInitStatus = AtomicMMInitStatus::new(MMInitStatus::NotInit);
#[inline(never)]
pub unsafe fn mm_init() {
send_to_default_serial8250_port("mm_init\n\0".as_bytes());
PrintkWriter

View File

@ -1,17 +1,12 @@
use crate::smp::core::smp_get_processor_id;
use super::{kthread::kthread_init, process_init, ProcessManager, __PROCESS_MANAGEMENT_INIT_DONE};
use super::{process_init, ProcessManager, __PROCESS_MANAGEMENT_INIT_DONE};
#[no_mangle]
unsafe extern "C" fn rs_process_init() {
process_init();
}
#[no_mangle]
unsafe extern "C" fn rs_kthread_init() {
kthread_init();
}
/// 临时用于获取空闲进程的栈顶的函数这个函数是为了旧的smp模块的初始化而写在这的
#[no_mangle]
unsafe extern "C" fn rs_get_idle_stack_top(cpu_id: u32) -> usize {

View File

@ -490,6 +490,8 @@ pub unsafe extern "C" fn kernel_thread_bootstrap_stage2(ptr: *const KernelThread
ProcessManager::exit(retval as usize);
}
/// 初始化内核线程机制
#[inline(never)]
pub fn kthread_init() {
static INIT: Once = Once::new();
INIT.call_once(|| {

View File

@ -91,6 +91,7 @@ impl SwitchResult {
#[derive(Debug)]
pub struct ProcessManager;
impl ProcessManager {
#[inline(never)]
fn init() {
static INIT_FLAG: AtomicBool = AtomicBool::new(false);
if INIT_FLAG

View File

@ -187,10 +187,9 @@ pub fn sched_enqueue(pcb: Arc<ProcessControlBlock>, mut reset_time: bool) {
}
}
/// @brief 初始化进程调度器模块
#[allow(dead_code)]
#[no_mangle]
pub extern "C" fn sched_init() {
/// 初始化进程调度器模块
#[inline(never)]
pub fn sched_init() {
kinfo!("Initializing schedulers...");
unsafe {
sched_cfs_init();

View File

@ -42,3 +42,15 @@ impl SchedPriority {
self.0
}
}
pub trait SchedArch {
/// 开启当前核心的调度
fn enable_sched_local();
/// 关闭当前核心的调度
fn disable_sched_local();
/// 在第一次开启调度之前,进行初始化工作。
///
/// 注意区别于sched_init这个函数只是做初始化时钟的工作等等。
fn initial_setup_sched_local() {}
}

View File

@ -15,3 +15,15 @@ pub fn kick_cpu(cpu_id: u32) -> Result<(), SystemError> {
send_ipi(IpiKind::KickCpu, IpiTarget::Specified(cpu_id as usize));
return Ok(());
}
pub trait SMPArch {
/// 准备SMP初始化所需的cpu拓扑数据。
///
/// 该函数需要标记为 `#[inline(never)]`
fn prepare_cpus() -> Result<(), SystemError>;
/// 初始化SMP
///
/// 该函数需要标记为 `#[inline(never)]`
fn init() -> Result<(), SystemError>;
}

View File

@ -59,23 +59,20 @@ extern "C" {
fn do_put_string(s: *const u8, front_color: u32, back_color: u32) -> usize;
}
#[no_mangle]
pub extern "C" fn syscall_init() -> i32 {
kinfo!("Initializing syscall...");
Syscall::init().expect("syscall init failed");
kinfo!("Syscall init successfully!");
return 0;
}
impl Syscall {
/// 初始化系统调用
#[inline(never)]
pub fn init() -> Result<(), SystemError> {
static INIT_FLAG: AtomicBool = AtomicBool::new(false);
let prev = INIT_FLAG.swap(true, Ordering::SeqCst);
if prev {
panic!("Cannot initialize syscall more than once!");
}
return crate::arch::syscall::arch_syscall_init();
kinfo!("Initializing syscall...");
let r = crate::arch::syscall::arch_syscall_init();
kinfo!("Syscall init successfully!");
return r;
}
/// @brief 系统调用分发器,用于分发系统调用。
///

View File

@ -2,6 +2,6 @@
extern int rs_clocksource_watchdog_kthread(void *_data);
extern void rs_clocksource_boot_finish();
void run_watchdog_kthread();

View File

@ -836,11 +836,6 @@ pub fn clocksource_boot_finish() {
}
// ======== 以下为对C的接口 ========
/// # 完成对clocksource模块的加载
#[no_mangle]
pub extern "C" fn rs_clocksource_boot_finish() {
clocksource_boot_finish();
}
/// # 启动watchdog线程的辅助函数
#[no_mangle]

View File

@ -1,3 +0,0 @@
#pragma once
extern void rs_jiffies_init();

View File

@ -1,3 +0,0 @@
#pragma once
extern void rs_timekeeping_init();

View File

@ -6,7 +6,11 @@ use crate::{
exception::InterruptArch,
kdebug, kinfo,
libs::rwlock::RwLock,
time::{jiffies::clocksource_default_clock, timekeep::ktime_get_real_ns, TimeSpec},
time::{
jiffies::{clocksource_default_clock, jiffies_init},
timekeep::ktime_get_real_ns,
TimeSpec,
},
};
use super::{
@ -203,6 +207,7 @@ pub fn do_gettimeofday() -> PosixTimeval {
}
/// # 初始化timekeeping模块
#[inline(never)]
pub fn timekeeping_init() {
kinfo!("Initializing timekeeping module...");
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
@ -233,6 +238,7 @@ pub fn timekeeping_init() {
__ADDED_SEC.store(0, Ordering::SeqCst);
drop(irq_guard);
jiffies_init();
kinfo!("timekeeping_init successfully");
}
@ -306,9 +312,3 @@ pub fn update_wall_time(delta_us: i64) {
}
// TODO timekeeping_adjust
// TODO wall_to_monotic
// ========= 以下为对C的接口 =========
#[no_mangle]
pub extern "C" fn rs_timekeeping_init() {
timekeeping_init();
}

View File

@ -1,11 +0,0 @@
#pragma once
#include <common/glib.h>
// 定义LONG_MAX为最大超时时间 - 允许负数
#define MAX_TIMEOUT (int64_t)((1ul << 63) - 1)
extern void rs_timer_init();
extern void rs_jiffies_init();

View File

@ -236,7 +236,8 @@ impl SoftirqVec for DoTimerSoftirq {
}
}
/// @brief 初始化timer模块
/// 初始化系统定时器
#[inline(never)]
pub fn timer_init() {
// FIXME 调用register_trap
let do_timer_softirq = Arc::new(DoTimerSoftirq::new());

View File

@ -52,8 +52,8 @@ pub fn vm(id: usize) -> Option<Vm> {
vm_list.iter().find(|&x| x.id == id).cloned()
}
#[no_mangle]
pub extern "C" fn kvm_init() {
#[inline(never)]
pub fn kvm_init() {
kdebug!("kvm init");
match KVMArch::kvm_arch_cpu_supports_vm() {