env支持,app_loader完善

This commit is contained in:
zhangzheng
2023-09-16 17:32:10 +08:00
parent 6f9cb317fe
commit f48036b1fb
20 changed files with 426 additions and 78 deletions

View File

@@ -5,6 +5,7 @@
#include <errno.h>
#include <u_prot.h>
#include <u_log.h>
#include <u_env.h>
#include <sys/uio.h>
static long be_read(long fd, char *buf, long size)
{
@@ -17,7 +18,7 @@ static long be_write(long fd, char *buf, long size)
case 0:
case 1:
case 2:
ulog_write_bytes(LOG_PROT, buf, size);
ulog_write_bytes(u_get_global_env()->log_hd, buf, size);
return size;
default:
return -ENOSYS;
@@ -29,7 +30,7 @@ static long be_writev(long fd, const struct iovec *iov, long iovcnt)
long wlen = 0;
for (int i = 0; i < iovcnt; i++)
{
ulog_write_bytes(LOG_PROT, iov[i].iov_base, iov[i].iov_len);
ulog_write_bytes(u_get_global_env()->log_hd, iov[i].iov_base, iov[i].iov_len);
wlen += iov[i].iov_len;
}
return wlen;

View File

@@ -20,39 +20,60 @@ weak_alias(dummy1, __init_ssp);
#ifdef __GNUC__
__attribute__((__noinline__))
#endif
void __init_libc(char **envp, char *pn)
void
__init_libc(char **envp, char *pn)
{
size_t i, *auxv, aux[AUX_CNT] = { 0 };
size_t i, *auxv, aux[AUX_CNT] = {0};
__environ = envp;
for (i=0; envp[i]; i++);
libc.auxv = auxv = (void *)(envp+i+1);
for (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT) aux[auxv[i]] = auxv[i+1];
for (i = 0; envp[i]; i++)
;
libc.auxv = auxv = (void *)(envp + i + 1);
for (i = 0; auxv[i]; i += 2)
{
if (auxv[i] < AUX_CNT)
{
aux[auxv[i]] = auxv[i + 1];
}
else if (auxv[i] == 0xfe)
{
extern void u_env_init(void * * in_env);
u_env_init((void *)auxv[i + 1]);
}
}
__hwcap = aux[AT_HWCAP];
if (aux[AT_SYSINFO]) __sysinfo = aux[AT_SYSINFO];
if (aux[AT_SYSINFO])
__sysinfo = aux[AT_SYSINFO];
libc.page_size = aux[AT_PAGESZ];
if (!pn) pn = (void*)aux[AT_EXECFN];
if (!pn) pn = "";
if (!pn)
pn = (void *)aux[AT_EXECFN];
if (!pn)
pn = "";
__progname = __progname_full = pn;
for (i=0; pn[i]; i++) if (pn[i]=='/') __progname = pn+i+1;
for (i = 0; pn[i]; i++)
if (pn[i] == '/')
__progname = pn + i + 1;
__init_tls(aux);
__init_ssp((void *)aux[AT_RANDOM]);
if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID]
&& !aux[AT_SECURE]) return;
if (aux[AT_UID] == aux[AT_EUID] && aux[AT_GID] == aux[AT_EGID] && !aux[AT_SECURE])
return;
struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} };
struct pollfd pfd[3] = {{.fd = 0}, {.fd = 1}, {.fd = 2}};
int r =
#ifdef SYS_poll
__syscall(SYS_poll, pfd, 3, 0);
__syscall(SYS_poll, pfd, 3, 0);
#else
__syscall(SYS_ppoll, pfd, 3, &(struct timespec){0}, 0, _NSIG/8);
__syscall(SYS_ppoll, pfd, 3, &(struct timespec){0}, 0, _NSIG / 8);
#endif
if (r<0) a_crash();
for (i=0; i<3; i++) if (pfd[i].revents&POLLNVAL)
if (__sys_open("/dev/null", O_RDWR)<0)
a_crash();
if (r < 0)
a_crash();
for (i = 0; i < 3; i++)
if (pfd[i].revents & POLLNVAL)
if (__sys_open("/dev/null", O_RDWR) < 0)
a_crash();
libc.secure = 1;
}
@@ -60,19 +81,19 @@ static void libc_start_init(void)
{
_init();
uintptr_t a = (uintptr_t)&__init_array_start;
for (; a<(uintptr_t)&__init_array_end; a+=sizeof(void(*)()))
for (; a < (uintptr_t)&__init_array_end; a += sizeof(void (*)()))
(*(void (**)(void))a)();
}
weak_alias(libc_start_init, __libc_start_init);
typedef int lsm2_fn(int (*)(int,char **,char **), int, char **);
typedef int lsm2_fn(int (*)(int, char **, char **), int, char **);
static lsm2_fn libc_start_main_stage2;
int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv,
void (*init_dummy)(), void(*fini_dummy)(), void(*ldso_dummy)())
int __libc_start_main(int (*main)(int, char **, char **), int argc, char **argv,
void (*init_dummy)(), void (*fini_dummy)(), void (*ldso_dummy)())
{
char **envp = argv+argc+1;
char **envp = argv + argc + 1;
/* External linkage, and explicit noinline attribute if available,
* are used to prevent the stack frame used during init from
@@ -82,30 +103,31 @@ int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv,
/* Barrier against hoisting application code or anything using ssp
* or thread pointer prior to its initialization above. */
lsm2_fn *stage2 = libc_start_main_stage2;
__asm__ ( "" : "+r"(stage2) : : "memory" );
__asm__("" : "+r"(stage2) : : "memory");
return stage2(main, argc, argv);
}
int __libc_start_main_init(int (*main)(int,char **,char **), int argc, char **argv,
void (*init_dummy)(), void(*fini_dummy)(), void(*ldso_dummy)())
int __libc_start_main_init(int (*main)(int, char **, char **), int argc, char **argv,
void (*init_dummy)(), void (*fini_dummy)(), void (*ldso_dummy)())
{
char **envp = argv+argc+1;
char **envp = argv + argc + 1;
/* External linkage, and explicit noinline attribute if available,
* are used to prevent the stack frame used during init from
* persisting for the entire process lifetime. */
// __init_libc(envp, argv[0]);
extern void u_env_default_init(void);
u_env_default_init();
/* Barrier against hoisting application code or anything using ssp
* or thread pointer prior to its initialization above. */
lsm2_fn *stage2 = libc_start_main_stage2;
__asm__ ( "" : "+r"(stage2) : : "memory" );
__asm__("" : "+r"(stage2) : : "memory");
return stage2(main, argc, argv);
}
static int libc_start_main_stage2(int (*main)(int,char **,char **), int argc, char **argv)
static int libc_start_main_stage2(int (*main)(int, char **, char **), int argc, char **argv)
{
char **envp = argv+argc+1;
char **envp = argv + argc + 1;
__libc_start_init();
/* Pass control to the application */

View File

@@ -5,6 +5,7 @@
typedef struct sys_info
{
umword_t sys_tick;
umword_t bootfs_start_addr;
} sys_info_t;
void sys_read_info(obj_handler_t obj, sys_info_t *info);
msg_tag_t sys_read_info(obj_handler_t obj, sys_info_t *info);

View File

@@ -1,2 +0,0 @@
#include "u_types.h"

View File

@@ -13,10 +13,11 @@ enum sys_op
REBOOT,
};
void sys_read_info(obj_handler_t obj, sys_info_t *info)
msg_tag_t sys_read_info(obj_handler_t obj, sys_info_t *info)
{
register volatile umword_t r0 asm("r0");
register volatile umword_t r1 asm("r1");
register volatile umword_t r2 asm("r2");
syscall(syscall_prot_create(SYS_INFO_GET, SYS_PROT, obj),
0,
@@ -25,9 +26,11 @@ void sys_read_info(obj_handler_t obj, sys_info_t *info)
0,
0,
0);
msg_tag_t tag = msg_tag_init(r0);
if (info)
{
info->sys_tick = r1;
info->bootfs_start_addr = r2;
}
return msg_tag_init(r0);
return tag;
}

View File

@@ -19,6 +19,7 @@ target_include_directories(
PUBLIC
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_util/inc
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/cpio
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/arch/arm/
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/arch/generic
@@ -33,6 +34,7 @@ target_link_libraries(
PUBLIC
sys
muslc
cpio
)
add_dependencies(sys_util sys)
add_dependencies(sys_util muslc)

View File

@@ -0,0 +1,3 @@
#pragma once
int app_load(const char *name);

View File

@@ -2,11 +2,14 @@
#include "u_types.h"
//!< 暂时只能是16字节
typedef struct uenv
{
obj_handler_t log_hd;
obj_handler_t rev0;
obj_handler_t ns_hd;
obj_handler_t rev1;
obj_handler_t rev2;
} uenv_t;
uenv_t *u_get_global_env(void);
void u_env_init(void *in_env);
void u_env_default_init(void);

View File

@@ -0,0 +1,218 @@
#include "u_types.h"
#include "u_prot.h"
#include "u_app.h"
#include "u_factory.h"
#include "u_mm.h"
#include "u_task.h"
#include "u_hd_man.h"
#include "u_thread.h"
#include "u_ipc.h"
#include "cpiofs.h"
#include "u_env.h"
#include "u_sys.h"
#include <assert.h>
#include <string.h>
#include <elf.h>
#include <stdio.h>
#include <errno.h>
/**
* @brief 向栈中存放数据
*
* @param stack
* @param val
* @return umword_t
*/
static umword_t app_stack_push(umword_t *stack, umword_t val)
{
*stack = val;
stack++;
return (umword_t)stack;
}
/**
* @brief 加载并执行一个app
*
* @param name app的名字
* @return int
*/
int app_load(const char *name)
{
msg_tag_t tag;
sys_info_t sys_info;
uenv_t *cur_env = u_get_global_env();
tag = sys_read_info(SYS_PROT, &sys_info);
if (msg_tag_get_val(tag))
{
return -ENOENT;
}
umword_t addr = cpio_find_file((umword_t)sys_info.bootfs_start_addr, (umword_t)(-1), name);
if (!addr)
{
return -ENOENT;
}
app_info_t *app = (app_info_t *)addr;
printf("app addr is 0x%x\n", app);
umword_t ram_base;
obj_handler_t hd_task = handler_alloc();
obj_handler_t hd_thread = handler_alloc();
// obj_handler_t hd_ipc = handler_alloc();
if (hd_task == HANDLER_INVALID)
{
goto end;
}
if (hd_thread == HANDLER_INVALID)
{
goto end;
}
// if (hd_ipc == HANDLER_INVALID)
// {
// goto end;
// }
tag = factory_create_task(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, hd_task));
if (msg_tag_get_prot(tag) < 0)
{
goto end_del_obj;
}
tag = factory_create_thread(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, hd_thread));
if (msg_tag_get_prot(tag) < 0)
{
goto end_del_obj;
}
// tag = factory_create_ipc(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, hd_ipc));
// if (msg_tag_get_prot(tag) < 0)
// {
// goto end_del_obj;
// }
// printf("ipc hd is %d\n", hd_ipc);
tag = task_alloc_ram_base(hd_task, app->i.ram_size, &ram_base);
if (msg_tag_get_prot(tag) < 0)
{
goto end_del_obj;
}
tag = task_map(hd_task, hd_task, TASK_PROT, 0);
if (msg_tag_get_prot(tag) < 0)
{
goto end_del_obj;
}
tag = task_map(hd_task, LOG_PROT, LOG_PROT, 0);
if (msg_tag_get_prot(tag) < 0)
{
goto end_del_obj;
}
// tag = task_map(hd_task, hd_ipc, hd_ipc, 0);
// if (msg_tag_get_prot(tag) < 0)
// {
// goto end_del_obj;
// }
tag = task_map(hd_task, hd_thread, THREAD_MAIN, 0);
if (msg_tag_get_prot(tag) < 0)
{
goto end_del_obj;
}
tag = task_map(hd_task, FACTORY_PROT, FACTORY_PROT, 0);
if (msg_tag_get_prot(tag) < 0)
{
goto end_del_obj;
}
tag = task_map(hd_task, MM_PROT, MM_PROT, 0);
if (msg_tag_get_prot(tag) < 0)
{
goto end_del_obj;
}
tag = thread_msg_buf_set(hd_thread, (void *)(ram_base + app->i.ram_size));
if (msg_tag_get_prot(tag) < 0)
{
goto end_del_obj;
}
tag = thread_bind_task(hd_thread, hd_task);
if (msg_tag_get_prot(tag) < 0)
{
goto end_del_obj;
}
// tag = ipc_bind(hd_ipc, hd_thread, 0);
// if (msg_tag_get_prot(tag) < 0)
// {
// goto end_del_obj;
// }
void *sp_addr = (char *)ram_base + app->i.stack_offset - app->i.data_offset;
void *sp_addr_top = (char *)sp_addr + app->i.stack_size;
umword_t usp_top = ((umword_t)((umword_t)sp_addr_top - 8) & ~0x7UL) - MSG_BUG_LEN;
/**处理传参*/
umword_t *buf;
thread_msg_buf_get(THREAD_MAIN, (umword_t *)(&buf), NULL);
umword_t *buf_bk = buf;
#define ARG_WORD_NR 10
buf = (umword_t *)app_stack_push(buf, 1); //!< argc 24
buf = (umword_t *)app_stack_push(buf, (umword_t)usp_top + ARG_WORD_NR * 4); //!< argv[0]
buf = (umword_t *)app_stack_push(buf, 0); //!< NULL
buf = (umword_t *)app_stack_push(buf, (umword_t)usp_top + ARG_WORD_NR * 4 + 16); //!< env[0...N]
buf = (umword_t *)app_stack_push(buf, 0); //!< NULL
buf = (umword_t *)app_stack_push(buf, (umword_t)AT_PAGESZ); //!< auxvt[0...N]
buf = (umword_t *)app_stack_push(buf, MK_PAGE_SIZE); //!< auxvt[0...N]
buf = (umword_t *)app_stack_push(buf, 0xfe); //!< auxvt[0...N] mkrtos_env
buf = (umword_t *)app_stack_push(buf, (umword_t)usp_top + ARG_WORD_NR * 4 + 16 + 16); //!< auxvt[0...N]
buf = (umword_t *)app_stack_push(buf, 0); //!< NULL
// set args & env.
memcpy((char *)buf_bk + ARG_WORD_NR * 4, name, strlen(name) + 1);
memcpy((char *)buf_bk + ARG_WORD_NR * 4 + 16, "PATH=/", strlen("PATH=/") + 1);
// set user env.
uenv_t *uenv = (uenv_t *)((char *)buf_bk + 9 * 4 + 16 + 16);
uenv->log_hd = LOG_PROT;
uenv->ns_hd = cur_env->ns_hd;
uenv->rev1 = HANDLER_INVALID;
uenv->rev2 = HANDLER_INVALID;
tag = thread_exec_regs(hd_thread, (umword_t)addr, (umword_t)sp_addr_top, ram_base, 1);
assert(msg_tag_get_prot(tag) >= 0);
/*启动线程运行*/
tag = thread_run(hd_thread, 2);
assert(msg_tag_get_prot(tag) >= 0);
// umword_t len;
// thread_msg_buf_get(THREAD_MAIN, (umword_t *)(&buf), NULL);
// strcpy((char *)buf, "hello shell.\n");
// ipc_call(hd_ipc, msg_tag_init4(0, ROUND_UP(strlen((char *)buf), WORD_BYTES), 0, 0), ipc_timeout_create2(0, 0));
// printf("test ok\n");
return 0;
end_del_obj:
if (hd_task != HANDLER_INVALID)
{
task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, hd_task));
}
if (hd_thread != HANDLER_INVALID)
{
task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, hd_thread));
}
// if (hd_ipc != HANDLER_INVALID)
// {
// task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, hd_ipc));
// }
end:
if (hd_task != HANDLER_INVALID)
{
handler_free(hd_task);
}
if (hd_thread != HANDLER_INVALID)
{
handler_free(hd_thread);
}
// if (hd_ipc != HANDLER_INVALID)
// {
// }
return -ENOMEM;
}

View File

@@ -0,0 +1,20 @@
#include "u_env.h"
#include "u_prot.h"
#include "u_hd_man.h"
static uenv_t env;
uenv_t *u_get_global_env(void)
{
return &env;
}
void u_env_default_init(void)
{
env.log_hd = LOG_PROT;
env.ns_hd = HANDLER_INVALID;
}
void u_env_init(void *in_env)
{
env = *((uenv_t *)in_env);
}

View File

@@ -10,6 +10,8 @@
#include "u_ipc.h"
#include "u_hd_man.h"
#include "u_irq_sender.h"
#include "u_app_loader.h"
#include "test/test.h"
extern void futex_init(void);
int main(int argc, char *args[])
@@ -27,8 +29,13 @@ int main(int argc, char *args[])
map_test();
ipc_timeout_test();
mm_test();
#endif
app_test();
#endif
int ret = app_load("shell");
if (ret < 0)
{
printf("app load fail, 0x%x\n", ret);
}
task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, TASK_THIS)); // 删除当前task以及申请得所有对象
printf("exit init.\n");
return 0;

View File

@@ -0,0 +1,59 @@
#include <u_types.h>
#include <string.h>
#include "u_hd_man.h"
#define NAMESPACE_PATH_LEN 32
#define NAMESAPCE_NR 32
typedef struct namespace_entry
{
char path[NAMESPACE_PATH_LEN];
obj_handler_t hd;
} namespace_entry_t;
typedef struct namespace
{
namespace_entry_t ne_list[NAMESAPCE_NR];
}
namespace_t;
static namespace_t ns;
static int ns_alloc(const char *path, obj_handler_t hd)
{
for (int i = 0; i < NAMESAPCE_NR; i++)
{
if (ns.ne_list[i].hd == HANDLER_INVALID)
{
ns.ne_list[i].hd = hd;
strncpy(ns.ne_list[i].path, path, NAMESPACE_PATH_LEN);
ns.ne_list[i].path[NAMESPACE_PATH_LEN - 1] = 0;
return i;
}
}
return -1;
}
int ns_register(const char *path, obj_handler_t hd)
{
if (ns_alloc(path, hd) < 0)
{
return -1;
}
return 0;
}
int ns_query(const char *path, obj_handler_t *hd)
{
for (int i = 0; i < NAMESAPCE_NR; i++)
{
if (ns.ne_list[i].hd == HANDLER_INVALID)
{
if (strncmp(ns.ne_list[i].path, path, NAMESPACE_PATH_LEN) == 0)
{
*hd = ns.ne_list[i].hd;
return 0;
}
}
}
return -1;
}

View File

@@ -6,6 +6,7 @@
#include "u_thread.h"
#include "u_task.h"
#include "u_ipc.h"
#include "u_env.h"
#include "test.h"
#include <assert.h>
#include <stdio.h>
@@ -30,16 +31,16 @@ void malloc_test(void)
int main(int argc, char *args[])
{
printf("argc:%d args[0]:%s\n", argc, args[0]);
ulog_write_str(LOG_PROT, "MKRTOS:\n");
ulog_write_str(u_get_global_env()->log_hd, "MKRTOS:\n");
malloc_test();
irq_test();
ipc_wait(12, 0);
ipc_reply(12, msg_tag_init4(0, 0, 0, 0));
char *buf;
umword_t len;
thread_msg_buf_get(THREAD_MAIN, (umword_t *)(&buf), NULL);
printf(buf);
// ipc_wait(12, 0);
// ipc_reply(12, msg_tag_init4(0, 0, 0, 0));
// char *buf;
// umword_t len;
// thread_msg_buf_get(THREAD_MAIN, (umword_t *)(&buf), NULL);
// printf(buf);
task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, TASK_THIS));
ulog_write_str(LOG_PROT, "Error.\n");
ulog_write_str(u_get_global_env()->log_hd, "Error.\n");
return 0;
}