From ce40582e9de912b77a671a6519a5c1beba73623b Mon Sep 17 00:00:00 2001 From: opencode Date: Thu, 12 Nov 2026 05:35:30 +0000 Subject: [PATCH] fix(termtris): run the 2ine loader under qemu-i386 when the kernel lacks 16-bit LDT The r5.01 tools are 16-bit OS/2 NE programs. A Linux kernel built without CONFIG_X86_16BIT (this box's cloud kernel) rejects modify_ldt for 16-bit segments, so lx_loader aborts at its first segment even though it is a 32-bit binary. Probe for that failure and use qemu-i386, whose linux-user modify_ldt supports 16-bit segments. LX_RUNNER overrides the choice. The toolchain output is unchanged: the build completes in ~10 s and the COFF differs only in its header timestamp. --- apps/termtris/build.sh | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/apps/termtris/build.sh b/apps/termtris/build.sh index 6b0c33e..9d0d407 100755 --- a/apps/termtris/build.sh +++ b/apps/termtris/build.sh @@ -32,6 +32,26 @@ if [ ! -x "$WORK/gspac.exe" ]; then unzip -oq "$Z1" -d "$WORK" unzip -oq "$Z2" -d "$WORK" fi + +# The r5.01 tools are 16-bit OS/2 NE programs, which 2ine runs through 16-bit +# LDT segments. A Linux kernel built without CONFIG_X86_16BIT rejects those +# (modify_ldt returns EINVAL), so the loader aborts at its first segment even +# though it is a 32-bit binary. Detect that with a probe run and, when needed, +# drive the same loader through qemu-i386, whose linux-user emulation does +# implement the 16-bit LDT. Set LX_RUNNER to a command prefix (for example +# "qemu-i386") to force one; leave it unset to auto-detect. +if [ -z "${LX_RUNNER:-}" ]; then + if ( cd "$WORK" && "$LX" ./gspac.exe ) 2>&1 | + grep -q 'failed to allocate LDT selector'; then + if command -v qemu-i386 >/dev/null 2>&1; then + LX_RUNNER=qemu-i386 + else + echo "build.sh: this kernel has no 16-bit LDT support and qemu-i386 is not installed" >&2 + echo "build.sh: install qemu-user, or set LX_RUNNER to a working runner" >&2 + exit 1 + fi + fi +fi for so in "$NINE"/lib*.so; do [ -e "$so" ] && ln -sf "$so" "$WORK/" done @@ -78,7 +98,7 @@ run() { shift i=0 while [ "$i" -lt 5 ]; do - ( cd "$WORK" && "$LX" "$@" ) >/dev/null 2>&1 || true + ( cd "$WORK" && ${LX_RUNNER} "$LX" "$@" ) >/dev/null 2>&1 || true if [ -f "$WORK/$_out" ]; then return 0 fi