支持cpiofs&&init能够监控进程的死亡
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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[] = {
|
||||
|
||||
Reference in New Issue
Block a user