Skip to content

Commit d871f25

Browse files
committed
rustvmm_gen: Introduce rustvmm_gen.py
`rustvmm_gen.py` integrates kernel version checking, source extraction, compilation and header installation. Header files could be prepared with command: ```command ./rustvmm_gen/rustvmm_gen.py --arch <arm64/x86_64/riscv> --version <X.Y/X.Y.Z> prepare ``` Source code required by `seccompiler` could be generated with command: ```command ./rustvmm_gen/rustvmm_gen.py --arch <arm64/x86_64/riscv> --version <X.Y/X.Y.Z> generate_syscall ``` Signed-off-by: Ruoqing He <[email protected]>
1 parent 9652fb7 commit d871f25

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

scripts/rustvmm_gen.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright 2025 © Institute of Software, CAS. All rights reserved.
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
import argparse
7+
import os
8+
from pathlib import Path
9+
from lib.kernel_source import (
10+
check_kernel_version,
11+
create_temp_dir,
12+
download_kernel,
13+
extract_kernel,
14+
install_headers,
15+
)
16+
from lib.syscall import (
17+
generate_syscall_table,
18+
generate_rust_code,
19+
)
20+
21+
# Map arch used in linux kernel to arch understandable for Rust
22+
MAP_RUST_ARCH = {"arm64": "aarch64", "x86_64": "x86_64", "riscv": "riscv64"}
23+
24+
25+
def prepare_command(args):
26+
check_kernel_version(args.version)
27+
28+
# Create `temp_dir` under `/tmp`
29+
temp_dir = create_temp_dir(args.version)
30+
31+
# Download kernel tarball from https://cdn.kernel.org/
32+
tarball = download_kernel(args.version, temp_dir)
33+
34+
# Extract kernel source
35+
src_dir = extract_kernel(tarball, temp_dir)
36+
37+
# Get headers of specific architecture
38+
installed_header_path = install_headers(
39+
src_dir=src_dir,
40+
arch=args.arch,
41+
install_path=args.install_path,
42+
)
43+
44+
print(f"\nSuccessfully installed kernel headers to {installed_header_path}")
45+
return src_dir
46+
47+
48+
def generate_syscall_command(args):
49+
src_dir = prepare_command(args)
50+
51+
# Generate syscall table
52+
header_path = os.path.join(
53+
os.path.dirname(src_dir), f"{args.arch}_headers/include/asm/unistd_64.h"
54+
)
55+
syscalls = generate_syscall_table(header_path)
56+
57+
# Create output directory if needed
58+
args.output_path.mkdir(parents=True, exist_ok=True)
59+
60+
# Generate architecture-specific filename
61+
output_file_path = args.output_path / f"{MAP_RUST_ARCH[args.arch]}.rs"
62+
63+
# Generate Rust code
64+
generate_rust_code(syscalls, output_file_path)
65+
66+
67+
def main():
68+
parser = argparse.ArgumentParser(prog="rustvmm_gen")
69+
subparsers = parser.add_subparsers(dest="command", required=True)
70+
parser.add_argument("--arch", help="Target architecture (x86_64, arm64, riscv64)")
71+
parser.add_argument("--version", help="Kernel version (e.g. 6.12.8)")
72+
parser.add_argument(
73+
"--install_path",
74+
default=None,
75+
help="Header installation directory path",
76+
)
77+
parser.add_argument("--keep", help="Keep temporary build files")
78+
79+
# Prepare subcommand
80+
prepare_parser = subparsers.add_parser("prepare", help="Prepare kernel headers")
81+
prepare_parser.set_defaults(func=prepare_command)
82+
83+
# Generate syscall subcommand
84+
generate_syscall_parser = subparsers.add_parser(
85+
"generate_syscall",
86+
help="Generate syscall for `rust-vmm/seccompiler` from prepared kernel headers",
87+
)
88+
generate_syscall_parser.add_argument(
89+
"--output_path",
90+
type=Path,
91+
default=os.getcwd(),
92+
help="Output directory path (default: current)",
93+
)
94+
generate_syscall_parser.set_defaults(func=generate_syscall_command)
95+
96+
args = parser.parse_args()
97+
args.func(args)
98+
99+
100+
if __name__ == "__main__":
101+
main()

0 commit comments

Comments
 (0)