try boot a guest os.

This commit is contained in:
zhangzheng
2024-06-08 02:53:33 +00:00
parent 2a648382e9
commit 6f84378c8d
23 changed files with 306 additions and 25 deletions

View File

@@ -83,7 +83,9 @@
"spinlock.h": "c",
"stdlib.h": "c",
"cpulock.h": "c",
"u_task.h": "c"
"u_task.h": "c",
"ipa_exeception.h": "c",
"guest_os.h": "c"
},
"cortex-debug.showRTOS": false,
"cortex-debug.variableUseNaturalFormat": false,

View File

@@ -70,6 +70,8 @@ typedef struct sysregs
umword_t contextidr_el1;
umword_t tpidrro_el0;
umword_t vmpidr_el2;
// 32bits sysregs.
umword_t spsr_abt;
umword_t spsr_und;

View File

@@ -95,6 +95,7 @@ static void hype_sche_arch_sw_sysregs(thread_t *cur_th, thread_t *next_th)
if (cur_th->is_vcpu)
{
cur_th->sp.sysregs.hstr_el2 = read_sysreg(hstr_el2);
cur_th->sp.sysregs.vmpidr_el2 = read_sysreg(vmpidr_el2);
cur_th->sp.sysregs.sp_el0 = read_sysreg(sp_el0);
cur_th->sp.sysregs.sctlr_el1 = read_sysreg(sctlr_el1);
cur_th->sp.sysregs.ttbr0_el1 = read_sysreg(ttbr0_el1);
@@ -121,6 +122,7 @@ static void hype_sche_arch_sw_sysregs(thread_t *cur_th, thread_t *next_th)
if (next_th->is_vcpu)
{
write_sysreg(next_th->sp.sysregs.hstr_el2, hstr_el2);
write_sysreg(next_th->sp.sysregs.vmpidr_el2, vmpidr_el2);
write_sysreg(next_th->sp.sysregs.sp_el0, sp_el0);
write_sysreg(next_th->sp.sysregs.sctlr_el1, sctlr_el1);
write_sysreg(next_th->sp.sysregs.ttbr0_el1, ttbr0_el1);

View File

@@ -50,6 +50,7 @@ void thread_arch_init(thread_t *th, umword_t flags)
// asm volatile("msr HSTR_EL2, %x0" : : "r"(Hstr_vm));
th->sp.hyp.hcr_el2 = 0x30023f | (1UL << 10) | (3UL << 13) | (1UL << 31); // read_sysreg(hcr_el2);0x30023f|(1UL<<10) |(3UL<<13)
th->sp.sysregs.hstr_el2 = Hstr_vm; // read_sysreg(hstr_el2);
th->sp.sysregs.vmpidr_el2 = 0; // TODO:虚拟mpidr_el1寄存器
th->sp.sysregs.sp_el0 = read_sysreg(sp_el0);
th->sp.sysregs.sctlr_el1 = read_sysreg(sctlr_el1);
th->sp.sysregs.ttbr0_el1 = read_sysreg(ttbr0_el1);

View File

@@ -9,9 +9,23 @@
#include <vma.h>
umword_t thread_get_pfa(void)
{
thread_t *th = thread_get_current();
umword_t a;
umword_t far_el2;
asm volatile("mrs %0, far_el2" : "=r"(far_el2));
asm volatile("mrs %0, far_el2" : "=r"(a));
if (th->is_vcpu)
{
asm volatile("mrs %0, hpfar_el2" : "=r"(a));
a >>= 4;
a <<= CONFIG_PAGE_SHIFT;
a |= far_el2 & ((1 << CONFIG_PAGE_SHIFT) - 1);
}
else
{
a = far_el2;
}
return a;
}
static void dump_stack(umword_t pc, umword_t x29)
@@ -30,11 +44,12 @@ static void dump_stack(umword_t pc, umword_t x29)
x29 = *(umword_t *)(knl_addr);
}
}
printk("knl pf stack: 0x%x,0x%x,0x%x,0x%x,0x%x\n", result[0], result[1], result[2], result[3], result[4]);
printk("knl pf stack: 0x%lx,0x%lx,0x%lx,0x%lx,0x%lx\n", result[0], result[1], result[2], result[3], result[4]);
}
void thread_sync_entry(entry_frame_t *regs)
{
umword_t ec = arm_esr_ec(esr_get());
umword_t esr = esr_get();
umword_t ec = arm_esr_ec(esr);
thread_t *th = thread_get_current();
task_t *tk = thread_get_bind_task(th);
// printk("user:0x%x ec:0x%x\n", !ec, ec);
@@ -47,9 +62,24 @@ void thread_sync_entry(entry_frame_t *regs)
if (task_vma_page_fault(&tk->mm_space.mem_vma, ALIGN_DOWN(addr, PAGE_SIZE)) < 0)
{
printk("[knl]0x20 pfa:0x%x\n", addr);
printk("[knl]0x20 pfa:0x%lx\n", addr);
dump_stack(regs->pc, regs->regs[29]);
task_knl_kill(th, FALSE);
ipc_msg_t *msg;
msg_tag_t ret_tag;
umword_t user_id;
msg = thread_get_kmsg_buf((thread_t *)(th));
msg->msg_buf[0] = esr;
msg->msg_buf[1] = addr;
int ret = thread_ipc_call((thread_t *)(tk->exec_th), msg_tag_init4(0, 2, 0, 0),
&ret_tag, ipc_timeout_create2(0, 0),
&user_id, TRUE);
if (ret < 0)
{
task_knl_kill(th, FALSE);
}
printk("%s:%d ret:%d\n", __func__, __LINE__, ret);
}
}
return;
@@ -59,9 +89,25 @@ void thread_sync_entry(entry_frame_t *regs)
if (task_vma_page_fault(&tk->mm_space.mem_vma, ALIGN_DOWN(addr, PAGE_SIZE)) < 0)
{
printk("[knl]0x24 pfa:0x%x\n", addr);
printk("[knl]0x24 esr:0x%lx pfa:0x%lx\n", esr, addr);
dump_stack(regs->pc, regs->regs[29]);
task_knl_kill(th, FALSE);
msg_tag_t ret_tag;
umword_t user_id;
ipc_msg_t *msg;
msg = thread_get_kmsg_buf((thread_t *)(th));
msg->msg_buf[0] = esr;
msg->msg_buf[1] = addr;
int ret = thread_ipc_call((thread_t *)(tk->exec_th), msg_tag_init4(0, 2, 0, 0),
&ret_tag, ipc_timeout_create2(0, 0),
&user_id, TRUE);
if (ret < 0)
{
task_knl_kill(th, FALSE);
}
printk("%s:%d pc:0x%lx ret:%d\n", __func__, __LINE__, regs->pc, ret);
regs->pc += 4;
}
}
return;

View File

@@ -15,6 +15,7 @@ typedef struct task
obj_space_t obj_space;
mm_space_t mm_space;
ram_limit_t *lim;
kobject_t *exec_th;
ref_counter_t ref_cn;
slist_head_t del_node;
pid_t pid;

View File

@@ -42,6 +42,7 @@ enum thread_op
MSG_BUG_SET,
YIELD,
DO_IPC = 6, //!< 与ipc对象中的额IPC_DO一致
SET_EXEC, //!< 设置异常处理
};
enum IPC_TYPE
{
@@ -114,7 +115,7 @@ void thread_init(thread_t *th, ram_limit_t *lim, umword_t flags)
ref_counter_init(&th->ref);
ref_counter_inc(&th->ref);
thread_arch_init(th, flags);
th->cpu = 0;
th->cpu = arch_get_current_cpu_id();
th->lim = lim;
th->kobj.invoke_func = thread_syscall;
th->kobj.put_func = thread_put;
@@ -976,6 +977,7 @@ __attribute__((optimize(0))) int thread_ipc_call(thread_t *to_th, msg_tag_t in_t
ret = 0;
end:
spinlock_set(&to_th->kobj.lock, lock_stats);
return ret;
}
/**
@@ -1251,6 +1253,19 @@ static void thread_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_t
tag = thread_do_ipc(kobj, f, 0);
}
break;
case SET_EXEC:
{
kobject_t *th_kobj = obj_space_lookup_kobj_cmp_type(&task->obj_space, f->regs[0], THREAD_TYPE);
if (th_kobj == NULL)
{
f->regs[0] = msg_tag_init4(0, 0, 0, -EINVAL).raw;
return;
}
ref_counter_inc(&((thread_t *)th_kobj)->ref);
task->exec_th = th_kobj;
tag = msg_tag_init4(0, 0, 0, 0);
}
break;
}
f->regs[0] = tag.raw;
}
@@ -1269,7 +1284,7 @@ static kobject_t *thread_create_func(ram_limit_t *lim, umword_t arg0, umword_t a
umword_t arg2, umword_t arg3)
{
kobject_t *kobj;
kobj = (kobject_t *)thread_create(lim, arg0);
if (!kobj)
{

View File

@@ -7,9 +7,9 @@
#define MSG_BUF_RECV_R_FLAGS 0x02U //!< 接收上次发送数据的接收者
#define MSG_BUF_REPLY_FLAGS 0x04U //!<
#define IPC_MSG_SIZE CONFIG_THREAD_IPC_MSG_LEN //!< IPC消息大小
#define MAP_BUF_SIZE CONFIG_THREAD_MAP_BUF_LEN //!< 映射消息大小
#define IPC_USER_SIZE 12 //!< 用户态消息大小
#define IPC_MSG_SIZE CONFIG_THREAD_IPC_MSG_LEN //!< IPC消息大小
#define MAP_BUF_SIZE CONFIG_THREAD_MAP_BUF_LEN //!< 映射消息大小
#define IPC_USER_SIZE 12 //!< 用户态消息大小
typedef struct ipc_msg
{
@@ -61,11 +61,12 @@ static inline msg_tag_t thread_run(obj_handler_t obj, uint8_t prio)
return thread_run_cpu(obj, prio, -1);
}
msg_tag_t thread_bind_task(obj_handler_t obj, obj_handler_t tk_obj);
msg_tag_t thread_set_exec(obj_handler_t obj, obj_handler_t exec_th);
msg_tag_t thread_ipc_wait(ipc_timeout_t timeout, umword_t *obj, obj_handler_t ipc_obj);
msg_tag_t thread_ipc_reply(msg_tag_t in_tag, ipc_timeout_t timeout);
msg_tag_t thread_ipc_send(msg_tag_t in_tag, obj_handler_t target_th_obj, ipc_timeout_t timeout);
__attribute__((optimize(0))) msg_tag_t thread_ipc_call(msg_tag_t in_tag, obj_handler_t target_th_obj, ipc_timeout_t timeout);
__attribute__((optimize(0))) msg_tag_t thread_ipc_call(msg_tag_t in_tag, obj_handler_t target_th_obj, ipc_timeout_t timeout);
static inline ipc_msg_t *thread_get_cur_ipc_msg(void)
{

View File

@@ -11,6 +11,7 @@ enum thread_op
MSG_BUG_SET,
YIELD,
DO_IPC,
SET_EXEC,
};
enum IPC_TYPE
{
@@ -208,4 +209,22 @@ msg_tag_t thread_bind_task(obj_handler_t obj, obj_handler_t tk_obj)
msg_tag_t tag = msg_tag_init(r0);
return tag;
}
}
msg_tag_t thread_set_exec(obj_handler_t obj, obj_handler_t exec_th)
{
register volatile umword_t r0 asm(ARCH_REG_0);
mk_syscall(syscall_prot_create(SET_EXEC, THREAD_PROT, obj).raw,
exec_th,
0,
0,
0,
0, 0);
asm __volatile__(""
:
:
: ARCH_REG_0);
msg_tag_t tag = msg_tag_init(r0);
return tag;
}

View File

@@ -10,7 +10,10 @@ target_link_libraries(hello.elf
PUBLIC
-Bstatic
${LIBC_NAME}
--whole-archive
${START_LIB}
libc_be
--no-whole-archive
printf
sys
sys_util
@@ -23,10 +26,7 @@ target_include_directories(
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_util/inc
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_svr/inc
${CMAKE_SOURCE_DIR}/mkrtos_user/server/hello/src/test
${CMAKE_SOURCE_DIR}/mkrtos_user/server/hello/bsp/core_inc
${CMAKE_SOURCE_DIR}/mkrtos_user/server/hello/bsp/inc
${CMAKE_SOURCE_DIR}/mkrtos_user/server/hello/src
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/printf/src/printf
)

Binary file not shown.

View File

@@ -0,0 +1,80 @@
#include <u_thread.h>
#include <u_hd_man.h>
#include <u_task.h>
#include <errno.h>
#include <u_prot.h>
#include <u_factory.h>
#include <u_vmam.h>
#include <string.h>
#include "guest_os.h"
#include "ipa_exeception.h"
// #define STACK_SIZE 4096
// static __attribute__((aligned(8))) uint8_t stack0[STACK_SIZE];
#define VCPU_DEFAULT_PRIO 2
int guest_os_create(guest_os_t *gos, void *entry)
{
msg_tag_t tag;
obj_handler_t th1_hd;
umword_t msg_buf_addr;
int ret;
th1_hd = handler_alloc();
if (th1_hd == HANDLER_INVALID)
{
return -ENOENT;
}
tag = factory_create_thread_vcpu(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, th1_hd));
if (msg_tag_get_prot(tag) < 0)
{
handler_free(th1_hd);
return msg_tag_get_prot(tag);
}
tag = u_vmam_alloc(VMA_PROT, vma_addr_create(VPAGE_PROT_RW, 0, 0),
PAGE_SIZE, 0, (addr_t *)(&msg_buf_addr));
if (msg_tag_get_val(tag) < 0)
{
ret = msg_tag_get_val(tag);
goto end;
}
memset((void *)msg_buf_addr, 0, PAGE_SIZE);
tag = thread_exec_regs(th1_hd, (umword_t)entry,
0, TASK_RAM_BASE(), 0);
if (msg_tag_get_prot(tag) < 0)
{
ret = msg_tag_get_prot(tag);
goto end_free_mm;
}
tag = thread_bind_task(th1_hd, TASK_THIS);
if (msg_tag_get_prot(tag) < 0)
{
goto end_free_mm;
}
tag = thread_msg_buf_set(th1_hd, (void *)msg_buf_addr);
if (msg_tag_get_prot(tag) < 0)
{
goto end_free_mm;
}
ret = ipc_execetion_create(gos);
if (ret < 0)
{
goto end_free_mm;
}
thread_set_exec(th1_hd, gos->ipa_execption_ipc);
gos->msg_buf = (void *)msg_buf_addr;
gos->prio = VCPU_DEFAULT_PRIO;
gos->vcpu_id = 0; // TODO:需要设置内核的寄存器
gos->vcpu_th = th1_hd;
thread_run(th1_hd, VCPU_DEFAULT_PRIO); // 优先级默认为2
ret = 0;
goto end_ok;
end_free_mm:
u_vmam_free(VMA_PROT, msg_buf_addr, PAGE_SIZE);
end:
handler_free_umap(th1_hd);
end_ok:
return ret;
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include <u_thread.h>
#include <pthread.h>
typedef struct guest_os
{
obj_handler_t vcpu_th; //!< TODO:暂时只支持一个cpu
void *msg_buf; //!< 消息传递的buf
int prio; //!< 优先级
int vcpu_id; //!< cpu id
pthread_t ipa_exeception_hd;
obj_handler_t ipa_execption_ipc;
// vgic_t gic; //!<gic虚拟化
// vuart_ts uart;//!<uart虚拟化
} guest_os_t;
int guest_os_create(guest_os_t *gos, void *entry);

View File

@@ -1,4 +1,6 @@
#include <u_util.h>
#ifndef IS_ENABLED(CONFIG_MMU)
#define HEAP_SIZE 512
#define STACK_SIZE 1024
@@ -15,3 +17,4 @@
__attribute__((used)) HEAP_ATTR static char _____heap_____[HEAP_SIZE];
__attribute__((used)) STACK_ATTR static char _____stack_____[STACK_SIZE];
#endif

View File

@@ -0,0 +1,75 @@
#include <pthread.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <u_hd_man.h>
#include <u_factory.h>
#include <pthread.h>
#include <u_thread.h>
#include "guest_os.h"
#include "u_sleep.h"
static void *ipc_execetion_thread_handler(void *arg)
{
msg_tag_t tag;
guest_os_t *gos = arg;
ipc_msg_t *msg;
printf("%s:%d\n", __func__, __LINE__);
while (1)
{
tag = thread_ipc_wait(ipc_timeout_create2(0, 0), NULL, -1);
if (msg_tag_get_val(tag) < 0)
{
continue;
}
thread_msg_buf_get(pthread_hd_get(pthread_self()), (umword_t *)(&msg), NULL);
if (msg->msg_buf[0] >> 26 != 0x24)
{
tag = msg_tag_init4(0, 0, 0, -1);
}
else
{
umword_t ipa_addr = msg->msg_buf[1];
if ((msg->msg_buf[0] >> 6) & 0x1)
{
// write.
}
else
{
// read.
}
tag = msg_tag_init4(0, 0, 0, 0);
}
// printf("%s:%d\n", __func__, __LINE__);
thread_ipc_reply(tag, ipc_timeout_create2(0, 0));
}
return NULL;
}
int ipc_execetion_create(guest_os_t *gos)
{
int ret = 0;
assert(gos);
ret = pthread_create(&gos->ipa_exeception_hd, NULL, ipc_execetion_thread_handler, gos);
if (ret)
{
return ret;
}
// obj_handler_t ipa_execption_ipc;
// ipa_execption_ipc = handler_alloc();
// if (ipa_execption_ipc == HANDLER_INVALID)
// {
// return -ENOENT;
// }
// msg_tag_t tag;
// tag = factory_create_ipc(FACTORY_PROT, vpage_create_raw3(0, 0, ipa_execption_ipc));
// if (msg_tag_get_val(tag) < 0)
// {
// return ret;
// }
gos->ipa_execption_ipc = pthread_hd_get(gos->ipa_exeception_hd);
u_sleep_ms(100);
return 0;
}

View File

@@ -0,0 +1,3 @@
#pragma once
#include "guest_os.h"
int ipc_execetion_create(guest_os_t *gos);

View File

@@ -1,8 +1,19 @@
#include <printf.h>
#include <unistd.h>
#include <u_types.h>
#include "guest_os.h"
extern umword_t os_bin;
guest_os_t gos;
int main(int argc, char *args[])
{
mk_printf("guest os entry addr:0x%lx\n", &os_bin);
guest_os_create(&gos, &os_bin);
while (1)
{
sleep(1);
}
mk_printf("print test0.\n");
mk_printf("print test1.\n");
mk_printf("print test2.\n");

View File

@@ -0,0 +1,4 @@
.global os_bin
.align 12
os_bin:
.incbin "/home/zhangzheng/mkrtos-real/mkrtos_user/server/hello/src/benos.bin"

View File

@@ -102,7 +102,7 @@ int console_read(uint8_t *data, size_t len)
}
else
{
memcpy(data, "1234\r\n", 6);
pthread_spin_lock(&cons_obj.r_lock);
if (q_queue_len(&cons_obj.r_queue) == 0)
{

View File

@@ -4,5 +4,5 @@
# dm9000_drv
# net
# lcd_drv
# cpiofs
# sh
cpiofs
sh

View File

@@ -35,8 +35,8 @@
static void test(void)
{
thread_vcpu_test();
#if 0
thread_vcpu_test();
pthread_lock_test();
pthread_cond_lock_test();
thread_cpu_test();

View File

@@ -52,7 +52,7 @@ if ((DEFINED CONFIG_ELF_LAUNCH) AND (CONFIG_ELF_LAUNCH STREQUAL "y"))
COMMAND
cp net.elf ${CMAKE_SOURCE_DIR}/build/output/cpio/net
)
add_dependencies(net_dump_elf shell_dump)
add_dependencies(net_dump_elf net_dump)
endif()
add_dependencies(net_dump net.elf)
add_dependencies(net.elf sys)