use crate::mm::address::VirtAddr;
use crate::mm::memory_set::KERNEL_SPACE;
use crate::{etext, println, stext};

pub mod heap_allocator;
pub mod address;
pub mod frame_allocator;
pub mod page_table;
pub mod memory_set;



pub fn init(){
    // 开启 内核的内存分配器
    heap_allocator::init_heap();
    // 初始化并测试 物理页帧管理器
    frame_allocator::frame_allocator_test();
    // 激活内核的地址空间
    KERNEL_SPACE.exclusive_access().activate();

    remap_test();
}


pub fn remap_test() {
    extern "C" {
        fn stext();
        fn etext();
        fn srodata();
        fn erodata();
        fn sdata();
        fn edata();
        fn sbss_with_stack();
        fn ebss();
        fn ekernel();
        fn strampoline();  // 这个符号 在linker.ld 中定义
    }

    let mut kernel_space = KERNEL_SPACE.exclusive_access();
    let mid_text: VirtAddr = ((stext as usize + etext as usize) / 2).into();
    let mid_rodata: VirtAddr = ((srodata as usize + erodata as usize) / 2).into();
    let mid_data: VirtAddr = ((sdata as usize + edata as usize) / 2).into();
    assert!(!kernel_space
        .page_table
        .get_pte(mid_text.floor())
        .unwrap()
        .writable(),);
    assert!(!kernel_space
        .page_table
        .get_pte(mid_rodata.floor())
        .unwrap()
        .writable(),);
    assert!(!kernel_space
        .page_table
        .get_pte(mid_data.floor())
        .unwrap()
        .executable(),);
    println!("remap_test passed!");
}
