finish exec3.1

This commit is contained in:
KAAAsS 2021-05-13 22:51:39 +08:00
parent 4282c20e93
commit b83368fb1f
Signed by: KAAAsS
GPG Key ID: D56625F3E671882F
5 changed files with 57 additions and 3 deletions

View File

@ -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")

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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
**** 切换上下文
返回上下文结构体的首地址就行