电子说
_start阶段
系统时先进入_start执行。首先判断cpu核,如果是0号核的话执行初始化过程,其它核则执行wfe指令进入睡眠。初始化的过程如下:
将异常等级转入el1
设置栈顶指针
清理bss段
初始化mmu的翻译控制寄存器
设置内核和用户空间页表基址寄存器并进行初始化阶段的页表设置,此时将内核空间虚拟地址映射为物理地址+0xffff0000000000,用户空间虚拟地址映射为物理地址+0x40000000。
使能mmu,启用页表翻译地址
使用户空间页表基地址寄存器失效(原来设置该寄存器只为了跳转高地址前的地址翻译),只用内核地址,并设置栈寄存器为sp_el1
跳转到rtthread_startup
rtthread_startup阶段
内存相关初始化过程及内存管理初步学习
在rt_hw_board_init中进行内存相关初始化,这里的目的是设置表示内核空间的相关全局数据结构,及对内存的分布进行设置。
执行完该部分后,内核地址空间相关数据结构如下:
// 表示内核地址空间
struct rt_aspace rt_kernel_space{
.start = 0xffff000000000000; // 内核起始地址
.size = 0x1000000000000; // 内核地址空间大小
.page_table = MMUTable; // 内核所使用的页表,为变量MMUTable地址
.pgtbl_lock;
.tree.tree.root_node = mpr_varea;
.bst_lock.parent.parent.name = "aspace"; // bst_lock的名字
.asid = 0; // 地址空间id
}
// 表示页表空间
struct rt_varea mpr_varea{
.start = rt_mpr_start; // 页元数据基址,值为0xfffffdfff0000000
.size = rt_mpr_size; // 页元数据区域大小,值为0x20000000000
.offset = 0;
.attr = 1536;
.flag = 8704;
.aspace = rt_kernel_space;
.mem_obj = mm_page_mapper; // 内存操作接口
.node;
.frames = 0;
.data = 0;
}
init_mpr_align_start = 0xfffffdfff0880000; // 表示页空间起始页对应的页元数据,由于页元数据起始地址(rt_mpr_start)是从0物理地址开始存,所以需要此数据
init_mpr_align_end = 0xfffffdfff0900000; // 表示页空间末尾页对应的页元数据
early_offset = 0xffff020013880000; // 表示的是起始页与起始页元数据之间距离
mpr_cont = 0xffff000003880000; // 表示的是如果将页的元数据放页区域前元数据起始位置
head_cont = 0xffff000004102000; // 表示将mpr_cont作为页元数据起始地址后页区域首页对应元数据位置
tail_cont = 0xffff000004180000; // 表示将mpr_cont作为页元数据起始地址后页区域尾页对应元数据位置
全部0条评论
快来发表一下你的评论吧 !