支持cpiofs&&init能够监控进程的死亡

This commit is contained in:
zhangzheng
2023-12-09 23:11:55 +08:00
parent 9e7c1e08ee
commit 22c5c91734
44 changed files with 904 additions and 130 deletions

View File

@@ -53,7 +53,7 @@ static void sys_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag,
case SYS_INFO_GET:
{
f->r[1] = sys_tick_cnt_get();
f->r[2] = KNL_TEXT + BOOTFS_ADDR_OFFSET;
f->r[2] = CONFIG_KNL_TEXT_ADDR + BOOTFS_ADDR_OFFSET;
tag = msg_tag_init4(0, 0, 0, 0);
}
break;

View File

@@ -18,19 +18,31 @@
#include "misc.h"
#include "spinlock.h"
#include "string.h"
/**
* @brief 任务的操作码
*
*/
enum task_op_code
{
TASK_OBJ_MAP,
TASK_OBJ_UNMAP,
TASK_ALLOC_RAM_BASE,
TASK_OBJ_VALID,
TASK_SET_PID,
TASK_GET_PID,
TASK_OBJ_MAP, //!< 进行映射操作
TASK_OBJ_UNMAP, //!< 进行解除映射操作
TASK_ALLOC_RAM_BASE, //!< 分配task的基础内存
TASK_OBJ_VALID, //!< 判断一个对象是否有效
TASK_SET_PID, //!< 设置task的pid
TASK_GET_PID, //!< 获取task的pid
};
static bool_t task_put(kobject_t *kobj);
static void task_release_stage1(kobject_t *kobj);
static void task_release_stage2(kobject_t *kobj);
/**
* @brief 为task分配其可以使用的内存空间
*
* @param tk
* @param lim
* @param size
* @return int
*/
int task_alloc_base_ram(task_t *tk, ram_limit_t *lim, size_t size)
{
if (tk->mm_space.mm_block)
@@ -49,10 +61,24 @@ int task_alloc_base_ram(task_t *tk, ram_limit_t *lim, size_t size)
printk("task alloc size is %d, base is 0x%x\n", size + THREAD_MSG_BUG_LEN, ram);
return 0;
}
/**
* @brief 获取线程绑定的task
*
* @param th
* @return task_t*
*/
task_t *thread_get_bind_task(thread_t *th)
{
return container_of(th->task, task_t, kobj);
}
/**
* @brief 同时解锁两个进程,防止死锁
*
* @param sp0
* @param sp1
* @param status0
* @param status1
*/
static void task_unlock_2(spinlock_t *sp0, spinlock_t *sp1, int status0, int status1)
{
if (sp0 < sp1)
@@ -66,6 +92,15 @@ static void task_unlock_2(spinlock_t *sp0, spinlock_t *sp1, int status0, int sta
spinlock_set(sp1, status1);
}
}
/**
* @brief 同时加锁两个进程
*
* @param sp0
* @param sp1
* @param st0
* @param st1
* @return int
*/
static int task_lock_2(spinlock_t *sp0, spinlock_t *sp1, int *st0, int *st1)
{
int status0;
@@ -104,6 +139,13 @@ static int task_lock_2(spinlock_t *sp0, spinlock_t *sp1, int *st0, int *st1)
}
return TRUE;
}
/**
* @brief 设置进程的pid只有pid为0的进程才能够设置
*
* @param task 任务对象
* @param pid 任务的pid
* @return int
*/
int task_set_pid(task_t *task, pid_t pid)
{
task_t *cur_task = thread_get_current_task();
@@ -118,6 +160,14 @@ int task_set_pid(task_t *task, pid_t pid)
return -EACCES;
}
}
/**
* @brief 进程的系统调用函数
*
* @param kobj
* @param sys_p
* @param in_tag
* @param f
*/
static void task_syscall_func(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag, entry_frame_t *f)
{
task_t *cur_task = thread_get_current_task();
@@ -132,19 +182,27 @@ static void task_syscall_func(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t i
switch (sys_p.op)
{
case TASK_OBJ_VALID:
case TASK_OBJ_VALID: //!< 查看某个obj在task中是否存在
{
mword_t status = spinlock_lock(&tag_task->kobj.lock);
if (status < 0)
{
tag = msg_tag_init4(0, 0, 0, -EINVAL);
break;
}
kobject_t *source_kobj = obj_space_lookup_kobj(&cur_task->obj_space, f->r[1]);
if (!source_kobj)
{
spinlock_set(&tag_task->kobj.lock, status);
tag = msg_tag_init4(0, 0, 0, -ENOENT);
break;
}
spinlock_set(&tag_task->kobj.lock, status);
tag = msg_tag_init4(0, 0, 0, 1);
}
break;
case TASK_OBJ_MAP:
case TASK_OBJ_MAP://!<从一个task中映射一个对象到目标进程
{
kobj_del_list_t del;
int st0, st1;
@@ -164,7 +222,7 @@ static void task_syscall_func(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t i
tag = msg_tag_init4(0, 0, 0, ret);
}
break;
case TASK_OBJ_UNMAP:
case TASK_OBJ_UNMAP://!<解除task中一个进程的创建
{
kobject_t *del_kobj;
kobj_del_list_t kobj_list;
@@ -175,16 +233,14 @@ static void task_syscall_func(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t i
tag = msg_tag_init4(0, 0, 0, -EINVAL);
break;
}
// ref_counter_inc(&tag_task->ref_cn);
kobj_del_list_init(&kobj_list);
obj_unmap(&tag_task->obj_space, vpage_create_raw(f->r[1]), &kobj_list);
kobj_del_list_to_do(&kobj_list);
// ref_counter_dec_and_release(&tag_task->ref_cn, &tag_task->kobj);
spinlock_set(&tag_task->kobj.lock, status);
tag = msg_tag_init4(0, 0, 0, 0);
}
break;
case TASK_ALLOC_RAM_BASE:
case TASK_ALLOC_RAM_BASE://!< 分配task所拥有的内存空间
{
mword_t status = spinlock_lock(&tag_task->kobj.lock);
if (status < 0)
@@ -198,12 +254,12 @@ static void task_syscall_func(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t i
spinlock_set(&tag_task->kobj.lock, status);
}
break;
case TASK_SET_PID:
case TASK_SET_PID://!<设置pid
{
tag = msg_tag_init4(0, 0, 0, task_set_pid(tag_task, f->r[0]));
}
break;
case TASK_GET_PID:
case TASK_GET_PID://!<获取pid
{
f->r[1] = tag_task->pid;
tag = msg_tag_init4(0, 0, 0, 0);
@@ -225,13 +281,14 @@ void task_init(task_t *task, ram_limit_t *ram, int is_knl)
mm_space_init(&task->mm_space, is_knl);
ref_counter_init(&task->ref_cn);
ref_counter_inc(&task->ref_cn);
slist_init(&task->del_node);
task->pid = -1;
task->lim = ram;
task->kobj.invoke_func = task_syscall_func;
task->kobj.put_func = task_put;
task->kobj.stage_1_func = task_release_stage1;
task->kobj.stage_2_func = task_release_stage2;
mm_space_add(&task->mm_space, KNL_TEXT, 64 * 1024 * 1024, REGION_RO); // TODO:
mm_space_add(&task->mm_space, CONFIG_KNL_TEXT_ADDR, 64 * 1024 * 1024, REGION_RO); // TODO:这里应该用config.配置
}
static bool_t task_put(kobject_t *kobj)

View File

@@ -583,7 +583,7 @@ again_check:
end:
spinlock_set(&cur_th->kobj.lock, lock_stats);
}
static int thread_ipc_call(thread_t *to_th, msg_tag_t in_tag, msg_tag_t *ret_tag, ipc_timeout_t timout, umword_t *ret_user_id)
int thread_ipc_call(thread_t *to_th, msg_tag_t in_tag, msg_tag_t *ret_tag, ipc_timeout_t timout, umword_t *ret_user_id)
{
assert(ret_tag);
int ret = -EINVAL;

View File

@@ -22,31 +22,79 @@
#include "mm_wrap.h"
#include "thread_armv7m.h"
#include "misc.h"
static uint8_t knl_msg_buf[THREAD_MSG_BUG_LEN];
static thread_t *knl_thread;
static task_t knl_task;
static thread_t *init_thread;
static task_t *init_task;
static slist_head_t del_task_head;
static spinlock_t del_lock;
static void knl_main(void)
{
umword_t status;
umword_t status2;
printk("knl main run..\n");
while (1)
{
task_t *pos;
if (slist_is_empty(&del_task_head))
{
continue;
}
status2 = spinlock_lock(&del_lock);
if (slist_is_empty(&del_task_head))
{
spinlock_set(&del_lock, status2);
continue;
}
slist_foreach_not_next(pos, &del_task_head, del_node)
{
task_t *next = slist_next_entry(pos, &del_task_head, del_node);
slist_del(&pos->del_node);
{
// TODO:给init发送消息该函数是在中断中调用的所以这个消息只能在knl_thread中调用。
msg_tag_t tag;
umword_t user_id;
ipc_msg_t *msg = (ipc_msg_t *)knl_msg_buf;
msg->msg_buf[0] = 1; /*KILL_TASK*/
msg->msg_buf[1] = pos->pid;
msg->msg_buf[2] = 0;
int ret = thread_ipc_call(init_thread, msg_tag_init4(0, 3, 0, 0x0005/*PM_PROT*/),
&tag, ipc_timeout_create2(0, 0), &user_id);
if (ret < 0)
{
printk("%s:%d ret:%d\n", __func__, __LINE__, ret);
}
}
task_kill(pos);
pos = next;
}
spinlock_set(&del_lock, status2);
}
}
/**
* 初始化内核线程
* 初始化内核任务
*/
static void knl_init_1(void)
{
thread_t *cur_th = thread_get_current();
knl_thread = thread_get_current();
thread_init(cur_th, &root_factory_get()->limit);
thread_init(knl_thread, &root_factory_get()->limit);
task_init(&knl_task, &root_factory_get()->limit, TRUE);
thread_knl_pf_set(cur_th, knl_main);
thread_bind(cur_th, &knl_task.kobj);
thread_ready(cur_th, FALSE);
thread_knl_pf_set(knl_thread, knl_main);
thread_bind(knl_thread, &knl_task.kobj);
thread_set_msg_bug(knl_thread, knl_msg_buf);
thread_ready(knl_thread, FALSE);
slist_init(&del_task_head);
}
INIT_STAGE1(knl_init_1);
@@ -59,12 +107,13 @@ INIT_STAGE1(knl_init_1);
static void knl_init_2(void)
{
mm_trace();
thread_t *init_thread = thread_create(&root_factory_get()->limit);
init_thread = thread_create(&root_factory_get()->limit);
assert(init_thread);
task_t *init_task = task_create(&root_factory_get()->limit, FALSE);
init_task = task_create(&root_factory_get()->limit, FALSE);
assert(init_task);
app_info_t *app = app_info_get((void *)(KNL_TEXT + INIT_OFFSET));
app_info_t *app = app_info_get((void *)(CONFIG_KNL_TEXT_ADDR + INIT_OFFSET));
// 申请init的ram内存
assert(task_alloc_base_ram(init_task, &root_factory_get()->limit, app->i.ram_size + THREAD_MSG_BUG_LEN) >= 0);
void *sp_addr = (char *)init_task->mm_space.mm_block + app->i.stack_offset - app->i.data_offset;
@@ -72,7 +121,7 @@ static void knl_init_2(void)
thread_set_msg_bug(init_thread, (char *)(init_task->mm_space.mm_block) + app->i.ram_size);
thread_bind(init_thread, &init_task->kobj);
thread_user_pf_set(init_thread, (void *)(KNL_TEXT + INIT_OFFSET), (void *)((umword_t)sp_addr_top - 8),
thread_user_pf_set(init_thread, (void *)(CONFIG_KNL_TEXT_ADDR + INIT_OFFSET), (void *)((umword_t)sp_addr_top - 8),
init_task->mm_space.mm_block, 0);
assert(obj_map_root(&init_thread->kobj, &init_task->obj_space, &root_factory_get()->limit, vpage_create3(KOBJ_ALL_RIGHTS, 0, THREAD_PROT)));
assert(obj_map_root(&init_task->kobj, &init_task->obj_space, &root_factory_get()->limit, vpage_create3(KOBJ_ALL_RIGHTS, 0, TASK_PROT)));
@@ -90,6 +139,26 @@ static void knl_init_2(void)
}
INIT_STAGE2(knl_init_2);
void task_knl_kill(thread_t *kill_thread, bool_t is_knl)
{
printk("kill task:0x%x.\n", kill_thread->task);
task_t *task = container_of(kill_thread->task, task_t, kobj);
if (!is_knl)
{
umword_t status2;
thread_suspend(kill_thread);
status2 = spinlock_lock(&del_lock);
slist_add_append(&del_task_head, &task->del_node);
spinlock_set(&del_lock, status2);
}
else
{
printk("[knl]: knl panic.\n");
assert(0);
}
}
static void print_mkrtos_info(void)
{
const char *start_info[] = {