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_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_PLAT "raspi3")
|
||||||
set(CHCORE_ARCH "aarch64")
|
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
|
* prepare the arguments for the two following function calls: pmo_init
|
||||||
* and vmspace_map_range.
|
* and vmspace_map_range.
|
||||||
* pmo_init allocates the demanded size of physical memory for the PMO.
|
* 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
|
* You should get the size of current segment and the virtual address
|
||||||
* to be mapped from elf headers.
|
* to be mapped from elf headers.
|
||||||
* HINT: we suggest you use the seg_sz and p_vaddr variables for
|
* 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
|
* page aligned segment size. Take care of the page alignment when allocating
|
||||||
* and mapping physical memory.
|
* 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));
|
pmo = obj_alloc(TYPE_PMO, sizeof(*pmo));
|
||||||
if (!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.
|
* 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.
|
* 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);
|
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,
|
ret = vmspace_map_range(vmspace,
|
||||||
ROUND_DOWN(p_vaddr, PAGE_SIZE),
|
ROUND_DOWN(p_vaddr, PAGE_SIZE),
|
||||||
seg_map_sz, flags, pmo);
|
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 */
|
/* 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 */
|
/* Set thread type */
|
||||||
thread->thread_ctx->type = 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
|
* Return the correct value in order to make eret_to_thread work correctly
|
||||||
* in main.c
|
* 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 即可。
|
因此只需要类似操作,补全中间的 256M 即可。
|
||||||
|
|
||||||
注意的是,寄存器保存的地址是 paddr_t
|
注意的是,寄存器保存的地址是 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