finish exec3.1
This commit is contained in:
parent
4282c20e93
commit
b83368fb1f
@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.14)
|
||||
|
||||
set(CMAKE_VERBOSE_MAKEFILE on)
|
||||
|
||||
set(CMAKE_BUILD_TYPE "Release") # "Release" or "Debug"
|
||||
set(CMAKE_BUILD_TYPE "Debug") # "Release" or "Debug"
|
||||
set(CHCORE_PLAT "raspi3")
|
||||
set(CHCORE_ARCH "aarch64")
|
||||
|
||||
|
@ -153,7 +153,7 @@ static u64 load_binary(struct process *process,
|
||||
* prepare the arguments for the two following function calls: pmo_init
|
||||
* and vmspace_map_range.
|
||||
* pmo_init allocates the demanded size of physical memory for the PMO.
|
||||
* vmspace_map_range maps the pmo to a sepcific virtual memory address.
|
||||
* vmspace_map_range maps the pmo to a specific virtual memory address.
|
||||
* You should get the size of current segment and the virtual address
|
||||
* to be mapped from elf headers.
|
||||
* HINT: we suggest you use the seg_sz and p_vaddr variables for
|
||||
@ -161,6 +161,15 @@ static u64 load_binary(struct process *process,
|
||||
* page aligned segment size. Take care of the page alignment when allocating
|
||||
* and mapping physical memory.
|
||||
*/
|
||||
// 段实际数据大小
|
||||
seg_sz = elf->p_headers[i].p_filesz;
|
||||
// 段虚拟地址
|
||||
p_vaddr = elf->p_headers[i].p_vaddr;
|
||||
// 段映射结果大小,其实不太需要对齐,因为之后的逻辑已经处理了
|
||||
seg_map_sz = ROUND_UP(elf->p_headers[i].p_memsz, PAGE_SIZE);
|
||||
if (ROUND_DOWN(p_vaddr, PAGE_SIZE) + seg_map_sz < p_vaddr + elf->p_headers[i].p_memsz) {
|
||||
seg_map_sz += PAGE_SIZE;
|
||||
}
|
||||
|
||||
pmo = obj_alloc(TYPE_PMO, sizeof(*pmo));
|
||||
if (!pmo) {
|
||||
@ -179,9 +188,19 @@ static u64 load_binary(struct process *process,
|
||||
* You should copy data from the elf into the physical memory in pmo.
|
||||
* The physical address of a pmo can be get from pmo->start.
|
||||
*/
|
||||
const char *section_data;
|
||||
char *alloc_section;
|
||||
|
||||
// 复制段内存
|
||||
section_data = bin + elf->p_headers[i].p_offset;
|
||||
alloc_section = (char *) phys_to_virt(pmo->start);
|
||||
kdebug("Copy segment[%d] from addr %lx -> %lx, len = %d\n", i, section_data, alloc_section, seg_sz);
|
||||
memcpy(alloc_section, section_data, seg_sz);
|
||||
|
||||
flags = PFLAGS2VMRFLAGS(elf->p_headers[i].p_flags);
|
||||
|
||||
kdebug("Map segment[%d] from paddr %lx -> %lx, len = %d\n",
|
||||
i, pmo->start, ROUND_DOWN(p_vaddr, PAGE_SIZE), seg_map_sz);
|
||||
ret = vmspace_map_range(vmspace,
|
||||
ROUND_DOWN(p_vaddr, PAGE_SIZE),
|
||||
seg_map_sz, flags, pmo);
|
||||
|
@ -56,6 +56,12 @@ void init_thread_ctx(struct thread *thread, u64 stack, u64 func, u32 prio,
|
||||
*/
|
||||
|
||||
/* Fill the context of the thread */
|
||||
// 栈寄存器
|
||||
thread->thread_ctx->ec.reg[SP_EL0] = stack;
|
||||
// PC 计数器
|
||||
thread->thread_ctx->ec.reg[ELR_EL1] = func;
|
||||
// 状态字寄存器
|
||||
thread->thread_ctx->ec.reg[SPSR_EL1] = SPSR_EL1_EL0t;
|
||||
|
||||
/* Set thread type */
|
||||
thread->thread_ctx->type = type;
|
||||
|
@ -72,5 +72,5 @@ u64 switch_context(void)
|
||||
* Return the correct value in order to make eret_to_thread work correctly
|
||||
* in main.c
|
||||
*/
|
||||
return 0;
|
||||
return (u64) &target_ctx->ec;
|
||||
}
|
||||
|
29
note.org
29
note.org
@ -121,3 +121,32 @@ boot/mmu.c:L109-110 映射了 KBASE+512M~KBASE+4G
|
||||
因此只需要类似操作,补全中间的 256M 即可。
|
||||
|
||||
注意的是,寄存器保存的地址是 paddr_t
|
||||
|
||||
** Lab 3
|
||||
|
||||
*** Capability
|
||||
|
||||
好像和 MC、Linux 的 Cap 都不太一样。这里的 Cap 是一个可变的描述符,用来指代一个内核资源。
|
||||
|
||||
比起 Cap,更像是一个对象表。
|
||||
|
||||
*** 练习1
|
||||
|
||||
**** ELF 读入
|
||||
|
||||
ELF Section、Segment 两个概念。
|
||||
|
||||
- Section 是程序中的不同节,比如 .text。
|
||||
- Segment 是程序中实际分配的不同段,包括多个 Section,可以用 `readelf -l` 查看关系
|
||||
|
||||
主要操作就是计算偏移与复制。
|
||||
|
||||
其实连对齐都不用,直接就干上去也行,反正之前页表的时候已经处理了没对齐的情况。
|
||||
|
||||
**** 初始化线程上下文
|
||||
|
||||
照着文字写就行,初始化 TCB
|
||||
|
||||
**** 切换上下文
|
||||
|
||||
返回上下文结构体的首地址就行
|
||||
|
Loading…
x
Reference in New Issue
Block a user