mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2025-12-26 01:07:21 +00:00
sync smart & dfs (#8672)
Signed-off-by: xqyjlj <xqyjlj@126.com> Signed-off-by: Shell <smokewood@qq.com> Co-authored-by: xqyjlj <xqyjlj@126.com>
This commit is contained in:
@@ -12,6 +12,8 @@
|
||||
* 2023-02-20 wangxiaoyao inv icache before new app startup
|
||||
* 2023-02-20 wangxiaoyao fix bug on foreground app switch
|
||||
* 2023-10-16 Shell Support a new backtrace framework
|
||||
* 2023-11-17 xqyjlj add process group and session support
|
||||
* 2023-11-30 Shell add lwp_startup()
|
||||
*/
|
||||
|
||||
#define DBG_TAG "lwp"
|
||||
@@ -39,7 +41,7 @@
|
||||
#include "lwp_arch_comm.h"
|
||||
#include "lwp_signal.h"
|
||||
#include "lwp_dbg.h"
|
||||
#include "console.h"
|
||||
#include <terminal/terminal.h>
|
||||
|
||||
#ifdef ARCH_MM_MMU
|
||||
#include <lwp_user_mm.h>
|
||||
@@ -59,16 +61,31 @@ static const char elf_magic[] = {0x7f, 'E', 'L', 'F'};
|
||||
#ifdef DFS_USING_WORKDIR
|
||||
extern char working_directory[];
|
||||
#endif
|
||||
static struct termios stdin_termios, old_stdin_termios;
|
||||
|
||||
int load_ldso(struct rt_lwp *lwp, char *exec_name, char *const argv[], char *const envp[]);
|
||||
|
||||
struct termios *get_old_termios(void)
|
||||
/**
|
||||
* @brief The default console is only a backup device with lowest priority.
|
||||
* It's always recommended to scratch the console from the boot arguments.
|
||||
* And dont forget to register the device with a higher priority.
|
||||
*/
|
||||
static rt_err_t lwp_default_console_setup(void)
|
||||
{
|
||||
return &old_stdin_termios;
|
||||
rt_device_t bakdev = rt_device_find("ttyS0");
|
||||
rt_err_t rc;
|
||||
|
||||
if (bakdev)
|
||||
{
|
||||
lwp_console_register_backend(bakdev, LWP_CONSOLE_LOWEST_PRIOR);
|
||||
rc = RT_EOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = -RT_EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int lwp_component_init(void)
|
||||
static int lwp_component_init(void)
|
||||
{
|
||||
int rc;
|
||||
if ((rc = lwp_tid_init()) != RT_EOK)
|
||||
@@ -83,10 +100,99 @@ int lwp_component_init(void)
|
||||
{
|
||||
LOG_E("%s: rt_channel_component_init failed", __func__);
|
||||
}
|
||||
else if ((rc = lwp_futex_init()) != RT_EOK)
|
||||
{
|
||||
LOG_E("%s: lwp_futex_init() failed", __func__);
|
||||
}
|
||||
else if ((rc = lwp_default_console_setup()) != RT_EOK)
|
||||
{
|
||||
LOG_E("%s: lwp_default_console_setup() failed", __func__);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
INIT_COMPONENT_EXPORT(lwp_component_init);
|
||||
|
||||
rt_weak int lwp_startup_debug_request(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define LATENCY_TIMES (3)
|
||||
#define LATENCY_IN_MSEC (128)
|
||||
#define LWP_CONSOLE_PATH "CONSOLE=/dev/console"
|
||||
const char *init_search_path[] = {
|
||||
"/sbin/init",
|
||||
"/bin/init",
|
||||
};
|
||||
|
||||
/**
|
||||
* Startup process 0 and do the essential works
|
||||
* This is the "Hello World" point of RT-Smart
|
||||
*/
|
||||
static int lwp_startup(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
const char *init_path;
|
||||
char *argv[] = {0, "&"};
|
||||
char *envp[] = {LWP_CONSOLE_PATH, 0};
|
||||
|
||||
#ifdef LWP_DEBUG
|
||||
int command;
|
||||
int countdown = LATENCY_TIMES;
|
||||
while (countdown)
|
||||
{
|
||||
command = lwp_startup_debug_request();
|
||||
if (command)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
rt_kprintf("Press any key to stop init process startup ... %d\n", countdown);
|
||||
countdown -= 1;
|
||||
rt_thread_mdelay(LATENCY_IN_MSEC);
|
||||
}
|
||||
rt_kprintf("Starting init ...\n");
|
||||
#endif
|
||||
|
||||
for (size_t i = 0; i < sizeof(init_search_path)/sizeof(init_search_path[0]); i++)
|
||||
{
|
||||
struct stat s;
|
||||
init_path = init_search_path[i];
|
||||
error = stat(init_path, &s);
|
||||
if (error == 0)
|
||||
{
|
||||
argv[0] = (void *)init_path;
|
||||
error = lwp_execve((void *)init_path, 0, sizeof(argv)/sizeof(argv[0]), argv, envp);
|
||||
if (error < 0)
|
||||
{
|
||||
LOG_E("%s: failed to startup process 0 (init)\n"
|
||||
"Switching to legacy mode...", __func__);
|
||||
}
|
||||
else if (error != 1)
|
||||
{
|
||||
LOG_E("%s: pid 1 is already allocated", __func__);
|
||||
error = -EBUSY;
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_lwp_t p = lwp_from_pid_locked(1);
|
||||
p->sig_protected = 0;
|
||||
|
||||
error = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
LOG_E("%s: init program not found\n"
|
||||
"Switching to legacy mode...", __func__);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
INIT_APP_EXPORT(lwp_startup);
|
||||
|
||||
void lwp_setcwd(char *buf)
|
||||
{
|
||||
struct rt_lwp *lwp = RT_NULL;
|
||||
@@ -100,11 +206,11 @@ void lwp_setcwd(char *buf)
|
||||
lwp = (struct rt_lwp *)rt_thread_self()->lwp;
|
||||
if (lwp)
|
||||
{
|
||||
rt_strncpy(lwp->working_directory, buf, DFS_PATH_MAX);
|
||||
rt_strncpy(lwp->working_directory, buf, DFS_PATH_MAX - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_strncpy(working_directory, buf, DFS_PATH_MAX);
|
||||
rt_strncpy(working_directory, buf, DFS_PATH_MAX - 1);
|
||||
}
|
||||
|
||||
return ;
|
||||
@@ -114,8 +220,13 @@ char *lwp_getcwd(void)
|
||||
{
|
||||
char *dir_buf = RT_NULL;
|
||||
struct rt_lwp *lwp = RT_NULL;
|
||||
rt_thread_t thread = rt_thread_self();
|
||||
|
||||
if (thread)
|
||||
{
|
||||
lwp = (struct rt_lwp *)thread->lwp;
|
||||
}
|
||||
|
||||
lwp = (struct rt_lwp *)rt_thread_self()->lwp;
|
||||
if (lwp)
|
||||
{
|
||||
if(lwp->working_directory[0] != '/')
|
||||
@@ -1077,25 +1188,35 @@ void lwp_cleanup(struct rt_thread *tid)
|
||||
return;
|
||||
}
|
||||
|
||||
static void lwp_copy_stdio_fdt(struct rt_lwp *lwp)
|
||||
static void lwp_execve_setup_stdio(struct rt_lwp *lwp)
|
||||
{
|
||||
struct dfs_file *d;
|
||||
struct dfs_fdtable *lwp_fdt;
|
||||
struct dfs_file *cons_file;
|
||||
int cons_fd;
|
||||
|
||||
lwp_fdt = &lwp->fdt;
|
||||
|
||||
/* open console */
|
||||
cons_fd = open("/dev/console", O_RDWR);
|
||||
if (cons_fd < 0)
|
||||
{
|
||||
LOG_E("%s: Cannot open console tty", __func__);
|
||||
return ;
|
||||
}
|
||||
LOG_D("%s: open console as fd %d", __func__, cons_fd);
|
||||
|
||||
/* init 4 fds */
|
||||
lwp_fdt->fds = rt_calloc(4, sizeof(void *));
|
||||
if (lwp_fdt->fds)
|
||||
{
|
||||
cons_file = fd_get(cons_fd);
|
||||
lwp_fdt->maxfd = 4;
|
||||
d = fd_get(0);
|
||||
fdt_fd_associate_file(lwp_fdt, 0, d);
|
||||
d = fd_get(1);
|
||||
fdt_fd_associate_file(lwp_fdt, 1, d);
|
||||
d = fd_get(2);
|
||||
fdt_fd_associate_file(lwp_fdt, 2, d);
|
||||
fdt_fd_associate_file(lwp_fdt, 0, cons_file);
|
||||
fdt_fd_associate_file(lwp_fdt, 1, cons_file);
|
||||
fdt_fd_associate_file(lwp_fdt, 2, cons_file);
|
||||
}
|
||||
|
||||
close(cons_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1197,11 +1318,8 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)
|
||||
int result;
|
||||
struct rt_lwp *lwp;
|
||||
char *thread_name;
|
||||
char *argv_last = argv[argc - 1];
|
||||
int bg = 0;
|
||||
struct process_aux *aux;
|
||||
int tid = 0;
|
||||
int ret;
|
||||
|
||||
if (filename == RT_NULL)
|
||||
{
|
||||
@@ -1213,7 +1331,7 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
lwp = lwp_create(LWP_CREATE_FLAG_ALLOC_PID);
|
||||
lwp = lwp_create(LWP_CREATE_FLAG_ALLOC_PID | LWP_CREATE_FLAG_NOTRACE_EXEC);
|
||||
|
||||
if (lwp == RT_NULL)
|
||||
{
|
||||
@@ -1236,12 +1354,6 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argv_last[0] == '&' && argv_last[1] == '\0')
|
||||
{
|
||||
argc--;
|
||||
bg = 1;
|
||||
}
|
||||
|
||||
if ((aux = lwp_argscopy(lwp, argc, argv, envp)) == RT_NULL)
|
||||
{
|
||||
lwp_tid_put(tid);
|
||||
@@ -1263,7 +1375,7 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)
|
||||
rt_thread_t thread = RT_NULL;
|
||||
rt_uint32_t priority = 25, tick = 200;
|
||||
|
||||
lwp_copy_stdio_fdt(lwp);
|
||||
lwp_execve_setup_stdio(lwp);
|
||||
|
||||
/* obtain the base name */
|
||||
thread_name = strrchr(filename, '/');
|
||||
@@ -1284,88 +1396,46 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)
|
||||
if (thread != RT_NULL)
|
||||
{
|
||||
struct rt_lwp *self_lwp;
|
||||
rt_session_t session;
|
||||
rt_processgroup_t group;
|
||||
|
||||
thread->tid = tid;
|
||||
lwp_tid_set_thread(tid, thread);
|
||||
LOG_D("lwp kernel => (0x%08x, 0x%08x)\n", (rt_size_t)thread->stack_addr,
|
||||
(rt_size_t)thread->stack_addr + thread->stack_size);
|
||||
self_lwp = lwp_self();
|
||||
|
||||
/* when create init, self_lwp == null */
|
||||
if (self_lwp == RT_NULL && lwp_to_pid(lwp) != 1)
|
||||
{
|
||||
self_lwp = lwp_from_pid_and_lock(1);
|
||||
}
|
||||
|
||||
if (self_lwp)
|
||||
{
|
||||
//lwp->tgroup_leader = &thread; //add thread group leader for lwp
|
||||
lwp->__pgrp = tid;
|
||||
lwp->session = self_lwp->session;
|
||||
/* lwp add to children link */
|
||||
lwp_children_register(self_lwp, lwp);
|
||||
}
|
||||
else
|
||||
|
||||
session = RT_NULL;
|
||||
group = RT_NULL;
|
||||
|
||||
group = lwp_pgrp_create(lwp);
|
||||
if (group)
|
||||
{
|
||||
//lwp->tgroup_leader = &thread; //add thread group leader for lwp
|
||||
lwp->__pgrp = tid;
|
||||
}
|
||||
if (!bg)
|
||||
{
|
||||
if (lwp->session == -1)
|
||||
lwp_pgrp_insert(group, lwp);
|
||||
if (self_lwp == RT_NULL)
|
||||
{
|
||||
struct tty_struct *tty = RT_NULL;
|
||||
struct rt_lwp *old_lwp;
|
||||
tty = (struct tty_struct *)console_tty_get();
|
||||
old_lwp = tty->foreground;
|
||||
if (old_lwp)
|
||||
{
|
||||
rt_mutex_take(&tty->lock, RT_WAITING_FOREVER);
|
||||
ret = tty_push(&tty->head, old_lwp);
|
||||
rt_mutex_release(&tty->lock);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
lwp_tid_put(tid);
|
||||
lwp_ref_dec(lwp);
|
||||
LOG_E("malloc fail!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
lwp->tty = tty;
|
||||
lwp->tty->pgrp = lwp->__pgrp;
|
||||
lwp->tty->session = lwp->session;
|
||||
lwp->tty->foreground = lwp;
|
||||
tcgetattr(1, &stdin_termios);
|
||||
old_stdin_termios = stdin_termios;
|
||||
stdin_termios.c_lflag |= ICANON | ECHO | ECHOCTL;
|
||||
tcsetattr(1, 0, &stdin_termios);
|
||||
session = lwp_session_create(lwp);
|
||||
lwp_session_insert(session, group);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self_lwp != RT_NULL)
|
||||
{
|
||||
rt_mutex_take(&self_lwp->tty->lock, RT_WAITING_FOREVER);
|
||||
ret = tty_push(&self_lwp->tty->head, self_lwp);
|
||||
rt_mutex_release(&self_lwp->tty->lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
lwp_tid_put(tid);
|
||||
lwp_ref_dec(lwp);
|
||||
LOG_E("malloc fail!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
lwp->tty = self_lwp->tty;
|
||||
lwp->tty->pgrp = lwp->__pgrp;
|
||||
lwp->tty->session = lwp->session;
|
||||
lwp->tty->foreground = lwp;
|
||||
}
|
||||
else
|
||||
{
|
||||
lwp->tty = RT_NULL;
|
||||
}
|
||||
|
||||
session = lwp_session_find(lwp_sid_get_byprocess(self_lwp));
|
||||
lwp_session_insert(session, group);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lwp->background = RT_TRUE;
|
||||
}
|
||||
|
||||
thread->lwp = lwp;
|
||||
#ifndef ARCH_MM_MMU
|
||||
struct lwp_app_head *app_head = (struct lwp_app_head*)lwp->text_entry;
|
||||
@@ -1381,6 +1451,8 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)
|
||||
#endif /* not defined ARCH_MM_MMU */
|
||||
rt_list_insert_after(&lwp->t_grp, &thread->sibling);
|
||||
|
||||
lwp->did_exec = RT_TRUE;
|
||||
|
||||
if (debug && rt_dbg_ops)
|
||||
{
|
||||
lwp->debug = debug;
|
||||
@@ -1482,30 +1554,30 @@ rt_err_t lwp_backtrace_frame(rt_thread_t uthread, struct rt_hw_backtrace_frame *
|
||||
char **argv;
|
||||
rt_lwp_t lwp;
|
||||
|
||||
if (uthread->lwp)
|
||||
if (uthread && uthread->lwp && rt_scheduler_is_available())
|
||||
{
|
||||
lwp = uthread->lwp;
|
||||
argv = lwp_get_command_line_args(lwp);
|
||||
if (argv)
|
||||
{
|
||||
LOG_RAW("please use: addr2line -e %s -a -f", argv[0]);
|
||||
rt_kprintf("please use: addr2line -e %s -a -f", argv[0]);
|
||||
lwp_free_command_line_args(argv);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_RAW("please use: addr2line -e %s -a -f", lwp->cmd);
|
||||
rt_kprintf("please use: addr2line -e %s -a -f", lwp->cmd);
|
||||
}
|
||||
|
||||
while (nesting < RT_BACKTRACE_LEVEL_MAX_NR)
|
||||
{
|
||||
LOG_RAW(" 0x%lx", frame->pc);
|
||||
rt_kprintf(" 0x%lx", frame->pc);
|
||||
if (rt_hw_backtrace_frame_unwind(uthread, frame))
|
||||
{
|
||||
break;
|
||||
}
|
||||
nesting++;
|
||||
}
|
||||
LOG_RAW("\n");
|
||||
rt_kprintf("\n");
|
||||
rc = RT_EOK;
|
||||
}
|
||||
return rc;
|
||||
|
||||
Reference in New Issue
Block a user