Notable changes in this release:


Multiple installation media are provided for PC, Raspberry Pi, and MNT Reform. For PC, burn an .iso file to CD, or dd it directly to USB media. For Raspberry Pi or MNT Reform, dd an .img file directly to sdcard.

The pi.img file can be used for Raspberry Pi 1, 2, and 3. The pi3.img file can be used for Raspberry Pi 3 and 4.






   ; sha1sum -2 256 9front-9931*gz
   b06118027bc8e692c640dfe801d427882f4a219685be1b0113aee3ebecc6b9c4      9front-9931.386.iso.gz
   f69abdadc82da7f9b6fd3f3e88b806f1050baa9235912165475ae9f0bb677828      9front-9931.amd64.iso.gz
   8e5fb4615e169f2d189f5ba284e672072513ed6c7fa37f4bca23e3fa5c172ea6      9front-9931.amd64.qcow2.gz
   020187247a9a59ddf68c5468b5fbff6b78fdf133f47d7c87c7b875ecd72cd97f      9front-9931.pi.img.gz
   52cb6b0c453432802da14f9e4ea45d894b956d64eab4486b00516d6e351e22d9      9front-9948.pi3.img.gz
   a11243fe5dd217e9ecbd6c98768dd0b860a44693c14d4946ae2ddf56fabbc969      9front-9948.reform.img.gz









dash 1 manual: http://9front.org/propaganda/books


by qwx


by sigrid


by sl







9boot: delay GetMemoryMap until right before ExitBootServices (thanks michael forney!)

9boot: implement nocga= and nokbd= kernel boot parameters

aux/acpi: -H is for HALT

aux/acpi: attempt to call PTS and TTS before shutdown

aux/acpi: correct fadt version check for new shutdown.

aux/acpi: ignore bad acpi 2.0 shutdown access widths.

aux/acpi: no need for amlval(), amleval() will dereference the name and run the method

aux/acpi: no need to require the embedded controller.

aux/acpi: use ACPI 2.0 64-bit pointers for power off

aux/kbdfs: accept names for layers in writes to kbmap

aux/kbdfs: error on invalid numerics in kbmap writes

aux/kbdfs: reset kbmap to ascii default when opened with OTRUNC

aux/kbdfs: use layer names in kbmap reads and document them

aux/mouse: use /dev/eia instead of #t/eia, should be bound by termrc

aux/vga: DP 1.2 on igfx; EDID wrapping; VGA display connections

bcm64: apply same mmu improvements from imx8

bcm64: move fpon()/fpoff() into l.s

bcm64: move pi3 VGPIO to 2MB aligned address, this makes 4K pages work

boot/bitsy: clean up checked in binary

boot/reform: bootm if loading the kernel worked

bootrc: bind devcap and devtls, make /root mount consistent with spec

bootrc: let /boot/boot run in a more natural namespace

devbridge: simplify ethermultiwrite()

devdraw: coding style (from drawterm)

devgpio: (Raspberry Pi3/4, revision 2, bcm scheme) (thans Matt!)

devip: Fix transfoward() iphash collision

devip: actually put igmp in ip section

devip: add igmp protocol support to all kernels

devip: address some ipv6 issues on pkt interface

devip: don’t leak temporary buffers on error

devip: dynamically allocate memory for /net/ndb, increase maximum to 32K

devip: fix icmp bugs

devip: generate more reasonable laddr for UDP “headers” connection writes

devip: ignore addmulti() errors in addselfcache()

devip: lilu dallas multicast.

devip: maintain packet counters for pktmedium

devip: provide large buffer for ipifc->local() generator

devip: remove subnet check for arpforme()

devip: rlock ifc before accessing interface parameters in ipifcstate()

devip: tcpmssclamp() to minimum of source and destination interface MTU

devip: generalize Rproxy route handling, allowing non point-to-point arp proxy

devip: icmp6: no need set vcf and ttl before ipoput6(), use MAXTTL instead of HOP_LIMIT

devip: icmp: only forward EchoRequest, Timestamp(request), InfoRequest and AddrMaskRequest

devip: the retunnel logic in the gre code is wrong.

devip: tcp: only create new translation when SYN packet

devproc: Fix a double-free reading note file (thanks Josiah Frentsos)

devsd: Fix memory leaks, wstst check, cleanup

devsd: fix wrong range check for subunit number

devsrv: Various fixes.

devsrv: fix recusrion deadlock on remove

devusb: provide usb hub device number instead of address in /dev/usb/ctl

etherbcm: support for newer BCM5717 series cards.

etherbcm: support the 57765 series

etheriwl: add pci id for AC 7265 card (thanks Chris Gorman)

ethervgbe: do not give userspace the frame check sequence

ethervgbe: reduce console spam (thanks Arne Meyer)

etherwpi: accept pci device id 4222 (thanks oliver simmons)

imx8: a simple softscreen

imx8: add vpu clocks and irq indices, correct a typo (no functional change)

imx8: cleanup framebuffer code

imx8: dont reuse the TTRB1 page tables for TTRB0 identity map, remove gpioinit()

imx8: make etheriwl work on MNT Reform, move it to port/ (thanks cinap); tested with 6205

imx8: move fpon()/fpoff() into l.s

imx8: provide PCIWINDOW constant, use PCIWADDR() for MSI_TARGET_ADDR

imx8: setup $terminal environment variable in init0()

imx8: usdhc: fix debug print, R1b response handled by controller

imx8: move SAI iomux/clock initialization into probe()

imx8: put default “console=0” in #ec

kernel: Clear secrets on reboot

kernel: Do not treat IPv6 ULA’s as GUA’s (thanks Arne Meyer)

kernel: fix devsrv compilation on arm32

kernel: free exec temporary stack segment under seglock

kernel: handle 64-bit multiboot framebuffer address

kernel: private srv boards

kernel: sdram: do not use xalloc for SDev

mt7688: add kernel

mouse: Make /dev/mousein readable to get mouse status without blocking

nusb/audio: add support for USB audio 2.0

nusb/audio: enumerate streams through control interface

nusb/audio: only consider data endpoints when setting up

nusb/audio: remove code for bi-directional endpoint

nusb/cam: interrupt reader proc on close to unstuck it

nusb/cam: rather than showing partially green frames (when not enough bandwidth), skip those altogether

nusb/cam: remove wrong func prototypes, print probe control

nusb/cam: rewrite yuy2convert with integer arithmetic

nusb/cam: take max payload transfer size into account when selecting for bandwidth

nusb/ether: set configuration, and use the first interface that matches

nusb/ether: support for asix ax88179 (thanks Aidan K. Wiggins)

nusb/kb: GAOMON S620 tablet support

nusb/lib: add setconf() to set the configuration

nusb/lib: move audio-specific requests to nusb/audio

nusb/usbd: use dprint() report to standard-error instad of standard-out

nusb/usbd: Fix wrong hname collision handling

nusb/usbd: add /dev/usbhubctl file to control port power and led indicators

nusb/usbd: assign hname to hubs

nusb/usbd: only fetch first 8 bytes of device descriptor for getmaxpkt() (thanks k0ga)

nusb/usbd: provide vid and did in device info string for hubs

nusbrc: remove service files left by nusb/kb (thanks kristo)

reform/pm: considering the keyboard might be absent altogether, fall back to lpc shutdown in any case

reform/pm: several improvements and fixes

sdiahci, sdodin, sdide, devsd: get it right…

sdiahci, sdodin: more unconfigure panic fixes

sdide: fix double free in clear() (devsd frees sdev already)

sdmmc: actually implement mmc support

sdmmc: implement boot partition access for emmc

sdmmc: multiple controller support

sdmmc: new interface for SDio

sdmmc: switch argument must be integer

sdnvme, fshalt: turn disks off on fshalt

sdnvme: add smart file for full smart info

sdnvme: collect useful smart/health info and report via ctl

sdnvme: remove unused mptr argument to qcmd()

sdnvme: use delay() instead of tsleep() in nvmedisable()

scram, aux/acpi: open /proc/$pid/ctl instead of #p/$pid/ctl for wirecpu0()

scram: → /rc/bin/scram

usbxhci: add some robustness checks

usbxhci: fix command ring wrap crash

usbxhci: split usbxhci in portable and pci / soc specific drivers

usbxhci: wait for reset to complete before continuing initialization

zynq: fix plcopy() source pointer increment

zynq: remove bogus main.bin file


/sys/src/games/^(aout2gba gba/rom): basic gba toolkit

5c, 7c: fix !x compilation when x is a negative float

5c, kc, qc: fix implicit return type of samaddr

5e: access /proc instead of #p

6c: copy all of packed structs in OAS

6c: eliminate the rathole

7c, 7l: fix linker clobbering offset if given the same register twice

7c: clean up the garbage in -S output, fix printing instructions using FCONST

7c: copy the remainder of packed structs

7c: elide type converting moves, registerize loads after store from local variables

7c: eliminate MOVWU r, r instructions when possible

7c: help and improve peephole optimizer

7c: implement bit rotations using ROR/EXT instruction

7c: more registers, improve constant propagation, implement load pipelining

7c: node offsets aren’t necessarily 0 - fixup packed structs

7c: peephole: ACASE needs two distinctive registers - nothing to optimize

7l, 7c: Remove STLP(W), finish LDAXR(W)/STLXR(W).

7l: allow byte/halfword register offset load/store

7l: allow paired SIMD load/store, correct a few comments

7l: register offset loads/stores

7l: rewrite Rl→REGTMP in the comment (thanks cinap)

7l: throw an error if CASE uses the same register for base and offset (CASE R1, R1)

7l: use floating point immediates where possible

Update: 7c: dont replace SXTW instruction following MOVW $const, r

c99: update dead web link

cc: NORET -> _Noreturn

cc: add NORET

cc: add func support

cc: do not wait for cpp to finish if there were errors

cc: fix suicide with undefined function arguments

cc: fix vlong->VOID cast (thanks cosa)

cc: fndecls: always ignore non-function types

cc: fndecls: use current fn node directly

cc: wait for cpp to report whether it was a success

cpp: #pragma once support

cpp: allow qid version change for #pragma once

cpp: correct #pragma once uniqueness check

cpp: stringified macros shouldn’t split words separate by a dot

libmach/acid: add basic FP support for arm64

libmach: add more floating point instructions decoding for arm64

libmach: fix reading .7 objects containing instructions with an extra register (from3)

libmach: fixup for fmovT Fd,u(SP)

libmach: remove obsolete fishy case in mips header parsing


ape: endian fixes for spim

ape: add stdnoreturn.h

lib9p: e*9p error tidy

lib9p: fix missing newlines in fprint()

libaml: implement ConcatRes and Mid opcodes.

libaml: replace ResEnd with it’s value.

libaml: tow eisaid inside the environment

libauth: Fix a memory leak in auth_getkey (thanks josiah fentsos)

libauth: aand also fix the leak it in the deactivated code

libauthsrv: deal with signed char in readcons()

libauthsrv: import better passtodeskey() function (from drawterm)

libauthsrv: readnvram: prompt for use of p9sk1 in nvram, with a default of no

libbio: abort on invalid state

libc: Add poolreset() function

libc: address kencc warning in date.c

libc: coding style (from drawterm)

libc: fix 32-bit arch vlong->double conversion (thans cosa)

libc: fix strchr() for little endian mips (thanks adventuresin9)

libc: remove dangling runetype.c

libc: runecomp: commit generated data files

libc: runecomp: move generated files to explicit regen rule

libc: sqrt() in assembly for arm64

libc: strtoull(): fix return value on overflow

libc: use /fd instead of #d in iounit()

libc: _tas() for spim

libgeometry: revamp

libgeometry: fix rframe xforms

libip: Provide iplocalonifc() and ipremoteonifc() functions

libip: avoid parentesis warnings from gcc (from drawterm)

libip: open temporary file-descriptors with OCEXEC flag

libjson: correctly escape strings in JSONfmt()

libmemdraw: coding style (from drawterm)

libmemdraw: don’t return Buffer copy from calc functions

libmp: parentesis (from drawterm)

libndb: add ndbvalfmt() formatter

libndb: make ndbipinfo() put each ip and attributes entry on its own line

libsec: add minimal support for the tls renegotiation

libsec: add parentesis to squelch gcc warning in drawterm

libsec: fix inconsistent prototypes for des (from drawterm)

libsec: use /net/tls instead of #a/tls

libtags: work around encoders producing Ogg containers with first granule position set to non-zero outside of the first page


audio/flacdec: throw out decoded audio until finished seeking

audio/mixfs: add “volume” file with “mix” control to set the output volume of the mixed inputs

audio/mixfs: fix locking for /dev/audio loopback

audio/mixfs: fix loopback

audio/mixfs: implement flush

audio/mixfs: no loopback delay

audio/scream: multicast audio protocol

audio/screamsend: actually have aux/dial exec screamenc (thanks sigrid!)

audio/screamsend: use dial(1)

audio/vocdec: Creative Voice File decoder

audio/vocdec: handle non type 1 blocks better

audio/zuke: do not clip the rightmost column

audio/zuke: fix -s not drawing properly and track being off by one; more OCLOSE

auth/*: use /fd/0 instead of #d/0

auth/*: use caphash and capuse under /dev instead of #¤

auth/*: fix up to report write errors

auth/acmed: better challenge error reporting.

auth/acmed: support getting a wildcard certificate.

auth/factotum: access /proc instead of #p for private()

auth/factotum: make sure we got a private key in ssh client protocol

auth/ssh2rsa: convert Unix ssh private keys to Plan 9 format.

aux/consolefs: post to /srv instead of #s

aux/depend: post to /srv instead of #s

aux/listen1: write status to standard error

aux/listen: add -o and -O options

aux/listen: log the real error when announce() fails

aux/listen: tweak per service namespaces

aux/timesync: don’t bind #r twice (already done in inittime())

awk: dont leak memory on extra format arguments

awk: getline: do not access unitialized data on EOF

bar: fix automatic resize and click location; ignore separator area when clicking

bar: increase the buffer to fit more aux data (noam decided to display the currently playing track there)

bar: static buffer for splitting, since it is getting used for clicks later on

bzfs: post to /srv instead of #s

cifs: remove redundant memsets after emalloc9p (thanks Arne Meyer)

cifs: use procsetname() instead of rolling your own

cwfs: add missing \n in error print

cwfs: post to /srv instead of #s

cwfs: remove noauth and nonone commans from fileserver console

cwfs: write /env/timezone instead of #e/timezone

dial: add dial command similar to plan9port

diff, merge3: refactor diff, implement merge3

diff: add missing file

diff: barf with explanation on binary diffs/merges

diff: fix suicide if binary files don’t diff

disk/partfs: fix bogus “%r” error response

disk/qcowfs: correct GET2 off by one

dossrv: Implement support for != 512 sector and track sizes

dossrv: better error handling and sanity checking in dosfs()

dossrv: post to /srv instead of #s, leave stderror alone

evdump: a program to dump input and window events

evdump: have evdump deal with new /dev/kbmap format

ext2srv: leave stderr alone

file: identify Creative Voice File

file: identify qcow images

fstype: add support for gefs

ftpfs: clarify usage and manpage

games/dmid: add control 00h, bank select

games/dmid: fix running status for streams

games/dmid: fix tempo changes causing desyncs in multitrack files

games/dmid: no longer threaded

games/dmid: properly skip delay field from stream

games/dmid: simplify and reuse input code for streaming

games/dmid: update for opl3 streaming

games/doom: experience it right from the start

games/gb: crude serial port emulation

games/gb: implement internal window line counter

games/midi: fix desyncs after tempo changes in multitrack files

games/opl3: implement real time streaming mode

games/wadfs: parse hexen map behavior lump

git/send: correctly delete branches with no local mirror

git: add support for another signed message format

git: fix nil dereference in corrupt repositories

git: prevent infinite recursion with cyclic symlinks (thanks cosa)

gs: patch CVE-2023-28879

history: fix walking and handling files with spaces

hjfs: check and fix print format errors

imap4d: add entry to detect file locked errors on hjfs

ip/dhcp6d: set source address to the receiving interface ip when multicast

ip/dhcpclient: ignore icmp advice messages

ip/httpd: fix duplicate array entry (thanks khayyam@cock.li)

ip/ipconfig: add -y flag to ipconfig to set proxy-arp for an interface

ip/ipconfig: avoid refreshing /net/dns for non-primary interface

ip/ipconfig: initial dhcpv6 support, clean default-routes and /net/ndb on remove

ip/ipconfig: leave ipnet= entries alone when updating /net/ndb, use ndbvalfmt()

ip/ipconfig: ignore “ANDROID_METERED” junk options

ip/ipconfig: remove non-existant ip addresses from /net/ndb, check link-local adress in ra6 daemon

ip/ppp, ip/pppoe: handle ipv6 address auto-configuration, call ip/ipconfig

ip/ppp: Implement echo request timeout, terminate

ip/ppp: allow specifying pair of local and remote address

ip/ppp: bring back arp proxy, but with explicit -y flag

ip/ppp: ipv6 support, cleanup routes, remove source filter, and more

ip/ppp: just use mtu requested from the peer.

ip/ppp: update the test-program

ip/pppoe: Handle termination request, add retry-forever (-r) option

ip/pppoe: aaand the code ;)

ip/pptpd: use /fd instead of #d

ip/tftpd: make syslog messages consistent

ircrc: fix race with pipe causing hangup

kbmap, kbremap: open kbmap file with OTRUNC and bugfixes

kbmap: fix multi column display for smaller windows (thanks mkf)

kbremap: switch keyboard maps with a keyboard shortcut

ktrans: correct ‘exit’ text (thanks Keegan)

ktrans: simplify kbdtap read loop

ktrans: tests and various bug fixes

lnfs: post to /srv instead of #s

lock: Fix some memory leaks (thanks steve simon!)

look: add -b for specifying numeric base

mothra: support article and figure tags

ndb/cs: Use ndbvalfmt() for quoting !ipinfo replies

ndb/cs: avoid trailing spaces when printing ndb line

ndb/cs: preserve ndbipinfo() line structure for !ipinfo, fix memory leak

ndb/dns, ndb/cs: post to /srv instead of #s

ndb/dns: allow specifying local ip addresses for serving dns

ndb/dns: don’t try to resolve local dns servers

ndb/dns: procgetname(): use /proc instead of #p

ndb/query, ndb/ipquery: use ndbvalfmt()

ndb/query: add -i and -c flags unifying the functionality of ndb/ipqeury

ndb/query: avoid trailing spaces when printing ndb line structure

netaudit: check none attach too

netaudit: fix format, always state the fileserver tested

netaudit: fix it for multiple results

netaudit: perform a clean connection to test auth status

netaudit: uncomment out warning about /srv/boot

netaudit: use new ndb/query flags instead of ndb/ipquery

paqfs: post to /srv, not #s

patch: preserve permissions of original file when patching

pic: error instead of crashing on nonexistent variables

play: aac support

play: use doom1.wad and dmid/opl3 for midi files by default

plumb fileaddr: match with a trailing colon

print, strtod: fix -0 and -NaN, respect verb flags when formatting

rc: make flag f [+-] clear status on success

rc: read standard-input from /fd/0 instead of ‘#d/0’

rc: use /fd/0 for standard-input instead of ‘#d/0’ in non-interactive mode

read: add -r to read runes instead of bytes (thanks umbraticus)

reform/shortcuts: use “mixfs” for volume control, fall back to “master”

rio: fix crash when walking windowless fid (thanks ilikebreadtoomuch)

rio: refactor the keyboardtap code a bit

rio: sync keyboard state with active window on switch

riow: add mod4+shift+q (delete current window)

riow: fix kbdtap reading logic and make it a bit easier to comprehend

riow: process the entire keyboard event at once

skelfs: remove useless code (thanks Arne Meyer)

sleep: implement long sleep

snoopy: fix error handling for convM2DNS()

snoopy: fix ipv6 option header parsing, add MLD messages to icmp6

sshnet: mount BEFORE /net (preserving /net/tls and /net/dns)

sysinfo: use usbtree instead of just cating #u/usb/ctl

sysupdate: only pull on ‘front’ branch

tcs: add nfc and nfd output formats

tee: remove unused variable (thanks mkf9)

termrc: start reform/pm and reform/audio drivers

test(1): add a missing space after -T

tlsclient: keep stderr

tlsclient: try /bin/$cmd for exec

trampoline: Add -o option to send protocol-specific ctl string

troff2html: handle more html attributes (thanks k0ga)

truetypefs: fall back instead of crashing when could not get a glyph

upas/Mail: don’t start plumb procs in their own note groups

upas/Mail: stop splitting headers

upas/fs, imap4d: make setname() use /proc instead of #p

upas/marshal: rfc2047-encode name of the sender (fixes non-ascii names in From: header)

usbtree: a little helper to pretty print usb hubs and devices in a tree

v8e: clean unused argument and tidy usage (thanks mkf)

venti/srv: open /proc instead of #p

vmx: read /dev/kbmap in new format

vnc: fix farsi key symbols

vncs: use procsetname() instead of rolling your own

vt: add OSC 7 support for plumbing of remote files without mount/bind magic

vt: ignore xterm Set/reset key modifier options escape sequence

zuke: apply clipping after replay gain (some cases found in track mode)

zuke: leave the fds alone (thanks deuteron)

zuke: prefer “mix” volume control if available


/sys/doc: “Namespaces as Security Domains”

/sys/doc: Remove some automatically generated PostScript files

/sys/doc/nssec.ms: small grammar fixes (ok’d by moody)

2c(1), 2l(1), tl: add thumb to the list. fix thechar: ‘5’ → ’t' trampoline(8): fix typo

a.out(6): document dynamically loadable modules

ascii(1), utf(6): /lib/unicode → /lib/ucd/UnicodeData.txt

authsrv(2): document readcons() function

bar(1): explain the items separation better, mention the default separator char

crop(1), memdraw(2): writememimage doesn’t always write compressed images

dial(1): document -o options

factotum(4): fix typos (thanks sirjofri)

games/dmid(1), games/opl3(1): formatting and update for streaming

geometry(2): corrections and improvements

git(1): The/ → The

git(1): fix quoting in .IR

git(1): update example to work with today’s github

gitfs(4): clean up junk in manpage

history(1): update SOURCE, formatting

ip(3): corrections to Udphdr field descriptions

mouse(2): not quite a typo (thanks Alex Musolino)

ndb(6): document “ quoting

ndb(8): document @rattr behaviour for ndb/query -i

nusb(4): document a88179 support (thanks llamaa)

plan9.ini(8): document the *debug option

pushtls(2): client certificates got implemented in 2012

reform(1): fix a missing space char

riow(1): no. I give up trying to understand wtf is wrong with rio

riow(1): provide better examples of how to run it (thanks be0ba)

riow(1): remove window(1) invocation

riow(1): running via window(1) requires rfork n

runecomp(2): clarify audience and history

segment(3): Fix typo

srv(3): improve the example (thanks mcf)

srv(3): provide /srv/clone example

srv(3): use /srv instead of #s in SYNOPSIS

ssh(1): fix usage and document -X flag

ssh(1): relies -> relays (thanks sigrid)

upasfs(4): remove self-reference and drop trailing comma (thanks fig)

zuke(1): replace Beats ‘n Breaks icy url with aNONradio


mkfiles: add ‘mk test’ support

cmd/mkfile: don’t recurse into test/ when looping

cmd/mkfile: make tests depend on cmd build

/lib/dict: improve downloading scripts

/lib/font/bit/vga: ⑨: it looks bad but it is there

/lib/glass: nfc normalize

/lib/namespace: add bind -c #s$srvspec /srv bind

/lib/namespace: bind devtls to /net, mount /root after binding /srv

joker was here

/lib/rob: I find this situation unsatisfactory.

/lib/rsc: “Go is the only software with telemetry you don’t need to worry about.”

/lib/rsc: I am not suggesting that instrumentation be added bsc: My plan is to not do any telemetry on Plan 9.

/lib/rsc: The plan9 port is becoming increasingly difficult to maintain and holds back non-plan9 development.

/lib/theo: I don’t care if code is old.

/lib/theo: The future doesn’t get better if you demand backwards compatibility forever.

/lib/theo: The invention of interrupts was a bad idea.

/lib/troll: Running Rust code on Plan 9 using webassembly

/lib/troll: [9fans] How to access this 9fans group from 9front?

/lib/unicode → /lib/ucd

standard farsi keymap