From 7da34dbffb92dc7d4bab998e3bd08f2aeae6dcc1 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sun, 23 Nov 2025 23:49:56 -0800 Subject: [PATCH] WIP linux multiarch support --- assets/build/linux/config.debug.yaml | 9 +++ assets/build/linux/config.release.yaml | 3 + assets/build/linux/global.yaml | 39 ++++++++++ assets/build/linux/rules.ninja | 91 ++++++++++++++++++++++ assets/build/linux/target.init.yaml | 39 ++++++++++ assets/build/linux/target.user.exe.yaml | 16 ++++ assets/build/linux/target.user.shared.yaml | 7 ++ assets/build/linux/target.user.yaml | 33 ++++++++ src/boot/boot.module | 1 + src/kernel/kernel.module | 1 + src/kernel/panic.serial/serial.module | 1 + src/libraries/j6/j6.module | 3 + src/libraries/j6/linux/syscalls.s.cog | 49 ++++++++++++ 13 files changed, 292 insertions(+) create mode 100644 assets/build/linux/config.debug.yaml create mode 100644 assets/build/linux/config.release.yaml create mode 100644 assets/build/linux/global.yaml create mode 100644 assets/build/linux/rules.ninja create mode 100644 assets/build/linux/target.init.yaml create mode 100644 assets/build/linux/target.user.exe.yaml create mode 100644 assets/build/linux/target.user.shared.yaml create mode 100644 assets/build/linux/target.user.yaml create mode 100644 src/libraries/j6/linux/syscalls.s.cog diff --git a/assets/build/linux/config.debug.yaml b/assets/build/linux/config.debug.yaml new file mode 100644 index 0000000..4434338 --- /dev/null +++ b/assets/build/linux/config.debug.yaml @@ -0,0 +1,9 @@ +--- +ccflags: [ + "-g3", + "-ggdb", +] + +ldflags: [ + "-g", +] \ No newline at end of file diff --git a/assets/build/linux/config.release.yaml b/assets/build/linux/config.release.yaml new file mode 100644 index 0000000..7574ae4 --- /dev/null +++ b/assets/build/linux/config.release.yaml @@ -0,0 +1,3 @@ +ccflags: [ + "-O3", +] \ No newline at end of file diff --git a/assets/build/linux/global.yaml b/assets/build/linux/global.yaml new file mode 100644 index 0000000..31eccdd --- /dev/null +++ b/assets/build/linux/global.yaml @@ -0,0 +1,39 @@ +--- +cc: "clang-16" +cxx: "clang++-16" +ld: "ld.lld-16" +ar: ar +nasm: nasm +objcopy: objcopy + +ccflags: [ + "-I${source_root}/src/include", + "-I${source_root}/sysroot/include/c++/v1", + "-fcolor-diagnostics", + "-U__STDCPP_THREADS__", + "-D__jsix_config=${build_config}", + "-D__jsix_config_${build_config}", + "-DVERSION_MAJOR=${version_major}", + "-DVERSION_MINOR=${version_minor}", + "-DVERSION_PATCH=${version_patch}", + "-DVERSION_GITSHA=0x${version_sha}", + '-DGIT_VERSION=\"${version_major}.${version_minor}.${version_patch}+${version_sha}\"', + '-DGIT_VERSION_WIDE=L\"${version_major}.${version_minor}.${version_patch}+${version_sha}\"', + + "-Wformat=2", "-Winit-self", "-Winline", "-Wmissing-format-attribute", + "-Wmissing-include-dirs", "-Wswitch", "-Wundef", "-Wdisabled-optimization", + "-Wpointer-arith", "-Wno-attributes", "-Wno-sign-compare", "-Wno-multichar", + "-Wno-div-by-zero", "-Wno-endif-labels", "-Wno-pragmas", "-Wno-format-extra-args", + "-Wno-unused-result", "-Wno-deprecated-declarations", "-Wno-unused-function", + "-Wno-address-of-packed-member", "-Wno-invalid-offsetof", "-Wno-format-nonliteral", + "-Werror" ] + +asflags: [ + "-DVERSION_MAJOR=${version_major}", + "-DVERSION_MINOR=${version_minor}", + "-DVERSION_PATCH=${version_patch}", + "-DVERSION_GITSHA=0x${version_sha}", + "-I${source_root}/src/include" ] + +cflags: [ "-std=c11" ] +cxxflags: [ "-std=c++17" ] diff --git a/assets/build/linux/rules.ninja b/assets/build/linux/rules.ninja new file mode 100644 index 0000000..0962d3d --- /dev/null +++ b/assets/build/linux/rules.ninja @@ -0,0 +1,91 @@ +rule compile.c + command = $cc -MMD -MF $out.d $cflags $ccflags -o $out -c $in + description = Compiling [$target]:$name + depfile = $out.d + deps = gcc + +rule dump_c_defs + command = echo | $cc $ccflags $cflags -dM -E - > $out + description = Dumping C defines for $target + +rule dump_c_run + command = echo '#!/bin/bash' > $out; echo '$cc $ccflags $cflags $$*' >> $ + $out; chmod a+x $out + description = Dumping C arguments for $target + +rule compile.cpp + command = $cxx -MMD -MF $out.d $cxxflags $ccflags -o $out -c $in + description = Compiling [$target]:$name + depfile = $out.d + deps = gcc + +rule dump_cpp_defs + command = echo | $cxx -x c++ $ccflags $cxxflags -dM -E - > $out + description = Dumping C++ defines for $target + +rule dump_cpp_run + command = echo '#!/bin/bash' > $out; echo '$cxx $ccflags $cxxflags $$*' $ + >> $out; chmod a+x $out + description = Dumping C++ arguments for $target + +rule compile.s + command = $nasm -o $out -felf64 -MD $out.d $asflags $in + description = Assembling [$target]:$name + depfile = $out.d + deps = gcc + +rule parse.cog + command = cog -o $out -d -D target=$target $cogflags $in + description = Parsing [$target]:$name + +rule exe + command = $ld $ldflags -o $out $in $libs + description = Linking exe [$target]:$name + +rule driver + command = $ld $ldflags -o $out $in $libs + description = Linking driver [$target]:$name + +rule lib + command = $ld -shared -soname $soname $ldflags -o $out $in $libs + description = Linking [$target]:$name + +rule lib_static + command = $ar qcs $out $in + description = Archiving [$target]:$name + +rule cp + command = cp $in $out + description = Copying [$target]:$name + +rule dump + command = objdump -DSC -M intel $in > $out + description = Dumping decompiled $name + +rule makest + description = Making symbol table + command = nm -n -S --demangle $in | ${source_root}/scripts/build_symbol_table.py $out + +rule makeinitrd + description = Creating $name + command = ${source_root}/scripts/mkj6romfs.py -c $format $in $out + +rule makefat + description = Creating $name + command = $ + cp $in $out; $ + mcopy -s -D o -i $out@@1M ${build_root}/fatroot/* ::/ + +rule strip + description = Stripping $name + command = $ + cp $in $out; $ + objcopy --only-keep-debug $out $debug; $ + strip --discard-all -g $out; $ + objcopy --add-gnu-debuglink=$debug $out + +rule touch + command = touch $out + +rule compdb + command = ninja -t compdb > $out diff --git a/assets/build/linux/target.init.yaml b/assets/build/linux/target.init.yaml new file mode 100644 index 0000000..474661d --- /dev/null +++ b/assets/build/linux/target.init.yaml @@ -0,0 +1,39 @@ +--- +ccflags: [ + "--target=x86_64-jsix-elf", + "-fno-omit-frame-pointer", + "-fno-stack-protector", + + "-fvisibility=hidden", + "-fvisibility-inlines-hidden", + + "-D__ELF__", + "-D__jsix__", + "-U__linux", + "-U__linux__", + + "-DMSPACES", + + "--sysroot='${source_root}/sysroot'" +] + + +cxxflags: [ + "-fno-exceptions", + "-fno-rtti", +] + +ldflags: [ + "-Bstatic", + "-m", "elf_x86_64", + "--sysroot='${source_root}/sysroot'", + "--no-eh-frame-hdr", + "-L", "${source_root}/sysroot/lib", + "-z", "separate-code", + "-lc++", "-lc++abi", "-lunwind", + "--no-dependent-libraries", +] + +libs: [ + "${target_dir}/crt0.o", +] \ No newline at end of file diff --git a/assets/build/linux/target.user.exe.yaml b/assets/build/linux/target.user.exe.yaml new file mode 100644 index 0000000..7831b81 --- /dev/null +++ b/assets/build/linux/target.user.exe.yaml @@ -0,0 +1,16 @@ +--- + +ccflags: [ + "-fpie" +] + +ldflags: [ + "-pie", + "-rpath", "${target_dir}", + "--dynamic-linker", "/lib64/ld-linux-x86-64.so.2", + "--push-state", "--as-needed", "-Bstatic", "-lc++", "-lc++abi", "-lunwind", "--pop-state", +] + +libs: [ + "${target_dir}/crt0.o", +] diff --git a/assets/build/linux/target.user.shared.yaml b/assets/build/linux/target.user.shared.yaml new file mode 100644 index 0000000..666830b --- /dev/null +++ b/assets/build/linux/target.user.shared.yaml @@ -0,0 +1,7 @@ +--- +ccflags: [ +] + +ldflags: [ + "-shared", +] diff --git a/assets/build/linux/target.user.yaml b/assets/build/linux/target.user.yaml new file mode 100644 index 0000000..99dfb00 --- /dev/null +++ b/assets/build/linux/target.user.yaml @@ -0,0 +1,33 @@ +--- +asflags: [] + +ccflags: [ + "--target=x86_64-jsix-elf", + "-fno-omit-frame-pointer", + "-fno-stack-protector", + + "-fvisibility=hidden", + "-fvisibility-inlines-hidden", + + "-D__ELF__", + "-D__jsix__", + "-U__linux", + "-U__linux__", + + "--sysroot='${source_root}/sysroot'", + "-fpic", +] + +cxxflags: [ + "-fno-exceptions", + "-fno-rtti", + ] + +ldflags: [ + "-m", "elf_x86_64", + "--sysroot='${source_root}/sysroot'", + "--no-eh-frame-hdr", + "-L", "${source_root}/sysroot/lib", + "-z", "separate-code", + "--no-dependent-libraries", +] diff --git a/src/boot/boot.module b/src/boot/boot.module index e4fb459..75d5435 100644 --- a/src/boot/boot.module +++ b/src/boot/boot.module @@ -6,6 +6,7 @@ boot = module("boot", target = "boot", deps = [ "cpu", "elf", "util", "bootproto" ], static = True, + skip_arches = [ "linux" ], sources = [ "allocator.cpp", "bootconfig.cpp", diff --git a/src/kernel/kernel.module b/src/kernel/kernel.module index 051a627..d609866 100644 --- a/src/kernel/kernel.module +++ b/src/kernel/kernel.module @@ -8,6 +8,7 @@ kernel = module("kernel", deps = [ "util", "cpu", "bootproto", "j6", "acpi" ], static = True, ld_script = "kernel.ld", + skip_arches = [ "linux" ], sources = [ "apic.cpp", "kassert.cpp", diff --git a/src/kernel/panic.serial/serial.module b/src/kernel/panic.serial/serial.module index 1f5cc5f..7a97d33 100644 --- a/src/kernel/panic.serial/serial.module +++ b/src/kernel/panic.serial/serial.module @@ -7,6 +7,7 @@ panic = module("panic.serial", includes = [ ".." ], description = "Serial panic handler", ld_script = "panic.serial.ld", + skip_arches = [ "linux" ], sources = [ "display.cpp", "entry.s", diff --git a/src/libraries/j6/j6.module b/src/libraries/j6/j6.module index 714c952..6f43e41 100644 --- a/src/libraries/j6/j6.module +++ b/src/libraries/j6/j6.module @@ -21,6 +21,9 @@ j6 = module("j6", "amd64": [ "syscalls.s.cog", ], + "linux": [ + "linux/syscalls.s.cog", + ], }, public_headers = [ "j6/cap_flags.h.cog", diff --git a/src/libraries/j6/linux/syscalls.s.cog b/src/libraries/j6/linux/syscalls.s.cog new file mode 100644 index 0000000..28e6df2 --- /dev/null +++ b/src/libraries/j6/linux/syscalls.s.cog @@ -0,0 +1,49 @@ +; vim: ft=asm + +%macro define_syscall 2 + global j6_%1: function (j6_%1.end - j6_%1) + j6_%1: + push rbp + mov rbp, rsp + + ; if the syscall has more than 6 arguments, the rest + ; will be pushed on the stack. in that case, we'd need + ; to pass this stack pointer to the kernel, so stash + ; off rbx (callee-saved) and pass the pointer to the + ; arguments there. + push rbx + mov rbx, rbp + add rbx, 16 ; account for stack frame + + ; args should already be in rdi, etc, but rcx will + ; get stomped, so stash it in r10, which isn't a + ; callee-saved register, but also isn't used in the + ; function call ABI. + mov r10, rcx + + mov rax, %2 + syscall + ; result is now already in rax, so just return + + pop rbx + pop rbp + ret + .end: +%endmacro + +; [[[cog code generation +; from definitions.context import Context +; +; ctx = Context(definitions_path) +; ctx.parse("syscalls.def") +; syscalls = ctx.interfaces['syscalls'] +; +; if target != "kernel": +; for id, scope, method in syscalls.methods: +; if scope: +; name = f"{scope.name}_{method.name}" +; else: +; name = method.name +; cog.outl(f"define_syscall {name:20}, {id}") +; ]]] +; [[[end]]]