Skip to content

Commit 0693ee3

Browse files
committed
Add VDSO functionality under the riscv64 architecture.
1 parent e7d870b commit 0693ee3

File tree

14 files changed

+518
-79
lines changed

14 files changed

+518
-79
lines changed

components/lwp/arch/risc-v/rv64/reloc.c renamed to components/lwp/arch/risc-v/common/reloc.c

+12-12
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@
1010

1111
typedef struct
1212
{
13-
Elf64_Word st_name;
14-
Elf64_Addr st_value;
15-
Elf64_Word st_size;
13+
Elf64_Word st_name;
14+
Elf64_Addr st_value;
15+
Elf64_Word st_size;
1616
unsigned char st_info;
1717
unsigned char st_other;
18-
Elf64_Half st_shndx;
18+
Elf64_Half st_shndx;
1919
} Elf64_sym;
2020

2121
#ifdef ARCH_MM_MMU
2222
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)
2323
{
2424
size_t rel_off;
25-
void* addr;
25+
void *addr;
2626

2727
if (rel_dyn_size && !dynsym)
2828
{
@@ -40,26 +40,26 @@ void arch_elf_reloc(rt_aspace_t aspace, void *text_start, void *rel_dyn_start, s
4040
addr = rt_hw_mmu_v2p(aspace, (void *)((rt_size_t)text_start + v1));
4141
if ((v2 & 0xff) == R_ARM_RELATIVE)
4242
{
43-
*(rt_size_t*)addr += (rt_size_t)text_start;
43+
*(rt_size_t *)addr += (rt_size_t)text_start;
4444
}
4545
else if ((v2 & 0xff) == R_ARM_ABS32)
4646
{
4747
uint32_t t;
4848
t = (v2 >> 8);
4949
if (t) /* 0 is UDF */
5050
{
51-
*(rt_size_t*)addr = (((rt_size_t)text_start) + dynsym[t].st_value);
51+
*(rt_size_t *)addr = (((rt_size_t)text_start) + dynsym[t].st_value);
5252
}
5353
}
5454
}
5555
/* modify got */
5656
if (got_size)
5757
{
58-
uint32_t *got_item = (uint32_t*)got_start;
58+
uint32_t *got_item = (uint32_t *)got_start;
5959

6060
for (rel_off = 0; rel_off < got_size; rel_off += 4, got_item++)
6161
{
62-
addr = rt_hw_mmu_v2p(aspace, got_item);
62+
addr = rt_hw_mmu_v2p(aspace, got_item);
6363
*(rt_size_t *)addr += (rt_size_t)text_start;
6464
}
6565
}
@@ -83,22 +83,22 @@ void arch_elf_reloc(void *text_start, void *rel_dyn_start, size_t rel_dyn_size,
8383

8484
if ((v2 & 0xff) == R_ARM_RELATIVE)
8585
{
86-
*(uint32_t*)(((rt_size_t)text_start) + v1) += (uint32_t)text_start;
86+
*(uint32_t *)(((rt_size_t)text_start) + v1) += (uint32_t)text_start;
8787
}
8888
else if ((v2 & 0xff) == R_ARM_ABS32)
8989
{
9090
uint32_t t;
9191
t = (v2 >> 8);
9292
if (t) /* 0 is UDF */
9393
{
94-
*(uint32_t*)(((rt_size_t)text_start) + v1) = (uint32_t)(((rt_size_t)text_start) + dynsym[t].st_value);
94+
*(uint32_t *)(((rt_size_t)text_start) + v1) = (uint32_t)(((rt_size_t)text_start) + dynsym[t].st_value);
9595
}
9696
}
9797
}
9898
/* modify got */
9999
if (got_size)
100100
{
101-
uint32_t *got_item = (uint32_t*)got_start;
101+
uint32_t *got_item = (uint32_t *)got_start;
102102

103103
for (rel_off = 0; rel_off < got_size; rel_off += 4, got_item++)
104104
{
+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright (c) 2006-2025 RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2025-04-22 ScuDays Add VDSO functionality under the riscv64 architecture.
9+
*/
10+
11+
#include <rtthread.h>
12+
#include <mmu.h>
13+
#include <lwp_user_mm.h>
14+
15+
#include "vdso.h"
16+
#include "vdso_datapage.h"
17+
#define DBG_TAG "vdso"
18+
#define DBG_LVL DBG_INFO
19+
#include <rtdbg.h>
20+
21+
enum vdso_abi
22+
{
23+
VDSO_ABI_RV64,
24+
};
25+
26+
enum vvar_pages
27+
{
28+
VVAR_DATA_PAGE_OFFSET,
29+
VVAR_TIMENS_PAGE_OFFSET,
30+
VVAR_NR_PAGES,
31+
};
32+
33+
34+
struct vdso_abi_info
35+
{
36+
const char *name;
37+
const char *vdso_code_start;
38+
const char *vdso_code_end;
39+
unsigned long vdso_pages;
40+
};
41+
42+
static struct vdso_abi_info vdso_info[] = {
43+
[VDSO_ABI_RV64] = {
44+
.name = "vdso_riscv64",
45+
.vdso_code_start = __vdso_text_start,
46+
.vdso_code_end = __vdso_text_end,
47+
},
48+
};
49+
50+
static union {
51+
struct vdso_data data[CS_BASES];
52+
uint8_t page[ARCH_PAGE_SIZE];
53+
} vdso_data_store __page_aligned_data;
54+
struct vdso_data *vdso_data = vdso_data_store.data;
55+
int init_ret_flag = RT_EOK;
56+
57+
static int __setup_additional_pages(enum vdso_abi abi, struct rt_lwp *lwp)
58+
{
59+
RT_ASSERT(lwp != RT_NULL);
60+
61+
int ret;
62+
void *vdso_base = RT_NULL;
63+
unsigned long vdso_data_len, vdso_text_len;
64+
65+
vdso_data_len = VVAR_NR_PAGES * ARCH_PAGE_SIZE;
66+
vdso_text_len = vdso_info[abi].vdso_pages << ARCH_PAGE_SHIFT;
67+
68+
vdso_base = lwp_map_user_phy(lwp, RT_NULL, rt_kmem_v2p((void *)vdso_data), vdso_data_len, 0);
69+
if (vdso_base != RT_NULL)
70+
{
71+
ret = RT_EOK;
72+
}
73+
else
74+
{
75+
ret = RT_ERROR;
76+
}
77+
78+
vdso_base += vdso_data_len;
79+
vdso_base = lwp_map_user_phy(lwp, vdso_base, rt_kmem_v2p((void *)vdso_info[abi].vdso_code_start), vdso_text_len, 0);
80+
81+
lwp->vdso_vbase = vdso_base;
82+
return ret;
83+
}
84+
85+
int arch_setup_additional_pages(struct rt_lwp *lwp)
86+
{
87+
int ret;
88+
if (init_ret_flag != RT_EOK) return -RT_ERROR;
89+
ret = __setup_additional_pages(VDSO_ABI_RV64, lwp);
90+
91+
return ret;
92+
}
93+
94+
95+
static void __initdata(void)
96+
{
97+
struct tm time_vdso = SOFT_RTC_VDSOTIME_DEFAULT;
98+
vdso_data->realtime_initdata = timegm(&time_vdso);
99+
}
100+
101+
102+
static int validate_vdso_elf(void)
103+
{
104+
if (rt_memcmp(vdso_info[VDSO_ABI_RV64].vdso_code_start, ELF_HEAD, ELF_HEAD_LEN))
105+
{
106+
LOG_E("vDSO is not a valid ELF object!");
107+
init_ret_flag = -RT_ERROR;
108+
return -RT_ERROR;
109+
}
110+
vdso_info[VDSO_ABI_RV64].vdso_pages = (vdso_info[VDSO_ABI_RV64].vdso_code_end - vdso_info[VDSO_ABI_RV64].vdso_code_start) >> ARCH_PAGE_SHIFT;
111+
112+
__initdata();
113+
return RT_EOK;
114+
}
115+
INIT_COMPONENT_EXPORT(validate_vdso_elf);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (c) 2006-2025 RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2025-04-22 ScuDays Add VDSO functionality under the riscv64 architecture.
9+
*/
10+
11+
#include <rtthread.h>
12+
#include <ktime.h>
13+
#include <time.h>
14+
#include <vdso_datapage.h>
15+
#include <vdso_data.h>
16+
#include <encoding.h>
17+
18+
void rt_vdso_update_glob_time(void)
19+
{
20+
struct vdso_data *vdata = get_k_vdso_data();
21+
struct timespec *vdso_ts;
22+
uint64_t initdata = vdata->realtime_initdata;
23+
rt_vdso_write_begin(vdata);
24+
25+
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
26+
rt_ktime_boottime_get_ns(vdso_ts);
27+
vdso_ts->tv_sec = initdata + vdso_ts->tv_sec;
28+
29+
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC];
30+
rt_ktime_boottime_get_ns(vdso_ts);
31+
32+
vdata->cycle_last = rdtime();
33+
rt_vdso_write_end(vdata);
34+
}

components/lwp/vdso/Kconfig

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
menuconfig RT_USING_VDSO
22
bool "vDSO"
33
default y
4-
depends on RT_USING_SMART && ARCH_ARMV8
4+
depends on RT_USING_SMART && (ARCH_ARMV8 || ARCH_RISCV)

components/lwp/vdso/SConscript

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ CPPPATH = [cwd, cwd + "/kernel"]
1212
if not GetDepend(['RT_USING_VDSO']):
1313
Return('group')
1414

15-
if rtconfig.ARCH != "aarch64":
15+
if rtconfig.ARCH != "aarch64" and rtconfig.ARCH != "risc-v":
1616
src = Glob('*.c')
1717
group = DefineGroup('VDSO', src, depend = ['RT_USING_SMART','RT_USING_VDSO'], CPPPATH = CPPPATH)
1818
Return('group')
@@ -21,15 +21,15 @@ list = os.listdir(cwd)
2121
src = Glob('kernel/*.c')
2222
src +=Glob('kernel/*.S')
2323

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

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

32-
vdso_file = os.path.join(cwd, 'user', 'SConstruct')
32+
vdso_file = os.path.join(cwd, 'user',"arch", rtconfig.ARCH, 'SConstruct')
3333
command = ["scons", "-f", vdso_file]
3434
clean = ["scons", "-f", vdso_file, "--clean"]
3535

components/lwp/vdso/user/SConstruct renamed to components/lwp/vdso/user/arch/aarch64/SConstruct

+5-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import subprocess
44

55
arguments = sys.argv[2]
66
vdso_usr = os.path.dirname(arguments)
7-
vdso_root = os.path.dirname(vdso_usr)
7+
user_path = os.path.dirname(vdso_usr)
8+
user_path = os.path.dirname(user_path)
9+
user_path = os.path.dirname(user_path)
810

911

1012
EXEC_PATH = os.getenv('RTT_EXEC_PATH') or '/usr/bin'
@@ -22,8 +24,7 @@ CXXFLAGS = DEVICE + ' -Wall -fdiagnostics-color=always'
2224
AFLAGS = ' -x assembler-with-cpp'
2325
CFLAGS = DEVICE + ' -Wall -Wno-cpp -std=gnu99 -fdiagnostics-color=always -fPIC -O2'
2426
LFLAGS = DEVICE + ' -Bsymbolic -Wl,--gc-sections,-u,system_vectors -T {path}/vdso.lds'.format(path=vdso_usr)
25-
CFLAGS += " -I {path} -I{path}/user".format(path=vdso_root)
26-
27+
CFLAGS += " -I {path} -I {upath} ".format(path=vdso_usr ,upath=user_path)
2728
env = Environment(tools=['gcc', 'link'],
2829
AS = AS, ASFLAGS = AFLAGS,
2930
CC = CC, CFLAGS = CFLAGS,
@@ -34,6 +35,6 @@ env.PrependENVPath('PATH', EXEC_PATH)
3435

3536
src = os.path.join(vdso_usr,'vdso_sys.c')
3637
target_name = 'librtos_vdso.so'
37-
target = os.path.join(vdso_usr, "build", target_name)
38+
target = os.path.join(user_path + "/user", "build", target_name)
3839
shared_lib = env.SharedLibrary(target=target, source=src)
3940
env.Default(shared_lib)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import os
2+
import sys
3+
import subprocess
4+
5+
arguments = sys.argv[2]
6+
vdso_usr = os.path.dirname(arguments)
7+
user_path = os.path.dirname(vdso_usr)
8+
user_path = os.path.dirname(user_path)
9+
user_path = os.path.dirname(user_path)
10+
rt_root_path = os.path.abspath(os.path.join(vdso_usr, "../../../../../../"))
11+
include_path = os.path.join(rt_root_path, "include")
12+
rtconfig_path = os.path.join(rt_root_path, "bsp", "qemu-virt64-riscv")
13+
14+
EXEC_PATH = os.getenv('RTT_EXEC_PATH') or '/usr/bin'
15+
PREFIX = os.getenv('RTT_CC_PREFIX') or 'riscv64-unknown-linux-gnu-'
16+
17+
CC = PREFIX + 'gcc'
18+
CXX = PREFIX + 'g++'
19+
CPP = PREFIX + 'cpp'
20+
AS = PREFIX + 'gcc'
21+
AR = PREFIX + 'ar'
22+
LINK = PREFIX + 'gcc'
23+
DEVICE = ' -march=rv64imafdc -mabi=lp64'
24+
CXXFLAGS = DEVICE + ' -Wall -fdiagnostics-color=always -fPIC -O0 -g'
25+
AFLAGS = ' -x assembler-with-cpp'
26+
CFLAGS = DEVICE + ' -Wall -Wno-cpp -std=gnu99 -fdiagnostics-color=always -fPIC -O2'
27+
LFLAGS = DEVICE + ' -Bsymbolic -Wl,--gc-sections -T {path}/vdso.lds'.format(path=vdso_usr)
28+
CFLAGS += " -I {path} -I {upath} -I {include_path} -I {rtconfig_path} ".format(path=vdso_usr, upath=user_path, include_path=include_path, rtconfig_path=rtconfig_path)
29+
30+
env = Environment(tools=['gcc', 'link'],
31+
AS = AS, ASFLAGS = AFLAGS,
32+
CC = CC, CFLAGS = CFLAGS,
33+
CXX = CXX, CXXFLAGS = CXXFLAGS,
34+
AR = AR,
35+
LINK = LINK, LINKFLAGS = LFLAGS)
36+
env.PrependENVPath('PATH', EXEC_PATH)
37+
38+
src = os.path.join(vdso_usr,'vdso_sys.c')
39+
target_name = 'librtos_vdso.so'
40+
target = os.path.join(user_path + "/user", "build", target_name)
41+
shared_lib = env.SharedLibrary(target=target, source=src)
42+
env.Default(shared_lib)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (c) 2006-2025 RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2025-04-22 ScuDays Add VDSO functionality under the riscv64 architecture.
9+
*/
10+
11+
#include <vdso_config.h>
12+
13+
OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv")
14+
OUTPUT_ARCH(riscv)
15+
16+
SECTIONS
17+
{
18+
PROVIDE(_vdso_data = . - __VVAR_PAGES * VDSO_PAGE_SIZE);
19+
. = SIZEOF_HEADERS;
20+
21+
.hash : { *(.hash) } :text
22+
.gnu.hash : { *(.gnu.hash) }
23+
.dynsym : { *(.dynsym) }
24+
.dynstr : { *(.dynstr) }
25+
.gnu.version : { *(.gnu.version) }
26+
.gnu.version_d : { *(.gnu.version_d) }
27+
.gnu.version_r : { *(.gnu.version_r) }
28+
29+
.dynamic : { *(.dynamic) } :text :dynamic
30+
.rela.dyn : ALIGN(8) { *(.rela .rela*) }
31+
32+
.rodata : {
33+
*(.rodata*)
34+
*(.got)
35+
*(.got.plt)
36+
*(.plt)
37+
*(.plt.*)
38+
*(.iplt)
39+
*(.igot .igot.plt)
40+
} :text
41+
/DISCARD/ : {
42+
*(.data .data.* .sdata*)
43+
*(.bss .sbss .dynbss .dynsbss)
44+
}
45+
}
46+
47+
PHDRS
48+
{
49+
text PT_LOAD FLAGS(5) FILEHDR PHDRS;
50+
dynamic PT_DYNAMIC FLAGS(4);
51+
}
52+
53+
VERSION
54+
{
55+
LINUX_2.6 {
56+
global:
57+
__vdso_clock_gettime;
58+
local: *;
59+
};
60+
}

0 commit comments

Comments
 (0)