X on the console: /dev/tty0, a palette, and startx that works
Xorg finds its VT through /dev/tty0, and without one ran on none: the console went on drawing into the framebuffer over the X screen. tty0 is the terminal on screen, as on Linux. FBIOPUTCMAP succeeds, as it does on a true-colour Linux framebuffer, instead of 256 logged errors per start. schos-base gives root a .xserverrc with -dumbSched, Xorg's switch for input on the main loop: SchOS has no threads, and Xorg crashed in pthread_join on its input thread when the first client left. It adds the hostname to /etc/hosts, so xauth can resolve schos:0. zsh loses PROMPT_SP: on a serial terminal narrower than the console its padding wrapped and left a # above every prompt. bootcheck knows zsh's prompt and matches without colour codes, so busybox's ls reads as text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
parent
a4ed556543
commit
906318f2b6
6 changed files with 51 additions and 4 deletions
|
|
@ -22,6 +22,12 @@ setopt EXTENDED_GLOB
|
|||
setopt INTERACTIVE_COMMENTS # a # in an interactive line is a comment
|
||||
setopt NO_BEEP # SchOS has no audio, but it would also scroll
|
||||
unsetopt FLOW_CONTROL # ^S/^Q are worth more as keys than as flow control
|
||||
# No PROMPT_SP. It marks output that did not end in a newline by printing a
|
||||
# `#` and then padding to $COLUMNS, trusting the terminal to wrap so the next
|
||||
# CR can erase it. The console is mirrored to the serial port, and a host
|
||||
# terminal narrower than the SchOS screen wraps the padding early: every
|
||||
# prompt came with a `#` line above it.
|
||||
unsetopt PROMPT_SP
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Keys
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#define FBIOGET_VSCREENINFO 0x4600
|
||||
#define FBIOPUT_VSCREENINFO 0x4601
|
||||
#define FBIOGET_FSCREENINFO 0x4602
|
||||
#define FBIOPUTCMAP 0x4605
|
||||
#define FBIOBLANK 0x4611
|
||||
#define FBIOPAN_DISPLAY 0x4606
|
||||
|
||||
|
|
|
|||
|
|
@ -230,6 +230,13 @@ fb_ioctl(int request, addr_t arg)
|
|||
// blanking does too, as Linux's own drivers without the hook do.
|
||||
case FBIOBLANK:
|
||||
return 0;
|
||||
|
||||
// A palette, on a framebuffer that is always true-colour. Linux's drivers
|
||||
// keep the values for the console's sixteen colours and succeed; refusing
|
||||
// made Xorg's fbdev driver log an error for every entry it loads, 256 of
|
||||
// them at each start.
|
||||
case FBIOPUTCMAP:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENOTTY;
|
||||
|
|
|
|||
|
|
@ -83,6 +83,11 @@ static const struct devnode devnodes[] = {
|
|||
was one terminal. Minor 10 resolves through proc->ctty; see
|
||||
vt_for_minor() in kernel/core/console.c. */
|
||||
{ "tty", 1, 10, D_ROOT },
|
||||
/* The terminal on screen, as on Linux. Xorg opens it to find a free VT and
|
||||
switch to it, and without one ran on no VT at all: the console went on
|
||||
drawing into the framebuffer over the X screen. Any minor that is not a
|
||||
numbered terminal or the controlling one resolves to vt_current(). */
|
||||
{ "tty0", 1, 0, D_ROOT },
|
||||
{ "tty1", 1, 11, D_ROOT },
|
||||
{ "tty2", 1, 12, D_ROOT },
|
||||
{ "tty3", 1, 13, D_ROOT },
|
||||
|
|
|
|||
|
|
@ -97,6 +97,18 @@ mkdir -p "$P/etc/profile.d"
|
|||
grep -v '^export \(PATH\|HOME\|TERM\)=' "$P/etc/profile" > "$P/etc/profile.d/schos.sh"
|
||||
rm -f "$P/etc/profile"
|
||||
|
||||
# How startx starts the X server for root: Alpine's xserverrc, plus
|
||||
# -dumbSched. Xorg reads input on a thread of its own, SchOS has no threads
|
||||
# yet, and the server crashed on its way out the first time a client
|
||||
# disconnected, in pthread_join on a thread that was never made. -dumbSched is
|
||||
# Xorg's own switch for input on the main loop. The file is root's own rather
|
||||
# than /etc/X11/xinit/xserverrc, which belongs to the xinit package.
|
||||
mkdir -p "$P/root"
|
||||
cat > "$P/root/.xserverrc" <<'XEOF'
|
||||
#!/bin/sh
|
||||
exec /usr/bin/X -nolisten tcp -dumbSched "$@"
|
||||
XEOF
|
||||
|
||||
# Mount points and runtime directories are alpine-baselayout's; an empty
|
||||
# directory here only duplicates it.
|
||||
for d in dev proc sys run tmp srv; do
|
||||
|
|
@ -110,6 +122,9 @@ sed -i 's|^\(root:[^:]*:0:0:[^:]*:[^:]*:\)/bin/sh$|\1/bin/zsh|' /etc/passwd
|
|||
for s in /bin/zsh /bin/mksh; do
|
||||
grep -qx "$s" /etc/shells 2>/dev/null || echo "$s" >> /etc/shells
|
||||
done
|
||||
# The machine's own name, which Alpine's hosts leaves out. Without it xauth
|
||||
# cannot resolve "schos:0", and startx says "bad display name" four times.
|
||||
grep -qw schos /etc/hosts || printf '127.0.1.1\tschos\n' >> /etc/hosts
|
||||
exit 0
|
||||
EOF
|
||||
cp "$PKG/post-install" "$PKG/post-upgrade"
|
||||
|
|
@ -157,7 +172,8 @@ ROOT_PI=$ROOT sh -c '
|
|||
sed -i "s|^\(root:[^:]*:0:0:[^:]*:[^:]*:\)/bin/sh$|\1/bin/zsh|" "$ROOT_PI/etc/passwd"
|
||||
for s in /bin/zsh /bin/mksh; do
|
||||
grep -qx "$s" "$ROOT_PI/etc/shells" 2>/dev/null || echo "$s" >> "$ROOT_PI/etc/shells"
|
||||
done'
|
||||
done
|
||||
grep -qw schos "$ROOT_PI/etc/hosts" || printf "127.0.1.1\tschos\n" >> "$ROOT_PI/etc/hosts"'
|
||||
|
||||
# The repository goes in too, so the installed system can reinstall and
|
||||
# upgrade schos-base, and Alpine's are listed for everything else.
|
||||
|
|
|
|||
|
|
@ -495,8 +495,11 @@ try {
|
|||
Start-Sleep -Milliseconds 150
|
||||
$t = Read-Log
|
||||
if ($null -eq $t -or $t.Length -le $Since) { continue }
|
||||
# A prompt at the very end, with nothing typed after it.
|
||||
if ($t.Substring($Since) -match '(?s)#[ ]?$') { return $true }
|
||||
# A prompt at the very end, with nothing typed after it: mksh's `#`,
|
||||
# or zsh's `»`, which root's shell has been since the root became
|
||||
# Alpine's. zsh follows it with erase-to-end-of-line and turns
|
||||
# bracketed paste on, so both escapes may trail the prompt.
|
||||
if ($t.Substring($Since) -match '(?s)(#|\u00bb)(\e\[[0-9;]*m)*[ ]?(\e\[K)?(\e\[\?2004h)?$') { return $true }
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
|
@ -629,6 +632,12 @@ if ($null -eq $text) { $text = '' }
|
|||
Write-Host "==> serial transcript ($($text.Length) bytes) -> $log" -ForegroundColor Cyan
|
||||
Write-Host $text
|
||||
|
||||
# Matched without terminal escapes. busybox's ls, which is the Alpine root's,
|
||||
# colours what it lists -- `copy.txt` arrives as ESC[1;32mcopy.txt -- and zsh
|
||||
# wraps every prompt in them, so a pattern anchored at a line start found
|
||||
# nothing in output that was perfectly right. Shown raw above, matched clean.
|
||||
$text = $text -replace '\e\[[0-9;?]*[A-Za-z]', '' -replace '\e[()][0-9A-Za-z]', '' -replace '[\x0e\x0f]', ''
|
||||
|
||||
$script:fail = $false
|
||||
function Expect($pattern, $what) {
|
||||
if ($script:text -match $pattern) {
|
||||
|
|
@ -697,7 +706,10 @@ Expect 'schfs: mounted' 'the kernel mounted SchFS as the root filesystem'
|
|||
Expect 'init: ready' 'init came up on a SchFS root'
|
||||
Expect 'label:\s*schos' '/proc/schfs reports the volume label'
|
||||
Expect 'root_objectid:\s*16' '/proc/schfs reports the root object id'
|
||||
Expect 'dir\s+bin' 'the root directory really contains bin/'
|
||||
# /proc/schfs lists the first 16 entries, in the tree's order, and on the
|
||||
# Alpine root bin/ is the seventeenth: any of the top-level directories proves
|
||||
# the same thing.
|
||||
Expect '(?m)^\s*dir\s+(bin|etc|usr)\s' 'the root directory really contains bin/, etc/ or usr/'
|
||||
# / is the mounted volume, so mounting that same device again must be
|
||||
# refused. Without this a kernel that had quietly fallen back to some other
|
||||
# root would still pass everything else here.
|
||||
|
|
|
|||
Loading…
Reference in a new issue