Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions components/lwp/Kconfig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
menuconfig RT_USING_LWP
bool "light-weight process"
bool "lwP(light weight Process)"
depends on RT_USING_SMART
default y
help
Expand Down Expand Up @@ -87,4 +87,3 @@ if RT_USING_LWP
rsource "terminal/Kconfig"
rsource "vdso/Kconfig"
endif

3 changes: 3 additions & 0 deletions components/lwp/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@ if platform in platform_file.keys(): # support platforms
if arch in support_arch.keys() and cpu in support_arch[arch]:
asm_path = 'arch/' + arch + '/' + cpu + '/*_' + platform_file[platform]
arch_common = 'arch/' + arch + '/' + 'common/*.c'
common = 'arch/common/*.c'
if not GetDepend('RT_USING_VDSO'):
vdso_files = ['vdso_data.c', 'vdso.c']
src += [f for f in Glob(arch_common) if os.path.basename(str(f)) not in vdso_files]
src += [f for f in Glob(common) if os.path.basename(str(f)) not in vdso_files]
else:
src += Glob(arch_common)
src += Glob(common)
if not GetDepend('ARCH_MM_MMU'):
excluded_files = ['ioremap.c', 'lwp_futex.c', 'lwp_mm_area.c', 'lwp_pmutex.c', 'lwp_shm.c', 'lwp_user_mm.c']
src += [f for f in Glob('*.c') if os.path.basename(str(f)) not in excluded_files] + Glob(asm_path)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,77 +1,83 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-07-04 rcitach init ver.
* 2025-04-22 ScuDays Add VDSO functionality under the riscv64 architecture.
*/

#include <rtthread.h>
#include <mmu.h>
#include <gtimer.h>
#include <lwp_user_mm.h>

#include "vdso.h"
#include "vdso_datapage.h"
#define DBG_TAG "vdso"
#define DBG_LVL DBG_INFO
#define DBG_TAG "vdso"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>

enum vdso_abi {
VDSO_ABI_AA64,
enum vdso_abi
{
VDSO_ABI_COMMON,
};
enum vvar_pages {

enum vvar_pages
{
VVAR_DATA_PAGE_OFFSET,
VVAR_TIMENS_PAGE_OFFSET,
VVAR_NR_PAGES,
};
struct vdso_abi_info {
const char *name;
const char *vdso_code_start;
const char *vdso_code_end;
unsigned long vdso_pages;


struct vdso_abi_info
{
const char *name;
const char *vdso_code_start;
const char *vdso_code_end;
unsigned long vdso_pages;
};

static struct vdso_abi_info vdso_info[] = {
[VDSO_ABI_AA64] = {
.name = "vdso_aarch64",
.vdso_code_start = __vdso_text_start,
.vdso_code_end = __vdso_text_end,
},
[VDSO_ABI_COMMON] = {
.name = "vdso_common",
.vdso_code_start = __vdso_text_start,
.vdso_code_end = __vdso_text_end,
},
};

static union {
struct vdso_data data[CS_BASES];
uint8_t page[ARCH_PAGE_SIZE];
struct vdso_data data[CS_BASES];
uint8_t page[ARCH_PAGE_SIZE];
} vdso_data_store __page_aligned_data;
struct vdso_data *vdso_data = vdso_data_store.data;
int init_ret_flag = RT_EOK;
struct vdso_data *vdso_data = vdso_data_store.data;
int init_ret_flag = RT_EOK;

static int __setup_additional_pages(enum vdso_abi abi, struct rt_lwp *lwp)
{
RT_ASSERT(lwp != RT_NULL);

int ret;
void *vdso_base = RT_NULL;
int ret;
void *vdso_base = RT_NULL;
unsigned long vdso_data_len, vdso_text_len;

vdso_data_len = VVAR_NR_PAGES * ARCH_PAGE_SIZE;
vdso_text_len = vdso_info[abi].vdso_pages << ARCH_PAGE_SHIFT;

vdso_base = lwp_map_user_phy(lwp, RT_NULL, rt_kmem_v2p((void *)vdso_data), vdso_data_len, 0);
if(vdso_base != RT_NULL)
if (vdso_base != RT_NULL)
{
ret = RT_EOK;
}
else
{
ret = RT_ERROR;
}

vdso_base += vdso_data_len;
vdso_base = lwp_map_user_phy(lwp, vdso_base, rt_kmem_v2p((void *)vdso_info[abi].vdso_code_start), vdso_text_len, 0);
vdso_base = lwp_map_user_phy(lwp, vdso_base, rt_kmem_v2p((void *)vdso_info[abi].vdso_code_start), vdso_text_len, 0);

lwp->vdso_vbase = vdso_base;
return ret;
Expand All @@ -81,28 +87,28 @@ int arch_setup_additional_pages(struct rt_lwp *lwp)
{
int ret;
if (init_ret_flag != RT_EOK) return -RT_ERROR;
ret = __setup_additional_pages(VDSO_ABI_AA64, lwp);
ret = __setup_additional_pages(VDSO_ABI_COMMON, lwp);

return ret;
}


static void __initdata(void)
{
struct tm time_vdso = SOFT_RTC_VDSOTIME_DEFAULT;
struct tm time_vdso = SOFT_RTC_VDSOTIME_DEFAULT;
vdso_data->realtime_initdata = timegm(&time_vdso);
}


static int validate_vdso_elf(void)
{
if (rt_memcmp(vdso_info[VDSO_ABI_AA64].vdso_code_start, ELF_HEAD, ELF_HEAD_LEN)) {
if (rt_memcmp(vdso_info[VDSO_ABI_COMMON].vdso_code_start, ELF_HEAD, ELF_HEAD_LEN))
{
LOG_E("vDSO is not a valid ELF object!");
init_ret_flag = -RT_ERROR;
return -RT_ERROR;
}
vdso_info[VDSO_ABI_AA64].vdso_pages = (
vdso_info[VDSO_ABI_AA64].vdso_code_end -
vdso_info[VDSO_ABI_AA64].vdso_code_start) >>
ARCH_PAGE_SHIFT;
vdso_info[VDSO_ABI_COMMON].vdso_pages = (vdso_info[VDSO_ABI_COMMON].vdso_code_end - vdso_info[VDSO_ABI_COMMON].vdso_code_start) >> ARCH_PAGE_SHIFT;

__initdata();
return RT_EOK;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@

typedef struct
{
Elf64_Word st_name;
Elf64_Addr st_value;
Elf64_Word st_size;
Elf64_Word st_name;
Elf64_Addr st_value;
Elf64_Word st_size;
unsigned char st_info;
unsigned char st_other;
Elf64_Half st_shndx;
Elf64_Half st_shndx;
} Elf64_sym;

#ifdef ARCH_MM_MMU
void arch_elf_reloc(rt_aspace_t aspace, void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, Elf64_sym *dynsym)
{
size_t rel_off;
void* addr;
void *addr;

if (rel_dyn_size && !dynsym)
{
Expand All @@ -40,26 +40,26 @@ void arch_elf_reloc(rt_aspace_t aspace, void *text_start, void *rel_dyn_start, s
addr = rt_hw_mmu_v2p(aspace, (void *)((rt_size_t)text_start + v1));
if ((v2 & 0xff) == R_ARM_RELATIVE)
{
*(rt_size_t*)addr += (rt_size_t)text_start;
*(rt_size_t *)addr += (rt_size_t)text_start;
}
else if ((v2 & 0xff) == R_ARM_ABS32)
{
uint32_t t;
t = (v2 >> 8);
if (t) /* 0 is UDF */
{
*(rt_size_t*)addr = (((rt_size_t)text_start) + dynsym[t].st_value);
*(rt_size_t *)addr = (((rt_size_t)text_start) + dynsym[t].st_value);
}
}
}
/* modify got */
if (got_size)
{
uint32_t *got_item = (uint32_t*)got_start;
uint32_t *got_item = (uint32_t *)got_start;

for (rel_off = 0; rel_off < got_size; rel_off += 4, got_item++)
{
addr = rt_hw_mmu_v2p(aspace, got_item);
addr = rt_hw_mmu_v2p(aspace, got_item);
*(rt_size_t *)addr += (rt_size_t)text_start;
}
}
Expand All @@ -83,22 +83,22 @@ void arch_elf_reloc(void *text_start, void *rel_dyn_start, size_t rel_dyn_size,

if ((v2 & 0xff) == R_ARM_RELATIVE)
{
*(uint32_t*)(((rt_size_t)text_start) + v1) += (uint32_t)text_start;
*(uint32_t *)(((rt_size_t)text_start) + v1) += (uint32_t)text_start;
}
else if ((v2 & 0xff) == R_ARM_ABS32)
{
uint32_t t;
t = (v2 >> 8);
if (t) /* 0 is UDF */
{
*(uint32_t*)(((rt_size_t)text_start) + v1) = (uint32_t)(((rt_size_t)text_start) + dynsym[t].st_value);
*(uint32_t *)(((rt_size_t)text_start) + v1) = (uint32_t)(((rt_size_t)text_start) + dynsym[t].st_value);
}
}
}
/* modify got */
if (got_size)
{
uint32_t *got_item = (uint32_t*)got_start;
uint32_t *got_item = (uint32_t *)got_start;

for (rel_off = 0; rel_off < got_size; rel_off += 4, got_item++)
{
Expand Down
34 changes: 34 additions & 0 deletions components/lwp/arch/risc-v/common/vdso_data.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-04-22 ScuDays Add VDSO functionality under the riscv64 architecture.
*/

#include <rtthread.h>
#include <ktime.h>
#include <time.h>
#include <vdso_datapage.h>
#include <vdso_data.h>
#include <encoding.h>

void rt_vdso_update_glob_time(void)
{
struct vdso_data *vdata = get_k_vdso_data();
struct timespec *vdso_ts;
uint64_t initdata = vdata->realtime_initdata;
rt_vdso_write_begin(vdata);

vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
rt_ktime_boottime_get_ns(vdso_ts);
vdso_ts->tv_sec = initdata + vdso_ts->tv_sec;

vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC];
rt_ktime_boottime_get_ns(vdso_ts);

vdata->cycle_last = rdtime();
rt_vdso_write_end(vdata);
}
2 changes: 1 addition & 1 deletion components/lwp/terminal/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ menuconfig LWP_USING_TERMINAL
if LWP_USING_TERMINAL
config LWP_PTY_MAX_PARIS_LIMIT
int "Max number of pty devices registered at the same time"
default 64
default 32
help
This upper limit is set to protect kernel memory from draining
out by the application if it keeps allocating pty devices.
Expand Down
6 changes: 3 additions & 3 deletions components/lwp/vdso/Kconfig
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
menuconfig RT_USING_VDSO
bool "vDSO"
config RT_USING_VDSO
bool "vDSO (Virtual Dynamic Shared Object)"
depends on (ARCH_ARMV8 || ARCH_RISCV)
default y
depends on RT_USING_SMART && ARCH_ARMV8
76 changes: 40 additions & 36 deletions components/lwp/vdso/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,51 @@ import os
import rtconfig
import subprocess
from building import *
Import('RTT_ROOT')

group = []

cwd = GetCurrentDir()
group = []
cwd = GetCurrentDir()
CPPPATH = [cwd, cwd + "/kernel"]
list = os.listdir(cwd)
src = Glob('kernel/*.c') + Glob('kernel/*.S')

if not GetDepend(['RT_USING_VDSO']):
Return('group')

if rtconfig.ARCH != "aarch64":
src = Glob('*.c')
group = DefineGroup('VDSO', src, depend = ['RT_USING_SMART','RT_USING_VDSO'], CPPPATH = CPPPATH)
Return('group')

list = os.listdir(cwd)
src = Glob('kernel/*.c')
src +=Glob('kernel/*.S')

if not os.path.exists(cwd + "/user/vdso.lds"):
Preprocessing("user/vdso.lds.S", ".lds", CPPPATH=[cwd])

#aarch64 vdso xmake
# vdso_file = os.path.join(cwd, 'usr', 'xmake.lua')
# command = ["xmake", "-F", vdso_file]
# clean = ["xmake", "clean"]

vdso_file = os.path.join(cwd, 'user', 'SConstruct')
command = ["scons", "-f", vdso_file]
clean = ["scons", "-f", vdso_file, "--clean"]

if not GetOption('clean'):
result = subprocess.run(command)
if rtconfig.ARCH != "aarch64" and rtconfig.ARCH != "risc-v":
# not supported arch
src = []
else:
result = subprocess.run(clean)

if result.returncode == 0:
print("Command executed successfully")
else:
print("Command failed with exit code:", result.returncode)
exit(1)

group = DefineGroup('VDSO', src, depend = ['RT_USING_SMART','RT_USING_VDSO'], CPPPATH = CPPPATH)
if not hasattr(rtconfig, 'CPP') or rtconfig.CPP is None:
rtconfig.CPP = rtconfig.PREFIX + 'cpp'
if not hasattr(rtconfig, 'CPPFLAGS') or rtconfig.CPPFLAGS is None:
rtconfig.CPPFLAGS = ' -E -P -x assembler-with-cpp'

if not os.path.exists(cwd + "/user" + "/arch" +"/" + rtconfig.ARCH + "/vdso.lds"):
Preprocessing("user/arch/" + rtconfig.ARCH + "/vdso.lds.S", ".lds", CPPPATH=[cwd])

vdso_arch = os.path.join(cwd, 'user',"arch", rtconfig.ARCH)

process_env = os.environ.copy()
if hasattr(rtconfig, 'EXEC_PATH') and rtconfig.EXEC_PATH is not None:
process_env['RTT_EXEC_PATH'] = rtconfig.EXEC_PATH
if hasattr(rtconfig, 'PREFIX') and rtconfig.PREFIX is not None:
process_env['RTT_CC_PREFIX'] = rtconfig.PREFIX
if hasattr(rtconfig, 'DEVICE') and rtconfig.DEVICE is not None:
process_env['RTT_DEVICE'] = rtconfig.DEVICE

command = ["scons", "-C", vdso_arch]
clean_command = ["scons", "-C", vdso_arch, "--clean"]

if not GetOption('clean'):
result = subprocess.run(command, env=process_env, check=True)
else:
result = subprocess.run(clean_command, env=process_env, check=True)

if result.returncode == 0:
print("Command executed successfully")
else:
print("Command failed with exit code:", result.returncode)
exit(1)

group = DefineGroup('vDSO', src, depend = ['RT_USING_SMART','RT_USING_VDSO'], CPPPATH = CPPPATH)
Return('group')
Loading