mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 22:36:48 +00:00
riscv: 映射内核到指定的虚拟地址,使得kinfo能正常工作 (#468)
* riscv: 映射内核到指定的虚拟地址,使得kinfo能正常工作
This commit is contained in:
parent
cf44232423
commit
666cffedab
2
env.mk
2
env.mk
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
ifeq ($(ARCH), )
|
ifeq ($(ARCH), )
|
||||||
# !!!!在这里设置ARCH,可选x86_64和riscv64
|
# !!!!在这里设置ARCH,可选 x86_64 和 riscv64
|
||||||
# !!!!!!!如果不同时调整这里以及vscode的settings.json,那么自动补全和检查将会失效
|
# !!!!!!!如果不同时调整这里以及vscode的settings.json,那么自动补全和检查将会失效
|
||||||
export ARCH?=x86_64
|
export ARCH?=x86_64
|
||||||
endif
|
endif
|
||||||
|
@ -2,12 +2,30 @@
|
|||||||
|
|
||||||
.section .bootstrap
|
.section .bootstrap
|
||||||
|
|
||||||
|
#define CSR_SSTATUS 0x100
|
||||||
#define CSR_SIE 0x104
|
#define CSR_SIE 0x104
|
||||||
|
#define CSR_STVEC 0x105
|
||||||
#define CSR_SIP 0x144
|
#define CSR_SIP 0x144
|
||||||
|
|
||||||
|
# define CSR_TVEC CSR_STVEC
|
||||||
|
|
||||||
|
# define CSR_STATUS CSR_SSTATUS
|
||||||
#define CSR_IE CSR_SIE
|
#define CSR_IE CSR_SIE
|
||||||
#define CSR_IP CSR_SIP
|
#define CSR_IP CSR_SIP
|
||||||
|
|
||||||
|
#define SR_FS 0x00006000
|
||||||
|
#define SR_VS 0x00000600
|
||||||
|
#define SR_FS_VS (SR_FS | SR_VS) /* Vector and Floating-Point Unit */
|
||||||
|
|
||||||
|
#define SATP_MODE_39 0x8000000000000000UL
|
||||||
|
#define SATP_MODE_48 0x9000000000000000UL
|
||||||
|
#define SATP_MODE_57 0xa000000000000000UL
|
||||||
|
|
||||||
|
#define PAGE_OFFSET 0xffffffc000000000
|
||||||
|
#define KERNEL_LINK_OFFSET 0x1000000
|
||||||
|
#define KERNEL_VIRT_START (PAGE_OFFSET + KERNEL_LINK_OFFSET)
|
||||||
|
|
||||||
|
|
||||||
// 内核入口(从DragonStub跳转到这里)
|
// 内核入口(从DragonStub跳转到这里)
|
||||||
// 参数:
|
// 参数:
|
||||||
// a0: hartid (核心ID)
|
// a0: hartid (核心ID)
|
||||||
@ -18,17 +36,317 @@ ENTRY(_start)
|
|||||||
/* Mask all interrupts */
|
/* Mask all interrupts */
|
||||||
csrw CSR_IE, zero
|
csrw CSR_IE, zero
|
||||||
csrw CSR_IP, zero
|
csrw CSR_IP, zero
|
||||||
/* Load the global pointer */
|
|
||||||
|
|
||||||
|
// 暂存hartid
|
||||||
|
la t0, __initial_hartid_ptr
|
||||||
|
sd a0, 0(t0)
|
||||||
|
// 暂存平坦设备树地址
|
||||||
|
la t0, __initial_fdt_ptr
|
||||||
|
sd a1, 0(t0)
|
||||||
|
|
||||||
|
|
||||||
|
// 暂存_start标签被DragonStub加载到的物理地址
|
||||||
|
auipc t0, 0
|
||||||
|
li t1, -4095
|
||||||
|
and t0, t0, t1
|
||||||
|
la t1, __initial_start_load_paddr
|
||||||
|
sd t0, 0(t1)
|
||||||
|
|
||||||
|
// 清空页表的空间
|
||||||
|
la a0, __initial_pgtable
|
||||||
|
call __initial_clear_pgtable
|
||||||
|
la a0, __initial_l1_pgtable
|
||||||
|
call __initial_clear_pgtable
|
||||||
|
la a0, __initial_l1_pgtable
|
||||||
|
li a1, 4096
|
||||||
|
add a0, a0, a1
|
||||||
|
call __initial_clear_pgtable
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 设置页表,把内核当前所在的物理地址映射到链接时的内核虚拟空间
|
||||||
|
la a0, __initial_start_load_paddr
|
||||||
|
ld a0, 0(a0)
|
||||||
|
|
||||||
|
// 偏移量0xffffffc000000000,计算起始的L0页表项
|
||||||
|
// 因为内核链接地址还有16M的空间,所以这里加上0x1000000
|
||||||
|
li a1, KERNEL_VIRT_START
|
||||||
|
|
||||||
|
// 映射物理地址到虚拟地址
|
||||||
|
call initial_map_256M_phys_addr
|
||||||
|
|
||||||
|
// 增加恒等映射
|
||||||
|
la a0, __initial_start_load_paddr
|
||||||
|
ld a0, 0(a0)
|
||||||
|
|
||||||
|
mv a1, a0
|
||||||
|
call initial_map_1g_identical
|
||||||
|
|
||||||
|
__init_set_pgtable_loop_end:
|
||||||
|
|
||||||
|
call __initial_reloacate_enable_mmu
|
||||||
|
|
||||||
.option push
|
.option push
|
||||||
.option norelax
|
.option norelax
|
||||||
la sp, BSP_IDLE_STACK_SPACE
|
|
||||||
|
la a0, BSP_IDLE_STACK_SPACE
|
||||||
|
mv sp, a0
|
||||||
li t0, 32768
|
li t0, 32768
|
||||||
add sp, sp, t0
|
add sp, sp, t0
|
||||||
.option pop
|
.option pop
|
||||||
|
/*
|
||||||
|
* Disable FPU & VECTOR to detect illegal usage of
|
||||||
|
* floating point or vector in kernel space
|
||||||
|
*/
|
||||||
|
li t0, SR_FS_VS
|
||||||
|
csrc CSR_STATUS, t0
|
||||||
|
|
||||||
/* Call the kernel */
|
/* Call the kernel */
|
||||||
|
la a0, __initial_hartid_ptr
|
||||||
|
ld a0, 0(a0)
|
||||||
|
la a1, __initial_fdt_ptr
|
||||||
|
ld a1, 0(a1)
|
||||||
|
|
||||||
|
|
||||||
|
// 跳转到kernel_main
|
||||||
call kernel_main
|
call kernel_main
|
||||||
nop
|
nop
|
||||||
_loop:
|
wfi
|
||||||
j _loop
|
|
||||||
|
|
||||||
|
|
||||||
|
__initial_reloacate_enable_mmu:
|
||||||
|
// 计算起始物理地址与内核高虚拟地址的偏移量
|
||||||
|
la t0, __initial_start_load_paddr
|
||||||
|
ld t0, 0(t0)
|
||||||
|
|
||||||
|
li t1, KERNEL_VIRT_START
|
||||||
|
sub t1, t1, t0
|
||||||
|
|
||||||
|
// 重定位返回地址
|
||||||
|
add ra, ra, t1
|
||||||
|
|
||||||
|
/* Point stvec to virtual address of intruction after satp write */
|
||||||
|
/* Set trap vector to spin forever to help debug */
|
||||||
|
la a2, __initial_Lsecondary_park
|
||||||
|
add a2, a2, t1
|
||||||
|
csrw CSR_TVEC, a2
|
||||||
|
|
||||||
|
// enable MMU
|
||||||
|
la a2, __initial_pgtable
|
||||||
|
srli a2, a2, 12
|
||||||
|
la a0, __initial_satp_mode
|
||||||
|
ld a0, 0(a0)
|
||||||
|
or a2, a2, a0
|
||||||
|
sfence.vma
|
||||||
|
csrw satp, a2
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
// 映射物理地址到虚拟地址(2M页,1G大小)
|
||||||
|
// 参数:
|
||||||
|
// a0: 物理地址
|
||||||
|
// a1: 虚拟地址
|
||||||
|
initial_map_256M_phys_addr:
|
||||||
|
// 检查物理地址是否对齐到2M
|
||||||
|
li t0, 0x1fffff
|
||||||
|
and t0, t0, a0
|
||||||
|
bnez t0, __initial_map_1g_phys_failed
|
||||||
|
|
||||||
|
// 检查虚拟地址是否对齐到2M
|
||||||
|
li t0, 0x1fffff
|
||||||
|
and t0, t0, a1
|
||||||
|
bnez t0, __initial_map_1g_phys_failed
|
||||||
|
|
||||||
|
// 把起始虚拟地址存储到t2中
|
||||||
|
mv t2, a1
|
||||||
|
// 按照2M对齐
|
||||||
|
li t1, -0x200000
|
||||||
|
and t2, t2, t1
|
||||||
|
|
||||||
|
// 计算L0页表项的索引
|
||||||
|
srl t2, t2, 30
|
||||||
|
andi t2, t2, 511
|
||||||
|
|
||||||
|
|
||||||
|
// 填写第一个L0页表项
|
||||||
|
la t4, __initial_pgtable
|
||||||
|
slli t5, t2, 3 // t5 = t2 * 8
|
||||||
|
add t4, t4, t5 // t4 = t4 + t5, t4指向L0页表项
|
||||||
|
|
||||||
|
// 提取L1页表的地址
|
||||||
|
la t5, __initial_l1_pgtable
|
||||||
|
srli t5, t5, 12
|
||||||
|
slli t5, t5, 10
|
||||||
|
ori t5, t5, 0x1 // 设置L1页表项属性,V = 1
|
||||||
|
// 设置L0页表项的值
|
||||||
|
sd t5, 0(t4)
|
||||||
|
|
||||||
|
// 计算是否需要填写第二个L1页表项(判断是否超过第一个L1页表的范围)
|
||||||
|
addi t3, t2, 128
|
||||||
|
li t5, 512
|
||||||
|
blt t3, t5, __initial_set_l1_pgtable
|
||||||
|
// 填写第二个L1页表
|
||||||
|
la t3, __initial_l1_pgtable
|
||||||
|
li t5, 4096
|
||||||
|
add t3, t3, t5
|
||||||
|
srli t3, t3, 12
|
||||||
|
slli t3, t3, 10
|
||||||
|
ori t3, t3, 0x1 // 设置L1页表项属性,V = 1
|
||||||
|
// 设置L0页表项的值
|
||||||
|
sd t3, 8(t4)
|
||||||
|
|
||||||
|
__initial_set_l1_pgtable: // 开始填写L1页表
|
||||||
|
|
||||||
|
// 获取起始物理地址
|
||||||
|
mv t6, a0
|
||||||
|
// 获取L1页表的地址
|
||||||
|
la t0, __initial_l1_pgtable
|
||||||
|
|
||||||
|
// 计算起始L1页表项的索引
|
||||||
|
mv t3, a1
|
||||||
|
srli t3, t3, 21
|
||||||
|
andi t3, t3, 511
|
||||||
|
|
||||||
|
slli t3, t3, 3 // t3 = t3 * 8
|
||||||
|
add t0, t0, t3 // t0 = t0 + t3
|
||||||
|
|
||||||
|
// 加载计数器
|
||||||
|
li t5, 0
|
||||||
|
__initial_set_l1_pgtable_loop:
|
||||||
|
|
||||||
|
mv t3, t6
|
||||||
|
srli t3, t3, 12 // t3 = t6 >> 12 (page frame number)
|
||||||
|
li t1, 0x3FFFFFFFFFFFFF
|
||||||
|
and t3, t3, t1 // t3 = t3 & 0x3FFFFFFFFFFFFF
|
||||||
|
slli t3, t3, 10 // t3 = t3 << 10
|
||||||
|
ori t3, t3, 0xf // 设置L1页表项属性,R/W/X/V = 1
|
||||||
|
// 设置L1页表项的值
|
||||||
|
sd t3, 0(t0)
|
||||||
|
|
||||||
|
// 增加 页表项指针
|
||||||
|
addi t0, t0, 8
|
||||||
|
// 增加 t6 的值(2M)
|
||||||
|
li t2, 0x200000
|
||||||
|
add t6, t6, t2
|
||||||
|
|
||||||
|
// 增加计数器
|
||||||
|
addi t5, t5, 1
|
||||||
|
// 判断计数器是否超过128
|
||||||
|
li t2, 128
|
||||||
|
blt t5, t2, __initial_set_l1_pgtable_loop
|
||||||
|
|
||||||
|
|
||||||
|
// 填写完成
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
__initial_map_1g_phys_failed:
|
||||||
|
// 地址没有对齐到2M
|
||||||
|
wfi
|
||||||
|
la a0, __initial_map_1g_phys_failed
|
||||||
|
// 跳转
|
||||||
|
jr a0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 映射物理地址到虚拟地址(恒等映射)
|
||||||
|
// 参数:
|
||||||
|
// a0: 物理地址
|
||||||
|
initial_map_1g_identical:
|
||||||
|
mv a1, a0
|
||||||
|
// 把_start向下对齐到1GB
|
||||||
|
li t0, -0x40000000
|
||||||
|
// 计算起始物理地址,存放在t0中
|
||||||
|
and t0, t0, a0
|
||||||
|
|
||||||
|
|
||||||
|
// 把起始虚拟地址存储到t2中
|
||||||
|
mv t2, a1
|
||||||
|
// 按照1g对齐
|
||||||
|
li t1, -0x40000000
|
||||||
|
and t2, t2, t1
|
||||||
|
|
||||||
|
// 右移30位,得到L0页表项的索引
|
||||||
|
srl t2, t2, 30
|
||||||
|
// 与511进行与运算,得到L0页表项的索引
|
||||||
|
andi t2, t2, 511
|
||||||
|
|
||||||
|
|
||||||
|
// 填写页表项
|
||||||
|
// li t2, 0xf // 页表项属性, R/W/X/V = 1
|
||||||
|
la t4, __initial_pgtable
|
||||||
|
slli t3, t2, 3 // t3 = t2 * 8
|
||||||
|
add t4, t4, t3 // t4 = t4 + t3
|
||||||
|
|
||||||
|
mv t3, t0
|
||||||
|
srli t3, t3, 12 // t3 = t0 >> 12 (page frame number)
|
||||||
|
slli t3, t3, 10 // t3 = t3 << 10
|
||||||
|
ori t3, t3, 0xf // set R/W/X/V = 1
|
||||||
|
// 设置t0地址在L0页表中的值
|
||||||
|
sd t3, 0(t4)
|
||||||
|
|
||||||
|
// 增加 t4 的值
|
||||||
|
addi t4, t4, 8
|
||||||
|
// 增加 t3 的值(1G)
|
||||||
|
li t2, 0x40000000
|
||||||
|
add t3, t3, t2
|
||||||
|
sd t3, 0(t4)
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
// 用于清空页表的空间
|
||||||
|
// 参数:
|
||||||
|
// a0: page table address
|
||||||
|
__initial_clear_pgtable:
|
||||||
|
mv t0, a0
|
||||||
|
li t1, 512
|
||||||
|
li t2, 0 // 用于存储 0
|
||||||
|
|
||||||
|
__initial_clear_pgtable_loop:
|
||||||
|
|
||||||
|
sd t2, 0(t0) // 将 0 存储到当前word
|
||||||
|
addi t0, t0, 8 // 增加 t0 的值
|
||||||
|
addi t1, t1, -1 // 减少剩余的word数
|
||||||
|
bnez t1, __initial_clear_pgtable_loop
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
__initial_Lsecondary_park:
|
||||||
|
/* We lack SMP support or have too many harts, so park this hart */
|
||||||
|
wfi
|
||||||
|
j __initial_Lsecondary_park
|
||||||
|
|
||||||
|
// 全局变量,存储平坦设备树的地址和hartid
|
||||||
|
.global __initial_fdt_ptr
|
||||||
|
__initial_fdt_ptr:
|
||||||
|
.quad 0
|
||||||
|
|
||||||
|
.global __initial_hartid_ptr
|
||||||
|
__initial_hartid_ptr:
|
||||||
|
.quad 0
|
||||||
|
|
||||||
|
// _start标签在启动时被加载到的物理地址
|
||||||
|
__initial_start_load_paddr:
|
||||||
|
.quad 0
|
||||||
|
|
||||||
|
__initial_kernel_main_vaddr:
|
||||||
|
.quad 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.global __initial_satp_mode
|
||||||
|
__initial_satp_mode:
|
||||||
|
.quad SATP_MODE_39
|
||||||
|
|
||||||
|
// 初始页表的空间(sv39模式的L0页表)
|
||||||
|
.section .initial_pgtable_section
|
||||||
|
__initial_pgtable:
|
||||||
|
.skip 4096
|
||||||
|
|
||||||
|
__initial_l1_pgtable:
|
||||||
|
.skip 8192
|
||||||
|
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
use core::intrinsics::unreachable;
|
use core::intrinsics::unreachable;
|
||||||
|
|
||||||
use crate::{
|
use crate::{init::init_before_mem_init, kinfo, mm::PhysAddr};
|
||||||
driver::tty::serial::serial8250::send_to_default_serial8250_port, init::init_before_mem_init,
|
|
||||||
kdebug,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn kernel_main(hartid: usize, fdt_addr: usize) -> ! {
|
unsafe extern "C" fn kernel_main(hartid: usize, fdt_paddr: usize) -> ! {
|
||||||
|
let fdt_paddr = PhysAddr::new(fdt_paddr);
|
||||||
init_before_mem_init();
|
init_before_mem_init();
|
||||||
send_to_default_serial8250_port(&b"Hello, world! RISC-V!\n"[..]);
|
kinfo!(
|
||||||
|
"DragonOS kernel is running on hart {}, fdt address:{:?}",
|
||||||
|
hartid,
|
||||||
|
fdt_paddr
|
||||||
|
);
|
||||||
loop {}
|
loop {}
|
||||||
unreachable()
|
unreachable()
|
||||||
}
|
}
|
||||||
|
@ -10,20 +10,23 @@ ENTRY(_start)
|
|||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
//KERNEL_VMA = 0xffffffc000000000;
|
KERNEL_VMA = 0xffffffc000000000;
|
||||||
KERNEL_VMA = 0;
|
|
||||||
. = 0x1000000;
|
. = 0x1000000;
|
||||||
|
. += KERNEL_VMA;
|
||||||
.boot.text :
|
. = ALIGN(4096);
|
||||||
|
boot_text_start_pa = .;
|
||||||
|
.boot.text : AT(boot_text_start_pa - KERNEL_VMA)
|
||||||
{
|
{
|
||||||
KEEP(*(.bootstrap))
|
KEEP(*(.bootstrap))
|
||||||
*(.bootstrap.code64)
|
*(.bootstrap)
|
||||||
*(.bootstrap.data)
|
*(.bootstrap.*)
|
||||||
|
. = ALIGN(4096);
|
||||||
|
*(.initial_pgtable_section)
|
||||||
. = ALIGN(4096);
|
. = ALIGN(4096);
|
||||||
}
|
}
|
||||||
|
|
||||||
. += KERNEL_VMA;
|
|
||||||
. = ALIGN(32768);
|
. = ALIGN(4096);
|
||||||
text_start_pa = .;
|
text_start_pa = .;
|
||||||
.text (text_start_pa): AT(text_start_pa - KERNEL_VMA)
|
.text (text_start_pa): AT(text_start_pa - KERNEL_VMA)
|
||||||
{
|
{
|
||||||
|
3
kernel/src/arch/riscv64/mm/init.rs
Normal file
3
kernel/src/arch/riscv64/mm/init.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
use virtio_drivers::PhysAddr;
|
||||||
|
|
||||||
|
pub fn setup_vm(dtb_paddr: PhysAddr) {}
|
@ -5,6 +5,7 @@ use crate::mm::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub mod bump;
|
pub mod bump;
|
||||||
|
pub(super) mod init;
|
||||||
|
|
||||||
pub type PageMapper = crate::mm::page::PageMapper<RiscV64MMArch, LockedFrameAllocator>;
|
pub type PageMapper = crate::mm::page::PageMapper<RiscV64MMArch, LockedFrameAllocator>;
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit bf26173f2b67d188d3c531d8b36e982748b062fc
|
Subproject commit 5d9a3c158772e628967d96e442c7398fa9da576a
|
@ -35,4 +35,4 @@ clean:
|
|||||||
libc: $(libc_objs) $(libc_sub_dirs) libc_rust
|
libc: $(libc_objs) $(libc_sub_dirs) libc_rust
|
||||||
|
|
||||||
libc_rust:
|
libc_rust:
|
||||||
cargo +nightly-2023-01-21 build --release --target ./arch/x86_64/x86_64-unknown-none.json
|
cargo +nightly-2023-08-15 build --release --target ./arch/x86_64/x86_64-unknown-none.json
|
||||||
|
Loading…
x
Reference in New Issue
Block a user